var project={"_id":"5a0c9961ab233e8499d665b0","id":"db16ab93345424f8a23ca318aa8ac8cb53fa5ed8","name":"SIMS-Live Ground - Public Site","user":"566ac9850286a8f9080cdd79","description":"Runway trace plotter","created":"2017-07-07T15:35:39.989Z","shared":false,"server":"micro","datafiles":[],"packs":["bootstrap","font-awesome","jquery"],"container":"mainpart","js":{"file":{"type":"","url":"","link":"","message":{"error":true,"text":"File not defined"},"depurl":"https://quipslibistars.s3.amazonaws.com/prod/db16ab93345424f8a23ca318aa8ac8cb53fa5ed8/script.js"},"title":"Javascript","activated":true,"name":"js","linkedtofile":false,"optional":true,"content":"\n$(\"#rwysel button\").click(function(e){\n e.preventDefault()\n window.location.href=window.location.href.split(\"?\")[0]+\"?airport=\"+$(this).attr(\"airport\")\n})\nvar tzones={KATL:{dstOffset: 0, rawOffset: -18000, status: \"OK\", timeZoneId: \"America/New_York\", timeZoneName: \"Eastern Standard Time\"},\nVHHH:{dstOffset: 0, rawOffset: 28800, status: \"OK\", timeZoneId: \"Asia/Hong_Kong\", timeZoneName: \"Hong Kong Standard Time\"},\nSKBO:{dstOffset: 0, rawOffset: -18000, status: \"OK\", timeZoneId: \"America/Bogota\", timeZoneName: \"Colombia Standard Time\"},\nSPJC:{dstOffset: 0, rawOffset: -18000, status: \"OK\", timeZoneId: \"America/Bogota\", timeZoneName: \"Colombia Standard Time\"},\nDXXX:{dstOffset: 0, rawOffset: 0, status: \"OK\", timeZoneId: \"Africa/Lome\", timeZoneName: \"Greenwich Mean Time\"},\nEHAM:{dstOffset: 0, rawOffset: 3600, status: \"OK\", timeZoneId: \"europe\", timeZoneName: \"Paris Time\"}\n}\n\nvar map = L.map('map')\nvar layout,offset=-4*60*60*1000\nvar runways=L.layerGroup()\nL.Control.InfoBox = L.Control.extend({\n onAdd: function(map) {\n return L.DomUtil.get(\"infobox\")\n\n },\n\n onRemove: function(map) {\n // Nothing to do here\n }\n});\n\nL.control.infobox = function(opts) {\n return new L.Control.InfoBox(opts);\n}\n\nL.control.infobox({ position: 'topleft' }).addTo(map);\nvar layers=[]\n\nvar flights={},prevdata\nvar markers=[],idmarkers={}\nvar currentlayer=L.layerGroup()\nvar seperationmarkers={}\nvar runwayseparation={},runwayendtracker={}\nvar runwayactivities={}\ncurrentlayer.addTo(map)\nvar fontcol=\"blue\"\nif (getParameterByName(\"dark\")) {\n\nL.tileLayer('https://{s}.tile.thunderforest.com/transport-dark/{z}/{x}/{y}.png', {\n\tattribution: '© Thunderforest, © OpenStreetMap',\n\tapikey: '',\n\tmaxZoom: 22\n}).addTo(map)\n \nfontcol=\"yellow\"\n}\nelse {\n//L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {\n L.tileLayer('https://a.tile.openstreetmap.org/{z}/{x}/{y}.png', {\n attribution: '© OpenStreetMap contributors'\n}).addTo(map);\n}\nvar airport=\"KATL\"\nif (getParameterByName(\"airport\")) {\nairport=getParameterByName(\"airport\")\n$(\"#rwysel button\").removeClass(\"active\")\n$(\"#rwysel button[airport='\"+airport+\"']\").addClass(\"active\")\n\n}\n\n$.getJSON(\"https://api.anbdata.com/anb/airports/locations/runway-list?callback=?\",\n{airports:airport,api_key:\"7c3cb620-ed23-11e5-a5f9-adff4fb3e3e1\"},\nfunction (res){\n layout=res\nrunways.addTo(map)\n$(layout).each(function(i,v){\n v.layer=L.geoJSON(v.buffered,{style:{color:\"green\"}})\n v.layer.addTo(runways)\n})\n\n$.getJSON(\"https://v4p4sz5ijk.execute-api.us-east-1.amazonaws.com/anbdata/airports/locations/operational-list?callback=?\",\n{airports:airport,api_key:\"7c3cb620-ed23-11e5-a5f9-adff4fb3e3e1\"},\nfunction (airport){\n map.setView([airport[0].latitude, airport[0].longitude], 15);\n $(\"#apname\").text(airport[0].airportName)\n //$.getJSON(\"https://maps.googleapis.com/maps/api/timezone/json\",\n // {location:airport[0].latitude+\",\"+airport[0].longitude,\n // key:\"AIzaSyB0f7gjT--7Tdr0tues0cmUCyb4SvqO80g\",\n // timestamp:Math.round(new Date().getTime()/1000)\n // },\n // function(timezone){\n // console.log(timezone)\n var timezone=tzones[airport[0].airportCode]\n offset=timezone.rawOffset*1000\n init(airport[0].airportCode)\n//})\n\n\n})\n})\n\nfunction init(airport){\nvar exampleSocket = new WebSocket(\"wss://api.anbdata.com:8080\");\n//var exampleSocket = new WebSocket(\"ws://test.anbdata.com:8000\");\n\nexampleSocket.onopen = function (event) {\n setInterval(function(){\n exampleSocket.send(JSON.stringify({start:true,airport:airport}));\n },1000)\n};\n\nfunction drawrunwayend(flight,id){\n var v=runwayendtracker[id]\n if (v) {\n if (v.zone) {\n currentlayer.removeLayer(v.zone)\n currentlayer.removeLayer(v.marker)\n }\n var p=turf.getCoord(turf.nearestPointOnLine(v.line,turf.point([flight.lon,flight.lat])))\n var line=turf.lineString([p,[v.runwayend.lon,v.runwayend.lat]])\n var buf=turf.transformTranslate(turf.buffer(\n line\n ,0.02),0.08,(v.runwayend.heading+90>180?v.runwayend.heading-90:v.runwayend.heading+90))\n var center=turf.getCoord(turf.centroid(buf))\n var dist= Math.round(turf.length(line, {units: 'miles'})*5280);\n var col=(dist>3000?\"green\":(dist>2000?\"orange\":\"red\"))\n if (flight.gs<60) col=\"green\"\n v.zone=L.geoJSON(buf,\n {style:{color:\"purple\",\n fillColor:\"purple\",\n fillOpacity:1\n \n }})\n v.zone.addTo(currentlayer)\n v.marker=L.marker(L.latLng(center[1],center[0]),\n {icon:new L.divIcon({\n className:'my-div-icon2',\n //iconAnchor:[-5,5],\n html:''+\n dist+\" FT\"\n })\n })\n v.marker.addTo(currentlayer)\n }\n}\n\nfunction drawseperation(clock){\n\n\n for (var id in runwayseparation) {\n var v=runwayseparation[id]\n if (v.clock'+\n v.time+\"\"\n })\n })\n v.marker.addTo(currentlayer)\n }\n else {\n v.marker.setIcon(L.divIcon({\n className:'my-div-icon2',\n //iconAnchor:[-5,5],\n html:''+\n v.time+\"\"\n }))\n }\n\n \n }\n \n }\n\n \n}\n\nexampleSocket.onmessage = function (event) {\nvar m=JSON.parse(event.data)\nvar layer=L.layerGroup()\nlayer.addTo(map)\nlayers.push(layer)\nvar clock=(m.data[0]?m.data[0].clock:Math.round(new Date().getTime()/1000)-10*60)\ndrawseperation(clock)\n$(\"#infobox .date\").text(new Date(clock*1000+offset).toISOString().substring(0,19).replace(\"T\",\" \"))\nif (prevdata) {\n var dataids=m.data.map(function(d){return d.id})\n $(prevdata.filter(function(d){return d.gs==0})).each(function(i,v){\n if (dataids.indexOf(v.id)<0&&v.clock>clock-10) m.data.push(v)\n })\n \n}\n\nvar ms=[]\nmarkers.push(ms)\n\n\n\n$(m.data).each(function(i,v){\n var prev=flights[v.id]\n if (prev||v.gs>0) {\n var acc=getacc(v,prev)\n var l=L.circleMarker(L.latLng(v.lat,v.lon),{radius:v.gs/3+5,\n color:getcolor(v,prev),\n fillOpacity:0.2\n})\n var hotcrossing=\"\",rwy\n var textcol=fontcol\n $(layout).each(function(j,u){\n if (turf.inside(turf.point([v.lon,v.lat]),u.buffered)) {\n hotcrossing='yellow'\n rwy=u\n if (!u.occupied) {\n u.occupied=true\n u.occupied_double=false\n u.occupied_clock=clock\n u.occupant=v.id\n u.layer.setStyle({color:\"red\"})\n }\n else if(u.occupant==v.id) {\n u.occupied_clock=clock\n }\n else {\n u.occupied_double=true\n u.occupied_double_clock=clock\n hotcrossing='red'\n u.layer.setStyle({color:\"black\"})\n }\n }\n })\n if (hotcrossing==\"yellow\"&&Math.abs(acc)>2&&v.gs>25) putevent(v,rwy,acc)\n var idmark=L.marker(L.latLng(v.lat,v.lon),\n {icon:new L.divIcon({\n className:'my-div-icon',\n iconAnchor:[-5,5],\n html:''+\n (v.ident&&v.ident.toUpperCase().indexOf(\"UNKNOWN\")<0?v.ident:\"---\")+\"
\"+v.gs+\"kts\"+\"
\"\n })\n })\n if (idmarkers[v.id]) {\n currentlayer.removeLayer(idmarkers[v.id].marker)\n if (idmarkers[v.id].triangle) currentlayer.removeLayer(idmarkers[v.id].triangle)\n }\n idmarkers[v.id]={marker:idmark,clock:v.clock,gs:v.gs}\n idmark.addTo(currentlayer)\n if (hotcrossing!=\"\") {\n drawrunwayend(v,rwy.id)\n var idmark2=L.marker(L.latLng(v.lat,v.lon),\n {icon:new L.divIcon({\n className:'my-div-icon',\n iconAnchor:[-10,30],\n html:''\n })\n })\n idmarkers[v.id].triangle=idmark2\n idmark2.addTo(currentlayer)\n }\n\n\n \n\n l.addTo(layer)\n ms.push(l)\n flights[v.id]=v\n}\n})\nfor (var key in idmarkers) {\n if (idmarkers[key].clock1&&Math.cos(Math.PI*(flight.heading-runway.runway_ends[1].heading)/180)>0.6) {\n rwy=runway.runway_ends[1]\n opposite=runway.runway_ends[0]\n }\n \n if (acc>2) {\n if ($(\"#takeoff\"+flight.id).length==0) {\n def.css(\"text-align\",\"right\")\n def.css(\"color\",\"red\")\n //def.css(\"opacity\",\"0.5\")\n def.find(\".ident\").text(flight.ident+\" RWY \"+rwy.id)\n def.find(\".time\").text(new Date(flight.clock*1000+offset).toISOString().substring(11,19))\n def.attr(\"id\",\"takeoff\"+flight.id)\n if (runwayseparation[runway.id]) {\n if (runwayseparation[runway.id].type==\"landing\") {\n def.append(''+\n runwayseparation[runway.id].time+\"\")\n }\n else {\n def.append(''+\n runwayseparation[runway.id].time+\"\")\n } \n runwayseparation[runway.id].freeze=true\n runwayseparation[runway.id].type=\"takeoff\"\n }\n runwayactivities[runway.id]=\"takeoff\"\n //runwayseparation[rwy.id]={type:\"takeoff\",clock:flight.clock,center:turf.coordAll(turf.centroid(runway.buffered))}\n //def.show()\n $(\"#evlist\").prepend(def)\n def.fadeIn('slow')\n }\n }\n else {\n if ($(\"#landing\"+flight.id).length==0) {\n //console.log(flight)\n //console.log(runway)\n //console.log(Math.cos(flight.heading-runway.runway_ends[1].heading))\n def.css(\"text-align\",\"left\")\n def.css(\"color\",\"blue\")\n //def.css(\"opacity\",\"0.5\")\n def.find(\".ident\").text(flight.ident+\" RWY \"+rwy.id)\n def.find(\".time\").text(new Date(flight.clock*1000+offset).toISOString().substring(11,19))\n def.attr(\"id\",\"landing\"+flight.id)\n runwayactivities[runway.id]=\"landing\"\n runwayendtracker[runway.id]={flight:flight,runwayend:opposite,line:runway.line}\n if (runwayseparation[runway.id]) {\n if (runwayseparation[runway.id].type==\"landing\") {\n def.append(''+\n runwayseparation[runway.id].time+\"\")\n }\n else {\n def.append(''+\n runwayseparation[runway.id].time+\"\")\n }\n runwayseparation[runway.id].freeze=true\n runwayseparation[runway.id].type=\"landing\"\n\n }\n //runwayseparation[rwy.id]={type:\"landing\",clock:flight.clock,center:turf.coordAll(turf.centroid(runway.buffered))}\n //def.show()\n $(\"#evlist\").prepend(def)\n def.fadeIn('slow')\n }\n } \n if ($(\"#evlist p.mainevent\").length>10) {$(\"#evlist p.mainevent:last\").remove();$(\"#ppp\").show()}\n}\n\nfunction getcolor(pos,prev){\nvar acc=getacc(pos,prev)\n if (pos.gs==0) {\n return \"gray\"\n }\n else if (acc<-2) {\n return \"blue\"\n }\n else if (acc>2) {\n return \"red\"\n }\n else {\n return \"orange\"\n }\n}\n\nfunction getacc(pos,prev){\nvar acc\nif (prev) acc=(pos.gs-prev.gs)/(pos.clock-prev.clock)\nreturn acc \n}\nfunction getParameterByName( name ){\n var regexS = \"[\\\\?&]\"+name+\"=([^&]*)\", \n regex = new RegExp( regexS ),\n results = regex.exec( window.location.search );\n if( results == null ){\n return \"\";\n } else{\n return decodeURIComponent(results[1].replace(/\\+/g, \" \"));\n }\n}\n"},"css":{"file":{"type":"","url":"","link":"","message":{"error":true,"text":"File not defined"}},"title":"Cascading Style Sheet (CSS)","activated":true,"name":"css","linkedtofile":false,"optional":true,"content":".my-div-iconyellow {\n background-color:yellow;\n}\n.my-div-iconred {\n background-color:red;\n}\n"},"jade":{"file":{"type":"","url":"","link":"","message":{"error":true,"text":"File not defined"},"depurl":"https://quipslibistars.s3.amazonaws.com/prod/db16ab93345424f8a23ca318aa8ac8cb53fa5ed8/main.jade"},"title":"Jade","activated":true,"name":"jade","linkedtofile":false,"optional":false,"content":".container(style=\"width:1300px\")\n p#rwysel Connect to the airport of \n button.btn.btn-info.active(airport=\"KATL\") Atlanta (USA)\n button.btn.btn-info(airport=\"VHHH\") Hong-Kong (China SAR)\n button.btn.btn-info(airport=\"SKBO\") Bogota (Colombia)\n button.btn.btn-info(airport=\"DXXX\") Lomé (Togo)\n button.btn.btn-info(airport=\"EHAM\") Amsterdam (Netherlands)\n button.btn.btn-info(airport=\"SPJC\") Lima (Peru)\n hr \n \n \n #map(style=\"width:1300px;height:700px;left:-200px\")\n#infobox.alert.alert-warning(style=\"width:200px\")\n .title.text-center\n h4#apname Atlanta Airport\n p\n em.date=new Date().toISOString().substring(0,19)\n span Local Time (LT)\n .row\n .col-md-6(style=\"text-align:left;color:blue\") Landings\n .col-md-6(style=\"text-align:right;color:red\") Takeoffs\n hr\n #evlist\n p.default(style=\"text-align:right;font-weight:bold;display:none\",flightid=\"yy\")\n span.ident AB202 Take-Off RWY07L\n br\n em.time(style=\"font-weight:normal;font-size:10px;\") 11:01:01 LT\n p#ppp(style=\"text-align:center;font-weight:bold;display:none;font-size:25px\") ...\n"},"morejs":[{"url":"https://unpkg.com/leaflet@1.0.2/dist/leaflet.js"},{"url":"https://s3.amazonaws.com/istarsshare/sims.js"},{"url":"https://npmcdn.com/@turf/turf/turf.min.js"}],"morecss":[{"url":"https://unpkg.com/leaflet@1.0.2/dist/leaflet.css"}],"capture":"https://quipslibistars.s3.amazonaws.com/prod/db16ab93345424f8a23ca318aa8ac8cb53fa5ed8/capture.png","prod":true,"sharedwith":["57dfeb1654955f1127d5672b"],"deploydate":"2018-02-27T14:13:39.000Z","libs":[{"_id":"5672b285f36b083214f3e63b","description":"A sleek, intuitive, and powerful mobile first front-end framework for faster and easier web development.","key":"","version":"3.3.6","link":"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css,https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css,https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js","name":"bootstrap","__v":0,"haskey":false,"required":false,"website":"http://www.getbootstrap.com"},{"_id":"5672b3e0f36b083214f3e63d","description":"","key":"","version":"4.5.0","link":"https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css","name":"font-awesome","__v":0,"haskey":false,"required":false,"website":"fontawesome.com"},{"_id":"5672b602f36b083214f3e63e","description":"The Write Less, Do More, JavaScript Library","key":"","version":"2.1.1","link":"https://code.jquery.com/jquery-2.1.4.js","name":"jquery","__v":0,"required":true,"haskey":false,"website":"https://jquery.com"}],"host":"https://quips.anbdata.com","version":"prod"} function loadjquery(url,callback) { if(typeof jQuery=='undefined') { loadScript(url,callback) } else { callback() } } function loadScript(url, callback) { var script = document.createElement("script") script.type = "text/javascript"; if (script.readyState) { //IE script.onreadystatechange = function () { if (script.readyState == "loaded" || script.readyState == "complete") { script.onreadystatechange = null; callback(); } }; } else { //Others script.onload = function () { callback(); }; } script.src = url; document.getElementsByTagName("head")[0].appendChild(script); } (function () { loadjquery("https://code.jquery.com/jquery-2.1.4.js", function () { //jQuery loaded $("#"+project.container).html("") var libs=[] $(project.libs).each(function(i,v){ if (v.name!="jquery") { $(v.link.split(",")).each(function(j,u){ if (u.slice(-2)=="js") { libs.push(u+(v.haskey?"?key="+project[v.name+"key"]:"")) } else { $("head").append("") } }) } }) if (project.morejs) { $(project.morejs).each(function(i,v){ if ((v.url.substring(0,2)=="//")||(v.url.substring(0,8)=="https://")||(v.url.substring(0,7)=="http://")) { libs.push(v.url) } }) } if (project.morecss) { $(project.morecss).each(function(i,v){ $("head").append("") }) } loadlibs(libs.reverse()) }); })(); function loadlibs(libs){ if (libs.length>0) { var l=libs.pop() loadScript(l,function(){ //$.getScript(l,function(res){ loadlibs(libs) }) //.fail(function(e){ // loadlibs(libs) // //}) } else { start() } } function putscriptcontent(content){ var script = document.createElement("script") script.type = "text/javascript"; $(script).text(content) document.getElementsByTagName("head")[0].appendChild(script); } function start(){ //load jade $.getJSON(project.host+"/project/"+project.version+"/"+project.id+"/render?callback=?"+(project.datachange?"&data="+project.datachange:""),function(res){ $("#"+project.container).html(res.html) if (project.css.activated) { if (project.css.linkedtofile) { $("head").append("")} else { $("head").append("")} } if (project.js.activated) { if (project.js.linkedtofile) { $.getScript(project.js.file[(project.prod?"depurl":"url")])} else { putscriptcontent(project.js.content)} if (project.mainjs) { window[project.mainjs]() } } }) }