var project={"_id":"5c7682c3ab233e8499c7b2d9","id":"17d459744b96d9a2ae0c72f8c038a06359cc62a7","name":"Public Contingency Planning Aid","user":"566ac9850286a8f9080cdd79","description":"","created":"2017-01-12T22:12:10.308Z","shared":false,"server":"micro","datafiles":[{"file":{"link":"https://v4p4sz5ijk.execute-api.us-east-1.amazonaws.com/anbdata/airspaces/zones/fir-list?api_key=7c3cb620-ed23-11e5-a5f9-adff4fb3e3e1&format=json","type":"URL/API","url":"https://v4p4sz5ijk.execute-api.us-east-1.amazonaws.com/anbdata/airspaces/zones/fir-list?api_key=7c3cb620-ed23-11e5-a5f9-adff4fb3e3e1&format=json","message":{"error":false,"text":""}},"varname":"FIRs","title":"FIRs","activated":true,"name":"datafile","linkedtofile":true,"optional":true,"content":"","sendtojs":true}],"packs":["jquery","D3","highstock"],"container":"mainpart","js":{"file":{"type":"","url":"","link":"","message":{"error":true,"text":"File not defined"},"depurl":"https://quipslibistars.s3.amazonaws.com/prod/17d459744b96d9a2ae0c72f8c038a06359cc62a7/script.js"},"title":"Javascript","activated":true,"name":"js","linkedtofile":false,"optional":true,"content":"//check if loaded\nvar thisuseremail=\"mmerens@icao.int\"\nif (typeof(getEmail)==\"function\") {\n getEmail(function(e){\n thisuseremail=e\n $(\"#email\").val(thisuseremail)\n })\n $(\"#emailbox\").hide()\n}\nif (getParameterByName(\"withprint\")) $(\"#nopdf\").show()\nif (getParameterByName(\"print\")) {\n $(\".printit\").hide()\n \n var options=JSON.parse(getParameterByName(\"options\"))\n $(options).each(function(i,v){\n if (v.value==\"checked\") {\n $(\"#\"+v.element).attr(\"checked\",true)\n }\n else if (v.value==\"unchecked\") {\n $(\"#\"+v.element).attr(\"checked\",false)\n }\n else {\n $(\"#\"+v.element).val(v.value)\n }\n })\n \n \n \n}\n\nvar map = L.map('map').setView([20, 10], 2);\nvar simmap = L.map('simmap').setView([20, 10], 2);\nL.control.scale().addTo(map); \n//length\nL.control.scale().addTo(simmap); \n\nvar currentfir,currentfirlayer,currentfirlayer2,currentfirnb,flightlayer,overlayer,inoutlayer,internallayer,\n fullfirlayer,statistics\nvar smallbuffer,bigbuffer\nvar markers={\n all:L.markerClusterGroup({iconCreateFunction: fc}),\n over:L.markerClusterGroup({iconCreateFunction: fc}),\n inout:L.markerClusterGroup({iconCreateFunction: fc})}\n//var t1=FIRs.filter(function(d){return d.properties.FIRname==\"FIR ISTANBUL\"})[0]\n//var t2=FIRs.filter(function(d){return d.properties.FIRname==\"FIR ANKARA\"})[0]\n//var t3=turf.union(t1,t2)\n//console.log(JSON.stringify(t3))\nvar flights,inters,simrec,simlayer,nextlayer,therec,smallrec,plusdist,nextfirs\nvar color={over:\"orange\",inout:\"green\",internal:\"red\",sim:\"green\"}\n\n/*\nL.tileLayer('https://{s}.tile.osm.org/{z}/{x}/{y}.png', {\n attribution: '© OpenStreetMap contributors'\n}).addTo(map);\nL.tileLayer('https://{s}.tile.osm.org/{z}/{x}/{y}.png', {\n attribution: '© OpenStreetMap contributors'\n}).addTo(simmap);\n*/\nL.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {\n attribution: '© OpenStreetMap contributors'\n}).addTo(map);\nL.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {\n attribution: '© OpenStreetMap contributors'\n}).addTo(simmap);\n\nsimlayer=L.layerGroup()\nsimlayer.addTo(simmap)\n\nflightlayer=L.layerGroup()\nflightlayer.addTo(map)\noverlayer=L.layerGroup()\noverlayer.addTo(map)\nnextlayer=L.layerGroup()\nnextlayer.addTo(simmap)\noverlayer2=L.layerGroup()\n//overlayer2.addTo(simmap)\ninoutlayer=L.layerGroup()\nfullfirlayer=L.layerGroup()\ninoutlayer.addTo(map)\ninternallayer=L.layerGroup()\ninternallayer.addTo(map)\nmap.addLayer(markers.all);\n\n\n $(FIRs).each(function(i,u){\n //if (currentfir.properties.ICAOCODE!=u.properties.ICAOCODE) {\n fullfirlayer.addLayer(L.geoJSON(u.geometry,\n {fillOpacity:0,opacity:0.5,code:u.properties.ICAOCODE})\n .bindPopup(u.properties.FIRname+\" (\"+u.properties.ICAOCODE+\")\"))\n //}\n })\n\n\n\ndraw()\n\n$(\"#editzones\").click(function(e){\n e.preventDefault()\n $(\"#customzone\").modal()\n})\n\n\nfunction fc(cluster) {\n var ids=[]\n var allmarkers = cluster.getAllChildMarkers();\n var childCount=0\n for (var i = 0; i < allmarkers.length; i++) {\n if(ids.indexOf(allmarkers[i].id)<0) {\n childCount++\n ids.push(allmarkers[i].id)\n }\n }\n var c = ' marker-cluster-';\n\t\tif (childCount < 10) {\n\t\t\tc += 'small';\n\t\t} else if (childCount < 100) {\n\t\t\tc += 'medium';\n\t\t} else {\n\t\t\tc += 'large';\n\t\t}\n\n\t\treturn new L.DivIcon({ html: '
' + childCount + '
', className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) });\n }\n\n$(\"#hotspots\").click(function(e){\n if ($(this).is(\":checked\")) {\n var val=$(\"#tftoggle .active input\").val()\n if (val!=\"internal\") {\n markers[val].addTo(map)\n }\n }\n else {\n map.removeLayer(markers.over)\n map.removeLayer(markers.inout)\n map.removeLayer(markers.all)\n }\n})\n\n$(\"#showallfirs\").click(function(e){\n if ($(this).is(\":checked\")) {\n map.addLayer(fullfirlayer)\n }\n else {\n map.removeLayer(fullfirlayer)\n }\n})\n\n\n\nfunction drawweekly(wstats){\n wstats.sort(function(a,b){return (a.dateIn \"+$(\"#theyear\").val()+\", \"+$(\"#mainfirname\").text()+\" handled approximatly \"+statistics.total+\" daily flights. \"\n s+=\"The largest proportion of traffic is coming from \"+data[0].type+\" with \"\n +Math.round(1000*data[0].traffic/statistics.total)/10+\"% of total traffic. There are around \"+\n statistics.overflights+\" overflights per day accounting for a total distance flown of \"+\n Math.round(statistics.overflight_distance_nm)+\" nm.

\"\n s+=\"

\"+Math.round(10*statistics.avoidance_pc)/10+\"% of flights seem to avoid overflying the \"+$(\"#mainfirname\").text()+\n \", as their shortest route would normally make them overfly this zone.

\"\n return s\n}\nfunction buildflights(res){\n markers.all.clearLayers()\n markers.over.clearLayers()\n markers.inout.clearLayers()\n map.removeLayer(markers.over)\n map.removeLayer(markers.inout)\n map.removeLayer(markers.all)\n\n //console.log(res[0])\n $(res.filter(function(d){return d.flight_type!=\"internal\"&&d.flight_type!=\"avoidance\"})).each(function(i,v){\n v.id=i\n addcluster(v,v.flight_type)\n })\n \n \n if ($(\"#hotspots\").is(\":checked\")) {\n var val=$(\"#tftoggle .active input\").val()\n if (val!=\"internal\") {\n markers[val].addTo(map)\n }\n \n }\n\n}\n\nfunction addnextlayers() {\n nextlayer.clearLayers()\n nextfirs={}\n $(FIRs).each(function(i,v){\n if (v.properties.ICAOCODE!=currentfir.properties.ICAOCODE) {\n if (v.geometry.type==\"MultiPolygon\") {\n if (multisect(v.geometry,therec)) {\n nextfirs[v.properties.ICAOCODE]=v\n nextlayer.addLayer(L.geoJSON(v.geometry,\n {fillColor:\"yellow\",color:\"orange\",opacity:0.5,code:v.properties.ICAOCODE})\n .bindPopup(v.properties.FIRname+\" (\"+v.properties.ICAOCODE+\")\")\n )\n }\n\n }\n else {\n if (turf.intersect(v.geometry,therec)) {\n nextfirs[v.properties.ICAOCODE]=v\n nextlayer.addLayer(L.geoJSON(v.geometry,\n {fillColor:\"yellow\",color:\"orange\",opacity:0.5,code:v.properties.ICAOCODE})\n .bindPopup(v.properties.FIRname+\" (\"+v.properties.ICAOCODE+\")\")\n )\n }\n }\n }\n })\n}\nfunction multisect(polys,layer){\n var s=0\n $.each(polys.coordinates,function(i,poly){\n if (turf.intersect({type:\"Polygon\",coordinates:poly},layer)) {\n s++\n }\n })\n return (s>0)\n}\n\n\nfunction buildsimflights3(){\n var fir=$(\"#zone\").val()\n var theyear=$(\"#theyear\").val()\n simlayer.clearLayers()\n $.getJSON(\"https://api.anbdata.com/anb/airspaces/traffic/fir-closure-trajectory-list?callback=?\",\n //$.getJSON(\"http://test.anbdata.com:8000/anb/airspaces/traffic/fir-closure-trajectory-list?callback=?\",\n {api_key:\"7c3cb620-ed23-11e5-a5f9-adff4fb3e3e1\",year:theyear,fir:fir},\n function(simulatedtrajectories){\n $(simulatedtrajectories).each(function(i,v){\n \n \n /*\n var ll=L.geodesic([], {\n \t //weight: 7,\n \t opacity: 0.2,\n \t color: color.sim,\n \t steps: 50,\n \t wrap: false\n }).addTo(simlayer)\n ll.geoJson(v.newline)\n */\n simlayer.addLayer(L.geoJSON(v.newline,{color:color.sim,opacity:0.2}))\n })\n \n })\n \n $(\"#totdist\").text(Math.round(statistics.total_delta_distance_nm)+\" nm\")\n $(\"#avdist\").text(Math.round(statistics.av_delta_distance_nm)+\" nm\")\n}\n\nfunction drawnextfirs(){\n var c=[]\n var total=0\n $(statistics.closure_impact.filter(function(d){return d.delta!=0}))\n .each(function(i,v){\n c.push({code:v.FIRCode,\n name:FIRs.filter(function(q){return q.properties.ICAOCODE==v.FIRCode})[0].properties.FIRname,\n flights:v.flights,\n delta:Math.round(100*v.delta)/100})\n total+=Math.abs(v.flights)\n })\n /*\n for (var key in nextfirs) {\n if (nextfirs[key].properties.delta!=0) {\n c.push({code:nextfirs[key].properties.ICAOCODE,\n name:nextfirs[key].properties.FIRname,\n delta:nextfirs[key].properties.delta\n })\n }\n } \n */\n c.sort(function(a,b){return b.delta-a.delta})\n var min=c[c.length-1].delta\n var max=c[0].delta\n \n var colorScale = d3.scale.linear().domain([min,0,max]).range([\"blue\",\"white\",\"red\"]);\n\n chart2.xAxis.categories=[]\n chart2.series[0].data=[]\n chart2.series[1].data=[]\n $.each(c,function(i,v){\n chart2.xAxis.categories.push(v.name+\" (\"+v.code+\")\")\n chart2.series[0].data.push({y:v.delta,color:colorScale(v.delta)})\n chart2.series[1].data.push({y:Math.round(1000*v.flights/statistics.overflights)/10})\n \n })\n nextlayer.eachLayer(function (layer) {\n var col=c.filter(function(d){return d.code==layer.options.code})[0]\n layer.setStyle({fillColor :colorScale((col?col.delta:0))})\n });\n\n $(\"#chart2\").highcharts(chart2)\n $(\"#pcfir\").text(c[0].name+\" (\"+c[0].code+\")\")\n $(\"#pcincrease\").text(Math.round(10*c[0].delta)/10)\n \n c.sort(function(a,b){return b.flights-a.flights})\n $(\"#firstfir\").text(c[0].name+\" (\"+c[0].code+\")\")\n $(\"#firstfirpart\").text(Math.round(1000*c[0].flights/statistics.overflights)/10)\n $(\"#firstfirpc\").text(c[0].flights)\n //console.log(c[0])\n //console.log(chart2.series)\n \n}\nfunction addcluster(v,ty){\n var p=turf.intersect(currentfir.geometry,v.line)\n if (p&&p.geometry.type==\"LineString\") {\n var f=L.marker(L.GeoJSON.coordsToLatLng(p.geometry.coordinates[0]))\n var l=L.marker(L.GeoJSON.coordsToLatLng(p.geometry.coordinates[p.geometry.coordinates.length-1]))\n //l.bindPopup(\"Flight \"+v.ident+\"
\"+v.orig+\" to \"+v.dest)\n //f.bindPopup(\"Flight \"+v.ident+\"
\"+v.orig+\" to \"+v.dest)\n f.id=v.id\n l.id=v.id\n if (ty==\"overflight\") {\n markers.over.addLayer(f);\n markers.over.addLayer(l);\n markers.all.addLayer(f);\n markers.all.addLayer(l);\n }\n else if (ty==\"inout\"&&turf.inside(turf.point(v.line.coordinates[0]),currentfir)) {\n markers.inout.addLayer(l);\n markers.all.addLayer(l);\n \n }\n else {\n markers.inout.addLayer(f);\n markers.all.addLayer(f);\n \n }\n }\n}\n\n\n$(\".gogo\").change(function(e){\n e.preventDefault()\n draw()\n})\n$(\"#tftoggle button\").click(function(e){\n e.preventDefault()\n $(\"#tftoggle button\").removeClass(\"active\" )\n $(this).addClass(\"active\")\n \n map.removeLayer(overlayer)\n map.removeLayer(inoutlayer)\n map.removeLayer(internallayer)\n map.removeLayer(markers.over)\n map.removeLayer(markers.all)\n map.removeLayer(markers.inout)\n if ($(this).find(\"input\").val()==\"over\") {\n overlayer.addTo(map)\n if ($(\"#hotspots\").is(\":checked\")) {\n markers.over.addTo(map)\n }\n }\n else if ($(this).find(\"input\").val()==\"inout\") {\n inoutlayer.addTo(map)\n if ($(\"#hotspots\").is(\":checked\")) {\n markers.inout.addTo(map)\n }\n \n }\n else if ($(this).find(\"input\").val()==\"internal\") {\n internallayer.addTo(map)\n }\n else {\n if ($(\"#hotspots\").is(\":checked\")) {\n\n markers.all.addTo(map)\n }\n overlayer.addTo(map)\n inoutlayer.addTo(map)\n internallayer.addTo(map)\n }\n \n \n})\n\nvar chart1={\n chart: {\n type: 'bar'\n },\n title: {\n text: ''\n },\n subtitle: {\n text: 'Traffic Distribution'\n },\n xAxis: {\n categories: ['Overflights', 'In/Out', 'Internal'],\n title: {\n text: null\n }\n },\n yAxis: {\n min: 0,\n max:100,\n title: {\n text: 'Daily Flights (%)'\n },\n labels: {\n overflow: 'justify',\n format:\"{value}%\"\n }\n },\n\n plotOptions: {\n series: {\n dataLabels: {\n enabled: true,\n format:\"{y}%\"\n }\n }\n },\n legend:{enabled:false},\n credits: {\n enabled: false\n },\n series: [{\n name: '',\n data: []\n }]\n }\nvar chart2={\n chart: {\n type: 'column'\n },\n title: {\n text: 'Change of workload per FIR'\n },\n subtitle: {\n text: ''\n },\n xAxis: {\n categories: [],\n title: {\n text: null\n }\n },\n\n yAxis: [{\n title: {\n text: 'Workload Change (%)'\n },\n labels: {\n overflow: 'justify',\n format:\"{value}%\"\n }\n }],\n\n \n legend:{enabled:true},\n credits: {\n enabled: false\n },\n tooltip:{\n valueSuffix:\"%\"\n },\n series: [{\n \n name: 'Impact on workload',\n data: []\n },\n {\n name: 'Traffic received/lost per rerouted traffic',\n color:\"lightgray\",\n type:\"line\",\n //dashStyle:\"LongDash\",\n data: []\n }]\n }\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\n$(\"#sendpdf\").click(function(e){\n \n e.preventDefault()\n \n thisuseremail=$(\"#email\").val()\n if (!thisuseremail) {\n alert(\"No valid email provided\")\n }\n else {\n \n var options=[]\n options.push({element:\"theyear\",value:$(\"#theyear\").val()})\n options.push({element:\"zone\",value:$(\"#zone\").val()})\n /*\n options.push({element:\"act\",value:($(\"#act\").is(\":checked\")?\"checked\":\"unchecked\")})\n options.push({element:\"fullssp\",value:($(\"#fullssp\").is(\":checked\")?\"checked\":\"unchecked\")})\n options.push({element:\"areasel2\",value:$(\"#areasel2\").val()})\n options.push({element:\"areasel\",value:$(\"#areasel\").val()})\n options.push({element:\"sort\",value:$(\"#sort\").val()})\n options.push({element:\"shownames\",value:($(\"#shownames\").is(\":checked\")?\"checked\":\"unchecked\")})\n options.push({element:\"showvals\",value:($(\"#showvals\").is(\":checked\")?\"checked\":\"unchecked\")})\n */\n\n //console.log(\"http://quips.anbdata.com/project/prod/016e106a6534385aae0c06049cd1d1545e044c04.html?print=true&options=\"+encodeURI(JSON.stringify(options)))\n //$.getJSON(\"https://v4p4sz5ijk.execute-api.us-east-1.amazonaws.com/anbdata/services/genpdf?callback=?\",\n $.getJSON(\"https://api.anbdata.com/anb/services/genpdfv2?callback=?\",\n {file:\"http://quips.anbdata.com/project/prod/016e106a6534385aae0c06049cd1d1545e044c04.html?print=true&options=\"+JSON.stringify(options),\n key:$(\"#zone\").val()+\"/\"+Math.round(new Date().getTime()/1000)+\"/contingencyplan.pdf\",\n header:\"Contingency Plan report for \"+$(\"#mainfirname\").text(),\n email:thisuseremail},function(res){\n \n })\n alert(\"The print request was sent. An email with the report will arrive in your mailbox.\")\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":".ph {\n background-color:#0055A5 !important;;\n color:white;\n}\n.card {\n border-color:#0055A5 !important;\n}\n.label-primary {\n background-color:#0055A5 !important;\n}"},"jade":{"file":{"type":"","url":"","link":"","message":{"error":true,"text":"File not defined"},"depurl":"https://quipslibistars.s3.amazonaws.com/prod/17d459744b96d9a2ae0c72f8c038a06359cc62a7/main.jade"},"title":"Jade","activated":true,"name":"jade","linkedtofile":false,"optional":false,"content":".container(style=\"width:950px\")\n - var statenames=[]\n - FIRs.forEach(function(v){if (statenames.indexOf(v.properties.StateName)<0) statenames.push(v.properties.StateName)})\n p.printit Select an airspace \n select#zone.gogo\n optgroup(label=\"FIRs\",type=\"fir\")\n for state in statenames.sort()\n optgroup(label=state,type=\"fir\")\n for fir in FIRs.sort(function(a,b){return (a.properties.FIRname") 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]() } } }) }