diff --git a/build/installer.nsh b/build/installer.nsh
new file mode 100644
index 0000000..9886d3d
--- /dev/null
+++ b/build/installer.nsh
@@ -0,0 +1,8 @@
+!macro preInit
+ SetRegView 64
+ WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$PROGRAMFILES64\flightgear-airports"
+ WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$PROGRAMFILES64\flightgear-airports"
+ SetRegView 32
+ WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$PROGRAMFILES32\flightgear-airports"
+ WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$PROGRAMFILES32\flightgear-airports"
+!macroend
diff --git a/src/renderer/components/ArcEditMulti.vue b/src/renderer/components/ArcEditMulti.vue
new file mode 100644
index 0000000..753eafc
--- /dev/null
+++ b/src/renderer/components/ArcEditMulti.vue
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+ Name :
+
+
+
+
+
+
+
+ Pushback :
+
+
+
+
+
+
+
+ Direction :
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/renderer/components/DirectorySelect.vue b/src/renderer/components/DirectorySelect.vue
index dde7b6b..64dbfab 100644
--- a/src/renderer/components/DirectorySelect.vue
+++ b/src/renderer/components/DirectorySelect.vue
@@ -3,7 +3,7 @@
...
-
+
@@ -20,9 +20,15 @@
methods: {
handleFileChange (e) {
- var first = e.target.files[0].webkitRelativePath.split("/")[0];
- var webkitdirectoryPath = e.target.files[0].path.split(first)[0] + first;
- this.$emit('input', webkitdirectoryPath)
+ try {
+ if (e.target.files && e.target.files.length>0) {
+ var first = e.target.files[0].webkitRelativePath.split("/")[0];
+ var webkitdirectoryPath = e.target.files[0].path.split(first)[0] + first;
+ this.$emit('input', webkitdirectoryPath)
+ }
+ } catch (error) {
+ console.error(error)
+ }
}
}
}
@@ -39,6 +45,8 @@
text-align: center;
font-weight: bold;
+ width: 28px;
+ height: 28px;
}
.directory-select > input[type="file"] {
diff --git a/src/renderer/components/EditLayer.vue b/src/renderer/components/EditLayer.vue
index 8f7c026..6f15642 100644
--- a/src/renderer/components/EditLayer.vue
+++ b/src/renderer/components/EditLayer.vue
@@ -41,11 +41,7 @@ You should have received a copy of the GNU General Public License along with FG
props: [],
created () {
- console.log(LMap)
- console.log(LMarker)
- console.log(L)
- console.log(LEdit)
- console.log(L2)
+ [LMap, LMarker, L, LEdit, L2]
console.log('Created Editlayer')
// console.log(LSymbol)
},
@@ -72,6 +68,16 @@ You should have received a copy of the GNU General Public License along with FG
deep: true //add this if u need to watch object properties change etc.
}
);
+ this.$store.watch(
+ function (state) {
+ return state.Editable.data.multiarc;
+ },
+ () => { this.editedMultiArc() }
+ ,
+ {
+ deep: true //add this if u need to watch object properties change etc.
+ }
+ );
this.$store.watch(
function (state) {
return state.Editable.data.parking;
@@ -125,12 +131,18 @@ You should have received a copy of the GNU General Public License along with FG
this.icao = icao
this.groundnetLayerGroup = readGroundnetXML(this.$store.state.Settings.settings.airportsDirectory, icao, force)
if (this.groundnetLayerGroup === undefined) {
- console.error('ICAO not loaded ' + icao)
+ console.warn('Groundnet for ICAO not loaded ' + icao)
return
}
+ if (this.groundnetLayerGroup.getLayers().length === 0) {
+ console.warn('Groundnet for ICAO not loaded ' + icao)
+ }
this.groundnetLayerGroup.eachLayer(l => {
if (l instanceof L.TaxiwaySegment) {
- l.addListeners()
+ l.addListeners()
+ }
+ if (l.updateArrows !== undefined) {
+ l.updateArrows(this.$store.state.Settings.zoom)
}
})
console.log(this.groundnetLayerGroup.maxId)
@@ -659,6 +671,7 @@ You should have received a copy of the GNU General Public License along with FG
!this.editing) {
return;
}
+ console.debug("Edit Type : " + this.$store.state.type);
var arc = this.groundnetLayerGroup.getLayer(this.$store.state.Editable.index);
if (arc && arc instanceof L.Polyline) {
console.log('Edited Arc : ' + this.$store.state.Editable.index);
@@ -666,6 +679,27 @@ You should have received a copy of the GNU General Public License along with FG
arc.updateStyle();
}
},
+ editedMultiArc() {
+ if (!this.groundnetLayerGroup ||
+ this.$store.state.Editable.data.multiarc === undefined ||
+ this.$store.state.Editable.data.multiarc.ids === undefined ||
+ this.featureLookup===undefined ||
+ !this.editing) {
+ return;
+ }
+ console.debug("Edit Type : " + this.$store.state.Editable.data.multiarc.ids);
+ this.$store.state.Editable.data.multiarc.ids.forEach(id => {
+ console.debug(id);
+ var arc = this.groundnetLayerGroup.getLayer(id);
+ if (arc && arc instanceof L.Polyline) {
+ console.log('Edited Arc : ' + this.$store.state.Editable.index);
+ arc.options.attributes.direction = this.$store.state.Editable.data.multiarc.direction
+ arc.options.attributes.name = this.$store.state.Editable.data.multiarc.name
+ arc.options.attributes.isPushBackRoute = this.$store.state.Editable.data.multiarc.isPushBackRoute
+ arc.updateStyle();
+ }
+ });
+ },
//Update Node
editedNode() {
if (this.$store.state.Editable.index === undefined ||
@@ -825,11 +859,11 @@ You should have received a copy of the GNU General Public License along with FG
this.$parent.mapObject.on('click', this.addParking)
},
removeLayerClick (event) {
- console.log(event)
+ console.debug(event)
this.groundnetLayerGroup.removeLayer(event.target)
},
addParking (event) {
- console.log(event.latlng)
+ console.debug(event.latlng)
if (event.latlng === undefined) {
return
}
diff --git a/src/renderer/components/FlightgearMap.vue b/src/renderer/components/FlightgearMap.vue
index 7002f4d..ca6eade 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
@@ -85,7 +87,7 @@ You should have received a copy of the GNU General Public License along with FG
},
(newValue, oldValue) => {
// debugger
- console.log('setIcaoLoading ' + oldValue + ' => ' + newValue + ' ' + this.groundnetLoaded + ' ' + this.pavementLoaded + ' ' + this.loadingInstance)
+ console.log('setIcaoLoading ' + oldValue + ' => ' + newValue + ' groundnetLoaded ' + this.groundnetLoaded + ' pavementLoaded ' + this.pavementLoaded + ' ' + this.loadingInstance)
if (newValue !== oldValue && newValue !== '') {
this.groundnetLoaded = newValue
if ((this.loadingInstance === null || this.loadingInstance === undefined)) {
@@ -105,7 +107,7 @@ You should have received a copy of the GNU General Public License along with FG
},
(newValue, oldValue) => {
// debugger
- console.log('groundnetLoaded ' + oldValue + ' => ' + newValue + ' ' + this.groundnetLoaded + ' ' + this.pavementLoaded + ' ' + this.loadingInstance)
+ console.log('groundnetLoaded ' + oldValue + ' => ' + newValue + ' groundnetLoaded ' + this.groundnetLoaded + ' pavementLoaded ' + this.pavementLoaded + ' ' + this.loadingInstance)
if (newValue !== oldValue) {
this.groundnetLoaded = newValue
if (this.groundnetLoaded &&
@@ -160,6 +162,9 @@ 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])
+ if (this.$refs.towerLayer) {
+ this.$refs.towerLayer.load(airportsToLoad[0])
+ }
this.editingAirport = airportsToLoad[0]
})
}
@@ -169,7 +174,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)
}
})
@@ -208,16 +212,34 @@ You should have received a copy of the GNU General Public License along with FG
if (this.$refs.pavementLayer.getLayer() === e.layer) {
// debugger
var l = this.layersControl._layers.filter(l => l.name === 'APT Layer')
+ if (l.length > 0 && l[0].layer !== this.$refs.pavementLayer.getLayer()) {
+ this.layersControl.removeLayer(l[0].layer)
+ this.layersControl.addOverlay(this.$refs.pavementLayer.getLayer(), 'APT Layer')
+ }
if (l.length === 0) {
this.layersControl.addOverlay(this.$refs.pavementLayer.getLayer(), 'APT Layer')
}
}
if (this.$refs.thresholdLayer.getLayer() === e.layer) {
l = this.layersControl._layers.filter(l => l.name === 'Threshold Layer')
+ if (l.length > 0 && l[0].layer !== this.$refs.thresholdLayer.getLayer()) {
+ this.layersControl.removeLayer(l[0].layer)
+ this.layersControl.addOverlay(this.$refs.thresholdLayer.getLayer(), 'Threshold Layer')
+ }
if (l.length === 0) {
this.layersControl.addOverlay(this.$refs.thresholdLayer.getLayer(), 'Threshold Layer')
}
}
+ if (this.$refs.towerLayer !== undefined && 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)
@@ -234,6 +256,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)
@@ -317,13 +340,36 @@ 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)
+ if (this.$refs.towerLayer) {
+ this.$refs.towerLayer.setVisible(this.zoom >= 12)
+ }
+ if (this.$refs.thresholdLayer) {
+ this.$refs.thresholdLayer.setVisible(this.zoom >= 12)
+ }
this.$refs.pavementLayer.setVisible(zoom >= 12)
}
+ this.$refs.editLayer.groundnetLayerGroup.eachLayer(function (layer) {
+ if (layer.updateArrows !== undefined) {
+ layer.updateArrows(zoom)
+ }
+ })
+ if (this.$refs.thresholdLayer) {
+ this.$refs.thresholdLayer.zoomUpdated()
+ }
+ 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)
+ if (this.$refs.thresholdLayer) {
+ this.$refs.thresholdLayer.setVisible(this.zoom >= 12)
+ }
+ if (this.$refs.towerLayer) {
+ this.$refs.towerLayer.setVisible(this.zoom >= 12)
+ }
this.$refs.pavementLayer.setVisible(this.zoom >= 12)
}
},
diff --git a/src/renderer/components/Help.vue b/src/renderer/components/Help.vue
index 5118886..582e14a 100644
--- a/src/renderer/components/Help.vue
+++ b/src/renderer/components/Help.vue
@@ -1,7 +1,18 @@
+
@@ -51,7 +60,9 @@
},
computed: {
-
+ version: function () {
+ return ' Flightgear Airports ' + require('electron').remote.app.getVersion()
+ }
}
}
diff --git a/src/renderer/components/LeafletSidebar.vue b/src/renderer/components/LeafletSidebar.vue
index 746190d..967de5b 100644
--- a/src/renderer/components/LeafletSidebar.vue
+++ b/src/renderer/components/LeafletSidebar.vue
@@ -38,6 +38,7 @@ You should have received a copy of the GNU General Public License along with FG
+
$emit('editParking', msg)">
@@ -74,6 +75,7 @@ You should have received a copy of the GNU General Public License along with FG
import L from 'leaflet'
import AirportEdit from './AirportEdit'
import ArcEdit from './ArcEdit'
+ import ArcEditMulti from './ArcEditMulti'
import CheckPanel from './CheckPanel'
import FileSelect from './FileSelect'
import Help from './Help'
@@ -89,7 +91,7 @@ You should have received a copy of the GNU General Public License along with FG
export default {
name: 'leaflet-sidebar',
- components: { Help, AirportEdit, ArcEdit, CheckPanel, NodeEdit, ParkingEdit, ParkingGroupEdit, RunScan, FileSelect, SettingsPanel, Search, Upload, WorkInProgress },
+ components: { Help, AirportEdit, ArcEdit, ArcEditMulti, CheckPanel, NodeEdit, ParkingEdit, ParkingGroupEdit, RunScan, FileSelect, SettingsPanel, Search, Upload, WorkInProgress },
props: [],
created () {
window.addEventListener('keydown', this.doCommand)
diff --git a/src/renderer/components/SettingsPanel.vue b/src/renderer/components/SettingsPanel.vue
index ee3ea39..d3c8789 100644
--- a/src/renderer/components/SettingsPanel.vue
+++ b/src/renderer/components/SettingsPanel.vue
@@ -11,17 +11,25 @@
Airports Directory
- {{ airports_directory }}
-
-
+ {{ airports_directory }}
+
+
+
+
Flightgear Data Directory
- {{ flightgear_directory }}
-
+ {{ flightgear_directory }}
+
- Traffic Directory
- {{ Traffic_directory }}
+ Traffic Directory
+
+
+ {{ Traffic_directory }}
- APT File
- {{ apt_file }}
+ APT File
+
+
+ {{ apt_file }}
Export Directory
- {{ test_directory }}
+ {{ test_directory }}
@@ -194,6 +206,14 @@
flightgear_directory: function () {
return this.$store.state.Settings.settings.flightgearDirectory
},
+ flightgear_directory_ok: function () {
+ try {
+ fs.accessSync(this.$store.state.Settings.settings.flightgearDirectory)
+ return true
+ } catch (error) {
+ return false
+ }
+ },
AI_directory: function () {
return this.$store.state.Settings.settings.flightgearDirectory_ai
},
@@ -222,9 +242,25 @@
airports_directory: function () {
return this.$store.state.Settings.settings.airportsDirectory
},
+ airports_directory_ok: function () {
+ try {
+ fs.accessSync(this.$store.state.Settings.settings.airportsDirectory)
+ return true
+ } catch (error) {
+ return false
+ }
+ },
test_directory: function () {
return this.$store.state.Settings.settings.testDirectory
},
+ test_directory_ok: function () {
+ try {
+ fs.accessSync(this.$store.state.Settings.settings.testDirectory)
+ return true
+ } catch (error) {
+ return false
+ }
+ },
scanLogging: {
// getter
get: function () {
@@ -247,14 +283,14 @@
border-radius: 4px;
}
.label {
- padding: 10px;
+ padding: 5px;
font-weight: bold;
}
-.file-label {
- padding: 10px;
+.file_label {
+ padding: 5px;
}
.invalid {
- padding: 10px;
+ padding: 5px;
background-color: red;
}
diff --git a/src/renderer/components/ThresholdLayer.vue b/src/renderer/components/ThresholdLayer.vue
index a6f75e7..545186a 100644
--- a/src/renderer/components/ThresholdLayer.vue
+++ b/src/renderer/components/ThresholdLayer.vue
@@ -31,6 +31,10 @@
load (icao) {
// Callback for add
this.layerGroup = readThresholdXML(this.$store.state.Settings.settings.airportsDirectory, icao, this.read)
+ if (!this.layerGroup) {
+ console.warn('Threshold for ICAO not loaded ' + icao)
+ return
+ }
this.layerGroup.addTo(this.$parent.mapObject)
this.visible = true
this.icao = icao
@@ -58,13 +62,21 @@
this.visible = visible
}
}
+ },
+ zoomUpdated () {
+ this.layerGroup.eachLayer(l => {
+ if (l instanceof L.Threshold) {
+ l.updateIcon(this.$parent.mapObject)
+ }
+ })
}
+
},
computed: {
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 041b2e6..073cac5 100644
--- a/src/renderer/loaders/TaxiwaySegmentExtender.js
+++ b/src/renderer/loaders/TaxiwaySegmentExtender.js
@@ -4,6 +4,7 @@ const Vue = require('vue');
var L = require('leaflet');
const store = require('../store');
const util = require('util');
+const assign = require('core-js/fn/object/assign');
const extendTaxiSegment = function (taxiwaySegment) {
taxiwaySegment.__proto__.begin;
@@ -36,7 +37,7 @@ const extendTaxiSegment = function (taxiwaySegment) {
this.editLayer = editLayer;
this._latlngs[0].glueindex = this.begin;
this._latlngs.slice(-1)[0].glueindex = this.end;
- if(this.featureLookup) {
+ if (this.featureLookup) {
if (typeof this.featureLookup[this.begin] === 'undefined') {
this.featureLookup[this.begin] = new Array();
}
@@ -45,7 +46,7 @@ const extendTaxiSegment = function (taxiwaySegment) {
}
this.featureLookup[this.begin].push(this);
this.featureLookup[this.end].push(this);
- this.bidirectional = true;
+ this.bidirectional = true;
}
};
taxiwaySegment.__proto__.select = function () {
@@ -53,50 +54,50 @@ const extendTaxiSegment = function (taxiwaySegment) {
this.updateStyle();
};
taxiwaySegment.__proto__.selectVertex = function (index) {
- this.getLatLngs().forEach( element => {
- if (Number(element.glueindex) === index) {
- if (element.__vertex._icon != null) {
- element.__vertex.__proto__.deselect = function () {
- if (this._icon != null) {
- this._icon.style.setProperty('background-color','white');
- this._icon.style.setProperty('color','white');
- } else if (this.icon != null) {
- if (this.icon.style != null) {
- this.icon.style['background-color'] = 'white';
- } else {
- this.setStyle({ color: 'white' })
+ this.getLatLngs().forEach(element => {
+ if (Number(element.glueindex) === index) {
+ if (element.__vertex._icon != null) {
+ element.__vertex.__proto__.deselect = function () {
+ if (this._icon != null) {
+ this._icon.style.setProperty('background-color', 'white');
+ this._icon.style.setProperty('color', 'white');
+ } else if (this.icon != null) {
+ if (this.icon.style != null) {
+ this.icon.style['background-color'] = 'white';
+ } else {
+ this.setStyle({ color: 'white' })
+ }
+ } else if (this.options.icon != null) {
+ if (this.options.icon.style != null) {
+ this.options.icon.style['background-color'] = 'white';
+ } else {
+ this.options.icon._setIconStyles({ color: 'white' })
+ }
+ }
}
- } else if (this.options.icon != null) {
- if (this.options.icon.style != null) {
- this.options.icon.style['background-color'] = 'white';
+ element.__vertex._icon.style.setProperty('background-color', 'red');
+ element.__vertex._icon.style.setProperty('color', 'red');
+ } else if (element.__vertex !== undefined && element.__vertex.icon != null) {
+ if (element.__vertex.icon.style != null) {
+ element.__vertex.icon.style['background-color'] = 'red';
} else {
- this.options.icon._setIconStyles({ color: 'white' })
+ element.__vertex.setStyle({ color: 'red' })
}
- }
+ } else if (element.__vertex.options.icon != null) {
+ if (element.__vertex.options.icon.style != null) {
+ element.__vertex.options.icon.style['background-color'] = 'red';
+ } else {
+ element.__vertex.options.icon._setIconStyles({ color: 'red' })
+ }
+ }
}
- element.__vertex._icon.style.setProperty('background-color','red');
- element.__vertex._icon.style.setProperty('color','red');
- } else if (element.__vertex !== undefined && element.__vertex.icon != null) {
- if (element.__vertex.icon.style != null) {
- element.__vertex.icon.style['background-color'] = 'red';
- } else {
- element.__vertex.setStyle({ color: 'red' })
- }
- } else if (element.__vertex.options.icon != null) {
- if (element.__vertex.options.icon.style != null) {
- element.__vertex.options.icon.style['background-color'] = 'red';
- } else {
- element.__vertex.options.icon._setIconStyles({ color: 'red' })
- }
- }
- }
- });
+ });
};
taxiwaySegment.__proto__.deselect = function () {
this.options.attributes.selected = false;
this.updateStyle();
- this.getLatLngs().forEach( element => {
- if (element.__vertex!==undefined) {
+ this.getLatLngs().forEach(element => {
+ if (element.__vertex !== undefined) {
if (element.__vertex._icon != null) {
element.__vertex._icon.style['background-color'] = 'white';
} else if (element.__vertex.icon != null) {
@@ -111,128 +112,170 @@ const extendTaxiSegment = function (taxiwaySegment) {
} else {
element.__vertex.options.icon._setIconStyles({ color: 'white' })
}
- }
+ }
}
});
};
taxiwaySegment.__proto__.addListeners = function () {
this.on('click', function (event) {
- if (Number(store.default.state.Editable.index) >= 0 &&
- this.featureLookup[store.default.state.Editable.index] !== undefined) {
+ if (Number(store.default.state.Editable.index) >= 0 &&
+ this.featureLookup[store.default.state.Editable.index] !== undefined) {
this.featureLookup[store.default.state.Editable.index].forEach(element => {
element.deselect();
});
}
event.target.select();
- console.log("Click : " + event.target);
- if (store.default.state.Editable.data.arc === undefined ||
- store.default.state.Editable.data.arc !== event.target.options.attributes) {
- if (event.target.options.attributes === undefined) {
- event.target.options.attributes = {};
- }
- event.target.options.attributes.index = event.target._leaflet_id;
+ console.debug("Click : " + util.inspect(event.originalEvent));
+ if (!event.originalEvent.ctrlKey) {
+ if (store.default.state.Editable.data.arc === undefined ||
+ store.default.state.Editable.data.arc !== event.target.options.attributes) {
+ if (event.target.options.attributes === undefined) {
+ event.target.options.attributes = {};
+ }
+ event.target.options.attributes.index = event.target._leaflet_id;
- this.editLayer.featureLookup[event.target._leaflet_id] = [];
- this.featureLookup[event.target._leaflet_id].push(this);
- event.target.options.attributes.selected = true;
- store.default.dispatch('setArc', event.target.options.attributes);
- }
+ this.editLayer.featureLookup[event.target._leaflet_id] = [];
+ this.featureLookup[event.target._leaflet_id].push(this);
+ event.target.options.attributes.selected = true;
+ store.default.dispatch('setArc', event.target.options.attributes);
+ }
+ } else {
+ var arcs = event.target.expandArc(event.target.options.attributes);
+ var multiarc = {name: '', index: 900719925474099, ids: [] ,isPushBackRoute: null, direction: null};
+ if (store.default.state.Editable.data.multiarc === undefined ||
+ store.default.state.Editable.data.multiarc !== event.target.options.attributes) {
+ if (event.target.options.attributes === undefined) {
+ event.target.options.attributes = {};
+ }
+ event.target.options.attributes.index = event.target._leaflet_id;
+
+ this.editLayer.featureLookup[event.target._leaflet_id] = [];
+ this.featureLookup[event.target._leaflet_id].push(this);
+ event.target.options.attributes.selected = true;
+
+ //multiarc.name = JSON.parse(JSON.stringify(event.target.options.attributes.name));
+ //multiarc.isPushBackRoute = JSON.parse(JSON.stringify(event.target.options.attributes.isPushBackRoute));
+ //multiarc.direction = JSON.parse(JSON.stringify(event.target.options.attributes.direction));
+ if(event.target.options.attributes.name!==undefined) {
+ multiarc.name = assign(event.target.options.attributes.name);
+ }
+ multiarc.isPushBackRoute = assign(event.target.options.attributes.isPushBackRoute);
+ multiarc.direction = assign(event.target.options.attributes.direction);
+
+ this.editLayer.featureLookup[900719925474099] = [];
+
+ multiarc.ids = [];
+
+ //TODO
+ store.default.dispatch('setMultiArc', multiarc);
+ }
+ var editLayer = this.editLayer;
+ arcs.forEach(id => {
+ console.debug(id);
+ var arc = editLayer.groundnetLayerGroup.getLayer(id);
+ if (arc && arc instanceof L.Polyline) {
+ editLayer.featureLookup[900719925474099].push(arc);
+ arc.select();
+ }
+ });
+ store.default.dispatch('setMultiArcIds', arcs);
+ }
});
this.on('editable:drawing:move', function (event) {
if (dragIndex >= 0) {
this.selectVertex(dragIndex);
- console.log('GlueDrag : '+ dragIndex + '\t' + event.target.dragIndex);
+ console.log('GlueDrag : ' + dragIndex + '\t' + event.target.dragIndex);
this.follow(dragIndex, event);
}
});
this.on('editable:middlemarker:mousedown', event => {
console.debug('editable:middlemarker:mousedown');
- } ),
- this.on('editable:vertex:new', event => {
- console.debug('editable:vertex:new ' + event.vertex.getIndex() + '\t' + event.vertex.getLastIndex() + '\t');
- // Find nearest node
- let closest = this.editLayer.closestLayerSnap(event.latlng, 5)
- let taxiwaySegment = event.latlng.__vertex.editor.feature;
- if (taxiwaySegment.options.attributes === undefined) {
- taxiwaySegment.options.attributes = { direction: 'bi-directional' };
- }
- taxiwaySegment.updateStyle();
- if(event.vertex.getIndex() !== 0 && event.vertex.getIndex() !== event.vertex.getLastIndex()) {
- var nextIndex = ++taxiwaySegment.editLayer.groundnetLayerGroup.maxId;
- var splitOffNodes = taxiwaySegment.getLatLngs().splice(-1);
- var remainingNodes = taxiwaySegment.getLatLngs();
- splitOffNodes.unshift(L.latLng(remainingNodes[1].lat, remainingNodes[1].lng, remainingNodes[1].alt));
- remainingNodes[1]['glueindex'] = nextIndex;
- remainingNodes[1].attributes = { index: nextIndex, isOnRunway: 0 };
- taxiwaySegment.options.attributes.end = nextIndex;
- splitOffNodes[0]['glueindex'] = nextIndex;
- splitOffNodes[0].attributes = { index: nextIndex, isOnRunway: 0 };
- taxiwaySegment.setLatLngs(remainingNodes);
- //taxiwaySegment.editor.refresh();
- //taxiwaySegment.editor.reset();
- if( splitOffNodes.length>1) {
- var polyline = new L.Polyline(splitOffNodes, { attributes: {} });
- polyline.addTo(taxiwaySegment.editLayer.$parent.$parent.$refs.map.mapObject);
- polyline.addTo(taxiwaySegment.editLayer.groundnetLayerGroup);
- extendTaxiSegment(polyline);
- polyline.addListeners();
- polyline.setEditlayer(taxiwaySegment.editLayer);
- polyline.enableEdit(taxiwaySegment.editLayer.$parent.$parent.$refs.map.mapObject);
- polyline.editor.refresh();
- //polyline.editor.reset();
- polyline.featureLookup = this.featureLookup;
- polyline.options.attributes.name = taxiwaySegment.options.attributes.name;
- polyline.options.attributes.direction = taxiwaySegment.options.attributes.direction;
- polyline.options.attributes.isPushBackRoute = taxiwaySegment.options.attributes.isPushBackRoute;
- polyline.options.attributes.begin = nextIndex;
- polyline.options.attributes.end = taxiwaySegment.end;
- polyline.updateStyle();
- polyline.begin = nextIndex;
- polyline.end = taxiwaySegment.end;
- taxiwaySegment.end = nextIndex;
- this.editLayer.featureLookup[nextIndex] = [];
- this.featureLookup[nextIndex].push(taxiwaySegment);
- this.featureLookup[nextIndex].push(polyline);
+ }),
+ this.on('editable:vertex:new', event => {
+ console.debug('editable:vertex:new ' + event.vertex.getIndex() + '\t' + event.vertex.getLastIndex() + '\t');
+ // Find nearest node
+ let closest = this.editLayer.closestLayerSnap(event.latlng, 5)
+ let taxiwaySegment = event.latlng.__vertex.editor.feature;
+ if (taxiwaySegment.options.attributes === undefined) {
+ taxiwaySegment.options.attributes = { direction: 'bi-directional' };
}
- } else {
- // Glue to another node
- if (closest) {
- event.latlng['glueindex'] = Number(closest.glueindex);
- event.latlng.__vertex.setLatLng(closest.latlng);
- event.latlng.attributes = { index: event.latlng.glueindex, isOnRunway: 0 };
- // Push Vertex to lookup
- this.editLayer.featureLookup[event.latlng.glueindex].push(event.latlng.__vertex);
- if (taxiwaySegment.options.attributes.begin === undefined) {
- taxiwaySegment.options.attributes.begin = event.latlng['glueindex']
- } else {
- taxiwaySegment.options.attributes.end = event.latlng['glueindex']
- }
- if (taxiwaySegment.getLatLngs().length === 1) {
- taxiwaySegment.begin = closest.glueindex;
- }
- taxiwaySegment.end = closest.glueindex;
- console.log(`Closest : ${closest}`)
- } else {
- event.vertex.latlng['glueindex'] = ++this.editLayer.groundnetLayerGroup.maxId;
- event.vertex.latlng.attributes = { index: event.vertex.latlng.glueindex, isOnRunway: 0 };
- this.editLayer.featureLookup[event.vertex.latlng.glueindex] = [];
- this.editLayer.featureLookup[event.vertex.latlng.glueindex].push(event.vertex);
- this.editLayer.featureLookup[event.vertex.latlng.glueindex].push(taxiwaySegment);
- // taxiwaySegment.editor.refresh();
+ taxiwaySegment.updateStyle();
+ if (event.vertex.getIndex() !== 0 && event.vertex.getIndex() !== event.vertex.getLastIndex()) {
+ var nextIndex = ++taxiwaySegment.editLayer.groundnetLayerGroup.maxId;
+ var splitOffNodes = taxiwaySegment.getLatLngs().splice(-1);
+ var remainingNodes = taxiwaySegment.getLatLngs();
+ splitOffNodes.unshift(L.latLng(remainingNodes[1].lat, remainingNodes[1].lng, remainingNodes[1].alt));
+ remainingNodes[1]['glueindex'] = nextIndex;
+ remainingNodes[1].attributes = { index: nextIndex, isOnRunway: 0 };
+ taxiwaySegment.options.attributes.end = nextIndex;
+ splitOffNodes[0]['glueindex'] = nextIndex;
+ splitOffNodes[0].attributes = { index: nextIndex, isOnRunway: 0 };
+ taxiwaySegment.setLatLngs(remainingNodes);
+ //taxiwaySegment.editor.refresh();
//taxiwaySegment.editor.reset();
- if (taxiwaySegment.options.attributes.begin === undefined) {
- taxiwaySegment.options.attributes.begin = event.vertex.latlng['glueindex']
- taxiwaySegment.begin = event.vertex.latlng.glueindex;
- } else if (taxiwaySegment.options.attributes.end === undefined ||
- (taxiwaySegment.getLatLngs()[taxiwaySegment.getLatLngs().length - 1].glueindex &&
- Number(taxiwaySegment.getLatLngs()[taxiwaySegment.getLatLngs().length - 1].glueindex) !== taxiwaySegment.options.attributes.end)) {
- taxiwaySegment.options.attributes.end = event.vertex.latlng['glueindex']
- taxiwaySegment.end = Number(event.vertex.latlng.glueindex);
+ if (splitOffNodes.length > 1) {
+ var polyline = new L.Polyline(splitOffNodes, { attributes: {} });
+ polyline.addTo(taxiwaySegment.editLayer.$parent.$parent.$refs.map.mapObject);
+ polyline.addTo(taxiwaySegment.editLayer.groundnetLayerGroup);
+ extendTaxiSegment(polyline);
+ polyline.addListeners();
+ polyline.setEditlayer(taxiwaySegment.editLayer);
+ polyline.enableEdit(taxiwaySegment.editLayer.$parent.$parent.$refs.map.mapObject);
+ polyline.editor.refresh();
+ //polyline.editor.reset();
+ polyline.featureLookup = this.featureLookup;
+ polyline.options.attributes.name = taxiwaySegment.options.attributes.name;
+ polyline.options.attributes.direction = taxiwaySegment.options.attributes.direction;
+ polyline.options.attributes.isPushBackRoute = taxiwaySegment.options.attributes.isPushBackRoute;
+ polyline.options.attributes.begin = nextIndex;
+ polyline.options.attributes.end = taxiwaySegment.end;
+ polyline.updateStyle();
+ polyline.begin = nextIndex;
+ polyline.end = taxiwaySegment.end;
+ taxiwaySegment.end = nextIndex;
+ this.editLayer.featureLookup[nextIndex] = [];
+ this.featureLookup[nextIndex].push(taxiwaySegment);
+ this.featureLookup[nextIndex].push(polyline);
+ }
+ } else {
+ // Glue to another node
+ if (closest) {
+ event.latlng['glueindex'] = Number(closest.glueindex);
+ event.latlng.__vertex.setLatLng(closest.latlng);
+ event.latlng.attributes = { index: event.latlng.glueindex, isOnRunway: 0 };
+ // Push Vertex to lookup
+ this.editLayer.featureLookup[event.latlng.glueindex].push(event.latlng.__vertex);
+ if (taxiwaySegment.options.attributes.begin === undefined) {
+ taxiwaySegment.options.attributes.begin = event.latlng['glueindex']
+ } else {
+ taxiwaySegment.options.attributes.end = event.latlng['glueindex']
+ }
+ if (taxiwaySegment.getLatLngs().length === 1) {
+ taxiwaySegment.begin = closest.glueindex;
+ }
+ taxiwaySegment.end = closest.glueindex;
+ console.log(`Closest : ${closest}`)
+ } else {
+ event.vertex.latlng['glueindex'] = ++this.editLayer.groundnetLayerGroup.maxId;
+ event.vertex.latlng.attributes = { index: event.vertex.latlng.glueindex, isOnRunway: 0 };
+ this.editLayer.featureLookup[event.vertex.latlng.glueindex] = [];
+ this.editLayer.featureLookup[event.vertex.latlng.glueindex].push(event.vertex);
+ this.editLayer.featureLookup[event.vertex.latlng.glueindex].push(taxiwaySegment);
+ // taxiwaySegment.editor.refresh();
+ //taxiwaySegment.editor.reset();
+ if (taxiwaySegment.options.attributes.begin === undefined) {
+ taxiwaySegment.options.attributes.begin = event.vertex.latlng['glueindex']
+ taxiwaySegment.begin = event.vertex.latlng.glueindex;
+ } else if (taxiwaySegment.options.attributes.end === undefined ||
+ (taxiwaySegment.getLatLngs()[taxiwaySegment.getLatLngs().length - 1].glueindex &&
+ Number(taxiwaySegment.getLatLngs()[taxiwaySegment.getLatLngs().length - 1].glueindex) !== taxiwaySegment.options.attributes.end)) {
+ taxiwaySegment.options.attributes.end = event.vertex.latlng['glueindex']
+ taxiwaySegment.end = Number(event.vertex.latlng.glueindex);
+ }
}
}
- }
- //this.splitShape(taxiwaySegment.getLatLngs(), )
- });
+ //this.splitShape(taxiwaySegment.getLatLngs(), )
+ });
this.on('editable:vertex:deleted', event => {
console.debug('editable:vertex:deleted')
});
@@ -251,7 +294,7 @@ const extendTaxiSegment = function (taxiwaySegment) {
if (Number(store.default.state.Editable.index) >= 0 &&
this.featureLookup[store.default.state.Editable.index] !== undefined) {
this.featureLookup[store.default.state.Editable.index].forEach(element => {
- if(element.deselect !== undefined) {
+ if (element.deselect !== undefined) {
element.deselect();
}
});
@@ -268,7 +311,7 @@ const extendTaxiSegment = function (taxiwaySegment) {
this.editLayer.featureLookup[event.vertex.latlng.glueindex].forEach
store.default.dispatch('setNode', event.vertex.latlng)
this.selectVertex(store.default.state.Editable.index)
- }
+ }
}
});
var dragIndex = -1;
@@ -282,7 +325,7 @@ const extendTaxiSegment = function (taxiwaySegment) {
if (Number(store.default.state.Editable.index) >= 0 &&
this.featureLookup[store.default.state.Editable.index] !== undefined) {
this.featureLookup[store.default.state.Editable.index].forEach(element => {
- if(element.deselect !== undefined) {
+ if (element.deselect !== undefined) {
element.deselect();
}
});
@@ -297,7 +340,7 @@ const extendTaxiSegment = function (taxiwaySegment) {
parking[0].selectParking();
} else {
this.selectVertex(Number(dragIndex))
- }
+ }
}
});
this.on('editable:vertex:dragend', function (event) {
@@ -316,29 +359,79 @@ const extendTaxiSegment = function (taxiwaySegment) {
if (parking.length > 0) {
parking[0].selectParking();
} else {
- if( Number(event.vertex.latlng.glueindex) !== store.default.state.Editable.index) {
+ if (Number(event.vertex.latlng.glueindex) !== store.default.state.Editable.index) {
if (Number(store.default.state.Editable.index) >= 0 &&
- this.featureLookup[store.default.state.Editable.index] !== undefined) {
- this.featureLookup[store.default.state.Editable.index].forEach(element => {
- if(element.deselect !== undefined) {
+ this.featureLookup[store.default.state.Editable.index] !== undefined) {
+ this.featureLookup[store.default.state.Editable.index].forEach(element => {
+ if (element.deselect !== undefined) {
element.deselect();
}
});
- }
- store.default.dispatch('setNode', event.vertex.latlng)
+ }
+ store.default.dispatch('setNode', event.vertex.latlng)
}
var lines = this.featureLookup[event.vertex.latlng.glueindex].filter(n => n instanceof L.Polyline);
Vue.default.nextTick(function () {
- lines.forEach( line => {
+ lines.forEach(line => {
line.selectVertex(store.default.state.Editable.index)
});
})
- }
+ }
} catch (error) {
console.error(error);
}
});
};
+
+ taxiwaySegment.__proto__.expandArc = function (attributes) {
+ var isPushBackRoute = attributes.isPushBackRoute;
+ var ids = [];
+ var walkedNodes = [];
+ var segmentIds = [];
+ console.debug('start Walk');
+ ids = ids.concat(this.walkPushbackRoute(attributes.begin, walkedNodes, isPushBackRoute));
+ ids = ids.concat(this.walkPushbackRoute(attributes.end, walkedNodes, isPushBackRoute));
+ return ids;
+ }
+
+ taxiwaySegment.__proto__.walkPushbackRoute = function (index, walkedNodes, isPushBackRoute) {
+ console.debug('Walk Level');
+ walkedNodes.push(index)
+ var segmentIds = [];
+ var polyLines = this.featureLookup[index].filter(n => n instanceof L.Polyline);
+ if (polyLines===undefined || polyLines.length>2) {
+ console.debug('Walk ' + index + '\t' + polyLines.length);
+ return;
+ }
+
+ polyLines.forEach(l => {
+ segmentIds.push(l._leaflet_id);
+ console.debug('Walk Next ' + index + '\t' +
+ (walkedNodes.indexOf(index)<0) + '\t'+
+ l.begin + '\t'+
+ (walkedNodes.indexOf(Number(l.begin))<0) + '\t'+
+ l.end + '\t'+
+ (walkedNodes.indexOf(Number(l.end))<0) + '\t'+
+ l.options.attributes.direction + '\t' +
+ l.options.attributes.begin + '\t' +
+ l.options.attributes.end);
+ console.debug('Walk isPushBackRoute ' + l.options.attributes.isPushBackRoute + '\t' + isPushBackRoute + '\t' + (l.options.attributes.isPushBackRoute === isPushBackRoute));
+ if(l.options.attributes.isPushBackRoute === isPushBackRoute ) {
+ console.debug(Number(l.begin) === index && walkedNodes.indexOf(Number(l.end)) < 0);
+ if (Number(l.begin) === index && walkedNodes.indexOf(Number(l.end)) < 0) {
+ console.debug( 'Walk forward ' + l.options.attributes.direction );
+ segmentIds = segmentIds.concat(this.walkPushbackRoute(Number(l.end), walkedNodes, isPushBackRoute))
+ }
+ console.debug(Number(l.end) === index && walkedNodes.indexOf(Number(l.begin)) < 0);
+ if (Number(l.end) === index && walkedNodes.indexOf(Number(l.begin)) < 0 ) {
+ console.debug( 'Walk backward ' + l.options.attributes.direction );
+ segmentIds = segmentIds.concat(this.walkPushbackRoute(Number(l.begin), walkedNodes, isPushBackRoute))
+ }
+ }
+ });
+ return segmentIds;
+ }
+
/**
*
*/
@@ -392,8 +485,38 @@ 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) {
+ this.setText(' >', { repeat: true, offset: 6, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 15px serif;' } })
+ } else if (zoom <= 19 ) {
+ this.setText(' > ', { repeat: true, offset: 7, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 20px serif;' } })
+ } else {
+ this.setText(' > ', { repeat: true, offset: 10, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 30px serif;' } })
+ }
+ } else if (this.options.attributes.direction === 'backward') {
+ this.setText(null);
+ if (zoom <= 16) {
+ this.setText(' <', { repeat: true, offset: 6, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 15px serif;' } })
+ } else if (zoom <= 19 ) {
+ this.setText(' < ', { repeat: true, offset: 7, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 20px serif;' } })
+ } else {
+ this.setText(' < ', { repeat: true, offset: 10, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 30px serif;' } })
+ }
+ } else {
+ this.setText(null);
+ }
+ }
+
taxiwaySegment.__proto__.updateStyle = function () {
var style = {};
+ if(!this.options.attributes) {
+ return;
+ }
if (this.options.attributes.selected) {
style.color = 'red';
} else if (this.options.attributes.isPushBackRoute) {
@@ -403,18 +526,18 @@ const extendTaxiSegment = function (taxiwaySegment) {
style.color = '#3388ff';
}
this.setStyle(style);
- if(this._map !== null) {
+ if (this._map !== null) {
if (this.options.attributes.direction === 'forward') {
this.setText(null);
- this.setText(' > ', { repeat: true, offset: 10, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 30px serif;' } })
+ this.setText(' > ', { repeat: true, offset: 10, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 30px serif;' } })
} else if (this.options.attributes.direction === 'backward') {
this.setText(null);
- this.setText(' < ', { repeat: true, offset: 10, attributes: { fill: 'red', style: 'vertical-align: bottom; font-weight: bold; font: bold 30px serif;' } })
+ this.setText(' < ', { repeat: true, offset: 10, attributes: { fill: 'red', style: 'vertical-align: bottom; vertical-align: bottom; font-weight: bold; font: bold 30px serif;' } })
} else {
this.setText(null);
}
-
- }
+
+ }
};
};
diff --git a/src/renderer/loaders/Threshold.js b/src/renderer/loaders/Threshold.js
index 9038342..27d3e57 100644
--- a/src/renderer/loaders/Threshold.js
+++ b/src/renderer/loaders/Threshold.js
@@ -1,141 +1,85 @@
+/*
+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');
-const turf = require('@turf/turf');
-const util = require('util');
-const store = require('../store');
+const fs = require('fs');
+const path = require('path');
-var $ = require('jquery');
-L.Threshold = L.Circle.extend({
- select() {
- var style = {};
- style['color'] = 'red';
- this.setStyle(style);
- },
- addListeners: function () {
- this.on('editable:drawing:move', function (event) {
- console.log("Move : ", event);
- console.log("Move : ", event.latlng);
- // Is it the edit vertex (Middle) moving?
- if(event.target.editor._resizeLatLng.__vertex._icon !== event.sourceTarget._element){
- event.target.setLatLng(event.latlng);
- event.target.updateVertexFromDirection();
- this.follow(event.target.id, event);
+/**http://wiki.openstreetmap.org/wiki/Zoom_levels*/
+
+
+L.Threshold = L.Marker.extend({
+ options: {
+ zIndexOffset: 20000,
+ },
+ 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) {
+ console.debug(`Lat Lng Threshold ${this.getLatLng()}`);
+ if(map !== null) {
+ var metersPP = this.metersPerPixel(map.getCenter().lat, map.getZoom());
+ console.debug('Old Meters per pixel ' + this.metersPP);
+ console.debug('New Meters per pixel ' + metersPP);
+ if(this._metersPP != metersPP) {
+ var pixelSize = (this.iconSize/2) / metersPP;
+ var scale = pixelSize/this.iconSize;
+ var offset = 0;//-(this.iconSize/2);
+ this.setIcon(L.divIcon({
+ iconSize: 64,
+ className: 'threshold-marker-icon',
+ html: `${this.svg}
`,
+ }));
+
+ this.update(this.getLatLng());
+ console.debug();
+ this.setLatLng(this.getLatLng());
+ this._metersPP = metersPP;
}
- else if(event.target.editor._resizeLatLng.__vertex._icon === event.sourceTarget._element) {
- event.target.updateDirectionFromVertex();
- event.target.updateVertexFromDirection();
- }
- });
- /*
- this.on('editable:vertex:drag', function (event) {
- console.log("Drag : ", event);
- });
- */
- this.on('click', function (event) {
- console.log("Click : " + event.target);
- store.default.dispatch('setParking', event.target.options.attributes);
- this.select();
- this.unwatch = store.default.watch(
- function (state) {
- return state.Editable.data.parking;
- },
- () => {
- if (event.target instanceof L.Threshold) {
- event.target.setStyle({color : '#3388ff'});
- this.unwatch();
- }
- }
- ,
- {
- deep: true //add this if u need to watch object properties change etc.
- }
- );
- });
- this.on('editable:vertex:clicked', function (event) {
- console.log(this.featureLookup[event.vertex.glueindex]);
- if(event.target.editor._resizeLatLng.__vertex._icon !== event.sourceTarget._element){
- event.vertex._icon.style['background-color'] = 'red';
- store.default.dispatch('setParking', event.target.options.attributes);
- this.unwatch = store.default.watch(
- function (state) {
- return state.Editable.data.parking;
- },
- () => {
- event.target.setStyle({color : '#3388ff'});
- this.unwatch();
- }
- ,
- {
- deep: true //add this if u need to watch object properties change etc.
- }
- );
+ }
+ },
+ onAdd : function(map) {
+ var metersPP = this.metersPerPixel(map.getCenter().lat, map.getZoom());
+ 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);
+ },
- }
-
- });
-
- this.on('editable:disable', function (event) {
- event.target.removeDirection();
- });
- },
- updateStyle: function () {
-
- },
- turfToLatLng: function (turfPoint) {
- return {lat: turfPoint.geometry.coordinates[1], lng: turfPoint.geometry.coordinates[0]};
- },
- extensions: function (editLayer) {
- this.createDirection();
- if (typeof this.featureLookup[this.id] === 'undefined') {
- this.featureLookup[this.id] = [];
- }
- this.featureLookup[this.id].push(this);
- },
-
- _getLatRadius: function () {
- return this._mRadius;
- },
-
- _getLngRadius: function () {
- return this._mRadius;
+ pixelValue: function (latitude, meters, zoomLevel) {
+ return meters / metersPerPixel(latitude, zoomLevel);
},
+
});
-var threshold = function (n, layerGroup) {
- //console.log(n.attr('lat') + " " + n.attr('lon'));
- var latlon = convert(n.find('lat/text()').text() + " " + n.find('lon/text()').text());
- //console.log(latlon.decimalLatitude);
- //console.log(convert(n.attr('lat') + " " + n.attr('lon')).decimalLongitude);
- const circle = new L.Threshold([latlon.decimalLatitude, latlon.decimalLongitude], { radius: 10, attributes: {} });
- circle.on('editable:enable', function (event) {
- // event.target.createDirection();
- });
- /*
-
-*/
- //circle.attributes = { type: n.attr('type'), name: n.attr('name'), radius: Number(n.attr('radius')), airlineCodes: n.attr('airlineCodes'), heading: Number(n.attr('heading')) };
+L.Threshold.addInitHook(function(){
+ this.svg = this.stripSVG('FGA_THR.svg');
+ this.iconSize = 500;
+});
- $.each( n.attrs, function( key, value ) {
- console.log( '$', circle.id, key , value);
-
- if(isNaN(value))
- circle.options.attributes[ key ] = value;
- else
- circle.options.attributes[ key ] = Number( value);
- });
- circle.addTo(layerGroup);
- return circle;
+//Builds a marker for a ai or multiplayer aircraft
+var threshold = function (n, options) {
+ var latlon = convert(n.find('lat/text()').text() + " " + n.find('lon/text()').text());
+ var heading = n.find('hdg-deg/text()').text();
+
+ var marker = new L.Threshold([latlon.decimalLatitude, latlon.decimalLongitude], {heading: heading});
+ return marker;
}
-module.exports = threshold;
\ No newline at end of file
+module.exports = threshold;
diff --git a/src/renderer/loaders/Tower.js b/src/renderer/loaders/Tower.js
new file mode 100644
index 0000000..0180eac
--- /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: 64,
+ className: 'tower-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/groundnet_writer.js b/src/renderer/loaders/groundnet_writer.js
index 5fa6463..4fc2c74 100644
--- a/src/renderer/loaders/groundnet_writer.js
+++ b/src/renderer/loaders/groundnet_writer.js
@@ -60,6 +60,11 @@ function walkPushbackRoute (index, walkedNodes, pushBackNodes) {
exports.writeGroundnetXML = function (fDir, icao, featureList) {
try {
+ try { fs.mkdirSync(path.join(fDir), { recursive: true })} catch (err) { }
+ try { fs.mkdirSync(path.join(fDir, icao[0]),{ recursive: true })} catch (err) { }
+ try { fs.mkdirSync(path.join(fDir, icao[0], icao[1]), { recursive: true })} catch (err) { }
+ try { fs.mkdirSync(path.join(fDir, icao[0], icao[1], icao[2]), { recursive: true })} catch (err) { }
+
var f = path.join(fDir, icao[0], icao[1], icao[2], icao + '.groundnet.new.xml');
var fBak = path.join(fDir, icao[0], icao[1], icao[2], icao + '.groundnet.bak.xml');
@@ -201,7 +206,12 @@ var mapParkings = function (o) {
console.debug(o.options.attributes.airlineCodes);
parking['@airlineCodes'] = o.options.attributes.airlineCodes;
}
- if(o.options.attributes.number) {
+ if(o.options.attributes.number !== undefined &&
+ typeof o.options.attributes.number === 'number' || (
+ typeof o.options.attributes.number === 'string' &&
+ o.options.attributes.number.trim() !== ''
+ )
+ ) {
console.debug(o.options.attributes.number);
parking['@number'] = o.options.attributes.number;
}
diff --git a/src/renderer/loaders/threshold_loader.js b/src/renderer/loaders/threshold_loader.js
index 9b6b5da..31ae532 100644
--- a/src/renderer/loaders/threshold_loader.js
+++ b/src/renderer/loaders/threshold_loader.js
@@ -50,8 +50,16 @@ exports.readThresholdXML = function (fDir, icao, force) {
thresholdNodes.map(n => {
- var circle = threshold(n, layerGroup);
- features.push(circle);
+ var icon = threshold(n);
+ icon.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(circle);
}).sort();
return layerGroup;
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/src/renderer/store/modules/Editable.js b/src/renderer/store/modules/Editable.js
index 1c10641..45270bf 100644
--- a/src/renderer/store/modules/Editable.js
+++ b/src/renderer/store/modules/Editable.js
@@ -1,15 +1,28 @@
+/**
+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/.
+*/
+
import Vue from 'vue'
const state = {
type: 'none',
index: 'none',
editing: false,
- data: {airports: {}, parking: {}, arc: {}, node: {}, runway: {}}
+ data: {airports: {}, parking: {}, arc: {}, multiarc: {}, node: {}, runway: {}}
}
const SET_EDIT_AIRPORT = 'SET_EDIT_AIRPORT'
const SET_EDIT_PARKING = 'SET_EDIT_PARKING'
const SET_EDIT_ARC = 'SET_EDIT_ARC'
+const SET_EDIT_MULTI_ARC = 'SET_EDIT_MULTI_ARC'
const SET_EDIT_RUNWAY = 'SET_EDIT_RUNWAY'
const mutations = {
@@ -62,6 +75,34 @@ const mutations = {
Vue.set(state, 'index', arc.index)
Vue.set(state, 'type', 'arc')
},
+ SET_EDIT_MULTI_ARC (state, arc) {
+ if (arc === undefined) {
+ return
+ }
+ if (!state.data || state.type !== 'multiarc') {
+ Vue.set(state, 'data', {multiarc: {}})
+ }
+ Vue.set(state.data.multiarc, 'isPushBackRoute', arc.isPushBackRoute)
+ Vue.set(state.data.multiarc, 'direction', arc.direction)
+ if (state.data.multiarc.name === undefined) {
+ Vue.set(state.data.multiarc, 'name', '')
+ }
+ Vue.set(state, 'index', arc.index)
+
+ Vue.set(state, 'type', 'multiarc')
+ },
+ 'SET_EDIT_MULTI_ARC_IDS' (state, arcs) {
+ if (arcs === undefined) {
+ return
+ }
+ if (!state.data || state.type !== 'multiarc') {
+ return
+ }
+ if (state.data.multiarc.ids === undefined) {
+ state.data.multiarc.ids = []
+ }
+ state.data.multiarc.ids = state.data.multiarc.ids.concat(arcs.filter(n => n).filter((v, i, a) => a.indexOf(v) === i))
+ },
'SET_EDIT_PARKING_NAME' (state, parkingName) {
Vue.set(state.data.parking, 'name', parkingName)
},
@@ -91,13 +132,25 @@ const mutations = {
Vue.set(state.data.parking, 'coords', coords)
},
'SET_EDIT_ARC_NAME' (state, arcName) {
- Vue.set(state.data.arc, 'name', arcName)
+ if (state.type === 'arc') {
+ Vue.set(state.data.arc, 'name', arcName)
+ } else {
+ Vue.set(state.data.multiarc, 'name', arcName)
+ }
},
'SET_EDIT_PUSHBACK' (state, isPushBackRoute) {
- Vue.set(state.data.arc, 'isPushBackRoute', Number(isPushBackRoute))
+ if (state.type === 'arc') {
+ Vue.set(state.data.arc, 'isPushBackRoute', Number(isPushBackRoute))
+ } else {
+ Vue.set(state.data.multiarc, 'isPushBackRoute', Number(isPushBackRoute))
+ }
},
'SET_EDIT_DIRECTION' (state, direction) {
- Vue.set(state.data.arc, 'direction', direction)
+ if (state.type === 'arc') {
+ Vue.set(state.data.arc, 'direction', direction)
+ } else {
+ Vue.set(state.data.multiarc, 'direction', direction)
+ }
},
'SET_EDIT_HOLDPOINTTYPE' (state, holdPointType) {
Vue.set(state.data.node, 'holdPointType', holdPointType)
@@ -132,6 +185,12 @@ const actions = {
async setArc (context, arc) {
context.commit(SET_EDIT_ARC, arc)
},
+ async setMultiArc (context, arc) {
+ context.commit(SET_EDIT_MULTI_ARC, arc)
+ },
+ async setMultiArcIds (context, arc) {
+ context.commit('SET_EDIT_MULTI_ARC_IDS', arc)
+ },
async setNode (context, node) {
context.commit('SET_EDIT_NODE', node.attributes)
context.commit('SET_EDIT_NODE_COORDS', node.lat.toFixed(6) + ' ' + node.lng.toFixed(6))
diff --git a/src/renderer/store/modules/Loading.js b/src/renderer/store/modules/Loading.js
index 75a16ee..d6cc7bf 100644
--- a/src/renderer/store/modules/Loading.js
+++ b/src/renderer/store/modules/Loading.js
@@ -31,9 +31,15 @@ const actions = {
context.commit('SET_ICAO_LOADING', p)
},
async setGroundnetLoaded (context, p) {
+ if (typeof p !== 'boolean') {
+ console.error('Not Boolean')
+ }
context.commit('SET_GROUNDNET_LOADED', p)
},
async setPavementLoaded (context, p) {
+ if (typeof p !== 'boolean') {
+ console.error('Not Boolean')
+ }
context.commit('SET_PAVEMENT_LOADED', p)
}
}
diff --git a/src/renderer/utils/scan.js b/src/renderer/utils/scan.js
index dd951e0..303bfc0 100644
--- a/src/renderer/utils/scan.js
+++ b/src/renderer/utils/scan.js
@@ -186,6 +186,9 @@ function scanTrafficIntoDB(p, features) {
function traverseDir(dir) {
var result = [];
+ if(!fs.existsSync(dir)) {
+ return result;
+ }
fs.readdirSync(dir).forEach(file => {
let fullPath = path.join(dir, file);
if (fs.lstatSync(fullPath).isDirectory()) {
diff --git a/static/FGA_ACT_A_GA.svg b/static/FGA_ACT_A_GA.svg
new file mode 100644
index 0000000..ea3bfb2
--- /dev/null
+++ b/static/FGA_ACT_A_GA.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/static/FGA_ACT_B_PROP.svg b/static/FGA_ACT_B_PROP.svg
new file mode 100644
index 0000000..cfb1b14
--- /dev/null
+++ b/static/FGA_ACT_B_PROP.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/static/FGA_ACT_B_SHORTEN.svg b/static/FGA_ACT_B_SHORTEN.svg
new file mode 100644
index 0000000..9fffc0e
--- /dev/null
+++ b/static/FGA_ACT_B_SHORTEN.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/static/FGA_ACT_C.svg b/static/FGA_ACT_C.svg
new file mode 100644
index 0000000..1353d30
--- /dev/null
+++ b/static/FGA_ACT_C.svg
@@ -0,0 +1,3 @@
+
+
+image/svg+xml
diff --git a/static/FGA_ACT_D.svg b/static/FGA_ACT_D.svg
new file mode 100644
index 0000000..87895c4
--- /dev/null
+++ b/static/FGA_ACT_D.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/static/FGA_ACT_E.svg b/static/FGA_ACT_E.svg
new file mode 100644
index 0000000..502a9a4
--- /dev/null
+++ b/static/FGA_ACT_E.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/static/FGA_ACT_F.svg b/static/FGA_ACT_F.svg
new file mode 100644
index 0000000..fee4f5e
--- /dev/null
+++ b/static/FGA_ACT_F.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+image/svg+xml
+
+
+
+
+
+
+
+
+
+
diff --git a/static/FGA_THR.svg b/static/FGA_THR.svg
new file mode 100644
index 0000000..aa41794
--- /dev/null
+++ b/static/FGA_THR.svg
@@ -0,0 +1,89 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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
+
+
+
+
+
+
+
+
+
+
+