Merge branch 'master' of gitorious.org:fg/fgdata
This commit is contained in:
commit
5a4195d15e
5 changed files with 3436 additions and 24 deletions
3137
webgui/3rdparty/flot/jquery.flot.js
vendored
Normal file
3137
webgui/3rdparty/flot/jquery.flot.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
60
webgui/3rdparty/flot/jquery.flot.resize.js
vendored
Normal file
60
webgui/3rdparty/flot/jquery.flot.resize.js
vendored
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/* Flot plugin for automatically redrawing plots as the placeholder resizes.
|
||||||
|
|
||||||
|
Copyright (c) 2007-2013 IOLA and Ole Laursen.
|
||||||
|
Licensed under the MIT license.
|
||||||
|
|
||||||
|
It works by listening for changes on the placeholder div (through the jQuery
|
||||||
|
resize event plugin) - if the size changes, it will redraw the plot.
|
||||||
|
|
||||||
|
There are no options. If you need to disable the plugin for some plots, you
|
||||||
|
can just fix the size of their placeholders.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Inline dependency:
|
||||||
|
* jQuery resize event - v1.1 - 3/14/2010
|
||||||
|
* http://benalman.com/projects/jquery-resize-plugin/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 "Cowboy" Ben Alman
|
||||||
|
* Dual licensed under the MIT and GPL licenses.
|
||||||
|
* http://benalman.com/about/license/
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function($,t,n){function p(){for(var n=r.length-1;n>=0;n--){var o=$(r[n]);if(o[0]==t||o.is(":visible")){var h=o.width(),d=o.height(),v=o.data(a);!v||h===v.w&&d===v.h?i[f]=i[l]:(i[f]=i[c],o.trigger(u,[v.w=h,v.h=d]))}else v=o.data(a),v.w=0,v.h=0}s!==null&&(s=t.requestAnimationFrame(p))}var r=[],i=$.resize=$.extend($.resize,{}),s,o="setTimeout",u="resize",a=u+"-special-event",f="delay",l="pendingDelay",c="activeDelay",h="throttleWindow";i[l]=250,i[c]=20,i[f]=i[l],i[h]=!0,$.event.special[u]={setup:function(){if(!i[h]&&this[o])return!1;var t=$(this);r.push(this),t.data(a,{w:t.width(),h:t.height()}),r.length===1&&(s=n,p())},teardown:function(){if(!i[h]&&this[o])return!1;var t=$(this);for(var n=r.length-1;n>=0;n--)if(r[n]==this){r.splice(n,1);break}t.removeData(a),r.length||(cancelAnimationFrame(s),s=null)},add:function(t){function s(t,i,s){var o=$(this),u=o.data(a);u.w=i!==n?i:o.width(),u.h=s!==n?s:o.height(),r.apply(this,arguments)}if(!i[h]&&this[o])return!1;var r;if($.isFunction(t))return r=t,s;r=t.handler,t.handler=s}},t.requestAnimationFrame||(t.requestAnimationFrame=function(){return t.webkitRequestAnimationFrame||t.mozRequestAnimationFrame||t.oRequestAnimationFrame||t.msRequestAnimationFrame||function(e,n){return t.setTimeout(e,i[f])}}()),t.cancelAnimationFrame||(t.cancelAnimationFrame=function(){return t.webkitCancelRequestAnimationFrame||t.mozCancelRequestAnimationFrame||t.oCancelRequestAnimationFrame||t.msCancelRequestAnimationFrame||clearTimeout}())})(jQuery,this);
|
||||||
|
|
||||||
|
(function ($) {
|
||||||
|
var options = { }; // no options
|
||||||
|
|
||||||
|
function init(plot) {
|
||||||
|
function onResize() {
|
||||||
|
var placeholder = plot.getPlaceholder();
|
||||||
|
|
||||||
|
// somebody might have hidden us and we can't plot
|
||||||
|
// when we don't have the dimensions
|
||||||
|
if (placeholder.width() == 0 || placeholder.height() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
plot.resize();
|
||||||
|
plot.setupGrid();
|
||||||
|
plot.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindEvents(plot, eventHolder) {
|
||||||
|
plot.getPlaceholder().resize(onResize);
|
||||||
|
}
|
||||||
|
|
||||||
|
function shutdown(plot, eventHolder) {
|
||||||
|
plot.getPlaceholder().unbind("resize", onResize);
|
||||||
|
}
|
||||||
|
|
||||||
|
plot.hooks.bindEvents.push(bindEvents);
|
||||||
|
plot.hooks.shutdown.push(shutdown);
|
||||||
|
}
|
||||||
|
|
||||||
|
$.plot.plugins.push({
|
||||||
|
init: init,
|
||||||
|
options: options,
|
||||||
|
name: 'resize',
|
||||||
|
version: '1.0'
|
||||||
|
});
|
||||||
|
})(jQuery);
|
4
webgui/3rdparty/jquery/jquery-1.11.0.min.js
vendored
Normal file
4
webgui/3rdparty/jquery/jquery-1.11.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
86
webgui/lib/jquery.flot.prop.js
Normal file
86
webgui/lib/jquery.flot.prop.js
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
(function ($) {
|
||||||
|
function init(plot) {
|
||||||
|
|
||||||
|
function optionProcessor(plot, options) {
|
||||||
|
}
|
||||||
|
|
||||||
|
plot.hooks.processOptions.push(optionProcessor);
|
||||||
|
|
||||||
|
var presample = { x: 0, y: 0, n: 0 };
|
||||||
|
|
||||||
|
plot.plotPropertyNode = function(n) {
|
||||||
|
var maxData = Math.floor(this.width() / 2);
|
||||||
|
if( maxData < 10 ) return;
|
||||||
|
|
||||||
|
var probeWidth = this.getOptions().historyLength / maxData;
|
||||||
|
var x = Math.floor(n.ts/probeWidth)*probeWidth;
|
||||||
|
var y = n.value * 1.0;
|
||||||
|
|
||||||
|
// first call
|
||||||
|
if( presample.n == 0 ) {
|
||||||
|
presample.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// same period as previous call?
|
||||||
|
if( x == presample.x ) {
|
||||||
|
// sum up the sample
|
||||||
|
presample.y += y;
|
||||||
|
presample.n++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sampledY = presample.y/presample.n;
|
||||||
|
var sampledX = presample.x;
|
||||||
|
|
||||||
|
// start sample next period
|
||||||
|
presample.x = x;
|
||||||
|
presample.y = y;
|
||||||
|
presample.n = 1;
|
||||||
|
|
||||||
|
var series = this.getData();
|
||||||
|
var data;
|
||||||
|
for( var seriesNumber = 0;
|
||||||
|
seriesNumber < series.length;
|
||||||
|
seriesNumber++ ) {
|
||||||
|
if( n.path == series[seriesNumber].propertyPath ) {
|
||||||
|
data = series[seriesNumber].data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ! data ) return;
|
||||||
|
|
||||||
|
data.push([sampledX, sampledY]);
|
||||||
|
|
||||||
|
var toomany = data.length - maxData;
|
||||||
|
if (toomany > 0) {
|
||||||
|
// slice returns a new array, so set series data
|
||||||
|
series[seriesNumber].data = data.slice(toomany);;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setData(series);
|
||||||
|
|
||||||
|
if( data.length >= 2 ) {
|
||||||
|
var xaxis = this.getAxes().xaxis;
|
||||||
|
var v = Math.ceil(data[data.length-1][0]);
|
||||||
|
v = Math.ceil(v/5)*5;
|
||||||
|
xaxis.options.max = v;
|
||||||
|
xaxis.options.min = xaxis.options.max - this.getOptions().historyLength;
|
||||||
|
var yaxis = this.getAxes().yaxis;
|
||||||
|
yaxis.options.min = Math.floor(yaxis.datamin);
|
||||||
|
yaxis.options.max = Math.ceil(yaxis.datamax);
|
||||||
|
this.setupGrid();
|
||||||
|
}
|
||||||
|
this.draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = { historyLength: 60 };
|
||||||
|
|
||||||
|
$.plot.plugins.push({
|
||||||
|
init: init,
|
||||||
|
options: options,
|
||||||
|
name: "propflot",
|
||||||
|
version: "0.1"
|
||||||
|
});
|
||||||
|
})(jQuery);
|
|
@ -1,16 +1,20 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<script src="http://code.jquery.com/jquery-1.11.0.js"
|
<script src="../3rdparty/jquery/jquery-1.11.0.min.js"
|
||||||
type="text/javascript"></script>
|
type="text/javascript"></script>
|
||||||
<link rel="stylesheet"
|
<link rel="stylesheet"
|
||||||
href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
|
href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
|
<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
|
||||||
|
<script
|
||||||
|
src="../3rdparty/flot/jquery.flot.js"></script>
|
||||||
<script src="../lib/props.js" type="text/javascript"></script>
|
<script src="../lib/props.js" type="text/javascript"></script>
|
||||||
|
<script src="../lib/jquery.flot.prop.js"></script>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="description" content="FlightGear - Map" />
|
<meta name="description" content="FlightGear - Map" />
|
||||||
<meta name="viewport"
|
<meta name="viewport"
|
||||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||||
|
<title>FlightGear - Map</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<style>
|
<style>
|
||||||
|
@ -39,13 +43,56 @@ html,body,#map {
|
||||||
}
|
}
|
||||||
|
|
||||||
.followAircraft {
|
.followAircraft {
|
||||||
background: white;
|
background: white;
|
||||||
background: rgba(255, 255, 255, 0.8);
|
background: rgba(255, 255, 255, 0.8);
|
||||||
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.altitudePlotter {
|
||||||
|
background: white;
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
|
||||||
|
border-radius: 5px;
|
||||||
|
width: 1200px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.axisLabel {
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yaxisLabel {
|
||||||
|
top: 50%;
|
||||||
|
left: 2px;
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
-o-transform: rotate(-90deg);
|
||||||
|
-ms-transform: rotate(-90deg);
|
||||||
|
-moz-transform: rotate(-90deg);
|
||||||
|
-webkit-transform: rotate(-90deg);
|
||||||
|
transform-origin: 0 0;
|
||||||
|
-o-transform-origin: 0 0;
|
||||||
|
-ms-transform-origin: 0 0;
|
||||||
|
-moz-transform-origin: 0 0;
|
||||||
|
-webkit-transform-origin: 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xaxisLabel {
|
||||||
|
top: 90%;
|
||||||
|
left: 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ie7 .yaxisLabel, .ie8 .yaxisLabel {
|
||||||
|
top: 40%;
|
||||||
|
font-size: 36px;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.0, M12=0.33, M21=-0.33, M22=0.0,sizingMethod='auto expand');
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<div id='map'></div>
|
<div id='map'></div>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
@ -213,15 +260,18 @@ html,body,#map {
|
||||||
|
|
||||||
filter : function(feature, layer) {
|
filter : function(feature, layer) {
|
||||||
var zoom = map.getZoom();
|
var zoom = map.getZoom();
|
||||||
switch( feature.properties.type ) {
|
switch (feature.properties.type) {
|
||||||
case 'airport':
|
case 'airport':
|
||||||
if( zoom >= 10 ) return true;
|
if (zoom >= 10)
|
||||||
|
return true;
|
||||||
return feature.properties.longestRwyLength_m >= 2000;
|
return feature.properties.longestRwyLength_m >= 2000;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'NDB':
|
case 'NDB':
|
||||||
if( zoom >= 10 ) return true;
|
if (zoom >= 10)
|
||||||
if( zoom >= 8 ) return feature.properties.range_nm >= 30;
|
return true;
|
||||||
|
if (zoom >= 8)
|
||||||
|
return feature.properties.range_nm >= 30;
|
||||||
return feature.properties.range_nm > 50;
|
return feature.properties.range_nm > 50;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -270,7 +320,7 @@ html,body,#map {
|
||||||
var lon = center.lng;
|
var lon = center.lng;
|
||||||
|
|
||||||
var url = "/navdb?q=findWithinRange&type=" + filter + "&range=" + radius + "&lat=" + lat + "&lon=" + lon;
|
var url = "/navdb?q=findWithinRange&type=" + filter + "&range=" + radius + "&lat=" + lat + "&lon=" + lon;
|
||||||
console.log(url);
|
|
||||||
var jqxhr = $.get(url).done(function(data) {
|
var jqxhr = $.get(url).done(function(data) {
|
||||||
navdbLayer.clearLayers();
|
navdbLayer.clearLayers();
|
||||||
navdbLayer.addData(data);
|
navdbLayer.addData(data);
|
||||||
|
@ -279,7 +329,9 @@ html,body,#map {
|
||||||
}).always(function() {
|
}).always(function() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
setTimeout(function() { navdbLayer.update() }, 5000);
|
setTimeout(function() {
|
||||||
|
navdbLayer.update()
|
||||||
|
}, 5000);
|
||||||
};
|
};
|
||||||
|
|
||||||
map.addLayer(navdbLayer);
|
map.addLayer(navdbLayer);
|
||||||
|
@ -292,8 +344,8 @@ html,body,#map {
|
||||||
|
|
||||||
var overlays = {
|
var overlays = {
|
||||||
"NAVDB" : navdbLayer,
|
"NAVDB" : navdbLayer,
|
||||||
"ICAO VFR (Germany)" : icaoGermany,
|
//"ICAO VFR (Germany)" : icaoGermany,
|
||||||
"Lower Airspace (Germany)" : lowerGermany,
|
//"Lower Airspace (Germany)" : lowerGermany,
|
||||||
"Precipitation" : owmPrecipitation,
|
"Precipitation" : owmPrecipitation,
|
||||||
"Isobares" : owmPressure,
|
"Isobares" : owmPressure,
|
||||||
};
|
};
|
||||||
|
@ -306,7 +358,7 @@ html,body,#map {
|
||||||
popupAncor : [ 0, -32 ],
|
popupAncor : [ 0, -32 ],
|
||||||
iconUrl : "images/aircraft.svg",
|
iconUrl : "images/aircraft.svg",
|
||||||
}),
|
}),
|
||||||
zIndexOffset: 10000,
|
zIndexOffset : 10000,
|
||||||
});
|
});
|
||||||
aircraftMarker.addTo(map);
|
aircraftMarker.addTo(map);
|
||||||
aircraftMarker.setState = function(s) {
|
aircraftMarker.setState = function(s) {
|
||||||
|
@ -338,14 +390,83 @@ html,body,#map {
|
||||||
this._div.innerHTML = s;
|
this._div.innerHTML = s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var altitudePlotter = L.control({
|
||||||
|
position : 'bottomright'
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
altitudePlotter.onAdd = function(map) {
|
||||||
|
this._div = L.DomUtil.create('div', 'altitudePlotter');
|
||||||
|
this._div.innerHTML = '<h4>Altitude</h4>';
|
||||||
|
return this._div;
|
||||||
|
};
|
||||||
|
|
||||||
|
altitudePlotter.initPlotter = function(map) {
|
||||||
|
var container = $(".altitudePlotter");
|
||||||
|
var w = $("#map").innerWidth() * .9;
|
||||||
|
container.css('width', w );
|
||||||
|
this.maxData = container.outerWidth() / 2 || 300;
|
||||||
|
|
||||||
|
var series = [ {
|
||||||
|
propertyPath : "/position/altitude-ft",
|
||||||
|
data : [],
|
||||||
|
color: 'blue',
|
||||||
|
lines : {
|
||||||
|
fill : true
|
||||||
|
}
|
||||||
|
} ];
|
||||||
|
|
||||||
|
this.plot = $.plot(container, series, {
|
||||||
|
historyLength: 600,
|
||||||
|
grid : {
|
||||||
|
borderWidth : 1,
|
||||||
|
minBorderMargin : 20,
|
||||||
|
labelMargin : 10,
|
||||||
|
backgroundColor : {
|
||||||
|
colors : [ "#fff", "#e4f4f4" ]
|
||||||
|
},
|
||||||
|
margin : {
|
||||||
|
top : 8,
|
||||||
|
bottom : 20,
|
||||||
|
left : 20
|
||||||
|
},
|
||||||
|
},
|
||||||
|
xaxis : {
|
||||||
|
min : 0,
|
||||||
|
max : 60,
|
||||||
|
},
|
||||||
|
yaxis : {
|
||||||
|
min : 0,
|
||||||
|
max : 1000
|
||||||
|
},
|
||||||
|
legend : {
|
||||||
|
show : true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.yaxisLabel = $("<div class='axisLabel yaxisLabel'></div>")
|
||||||
|
.text("Altitude (ft)")
|
||||||
|
.appendTo(container);
|
||||||
|
|
||||||
|
this.xaxisLabel = $("<div class='axisLabel xaxisLabel'></div>")
|
||||||
|
.text("Simulation time (s)")
|
||||||
|
.appendTo(container);
|
||||||
|
};
|
||||||
|
|
||||||
|
altitudePlotter.addTo(map);
|
||||||
|
altitudePlotter.initPlotter(map);
|
||||||
|
|
||||||
var FollowAircraftControl = L.control();
|
var FollowAircraftControl = L.control();
|
||||||
FollowAircraftControl.onAdd = function(map) {
|
FollowAircraftControl.onAdd = function(map) {
|
||||||
this._div = L.DomUtil.create('div', 'followAircraft');
|
this._div = L.DomUtil.create('div', 'followAircraft');
|
||||||
this._div.innerHTML = '<img src="images/followAircraft.svg" title="Center Map on Aircraft Position" />';
|
this._div.innerHTML = '<img src="images/followAircraft.svg" title="Center Map on Aircraft Position" />';
|
||||||
this._div.onclick = function() { toggleFollowAircraft(); return true; };
|
this._div.onclick = function() {
|
||||||
|
toggleFollowAircraft();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
return this._div;
|
return this._div;
|
||||||
}
|
}
|
||||||
|
|
||||||
L.control.scale().addTo(map);
|
L.control.scale().addTo(map);
|
||||||
info.addTo(map);
|
info.addTo(map);
|
||||||
FollowAircraftControl.addTo(map);
|
FollowAircraftControl.addTo(map);
|
||||||
|
@ -362,7 +483,7 @@ html,body,#map {
|
||||||
map.on('moveend', function(e) {
|
map.on('moveend', function(e) {
|
||||||
navdbLayer.dirty = true;
|
navdbLayer.dirty = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
map.on('dragstart', function(e) {
|
map.on('dragstart', function(e) {
|
||||||
followAircraft = false;
|
followAircraft = false;
|
||||||
});
|
});
|
||||||
|
@ -371,7 +492,6 @@ html,body,#map {
|
||||||
function toggleFollowAircraft() {
|
function toggleFollowAircraft() {
|
||||||
followAircraft = !followAircraft;
|
followAircraft = !followAircraft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
@ -385,16 +505,21 @@ html,body,#map {
|
||||||
|
|
||||||
navdbLayer.update();
|
navdbLayer.update();
|
||||||
|
|
||||||
|
var latlng;
|
||||||
|
var i = 0;
|
||||||
setInterval(function() {
|
setInterval(function() {
|
||||||
var latlng = new L.LatLng(aircraftState.lat, aircraftState.lon);
|
latlng = new L.LatLng(aircraftState.lat, aircraftState.lon);
|
||||||
if( followAircraft )
|
if (followAircraft) {
|
||||||
map.setView(latlng);
|
if (++i % 10 == 0)
|
||||||
|
map.setView(latlng);
|
||||||
|
}
|
||||||
aircraftMarker.setState(aircraftState);
|
aircraftMarker.setState(aircraftState);
|
||||||
}, 1000);
|
}, 100);
|
||||||
|
|
||||||
PropertyChangeListener(function() {
|
PropertyChangeListener(function() {
|
||||||
SetListener("/position/altitude-ft", function(n) {
|
SetListener("/position/altitude-ft", function(n) {
|
||||||
aircraftState.alt = Math.round(n.value);
|
aircraftState.alt = Math.round(n.value);
|
||||||
|
altitudePlotter.plot.plotPropertyNode(n);
|
||||||
});
|
});
|
||||||
SetListener("/position/latitude-deg", function(n) {
|
SetListener("/position/latitude-deg", function(n) {
|
||||||
aircraftState.lat = n.value;
|
aircraftState.lat = n.value;
|
||||||
|
|
Loading…
Reference in a new issue