{"id":2713,"date":"2024-05-18T06:49:35","date_gmt":"2024-05-18T06:49:35","guid":{"rendered":"https:\/\/havana.vatcar.net\/?page_id=2713"},"modified":"2025-01-23T23:59:38","modified_gmt":"2025-01-23T23:59:38","slug":"2713-2","status":"publish","type":"page","link":"https:\/\/havana.vatcar.net\/?page_id=2713","title":{"rendered":"MUHA Stand Allocation"},"content":{"rendered":"\n<iframe loading=\"lazy\" src=\"https:\/\/havana.vatcar.net\/muha-stands-poc.html\" width=\"100%\" height=\"1500\"><\/iframe>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":12,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"<!-- wp:html -->\n<html>\n<link rel=\"icon\" href=\"data:,\">\n<script src=\"https:\/\/ajax.googleapis.com\/ajax\/libs\/jquery\/1.11.1\/jquery.min.js\"><\/script>\n<style>\n    #table_stands {\n      font-family: Arial, Helvetica, sans-serif;\n      margin: 0 auto;\n      min-width: 500px;\n    }\n    #table_stands th {\n      border-bottom: 2px solid black;\n    }\n    #table_stands td:not([colspan=\"3\"]) {\n      padding: 3px 10px;\n    }\n    .apron-id { \n      width: 100%;\n      text-align: center;\n      font-size: larger;\n      padding-top: 20px;\n    }\n    .stand-id {\n      background-color: yellow;\n      color: black;\n      border: 2px solid black;\n      border-radius: 3px;\n      width: 10%;\n      text-align: center;\n      font-size: 1.2em;\n      font-weight: bold;\n    }\n    .stand-sts {\n      border-radius: 3px;\n      min-width: 380px;\n    }\n    .stand-free {\n      background-color: rgba(0, 128, 0, 0.1);\n    }\n    .stand-occupied {\n      background-color: rgba(128, 9, 0, 0.1);\n    }\n    .stand-fits {\n      background-color: black;\n      color: yellow;\n      border: 2px solid yellow;\n      border-radius: 5px;\n      padding: 2px 5px;\n    }\n<\/style>\n<body>\n    <div>\n      <table id=\"table_stands\">\n        <tbody>\n        <\/tbody>\n      <\/table>\n    <\/div>\n<\/body>\n<script>\n  class StandsFactory {\n    constructor(standsJson, filters, options) {\n      if (!standsJson || typeof standsJson !== 'object') {\n        throw new Error('Invalid stands definition provided');\n      }\n      if (!Array.isArray(standsJson.stands)) {\n        throw new Error('Provided stands definition missing stands array');\n      }\n      this.options = { ...options };\n      this._logs = [];\n      this.icao = standsJson.airport?.icao;\n      this._icaoCodes = standsJson.icaoCodes;\n      this._stands = standsJson.stands\n        .filter(stand => stand.lat && stand.lon \n          && (!filters?.apron || filters.apron.includes(stand.apron)) \n          && (!filters?.size || filters.size.includes(stand.size))\n        );\n      if (standsJson.airport?.apronPreference) {\n        this._stands.sort(function(a, b) {\n          const idxa = standsJson.airport.apronPreference.indexOf(a.apron);\n          const idxb = standsJson.airport.apronPreference.indexOf(b.apron);\n          if (idxa < 0 || idxb < 0) {\n            return idxa === idxb ? 0 : (idxa < 0 ? 1 : -1);\n          }\n          return idxa - idxb;\n        });\n      }\n    }\n    getStatus(pilots) {\n      if (!Array.isArray(pilots)) {\n        throw new Error('Invalid pilots list provided');\n      }\n      this.logs.length = 0;\n      pilots = [ ...pilots ];\n      const standsStatus = this._stands.map(std => {\n        const { apron, stand, type, size, fits } = std;\n        let equip = null;\n        for (let i = 0; i < pilots.length; i++) {\n          let pilot = pilots[i];\n          let distMeters = Math.sqrt(Math.pow(Math.abs(std.lat-pilot.latitude)*111, 2)\n            + Math.pow(Math.abs(std.lon-pilot.longitude)*102, 2)) * 1000;\n          if (this.options.debug) {\n            this._logs.push(`distance from apron ${apron} - stand ${stand} to ${pilot.callsign} in meters: ` + distMeters);\n          }\n          if (distMeters <= 25) {\n            equip = { \n              cid: pilot.cid,\n              cs: pilot.callsign, \n              icao: pilot.flight_plan?.aircraft_short || null,\n              arr: pilot.flight_plan?.arrival || null,\n              dep: pilot.flight_plan?.departure || null,\n            };\n            pilots.splice(i, 1);\n            break;\n          }\n        }\n        const fits2 = fits && (Array.isArray(fits) ? fits : this._icaoCodes?.[fits]) || null;\n        return { apron, stand, type, size, fits: fits2, equip };\n      });\n      return standsStatus;\n    }\n    get stands() {\n      return [ ...this._stands ];\n    }\n    get logs() {\n      return this._logs;\n    }\n    static create(standsJson, filters, options) {\n      return new StandsFactory(standsJson, filters, options);\n    }\n  }\n<\/script>\n<script>\n  (function () {\n    const standsUrl = 'https:\/\/miguelarmas.ca\/vatsim\/muha-stands.json';\n    const muhaParkedUrl = 'https:\/\/miguelarmas.ca\/vatsim\/muha-parked.json';\n\n    function populateTableStands(standStatus) {\n      const table = $('#table_stands');\n      table.find('tr').remove();\n      let apron;\n      standStatus.forEach(s => {\n        let status = s.equip ? \n          s.equip.icao ? \n            (`${s.equip.icao} ${s.equip.arr === 'MUHA' ? `arrived from ${s.equip.dep}` : `departing for ${s.equip.arr}`} as ${s.equip.cs} (${s.equip.cid})`) \n            : `${s.equip.cs} (${s.equip.cid})`\n          : 'Available' + (false && s.marks ? ` (${Array.isArray(s.marks) ? s.marks.join('|') : s.marks})` : '');\n        if (s.apron !== apron) {\n          apron = s.apron;\n          table.append($('<tr>').append($('<td>').text('Apron ' + s.apron).addClass('apron-id').attr('colspan', 3)));\n          table.append($('<tr>').append($('<th>').text('Stand')).append($('<th>').text('Status')).append($('<th>').text('Fit Types')));\n        }\n        let row = $('<tr>');\n        row.append($('<td>').text(s.stand).addClass('stand-id'));\n        row.append($('<td>').text(status).addClass('stand-sts').addClass(status.startsWith('Available') ? 'stand-free' : 'stand-occupied'));\n        row.append($('<td>').html(s.fits ? $('<span>').text(s.fits?.join(' ')).addClass('stand-fits') : null));\n        table.append(row);\n      });\n    }\n\n    function updateStandsAvailability() {\n      if (!StandsFactory.muha.stands) {\n        throw new Error('*** ERROR no stand data available, reload page');\n      }\n      $.getJSON(muhaParkedUrl, function(pilots) {\n        if (!pilots) {\n          throw new Error('*** ERROR retrieving parked data');\n        }\n        const standStatus = StandsFactory.muha.getStatus(pilots);\n        populateTableStands(standStatus);\n      })\n      .fail(function() {\n        console.log(\"error loading parked pilots data\");\n      });\n    }\n  \n    $.getJSON(standsUrl, function(data) {\n      if (!data?.stands) {\n        throw new Error('*** ERROR retrieving stands data');\n      }\n      StandsFactory['muha'] = StandsFactory.create(data, {apron: ['1', '2', '3'], size: ['large', 'medium', 'small']}, {_debug: true});\n      updateStandsAvailability();\n    })\n    .fail(function() {\n      console.log(\"error\");\n    });\n  })();\n<\/script>\n<\/html>\n\n<!-- \/wp:html -->","_et_gb_content_width":"1080","footnotes":""},"class_list":["post-2713","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>MUHA Stand Allocation - Havana FIR<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/havana.vatcar.net\/?page_id=2713\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"MUHA Stand Allocation - Havana FIR\" \/>\n<meta property=\"og:url\" content=\"https:\/\/havana.vatcar.net\/?page_id=2713\" \/>\n<meta property=\"og:site_name\" content=\"Havana FIR\" \/>\n<meta property=\"article:modified_time\" content=\"2025-01-23T23:59:38+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/havana.vatcar.net\\\/?page_id=2713\",\"url\":\"https:\\\/\\\/havana.vatcar.net\\\/?page_id=2713\",\"name\":\"MUHA Stand Allocation - Havana FIR\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/havana.vatcar.net\\\/#website\"},\"datePublished\":\"2024-05-18T06:49:35+00:00\",\"dateModified\":\"2025-01-23T23:59:38+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/havana.vatcar.net\\\/?page_id=2713#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/havana.vatcar.net\\\/?page_id=2713\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/havana.vatcar.net\\\/?page_id=2713#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/havana.vatcar.net\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"MUHA Stand Allocation\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/havana.vatcar.net\\\/#website\",\"url\":\"https:\\\/\\\/havana.vatcar.net\\\/\",\"name\":\"Havana FIR\",\"description\":\"Havana Flight Information Region\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/havana.vatcar.net\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"MUHA Stand Allocation - Havana FIR","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/havana.vatcar.net\/?page_id=2713","og_locale":"en_US","og_type":"article","og_title":"MUHA Stand Allocation - Havana FIR","og_url":"https:\/\/havana.vatcar.net\/?page_id=2713","og_site_name":"Havana FIR","article_modified_time":"2025-01-23T23:59:38+00:00","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/havana.vatcar.net\/?page_id=2713","url":"https:\/\/havana.vatcar.net\/?page_id=2713","name":"MUHA Stand Allocation - Havana FIR","isPartOf":{"@id":"https:\/\/havana.vatcar.net\/#website"},"datePublished":"2024-05-18T06:49:35+00:00","dateModified":"2025-01-23T23:59:38+00:00","breadcrumb":{"@id":"https:\/\/havana.vatcar.net\/?page_id=2713#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/havana.vatcar.net\/?page_id=2713"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/havana.vatcar.net\/?page_id=2713#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/havana.vatcar.net\/"},{"@type":"ListItem","position":2,"name":"MUHA Stand Allocation"}]},{"@type":"WebSite","@id":"https:\/\/havana.vatcar.net\/#website","url":"https:\/\/havana.vatcar.net\/","name":"Havana FIR","description":"Havana Flight Information Region","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/havana.vatcar.net\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"_links":{"self":[{"href":"https:\/\/havana.vatcar.net\/index.php?rest_route=\/wp\/v2\/pages\/2713","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/havana.vatcar.net\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/havana.vatcar.net\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/havana.vatcar.net\/index.php?rest_route=\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/havana.vatcar.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2713"}],"version-history":[{"count":5,"href":"https:\/\/havana.vatcar.net\/index.php?rest_route=\/wp\/v2\/pages\/2713\/revisions"}],"predecessor-version":[{"id":2863,"href":"https:\/\/havana.vatcar.net\/index.php?rest_route=\/wp\/v2\/pages\/2713\/revisions\/2863"}],"wp:attachment":[{"href":"https:\/\/havana.vatcar.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2713"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}