Overhaul the browser-map (still incomplete)
This commit is contained in:
parent
654ef82691
commit
6d9456c7cc
3 changed files with 397 additions and 0 deletions
58
webgui/map/FollowControl.js
Normal file
58
webgui/map/FollowControl.js
Normal file
|
@ -0,0 +1,58 @@
|
|||
L.FollowControl = L.Control.extend({
|
||||
options: {
|
||||
getPosition: function() { return L.latLng(53.5,10); },
|
||||
element: 'div',
|
||||
cssClass: '',
|
||||
innerHTML: '',
|
||||
initialFollow: true,
|
||||
followUpdateInterval: 100,
|
||||
noFollowUpdateInterval: 1000,
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
L.Control.prototype.initialize.call(this,options);
|
||||
L.Util.setOptions(this,options);
|
||||
},
|
||||
|
||||
onAdd: function(map) {
|
||||
this._map = map;
|
||||
this._div = L.DomUtil.create(this.options.element, this.options.cssClass );
|
||||
this._div.innerHTML = this.options.innerHTML;
|
||||
this._doFollow = this.options.initialFollow;
|
||||
var that = this;
|
||||
this._div.onclick = function() {
|
||||
that.setFollow(true);
|
||||
return true;
|
||||
};
|
||||
this.update();
|
||||
return this._div;
|
||||
},
|
||||
|
||||
onRemove: function(map) {
|
||||
this._map = null;
|
||||
},
|
||||
|
||||
setFollow: function( v ) {
|
||||
this._doFollow = v;
|
||||
},
|
||||
|
||||
update: function() {
|
||||
if( this._map && this._doFollow ) {
|
||||
this._map.setView( this.options.getPosition() );
|
||||
var that = this;
|
||||
setTimeout( function() { that.update(); }, this.options.noFollowUpdateInterval );
|
||||
} else {
|
||||
var that = this;
|
||||
setTimeout( function() { that.update(); }, this.options.followUpdateInterval );
|
||||
}
|
||||
},
|
||||
|
||||
_map: null,
|
||||
_doFollow: true,
|
||||
});
|
||||
|
||||
L.followControl = function( options ) {
|
||||
return new L.FollowControl( options );
|
||||
}
|
||||
|
||||
|
96
webgui/map/Marker.js
Normal file
96
webgui/map/Marker.js
Normal file
|
@ -0,0 +1,96 @@
|
|||
L.RotatedMarker = L.Marker.extend({
|
||||
|
||||
options : {
|
||||
angle : 0
|
||||
},
|
||||
|
||||
_setPos : function(pos) {
|
||||
L.Marker.prototype._setPos.call(this, pos);
|
||||
|
||||
if (L.DomUtil.TRANSFORM) {
|
||||
// use the CSS transform rule if available
|
||||
this._icon.style[L.DomUtil.TRANSFORM] += ' rotate(' + this.options.angle + 'deg)';
|
||||
} else if (L.Browser.ie) {
|
||||
// fallback for IE6, IE7, IE8
|
||||
var rad = this.options.angle * (Math.PI / 180), costheta = Math.cos(rad), sintheta = Math.sin(rad);
|
||||
this._icon.style.filter += ' progid:DXImageTransform.Microsoft.Matrix(sizingMethod=\'auto expand\', M11=' + costheta
|
||||
+ ', M12=' + (-sintheta) + ', M21=' + sintheta + ', M22=' + costheta + ')';
|
||||
}
|
||||
},
|
||||
|
||||
initialize: function(latlng,options) {
|
||||
L.Marker.prototype.initialize(latlng,options);
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
L.rotatedMarker = function(pos) {
|
||||
return new L.RotatedMarker(pos);
|
||||
}
|
||||
|
||||
L.AircraftMarker = L.RotatedMarker.extend({
|
||||
options : {
|
||||
angle : 0,
|
||||
getProperties:function() {
|
||||
return {};
|
||||
},
|
||||
icon : L.divIcon({
|
||||
iconSize : [ 60, 60 ],
|
||||
iconAnchor : [ 30, 30 ],
|
||||
className: 'aircraft-marker-icon',
|
||||
html: '<svg xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" viewBox="0 0 500 500" preserveAspectRatio="xMinYMin meet"><path d="M250.2,59.002c11.001,0,20.176,9.165,20.176,20.777v122.24l171.12,95.954v42.779l-171.12-49.501v89.227l40.337,29.946v35.446l-60.52-20.18-60.502,20.166v-35.45l40.341-29.946v-89.227l-171.14,49.51v-42.779l171.14-95.954v-122.24c0-11.612,9.15-20.777,20.16-20.777z" fill="#808080" stroke="black" stroke-width="5"/></svg>',
|
||||
}),
|
||||
zIndexOffset : 10000,
|
||||
updateInterval: 100,
|
||||
},
|
||||
|
||||
initialize: function(latlng,options) {
|
||||
L.RotatedMarker.prototype.initialize(latlng,options);
|
||||
L.Util.setOptions(this,options);
|
||||
},
|
||||
|
||||
onAdd: function( map ) {
|
||||
L.RotatedMarker.prototype.onAdd.call(this,map);
|
||||
this.popup = L.popup( {
|
||||
closeButton: false,
|
||||
className: 'aircraft-marker-popup',
|
||||
closeOnClick: false,
|
||||
maxWidth: 200,
|
||||
minWidth: 100,
|
||||
offset: [30,30],
|
||||
}, this );
|
||||
this.popup.setContent("");
|
||||
this.bindPopup( this.popup );
|
||||
this.addTo(this._map);
|
||||
this.openPopup();
|
||||
|
||||
this.timeout();
|
||||
},
|
||||
|
||||
onRemove: function( map ) {
|
||||
if( this.timeoutid != null )
|
||||
clearTimeout(this.timeoutid);
|
||||
L.RotatedMarker.prototype.onRemove.call(this,map);
|
||||
},
|
||||
|
||||
timeoutid: null,
|
||||
timeout: function() {
|
||||
var props = this.options.getProperties.call(this);
|
||||
var popup =
|
||||
'<div class="aircraft-marker-callsign">' + props.callsign + '</div>' +
|
||||
'<div class="aircraft-marker-model">' + props.model + '</div>' +
|
||||
'<div class="aircraft-marker-altitude">' + props.altitude + '</div>' +
|
||||
'<div class="aircraft-marker-gs">' + props.speed + '</div><div style="clear: both"/>';
|
||||
this.popup.setContent(popup);
|
||||
|
||||
this.options.angle = props.heading;
|
||||
this.setLatLng( props.position );
|
||||
var that = this;
|
||||
this.timeoutid = setTimeout( function() { that.timeout(); }, this.options.updateInterval );
|
||||
},
|
||||
});
|
||||
|
||||
L.aircraftMarker = function(latlng,options) {
|
||||
return new L.AircraftMarker(latlng,options);
|
||||
}
|
||||
|
243
webgui/map/index-2.0.html
Normal file
243
webgui/map/index-2.0.html
Normal file
|
@ -0,0 +1,243 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="description" content="FlightGear - Map" />
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<link rel="apple-touch-icon" href="/img/FlightGear_logo.png">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<link rel="shortcut icon" sizes="200x200" href="/img/FlightGear_logo.png">
|
||||
<link rel="icon" sizes="200x200" href="/img/FlightGear_logo.png">
|
||||
|
||||
<script src="../3rdparty/jquery/jquery-1.11.1.min.js" type="text/javascript"></script>
|
||||
<link rel="stylesheet" href="../3rdparty/leaflet-0.7.3/leaflet.css" />
|
||||
<script src="../3rdparty/leaflet-0.7.3/leaflet.js" type="text/javascript"></script>
|
||||
<script src="../lib/fgfs.js" type="text/javascript"></script>
|
||||
<script src="FollowControl.js" type="text/javascript"></script>
|
||||
<script src="Marker.js" type="text/javascript"></script>
|
||||
|
||||
<title>FlightGear - Map</title>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
html,body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#map {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.aircraft-marker-icon {
|
||||
background-color: rgba(255,255,255,0);
|
||||
}
|
||||
|
||||
.aircraft-marker-icon path {
|
||||
fill: #00ff00;
|
||||
}
|
||||
|
||||
.aircraft-marker-popup .leaflet-popup-tip {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.aircraft-marker-popup .leaflet-popup-content-wrapper {
|
||||
background-color: rgba(255,255,255,0.50);
|
||||
}
|
||||
|
||||
.aircraft-marker-popup .leaflet-popup-content {
|
||||
margin: 5px 5px;
|
||||
}
|
||||
.aircraft-marker-callsign,.aircraft-marker-altitude,.aircraft-marker-model,.aircraft-marker-gs {
|
||||
float: left;
|
||||
color: #00ff00;
|
||||
text-shadow: 1px 1px #404040;
|
||||
|
||||
}
|
||||
|
||||
.aircraft-marker-model,.aircraft-marker-gs {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.aircraft-marker-altitude,.aircraft-marker-callsign {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.followAircraft {
|
||||
background: white;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 5px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<div id='map'></div>
|
||||
<script type="text/javascript">
|
||||
/* <![CDATA[ */
|
||||
|
||||
var propertyMirror = new FGFS.PropertyMirror([
|
||||
[ "latitude", "/position/latitude-deg" ],
|
||||
[ "longitude", "/position/longitude-deg" ],
|
||||
[ "altitude", "/position/altitude-deg" ],
|
||||
[ "heading", "/orientation/heading-deg" ],
|
||||
[ "groundspeed", "/velocities/groundspeed-kt" ],
|
||||
[ "model", "/sim/model/path" ],
|
||||
[ "callsign", "/sim/multiplay/callsign" ],
|
||||
]);
|
||||
|
||||
|
||||
var osmLayer = new L.TileLayer(
|
||||
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
{
|
||||
maxZoom : 18,
|
||||
attribution : 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors'
|
||||
});
|
||||
|
||||
var map = new L.Map('map', {
|
||||
center : [ 53.7, 10.0 ],
|
||||
zoom : 10,
|
||||
layers: [ osmLayer ],
|
||||
zoomControl: true,
|
||||
attributionControl: true,
|
||||
});
|
||||
|
||||
L.control.layers({
|
||||
"OpenStreetMaps" : osmLayer,
|
||||
"MapQuest Satelite" : new L.TileLayer(
|
||||
'http://otile{s}.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.png',
|
||||
{
|
||||
maxZoom : 18,
|
||||
subdomains : [ '1', '2', '3', '4' ],
|
||||
attribution : 'Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a>.'
|
||||
}),
|
||||
|
||||
"MapQuest Roads" : new L.TileLayer(
|
||||
'http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png',
|
||||
{
|
||||
maxZoom : 18,
|
||||
subdomains : [ '1', '2', '3', '4' ],
|
||||
attribution :
|
||||
'Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a>. Map data (c) <a href="http://www.openstreetmap.org/" target="_blank">OpenStreetMap</a> contributors, CC-BY-SA.'
|
||||
}),
|
||||
},{
|
||||
// "NAVDB" : navdbLayer,
|
||||
// "AI" : aiLayer,
|
||||
"VFRMap.com Sectionals (US)" : new L.TileLayer(
|
||||
'http://vfrmap.com/20140918/tiles/vfrc/{z}/{y}/{x}.jpg',
|
||||
{
|
||||
maxZoom : 12,
|
||||
minZoom : 3,
|
||||
attribution : '(c) <a href="VFRMap.com">VFRMap.com</a>',
|
||||
tms: true,
|
||||
opacity: 0.5,
|
||||
bounds: L.latLngBounds(L.latLng(16.0,-179.0), L.latLng(72.0,-60.0) ),
|
||||
}),
|
||||
|
||||
"VFRMap.com - Low IFR (US)" : new L.TileLayer(
|
||||
'http://vfrmap.com/20140918/tiles/ifrlc/{z}/{y}/{x}.jpg',
|
||||
{
|
||||
maxZoom : 12,
|
||||
minZoom : 5,
|
||||
attribution : '© <a href="VFRMap.com">VFRMap.com</a>',
|
||||
tms: true,
|
||||
opacity: 0.5,
|
||||
bounds: L.latLngBounds(L.latLng(16.0,-179.0), L.latLng(72.0,-60.0) ),
|
||||
}),
|
||||
|
||||
|
||||
"dfs.de VFR" : new L.TileLayer(
|
||||
'https://secais.dfs.de/static-maps/ICAO500-2014-DACH-Reprojected_01/tiles/{z}/{x}/{y}.png',
|
||||
{
|
||||
minZoom : 5,
|
||||
maxZoom : 15,
|
||||
attribution : 'Map data © <a href="http://www.dfs.de">DFS</a>',
|
||||
bounds: L.latLngBounds(L.latLng(46.0,5.0), L.latLng(55.1,16.5) ),
|
||||
}),
|
||||
|
||||
"Lower Airspace (Germany)" : new L.TileLayer(
|
||||
'https://secais.dfs.de/static-maps/lower_20131114/tiles/{z}/{x}/{y}.png',
|
||||
{
|
||||
minZoom : 5,
|
||||
maxZoom : 15,
|
||||
attribution : 'Map data © <a href="http://www.dfs.de">DFS</a>',
|
||||
bounds: L.latLngBounds(L.latLng(46.0,5.0), L.latLng(55.1,16.5) ),
|
||||
}),
|
||||
|
||||
"Precipitation" : new L.TileLayer(
|
||||
'http://{s}.tile.openweathermap.org/map/precipitation/{z}/{x}/{y}.png',
|
||||
{
|
||||
maxZoom : 14,
|
||||
minZoom : 0,
|
||||
subdomains : '12',
|
||||
format : 'image/png',
|
||||
transparent : true,
|
||||
opacity : 0.5
|
||||
}),
|
||||
|
||||
"Isobares" : new L.TileLayer(
|
||||
'http://{s}.tile.openweathermap.org/map/pressure_cntr/{z}/{x}/{y}.png',
|
||||
{
|
||||
maxZoom : 7,
|
||||
minZoom : 0,
|
||||
subdomains : '12',
|
||||
format : 'image/png',
|
||||
transparent : true,
|
||||
opacity : 0.5
|
||||
}),
|
||||
}).addTo(map);
|
||||
|
||||
var followAircraft = L.followControl({
|
||||
cssClass: 'followAircraft',
|
||||
innerHTML: '<img src="images/followAircraft.svg" title="Center Map on Aircraft Position" />',
|
||||
getPosition: function() {
|
||||
return L.latLng(propertyMirror.getNode("latitude").getNumValue(), propertyMirror.getNode("longitude").getNumValue() );
|
||||
},
|
||||
});
|
||||
followAircraft.addTo(map);
|
||||
map.on('dragstart', function(e) {
|
||||
followAircraft.setFollow(false);
|
||||
});
|
||||
|
||||
var aircraftMarker = L.aircraftMarker( L.latLng(53.6,10.1), {
|
||||
getProperties:function() {
|
||||
var model = propertyMirror.getNode("model").getStringValue("");
|
||||
model = model.slice( model.lastIndexOf('/')+1 );
|
||||
model = model.slice( 0, model.lastIndexOf('.') );
|
||||
|
||||
var callsign = propertyMirror.getNode("callsign").getStringValue("You!");
|
||||
if( callsign == 'callsign' ) callsign = "You!";
|
||||
|
||||
return {
|
||||
"model": model,
|
||||
"callsign": callsign,
|
||||
"altitude": Math.round(propertyMirror.getNode("altitude").getNumValue()/100),
|
||||
"speed": Math.round(propertyMirror.getNode("groundspeed").getNumValue()),
|
||||
"heading": Math.round(propertyMirror.getNode("heading").getNumValue()),
|
||||
"position": L.latLng(
|
||||
propertyMirror.getNode("latitude").getNumValue(),
|
||||
propertyMirror.getNode("longitude").getNumValue() ),
|
||||
};
|
||||
},
|
||||
|
||||
updateInterval: 100,
|
||||
});
|
||||
aircraftMarker.addTo(map);
|
||||
|
||||
|
||||
/* ]]> */
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Reference in a new issue