Files
flightgear-airports-old/src/renderer/components/EditLayer.vue
2020-12-31 16:01:00 +01:00

1058 lines
42 KiB
Vue

<!--
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/.
-->
<template></template>
<script lang="js">
/* eslint-disable */
import {LMap, LMarker} from 'vue2-leaflet'
import L from 'leaflet'
import LEdit from 'leaflet-editable/src/Leaflet.Editable.js'
import {readGroundnetXML, addFeature} from '../loaders/groundnet_loader'
import {extendTaxiSegment} from '../loaders/TaxiwaySegmentExtender'
import {writeGroundnetXML} from '../loaders/groundnet_writer'
import L2 from 'leaflet-textpath'
import Vue from 'vue'
import { MessageBox } from 'element-ui';
import { EventBus } from './event-bus.js';
const turf = require('@turf/turf')
const Coordinates = require('coordinate-parser');
const path = require('path')
const fs = require('fs')
var selectedItem
// import {LSymbol} from 'leaflet-polylinedecorator'
export default {
name: 'edit-layer',
components: {},
props: [],
created () {
[LMap, LMarker, L, LEdit, L2]
console.log('Created Editlayer')
// console.log(LSymbol)
},
mounted () {
this.selectionLayerGroup = L.layerGroup();
this.selectionLayerGroup.addTo(this.$parent.mapObject)
this.$store.watch(
function (state) {
return state.Editable.data.node;
},
() => { this.editedNode() }
,
{
deep: true //add this if u need to watch object properties change etc.
}
);
this.$store.watch(
function (state) {
return state.Editable.data.arc;
},
() => { this.editedArc() }
,
{
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;
},
() => { this.editedParking() }
,
{
deep: true //add this if u need to watch object properties change etc.
}
);
this.$store.watch(
function (state) {
return state.Parkings.items;
},
() => { this.editedParkings() }
,
{
deep: true //add this if u need to watch object properties change etc.
}
);
},
beforeDestroy () {
this.remove()
},
data () {
return {
maxId: 1, icao: String, checking: false, editing: false
}
},
methods: {
getParkings(ring) {
var poly = turf.polygon(ring);
var parkings = []
this.groundnetLayerGroup.eachLayer(l => {
//console.log(l)
if (l instanceof L.ParkingSpot) {
var tp = turf.point([l.getLatLng().lat, l.getLatLng().lng]);
if (turf.booleanPointInPolygon(tp, poly)) {
parkings.push(l);
}
}
})
this.selection = parkings;
return parkings;
},
load (icao, force) {
if (this.groundnetLayerGroup !== undefined) {
this.groundnetLayerGroup.removeFrom(this.$parent.mapObject)
}
this.$parent.$parent.setIcao(icao)
this.icao = icao
this.groundnetLayerGroup = readGroundnetXML(this.$store.state.Settings.settings.airportsDirectory, icao, force)
if (this.groundnetLayerGroup === undefined) {
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()
}
if (l.updateArrows !== undefined) {
l.updateArrows(this.$store.state.Settings.zoom)
}
})
console.log(this.groundnetLayerGroup.maxId)
this.groundnetLayerGroup.addTo(this.$parent.mapObject)
this.icao = icao
console.log(EventBus)
EventBus.$emit('i-got-clicked', 1);
},
visible (feature) {
let bounds = this.$store.state.Settings.bounds
let coordinates = feature.geometry.coordinates
let ret = bounds.getNorthEast().lat > Number(coordinates[1]) &&
bounds.getNorthEast().lng > Number(coordinates[0])
let ret2 = bounds.getSouthWest().lat < Number(coordinates[1]) &&
bounds.getSouthWest().lng < Number(coordinates[0])
return ret && ret2
},
deferredMountedTo (parent) {
this.layerGroup = L.layerGroup()
},
remove () {
if (this.layerGroup) {
this.$parent.removeLayer(this.layerGroup)
}
},
add () {
if (this.$parent._isMounted) {
this.deferredMountedTo(this.$parent.mapObject)
}
},
showCheck() {
Vue.set(this, 'checking', true)
},
getEditing () {
return this.editing;
},
onEdit (event) {
switch (event.type) {
case 'parking-group-angle':
this.selection.forEach(element => {
element.updateHeading(event.angle)
});
break;
case 'parking-group-wingspan':
this.selection.forEach(element => {
element.updateRadius(event.wingspan/2)
});
break;
default:
break;
}
},
enableEdit () {
this.editable = true
this.editing = true
this.$store.commit('SET_EDIT', true)
this.featureLookup = [];
this.groundnetLayerGroup.eachLayer(l => {
l.enableEdit()
l.featureLookup = this.featureLookup;
if (typeof l.extensions === 'function') {
l.extensions(this)
}
if (typeof l.bringToFront === 'function') {
l.bringToFront()
}
if (typeof l.updateStyle === 'function') {
l.updateStyle()
}
if (typeof l.setInteractive === 'function') {
l.setInteractive(true)
}
})
this.$store.dispatch('addWip', {icao: this.icao}); },
disableEdit () {
this.editable = false
this.editing = false
this.$store.commit('SET_EDIT', false)
this.groundnetLayerGroup.eachLayer(l => {
if (typeof l.setInteractive === 'function') {
l.setInteractive(false)
}
l.disableEdit()
})
},
deleteFeature () {
switch (this.$store.state.Editable.type) {
case 'node':
this.removeNode(this.$store.state.Editable.index)
break;
case 'runway':
this.removeNode(this.$store.state.Editable.index)
break;
case 'parking':
this.removeParking(this.$store.state.Editable.index)
break;
case 'arc':
this.removeArc(this.$store.state.Editable.data.arc)
break;
default:
console.log('Remove : ' + this.$store.state.Editable.type)
}
},
findRouteToPushback (index) {
if (this.featureLookup===undefined || this.featureLookup[index]===undefined) {
return
}
var parking = this.featureLookup[index].filter(n => n instanceof L.ParkingSpot)
var walkedNodes = [index]
var pushBackNodes = []
this.walkPushbackRoute(index, walkedNodes, pushBackNodes)
return pushBackNodes
},
walkPushbackRoute (index, walkedNodes, pushBackNodes) {
var polyLines = this.featureLookup[index].filter(n => n instanceof L.Polyline)
var holdNodes = this.featureLookup[index].filter(n => n instanceof L.HoldNode)
holdNodes.forEach(n => {
pushBackNodes.push(Number(n.glueindex));
});
polyLines.forEach(l => {
if( l.options.attributes.isPushBackRoute === 1 ) {
if (Number(l.begin) === index && walkedNodes.indexOf(Number(l.end)) < 0) {
walkedNodes.push(Number(l.end))
pushBackNodes.concat(this.walkPushbackRoute(Number(l.end), walkedNodes, pushBackNodes))
}
if (Number(l.end) === index && walkedNodes.indexOf(Number(l.begin)) < 0 ) {
walkedNodes.push(Number(l.begin))
pushBackNodes.concat(this.walkPushbackRoute(Number(l.begin), walkedNodes, pushBackNodes))
}
}
});
},
removeArc (arc) {
console.debug('Remove Arc : ' + arc);
var arcLayer = this.groundnetLayerGroup.getLayer(this.$store.state.Editable.index);
arcLayer.removeFrom(this.groundnetLayerGroup);
},
removeParking (index) {
if(this.featureLookup[index]===undefined) {
console.error("Lookup " + index + " failed ");
return;
}
this.featureLookup[index].forEach((element, i) => {
if (element instanceof L.ParkingSpot) {
element.removeFrom(this.groundnetLayerGroup);
}
});
},
show (index) {
if(Number.isNaN(index)) {
return;
}
if(this.featureLookup===undefined || this.featureLookup[index]===undefined) {
console.error("Lookup " + index + " failed ");
this.buildLookup()
}
if (Number(this.$store.state.Editable.index) >= 0 &&
this.featureLookup[this.$store.state.Editable.index]!==undefined) {
this.featureLookup[this.$store.state.Editable.index].forEach(element => {
element.deselect();
});
}
this.featureLookup[index].forEach((element, i) => {
if (element instanceof L.Polyline) {
element._latlngs.forEach((e1, index1) => {
console.log(e1);
if (e1.attributes.index===Number(index)) {
var latlng = {};
latlng.lat = e1.lat;
latlng.lng = e1.lng;
this.$store.dispatch('setCenter', latlng);
if(e1.__vertex !== undefined && e1.__vertex !== null && e1.__vertex._icon.style!=null) {
e1.__vertex._icon.style['background-color'] = 'red';
}
return;
}
});
} else if (element instanceof L.RunwayNode) {
var latlng = {};
latlng.lat = element._latlng.lat;
latlng.lng = element._latlng.lng;
if (this.selectedItem != null && this.selectedItem.deselect !== undefined) {
this.selectedItem.deselect();
}
this.selectedItem = element;
element.select();
this.$store.dispatch('setCenter', latlng);
} else if (element instanceof L.ParkingSpot) {
console.log(element);
var latlng = {};
latlng.lat = element._latlng.lat;
latlng.lng = element._latlng.lng;
if (this.selectedItem != null && this.selectedItem.deselect !== undefined) {
this.selectedItem.deselect();
}
this.selectedItem = element;
element.select();
this.$store.dispatch('setCenter', latlng);
}
});
},
buildLookup () {
this.featureLookup = {};
this.groundnetLayerGroup.eachLayer((layer) => {
if (layer instanceof L.Polyline) {
// console.log(layer._latlngs)
layer._latlngs.forEach(latlng => {
if (latlng.attributes.index) {
if( this.featureLookup[latlng.attributes.index] == undefined) {
this.featureLookup[latlng.attributes.index] = [];
}
this.featureLookup[latlng.attributes.index].push(layer);
}
})
} else if (layer instanceof L.RunwayNode || layer instanceof L.ParkingSpot || layer instanceof L.HoldNode) {
if( this.featureLookup[layer.glueindex] == undefined) {
this.featureLookup[layer.glueindex] = [];
}
this.featureLookup[layer.glueindex].push(layer);
} else {
console.warn(layer)
}
})
},
getPointCoords (index) {
if(this.featureLookup[index]===undefined) {
console.error("Lookup " + index + " failed ");
return;
}
return this.featureLookup[index].map((element, i) => {
if (element instanceof L.Polyline) {
var latLng = element._latlngs.map((e1, index1) => {
console.log(e1);
if (e1.attributes.index===index) {
var latlng = {};
latlng.lat = e1.lat;
latlng.lng = e1.lng;
return latlng;
}
}).filter(n => n);
return latLng[0];
} else if (element instanceof L.RunwayNode) {
var latlng = {};
latlng.lat = element._latlng.lat;
latlng.lng = element._latlng.lng;
return latlng;
} else if (element instanceof L.ParkingSpot) {
console.log(element);
var latlng = {};
latlng.lat = element._latlng.lat;
latlng.lng = element._latlng.lng;
return latlng;
}
}).filter(n => n);
},
/**
*
*/
setPointCoords (index, coordinates) {
var position = new Coordinates(coordinates);
var latlng = {lat: position.latitude, lng: position.longitude };
if(this.featureLookup[index]===undefined) {
console.error("Lookup " + index + " failed ");
return;
}
return this.featureLookup[index].map((element, i) => {
if (element instanceof L.RunwayNode) {
element.setLatLng(latlng);
}
else if (element instanceof L.HoldNode) {
element.setLatLng(latlng);
}
else if (element instanceof L.ParkingSpot) {
// element.disableEdit();
element.setLatLng(latlng);
// element.enableEdit();
// element.extensions();
element.updateMiddleMarker();
element.updateVertexFromDirection();
element.updateWheelPos();
element.updateBox();
}
else if (element instanceof L.Polyline) {
element._latlngs.forEach((e1, index1) => {
if (e1.attributes.index===index && (
latlng.lat !== element.getLatLngs()[index1].lat ||
latlng.lng !== element.getLatLngs()[index1].lng
)
) {
element.getLatLngs()[index1].update(latlng);
element.setLatLngs(element.getLatLngs());
element.updateBeginVertex(latlng);
element.editor.refresh();
element.editor.reset();
element.updateMiddle();
}
})
} else if (element instanceof L.Editable.VertexMarker) {
/*
console.log(element);
element.setLatLng(latlng);
element.latlngs.forEach((latlng1, index) => {
console.log(latlng1);
if (latlng1.__vertex === element) {
latlng1.update(latlng);
}
});
element.editor.feature.setLatLngs(element.latlngs);
element.editor.feature.updateMiddle();
*/
}
});
},
refreshLookup(index) {
//element.__vertex
this.featureLookup[index] = this.featureLookup[index].filter(item => {
return !(item instanceof L.Editable.VertexMarker && item.editor.__vertex === undefined)
}
);
this.featureLookup[index].forEach((element, i) => {
if (element instanceof L.Polyline) {
element.editor.refresh();
element.editor.reset();
}
});
},
removeNode (index) {
if(this.featureLookup[index]===undefined) {
console.error("Lookup " + index + " failed ");
return;
}
try {
this.featureLookup[index].forEach((element, i) => {
if (element instanceof L.Polyline) {
console.debug('Poly : ' + i + ' ' + element.attributes);
// Complete poly with be removed
if ( element._latlngs.length <= 3 ) {
console.debug('Remove short ' + element);
if(Number(element.begin) !== index) {
this.featureLookup[Number(element.begin)] = this.featureLookup[Number(element.begin)].filter(item => item !== element);
this.refreshLookup(Number(element.begin))
}
if(Number(element.end) !== index) {
this.featureLookup[Number(element.end)] = this.featureLookup[Number(element.end)].filter(item => item !== element);
this.refreshLookup(Number(element.end))
}
element.removeFrom(this.groundnetLayerGroup);
element.removeFrom(this.$parent.mapObject);
}
else {
element.getLatLngs().forEach((e1, index1) => {
console.debug('Remove Long' + index1 + ' ' + e1);
if (e1.attributes.index===index) {
var splitOffNodes = element.getLatLngs().splice(index1);
element.editor.refresh();
element.editor.reset();
splitOffNodes.splice(0, 1);
if( splitOffNodes.length>1) {
var polyline = new L.Polyline(splitOffNodes, { attributes: {} }).addTo(layerGroup);
extendTaxiSegment(polyline);
polyline.addListeners();
polyline.setEditlayer(this);
polyline.enableEdit();
polyline.editor.refresh();
polyline.editor.reset();
polyline.addTo(this.groundnetLayerGroup);
polyline.end = element.end;
// Remove from end lookup
this.featureLookup[element.options.attributes.end] = this.featureLookup[element.options.attributes.end].filter(item => item !== element);
// push to the end lookup
this.featureLookup[element.options.attributes.end].push(polyline);
}
if(element.getLatLngs().length === 1) {
this.featureLookup[index] = this.featureLookup[index].filter(item => item !== element);
element.removeFrom(this.groundnetLayerGroup);
}
// element.editor.splitShape(element._latlngs, index1);
console.log('Removed');
}
});
}
} else if (element instanceof L.RunwayNode) {
console.log('Runway : ' + i + ' ' + element.attributes);
this.featureLookup[index] = this.featureLookup[index].filter(item => item !== element);
element.removeFrom(this.groundnetLayerGroup);
} else {
console.warn('WTF' + element);
}
});
} catch (error) {
console.error(error);
}
},
stopDrawing () {
this.$parent.mapObject.editTools.stopDrawing()
},
drawPolyline () {
var polyLine = this.$parent.mapObject.editTools.startPolyline()
polyLine.addTo(this.groundnetLayerGroup)
polyLine.groundnetLayerGroup = this.groundnetLayerGroup;
polyLine.attributes = [];
polyLine.featureLookup = this.featureLookup;
extendTaxiSegment(polyLine);
polyLine.setEditlayer(this);
//polyLine.extensions(this);
polyLine.addListeners()
polyLine.on('editable:drawing:end', event => {
console.log(event)
event.target.addTo(this.groundnetLayerGroup)
})
},
drawForwardPolyline () {
var polyLine = this.$parent.mapObject.editTools.startPolyline()
polyLine.addTo(this.groundnetLayerGroup)
polyLine.groundnetLayerGroup = this.groundnetLayerGroup;
polyLine.attributes = [];
polyLine.options.attributes = {direction: 'forward' };
polyLine.featureLookup = this.featureLookup;
extendTaxiSegment(polyLine);
polyLine.setEditlayer(this);
//polyLine.extensions(this);
polyLine.addListeners()
polyLine.on('editable:drawing:end', event => {
console.debug(event)
event.target.addTo(this.groundnetLayerGroup)
})
},
drawPushbackPolyline () {
var polyLine = this.$parent.mapObject.editTools.startPolyline()
polyLine.addTo(this.groundnetLayerGroup)
polyLine.groundnetLayerGroup = this.groundnetLayerGroup;
polyLine.attributes = [];
polyLine.options.attributes = {isPushBackRoute: 1, direction: 'bi-directional' };
polyLine.featureLookup = this.featureLookup;
extendTaxiSegment(polyLine);
polyLine.setEditlayer(this);
polyLine.updateStyle();
//polyLine.extensions(this);
polyLine.addListeners()
polyLine.on('editable:drawing:end', event => {
console.debug(event)
event.target.addTo(this.groundnetLayerGroup)
var pt = event.sourceTarget._latlngs[event.sourceTarget._latlngs.length-1];
pt.attributes['holdPointType'] = 'PushBack'
var nIndex = pt.attributes.index
var fa_icon = "<div style='background-color:#4838cc;' class='marker-pin'></div><i class='fas fa-arrows-alt-h'></i>";
const icon = new L.DivIcon({
className: 'custom-div-icon',
html: fa_icon,
iconSize: [30, 42],
iconAnchor: [15, 42]
});
const node = new L.HoldNode(pt, { icon: icon });
node.glueindex = nIndex;
node.addTo(this.groundnetLayerGroup);
node.featureLookup = this.featureLookup;
node['holdPointType'] = 'PushBack'
this.featureLookup[nIndex].push(node);
node.addListeners();
node.extensions();
})
},
editedParking() {
if (this.$store.state.Editable.index === undefined ||
this.$store.state.Editable.data.parking === undefined ||
this.featureLookup===undefined) {
return
}
console.log('Edited Parking : ' + this.$store.state.Editable.data.parking)
//Notify list
if (this.featureLookup[this.$store.state.Editable.index]===undefined) {
return
}
this.featureLookup[this.$store.state.Editable.index].forEach((element,index) => {
if (element instanceof L.ParkingSpot) {
element.options.attributes = Object.assign({}, this.$store.state.Editable.data.parking)
element.updateVertexFromDirection();
element.updateWheelPos();
element.updateBox();
}
})
if (this.$store.state.Editable.data.parking.coords) {
this.setPointCoords(this.$store.state.Editable.index, this.$store.state.Editable.data.parking.coords)
}
},
editedParkings() {
if (this.featureLookup===undefined) {
console.warn("Lookup undefined");
this.buildLookup()
}
if (this.featureLookup===undefined) {
return
}
console.debug('Edited Parkings : ' + this.$store.state.Parkings.items)
this.$store.state.Parkings.items.forEach( newElement => {
console.debug(newElement);
if(this.featureLookup[newElement.index]) {
this.featureLookup[newElement.index].forEach((element,index) => {
if (element instanceof L.ParkingSpot) {
element.options.attributes.name = newElement.name
element.options.attributes.number = newElement.number
element.options.attributes.type = newElement.type
//element.updateVertexFromDirection();
}
})
}
})
/*
this.$store.dispatch('updatedParking', this.$store.state.Editable.data.parking);
this.featureLookup[this.$store.state.Editable.index].forEach((element,index) => {
if (element instanceof L.ParkingSpot) {
element.options.attributes = Object.assign({}, this.$store.state.Editable.data.parking)
element.updateVertexFromDirection();
}
})
*/
},
editedArc() {
if (!this.groundnetLayerGroup ||
this.$store.state.Editable.index === undefined ||
this.$store.state.Editable.data.arc === undefined ||
this.featureLookup===undefined ||
!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);
arc.options.attributes = Object.assign({}, this.$store.state.Editable.data.arc)
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 + ' ' + String(this.$store.state.Editable.data.multiarc.direction));
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 = String(this.$store.state.Editable.data.multiarc.direction)
arc.options.attributes.name = String(this.$store.state.Editable.data.multiarc.name)
arc.options.attributes.isPushBackRoute = Number(this.$store.state.Editable.data.multiarc.isPushBackRoute)
arc.updateStyle();
}
});
},
//Update Node
editedNode() {
if (this.$store.state.Editable.index === undefined ||
this.$store.state.Editable.data.node === undefined ||
this.featureLookup===undefined ||
!this.editing) {
return;
}
var isOnRunway = Number(this.$store.state.Editable.data.node.isOnRunway);
var isHoldPoint = this.$store.state.Editable.data.node.holdPointType !== 'none' &&
this.$store.state.Editable.data.node.holdPointType !== undefined;
var nIndex = this.$store.state.Editable.index;
var hasRunwayNode = false;
var hasHoldPointNode = false;
var latlng;
this.featureLookup[nIndex].forEach((element,index) => {
if (element instanceof L.RunwayNode) {
if (isOnRunway === 0) {
// We shouldn't have a RunwayNode
element.removeFrom(this.groundnetLayerGroup);
this.featureLookup[nIndex].splice(index,1);
}
hasRunwayNode = true;
} else if (element instanceof L.HoldNode) {
if (!isHoldPoint) {
// We shouldn't have a RunwayNode
element.removeFrom(this.groundnetLayerGroup);
this.featureLookup[nIndex].splice(index,1);
} else {
var fa_icon;
if (this.$store.state.Editable.data.node.holdPointType === 'PushBack') {
fa_icon = "<div style='background-color:#4838cc;' class='marker-pin'></div><i class='fas fa-arrows-alt-h'></i>";
} else if (this.$store.state.Editable.data.node.holdPointType === 'normal') {
fa_icon = "<div style='background-color:#4838cc;' class='marker-pin'></div><i class='fas fa-hand-paper'></i>";
}
const icon = new L.DivIcon({
className: 'custom-div-icon',
html: fa_icon,
iconSize: [30, 42],
iconAnchor: [15, 42]
});
element['holdPointType'] = this.$store.state.Editable.data.node.holdPointType;
element.setIcon(icon);
}
hasHoldPointNode = true;
}
else if (element instanceof L.ParkingSpot) {
}
else if (element instanceof L.Editable.VertexMarker) {
latlng = element.latlng;
}
else if (element instanceof L.TaxiwaySegment) {
if (Number(element.begin) === Number(nIndex)) {
latlng = element._latlngs[0];
}
if (Number(element.end) === nIndex) {
latlng = element._latlngs[1];
}
} else if (element instanceof L.Polyline) {
element._latlngs.forEach(element => {
if(element.__vertex && Number(element.glueindex) === Number(nIndex)){
if (this.$store.state.Editable.data.node.coords) {
this.setPointCoords(this.$store.state.Editable.index, this.$store.state.Editable.data.node.coords)
var position = new Coordinates(this.$store.state.Editable.data.node.coords);
latlng = {lat: position.latitude, lng: position.longitude };
}
}
});
}
})
if (!hasRunwayNode && isOnRunway && latlng !== undefined) {
this.$store.state.Editable.data.node.holdPointType
const icon = new L.DivIcon({
className: 'custom-div-icon',
html: "<div style='background-color:#4838cc;' class='marker-pin'></div><i class='fas fa-plane-departure'></i>",
iconSize: [30, 42],
iconAnchor: [15, 42]
});
const node = new L.RunwayNode(latlng, { icon: icon });
node.glueindex = nIndex;
node.addTo(this.groundnetLayerGroup);
this.featureLookup[nIndex].push(node);
node.featureLookup = this.featureLookup;
node.addListeners();
node.extensions();
}
if (!hasHoldPointNode && isHoldPoint) {
var fa_icon = null;
if (this.$store.state.Editable.data.node.holdPointType === 'PushBack') {
fa_icon = "<div style='background-color:#4838cc;' class='marker-pin'></div><i class='fas fa-arrows-alt-h'></i>";
} else if (this.$store.state.Editable.data.node.holdPointType === 'normal') {
fa_icon = "<div style='background-color:#4838cc;' class='marker-pin'></div><i class='fas fa-hand-paper'></i>";
}
const icon = new L.DivIcon({
className: 'custom-div-icon',
html: fa_icon,
iconSize: [30, 42],
iconAnchor: [15, 42]
});
const node = new L.HoldNode(latlng, { icon: icon });
node.glueindex = nIndex;
node.addTo(this.groundnetLayerGroup);
node.featureLookup = this.featureLookup;
this.featureLookup[nIndex].push(node);
node['holdPointType'] = this.$store.state.Editable.data.node.holdPointType;
node.addListeners();
node.extensions();
}
},
// Finde nearest node
closestLayerSnap (eventLatlng, snap) {
var layers = []
this.groundnetLayerGroup.eachLayer((layer) => {
if (layer instanceof L.Polyline) {
// console.log(layer._latlngs)
layer._latlngs.forEach(latlng => {
if (latlng.__vertex) {
if (Number.isNaN(latlng.glueindex)) {
console.warn('No glueindex : ' + latlng.__vertex);
}
let distance = latlng.distanceTo(eventLatlng)
if (distance >= 0 && distance < snap && latlng.glueindex >=0) {
layers.push({d: distance, l: layer, latlng: latlng.__vertex.latlng, glueindex: latlng.glueindex})
}
} else {
console.log(latlng);
}
})
} else if (layer instanceof L.RunwayNode) {
let distance = layer._latlng.distanceTo(eventLatlng)
if (distance > 0 && distance < snap) {
layers.push({d: distance, l: layer, latlng: layer._latlng, glueindex: layer.glueindex})
}
} else if (layer instanceof L.ParkingSpot) {
let distance = layer._latlng.distanceTo(eventLatlng)
if (distance > 0 && distance < snap) {
layers.push({d: distance, l: layer, latlng: layer._latlng, glueindex: layer.glueindex})
}
} else if (layer instanceof L.HoldNode) {
let distance = layer._latlng.distanceTo(eventLatlng)
if (distance > 0 && distance < snap) {
layers.push({d: distance, l: layer, latlng: layer._latlng, glueindex: layer.glueindex})
}
} else {
console.log(layer)
}
})
layers.sort((l1, l2) => l1.d - l2.d)
if (layers.length > 0) {
return layers[0]
}
},
drawParking () {
this.$parent.mapObject._container.style.cursor = 'crosshair'
this.$parent.mapObject.on('click', this.addParking)
},
removeLayerClick (event) {
console.debug(event)
this.groundnetLayerGroup.removeLayer(event.target)
},
addParking (event) {
console.debug(event.latlng)
if (event.latlng === undefined) {
return
}
const newIndex = (++this.groundnetLayerGroup.maxId)
const circle = new L.ParkingSpot(event.latlng, {attributes: {index: newIndex, radius: 26, heading: 0, type: 'gate'}})
circle.id = newIndex
circle.glueindex = circle.id
circle.addTo(this.groundnetLayerGroup)
circle.featureLookup = this.featureLookup
circle.addListeners()
circle.enableEdit()
circle.extensions()
circle.updateVertexFromDirection();
circle.updateWheelPos();
circle.updateBox();
if (Number(this.$store.state.Editable.index) >= 0 &&
this.featureLookup[this.$store.state.Editable.index]!==undefined) {
this.featureLookup[this.$store.state.Editable.index].forEach(element => {
if(element.deselect !== undefined) {
element.deselect();
}
});
}
this.$store.dispatch('setParking', circle.options.attributes);
this.$store.dispatch('setParkingCoords', circle.getLatLng().lat.toFixed(6) + ' ' + circle.getLatLng().lng.toFixed(6));
circle.select()
addFeature(circle)
// console.log(this.groundnetLayerGroup)
this.$parent.mapObject.off('click', this.addParking)
this.$parent.mapObject._container.style.cursor = ''
},
reload (force) {
this.load(this.icao, force)
},
link (index) {
var layers = []
var centerLatLng = null
this.featureLookup[index].forEach(layer => {
if (layer instanceof L.Polyline) {
// console.log(layer._latlngs)
layer._latlngs.forEach(latlng => {
if (latlng.__vertex) {
if (Number.isNaN(latlng.glueindex)) {
console.warn('No glueindex : ' + latlng.__vertex);
}
if (Number(latlng.glueindex) === index) {
centerLatLng = latlng;
}
}
})}
})
var newIndex = index
var nearest = [];
this.featureLookup.forEach(layers => {
layers.forEach(layer => {
if (layer instanceof L.ParkingSpot) {
let distance = layer.getLatLng().distanceTo(centerLatLng);
if (Number(layer.glueindex) !== newIndex && distance < 10) {
nearest.push({d: distance, l: layer, glueindex: layer.glueindex })
}
}
else if (layer instanceof L.Polyline) {
// console.log(layer._latlngs)
layer._latlngs.forEach(latlng => {
if (latlng.__vertex) {
if (Number.isNaN(latlng.glueindex)) {
console.warn('No glueindex : ' + latlng.__vertex);
}
let distance = latlng.distanceTo(centerLatLng)
if (Number(latlng.glueindex) !== Number(newIndex) && distance < 10) {
nearest.push({d: distance, l: layer, latlng: latlng.__vertex.latlng, glueindex: latlng.glueindex })
}
} else {
console.error("No __Vertex");
}
})
}
});
})
var featureLookup = this.featureLookup;
nearest = nearest.map(e => e.glueindex).filter((v, i, a) => a.indexOf(v) === i).filter(i => Number(i)!==newIndex)
nearest.forEach(glueindex => {
featureLookup[glueindex].forEach(layer => {
featureLookup[newIndex].push(layer);
if (layer instanceof L.RunwayNode) {
layer.setLatLng(centerLatLng);
}
else if (layer instanceof L.HoldNode) {
layer.setLatLng(centerLatLng);
}
else if (layer instanceof L.ParkingSpot) {
layer.setLatLng(centerLatLng);
layer.glueindex = String(newIndex);
layer.id = String(newIndex);
layer.options.attributes.index = newIndex;
}
else if (layer instanceof L.Polyline) {
layer._latlngs.forEach((e1, index1) => {
if (e1.attributes.index===Number(glueindex)) {
if( Number(layer.begin)===Number(glueindex)) {
layer.begin = String(newIndex);
}
if( Number(layer.end)===Number(glueindex)) {
layer.end = String(newIndex);
}
e1.attributes.index = newIndex;
e1.glueindex = newIndex;
layer.getLatLngs()[index1].update(centerLatLng);
layer.editor.refresh();
layer.editor.reset();
layer.updateMiddle();
}
})
}
})
featureLookup[glueindex] = [];
});
},
save () {
var xml = []
this.groundnetLayerGroup.eachLayer(l => {
//console.debug(l)
xml.push(l)
})
writeGroundnetXML(this.$store.state.Settings.settings.airportsDirectory, this.icao, xml)
this.load(this.icao, false)
},
//Copy to test directory
test() {
var f = path.join(this.$store.state.Settings.settings.airportsDirectory, this.icao[0], this.icao[1], this.icao[2], this.icao + '.groundnet.new.xml');
var fNew = path.join(this.$store.state.Settings.settings.testDirectory, 'Airports', this.icao[0], this.icao[1], this.icao[2], this.icao + '.groundnet.xml');
try { fs.mkdirSync(path.join(this.$store.state.Settings.settings.testDirectory, 'Airports'), { recursive: true })} catch (err) { }
try { fs.mkdirSync(path.join(this.$store.state.Settings.settings.testDirectory, 'Airports', this.icao[0]),{ recursive: true })} catch (err) { }
try { fs.mkdirSync(path.join(this.$store.state.Settings.settings.testDirectory, 'Airports', this.icao[0], this.icao[1]), { recursive: true })} catch (err) { }
try { fs.mkdirSync(path.join(this.$store.state.Settings.settings.testDirectory, 'Airports', this.icao[0], this.icao[1], this.icao[2]), { recursive: true })} catch (err) { }
try {
fs.copyFileSync(f, fNew)
this.$message({
type: 'info',
message: `Copied to ${fNew}`
});
} catch (error) {
this.$message({
type: 'error',
message: `Copy error : ${error}`
});
}
},
setVisible(visible) {
if (this.layerGroup) {
if (visible) {
this.layerGroup.addTo(this.$parent.mapObject)
} else {
this.layerGroup.removeFrom(this.$parent.mapObject)
}
}
if (this.groundnetLayerGroup === undefined) {
return;
}
if (visible) {
this.groundnetLayerGroup.addTo(this.$parent.mapObject)
} else {
this.groundnetLayerGroup.removeFrom(this.$parent.mapObject)
}
}
},
computed: {
edit: function () {
console.log('Zoom : ' + this.$store.state.Settings.zoom)
if (this.$store.state.Settings.zoom > 12) {
console.log()
}
}
}
}
</script>
<style scoped lang="css">
</style>