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 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + +