diff --git a/src/renderer/components/FlightgearMap.vue b/src/renderer/components/FlightgearMap.vue
index 473d276..79e97b7 100644
--- a/src/renderer/components/FlightgearMap.vue
+++ b/src/renderer/components/FlightgearMap.vue
@@ -30,8 +30,6 @@ You should have received a copy of the GNU General Public License along with FG
-
-
+
+
+
@@ -60,6 +61,7 @@ You should have received a copy of the GNU General Public License along with FG
import ToolBar from './ToolBar'
import EditLayer from './EditLayer'
import ToolLayer from './ToolLayer'
+ import TowerLayer from './TowerLayer'
import PavementLayer from './PavementLayer'
import ThresholdLayer from './ThresholdLayer'
@@ -75,7 +77,7 @@ You should have received a copy of the GNU General Public License along with FG
})
export default {
name: 'flightgear-map',
- components: { LMap, LTileLayer, LMarker, LCircle, LeafletSidebar, AiLayer, EditBar, ToolBar, EditLayer, PavementLayer, LLayerGroup, LControl, ThresholdLayer, ToolLayer },
+ components: { LMap, LTileLayer, LMarker, LCircle, LeafletSidebar, AiLayer, EditBar, ToolBar, EditLayer, TowerLayer, PavementLayer, LLayerGroup, LControl, ThresholdLayer, ToolLayer },
props: [],
created () {
this.loadingInstance = null
@@ -160,6 +162,7 @@ You should have received a copy of the GNU General Public License along with FG
this.$refs.pavementLayer.load(airportsToLoad[0])
this.$refs.editLayer.load(airportsToLoad[0])
this.$refs.thresholdLayer.load(airportsToLoad[0])
+ this.$refs.towerLayer.load(airportsToLoad[0])
this.editingAirport = airportsToLoad[0]
})
}
@@ -169,7 +172,6 @@ You should have received a copy of the GNU General Public License along with FG
if (this.$refs.airportLayer) {
this.$refs.airportLayer.setVisible(this.zoom < 12)
}
-
// console.log(this.groundnet)
}
})
@@ -226,6 +228,16 @@ You should have received a copy of the GNU General Public License along with FG
this.layersControl.addOverlay(this.$refs.thresholdLayer.getLayer(), 'Threshold Layer')
}
}
+ if (this.$refs.towerLayer.getLayer() === e.layer) {
+ l = this.layersControl._layers.filter(l => l.name === 'Tower Layer')
+ if (l.length > 0 && l[0].layer !== this.$refs.towerLayer.getLayer()) {
+ this.layersControl.removeLayer(l[0].layer)
+ this.layersControl.addOverlay(this.$refs.towerLayer.getLayer(), 'Tower Layer')
+ }
+ if (l.length === 0) {
+ this.layersControl.addOverlay(this.$refs.towerLayer.getLayer(), 'Tower Layer')
+ }
+ }
},
onSelectedPolygon (ring) {
var parkings = this.$refs.editLayer.getParkings(ring)
@@ -242,6 +254,7 @@ You should have received a copy of the GNU General Public License along with FG
this.$refs.map.mapObject.options.minZoom = 1
}
this.$refs.editLayer.enableEdit()
+ this.$refs.towerLayer.enableEdit()
this.$refs.editBar.setEditing(event)
this.$refs.toolBar.setEditing(event)
this.$refs.sidebar.setEditing(event)
@@ -325,6 +338,7 @@ You should have received a copy of the GNU General Public License along with FG
if (zoom !== this.$store.state.Settings.zoom) {
this.$store.dispatch('setZoom', zoom)
this.$refs.airportLayer.setVisible(zoom < 12)
+ this.$refs.towerLayer.setVisible(this.zoom >= 12)
this.$refs.pavementLayer.setVisible(zoom >= 12)
}
this.$refs.editLayer.groundnetLayerGroup.eachLayer(function (layer) {
@@ -332,11 +346,15 @@ You should have received a copy of the GNU General Public License along with FG
layer.updateArrows(zoom)
}
})
+ if (this.$refs.towerLayer) {
+ this.$refs.towerLayer.zoomUpdated()
+ }
},
async centerUpdated (center) {
if (center !== this.$store.state.Settings.center) {
this.$store.dispatch('setCenter', center)
this.$refs.airportLayer.setVisible(this.zoom < 12)
+ this.$refs.towerLayer.setVisible(this.zoom >= 12)
this.$refs.pavementLayer.setVisible(this.zoom >= 12)
}
},
diff --git a/src/renderer/components/ThresholdLayer.vue b/src/renderer/components/ThresholdLayer.vue
index 4f8c779..4ba902b 100644
--- a/src/renderer/components/ThresholdLayer.vue
+++ b/src/renderer/components/ThresholdLayer.vue
@@ -68,7 +68,7 @@
edit: function () {
console.log('Zoom : ' + this.$store.state.Settings.zoom)
if (this.$store.state.Settings.zoom > 12) {
- console.log()
+ console.log('Zoom above 12')
}
}
}
diff --git a/src/renderer/components/TowerLayer.vue b/src/renderer/components/TowerLayer.vue
new file mode 100644
index 0000000..3718b94
--- /dev/null
+++ b/src/renderer/components/TowerLayer.vue
@@ -0,0 +1,104 @@
+
+
+
+
+
+
diff --git a/src/renderer/loaders/TaxiwaySegmentExtender.js b/src/renderer/loaders/TaxiwaySegmentExtender.js
index 0ae0130..073cac5 100644
--- a/src/renderer/loaders/TaxiwaySegmentExtender.js
+++ b/src/renderer/loaders/TaxiwaySegmentExtender.js
@@ -486,6 +486,9 @@ const extendTaxiSegment = function (taxiwaySegment) {
};
taxiwaySegment.__proto__.updateArrows = function (zoom) {
+ if( this._map === null) {
+ return;
+ }
if (this.options.attributes.direction === 'forward') {
this.setText(null);
if (zoom <= 16) {
diff --git a/src/renderer/loaders/Threshold.js b/src/renderer/loaders/Threshold.js
index 9038342..b50f506 100644
--- a/src/renderer/loaders/Threshold.js
+++ b/src/renderer/loaders/Threshold.js
@@ -1,3 +1,14 @@
+/*
+Copyright 2020 Keith Paterson
+
+This file is part of FG Airports.
+
+FG Airports is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+
+FG Airports is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with FG Airports. If not, see http://www.gnu.org/licenses/.
+*/
/* eslint-disable */
const convert = require('geo-coordinates-parser');
const leaflet = require('leaflet');
diff --git a/src/renderer/loaders/Tower.js b/src/renderer/loaders/Tower.js
new file mode 100644
index 0000000..efe5e84
--- /dev/null
+++ b/src/renderer/loaders/Tower.js
@@ -0,0 +1,84 @@
+/*
+Copyright 2020 Keith Paterson
+
+This file is part of FG Airports.
+
+FG Airports is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+
+FG Airports is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with FG Airports. If not, see http://www.gnu.org/licenses/.
+*/
+/* eslint-disable */
+
+const convert = require('geo-coordinates-parser');
+const fs = require('fs');
+const path = require('path');
+
+/**http://wiki.openstreetmap.org/wiki/Zoom_levels*/
+
+
+L.TowerMarker = L.Marker.extend({
+ options: {
+ zIndexOffset: 10000,
+ },
+
+ initialize: function (latlng, options) {
+ L.Marker.prototype.initialize(latlng, options);
+ L.Util.setOptions(this, options);
+ this.svg = this.stripSVG('tower.svg');
+
+ this.isDragging = false;
+ },
+ updateProperties: function(properties) {
+ this.heading = properties.heading;
+ this.updateIcon();
+ },
+ stripSVG: function(fName) {
+ var rx = /<\s*svg[^>]*>([\s\S]*)<\s*\/svg[^>]*>/gm;
+ var svg = fs.readFileSync(path.join(__static, '/', fName), 'utf8');
+ var svg2 = rx.exec(svg);
+ return svg2[0];
+ },
+ updateIcon : function(map) {
+ if(map !== null) {
+ var metersPP = this.metersPerPixel(map.getCenter().lat, map.getZoom());
+ if(this._metersPP != metersPP) {
+ console.debug('Meters per pixel ' + metersPP);
+ var pixelSize = 32 / metersPP;
+ var scale = pixelSize/64;
+ var offset = -(64/2);
+ this.setIcon(L.divIcon({
+ iconSize: null,
+ className: 'aircraft-marker-icon',
+ html: `
${this.svg}
`,
+ }));
+ this._metersPP = metersPP;
+ }
+ }
+ },
+ onAdd : function(map) {
+ var metersPP = this.metersPerPixel(map.getCenter().lat, map.getZoom());
+ console.debug('Meters per pixel ' + metersPP);
+ this.updateIcon(map);
+ },
+ metersPerPixel: function (latitude, zoomLevel) {
+ var earthCircumference = 40075017;
+ var latitudeRadians = latitude * (Math.PI / 180);
+ return earthCircumference * Math.cos(latitudeRadians) / Math.pow(2, zoomLevel + 8);
+ },
+
+ pixelValue: function (latitude, meters, zoomLevel) {
+ return meters / metersPerPixel(latitude, zoomLevel);
+ },
+
+
+});
+
+//Builds a marker for a ai or multiplayer aircraft
+var tower = function (n, options) {
+ var latlon = convert(n.find('lat/text()').text() + " " + n.find('lon/text()').text());
+ return new L.TowerMarker([latlon.decimalLatitude, latlon.decimalLongitude], options);
+}
+
+module.exports = tower;
diff --git a/src/renderer/loaders/tower_loader.js b/src/renderer/loaders/tower_loader.js
new file mode 100644
index 0000000..e898bd1
--- /dev/null
+++ b/src/renderer/loaders/tower_loader.js
@@ -0,0 +1,83 @@
+/*
+Copyright 2020 Keith Paterson
+
+This file is part of FG Airports.
+
+FG Airports is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+
+FG Airports is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with FG Airports. If not, see http://www.gnu.org/licenses/.
+*/
+/* eslint-disable */
+const fs = require('fs');
+const path = require('path');
+var xamel = require('xamel');
+const convert = require('geo-coordinates-parser');
+
+const store = require('../store');
+
+const util = require('util');
+
+const tower = require('./Tower.js');
+
+
+var $ = require('jquery');
+
+exports.readTowerXML = function (fDir, icao, force) {
+ try {
+ var layerGroup = L.layerGroup();
+ layerGroup.maxId = 0;
+ var f = path.join(fDir, icao[0], icao[1], icao[2], icao + '.twr.xml');
+ var fNew = path.join(fDir, icao[0], icao[1], icao[2], icao + '.twr.new.xml');
+
+ if (f == null || !fs.existsSync(f))
+ return;
+ if (fNew != null && fs.existsSync(fNew) && !force) {
+ f = fNew;
+ }
+
+ var features = new Array();
+
+ // map.on("editable:vertex:new", function (event) {
+ // log.console("Add vertex " + event);
+ // });
+
+ var xmlGroundnet = fs.readFileSync(f, 'utf8').toString();
+ xamel.parse(xmlGroundnet, function (err, xml) {
+ console.debug("parsed " + path.basename(f));
+ if (err !== null) {
+ console.error("Error in " + airline);
+ throw err;
+ }
+
+ var towerNodes = xml.find('PropertyList/tower/twr');
+ console.log("Tower " + towerNodes.length);
+
+ var merged = new Array();
+
+ var nodesLookup = {};
+ featureLookup = [];
+
+
+ towerNodes.map(n => {
+ var towerIcon = tower(n, layerGroup);
+ towerIcon.addTo(layerGroup);
+ var latlon = convert(n.find('lat/text()').text() + " " + n.find('lon/text()').text());
+ /*
+ var marker = new L.Circle([latlon.decimalLatitude, latlon.decimalLongitude], 5);
+ marker.addTo(layerGroup);
+ */
+
+ features.push(towerIcon);
+ }).sort();
+
+ return layerGroup;
+ });
+ // var jsonAirports = JSON.parse(geoJSON);
+ // return jsonAirports;
+ } catch (error) {
+ console.error(error);
+ }
+ return layerGroup;
+};
\ No newline at end of file
diff --git a/static/tower.svg b/static/tower.svg
new file mode 100644
index 0000000..93d5265
--- /dev/null
+++ b/static/tower.svg
@@ -0,0 +1,78 @@
+
+
+
+