Export/Save
This commit is contained in:
parent
872f7dc109
commit
7fe712c94b
5
package-lock.json
generated
5
package-lock.json
generated
@ -20008,6 +20008,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/xml-writer/-/xml-writer-1.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/xml-writer/-/xml-writer-1.4.2.tgz",
|
||||||
"integrity": "sha1-7/wpYGXi5T27WkSR60LV41VP42w="
|
"integrity": "sha1-7/wpYGXi5T27WkSR60LV41VP42w="
|
||||||
},
|
},
|
||||||
|
"xmlbuilder": {
|
||||||
|
"version": "13.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz",
|
||||||
|
"integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ=="
|
||||||
|
},
|
||||||
"xmlhttprequest-ssl": {
|
"xmlhttprequest-ssl": {
|
||||||
"version": "1.5.5",
|
"version": "1.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
|
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
|
||||||
|
@ -86,7 +86,8 @@
|
|||||||
"vuex-persist": "^2.2.0",
|
"vuex-persist": "^2.2.0",
|
||||||
"vuex-persistedstate": "^2.7.0",
|
"vuex-persistedstate": "^2.7.0",
|
||||||
"worker-threads": "^1.0.0",
|
"worker-threads": "^1.0.0",
|
||||||
"xamel": "^0.3.1"
|
"xamel": "^0.3.1",
|
||||||
|
"xmlbuilder": "^13.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^5.12.0",
|
"@fortawesome/fontawesome-free": "^5.12.0",
|
||||||
|
37
src/renderer/assets/global.css
Normal file
37
src/renderer/assets/global.css
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
.marker-pin {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 50% 50% 50% 0;
|
||||||
|
background: #c30b82;
|
||||||
|
position: absolute;
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
margin: -15px 0 0 -15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marker-pin::after {
|
||||||
|
content: '';
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin: 3px 0 0 3px;
|
||||||
|
background: #fff;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-div-icon i {
|
||||||
|
position: absolute;
|
||||||
|
width: 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: 12px auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-div-icon i.awesome {
|
||||||
|
margin: 8px auto;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
@ -48,7 +48,4 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.edit-layer {
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
import L from 'leaflet'
|
import L from 'leaflet'
|
||||||
import LEdit from 'leaflet-editable/src/Leaflet.Editable.js'
|
import LEdit from 'leaflet-editable/src/Leaflet.Editable.js'
|
||||||
import {readGroundnetXML, addFeature} from '../loaders/groundnet_loader'
|
import {readGroundnetXML, addFeature} from '../loaders/groundnet_loader'
|
||||||
|
import {writeGroundnetXML} from '../loaders/groundnet_writer'
|
||||||
import L2 from 'leaflet-textpath'
|
import L2 from 'leaflet-textpath'
|
||||||
// import {LSymbol} from 'leaflet-polylinedecorator'
|
// import {LSymbol} from 'leaflet-polylinedecorator'
|
||||||
|
|
||||||
@ -38,7 +39,12 @@
|
|||||||
if (this.groundnetLayerGroup !== undefined) {
|
if (this.groundnetLayerGroup !== undefined) {
|
||||||
this.groundnetLayerGroup.removeFrom(this.$parent.mapObject)
|
this.groundnetLayerGroup.removeFrom(this.$parent.mapObject)
|
||||||
}
|
}
|
||||||
|
this.icao = icao
|
||||||
this.groundnetLayerGroup = readGroundnetXML(this.$store.state.Settings.settings.airportsDirectory, icao)
|
this.groundnetLayerGroup = readGroundnetXML(this.$store.state.Settings.settings.airportsDirectory, icao)
|
||||||
|
if (this.groundnetLayerGroup === undefined) {
|
||||||
|
console.console.error('ICAO not loaded ' + icao)
|
||||||
|
return
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
this.groundnetLayerGroup.eachLayer(l => {
|
this.groundnetLayerGroup.eachLayer(l => {
|
||||||
if (l instanceof L.TaxiwaySegment) {
|
if (l instanceof L.TaxiwaySegment) {
|
||||||
@ -60,6 +66,7 @@
|
|||||||
},
|
},
|
||||||
visible (feature) {
|
visible (feature) {
|
||||||
let bounds = this.$store.state.Settings.bounds
|
let bounds = this.$store.state.Settings.bounds
|
||||||
|
|
||||||
let coordinates = feature.geometry.coordinates
|
let coordinates = feature.geometry.coordinates
|
||||||
let ret = bounds.getNorthEast().lat > Number(coordinates[1]) &&
|
let ret = bounds.getNorthEast().lat > Number(coordinates[1]) &&
|
||||||
bounds.getNorthEast().lng > Number(coordinates[0])
|
bounds.getNorthEast().lng > Number(coordinates[0])
|
||||||
@ -87,7 +94,9 @@
|
|||||||
if (typeof l.extensions === 'function') {
|
if (typeof l.extensions === 'function') {
|
||||||
l.extensions()
|
l.extensions()
|
||||||
}
|
}
|
||||||
l.bringToFront()
|
if (typeof l.bringToFront === 'function') {
|
||||||
|
l.bringToFront()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
disableEdit () {
|
disableEdit () {
|
||||||
@ -104,6 +113,9 @@
|
|||||||
drawPolyline () {
|
drawPolyline () {
|
||||||
var polyLine = this.$parent.mapObject.editTools.startPolyline()
|
var polyLine = this.$parent.mapObject.editTools.startPolyline()
|
||||||
polyLine.addTo(this.groundnetLayerGroup)
|
polyLine.addTo(this.groundnetLayerGroup)
|
||||||
|
polyLine.on('editable:drawing:end', event => {
|
||||||
|
console.log(event)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
drawParking () {
|
drawParking () {
|
||||||
this.$parent.mapObject.on('click', this.addParking)
|
this.$parent.mapObject.on('click', this.addParking)
|
||||||
@ -131,7 +143,11 @@
|
|||||||
this.load(this.icao)
|
this.load(this.icao)
|
||||||
},
|
},
|
||||||
save () {
|
save () {
|
||||||
|
var xml = []
|
||||||
|
this.groundnetLayerGroup.eachLayer(l => {
|
||||||
|
xml.push(l)
|
||||||
|
})
|
||||||
|
writeGroundnetXML(this.$store.state.Settings.settings.airportsDirectory, this.icao, xml)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -145,5 +161,5 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="css">
|
||||||
</style>
|
</style>
|
||||||
|
37
src/renderer/loaders/RunwayNode.js
Normal file
37
src/renderer/loaders/RunwayNode.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* 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');
|
||||||
|
|
||||||
|
var $ = require('jquery');
|
||||||
|
L.RunwayNode = L.Marker.extend({
|
||||||
|
addListeners: function () {
|
||||||
|
this.on('editable:drawing:move', function (event) {
|
||||||
|
console.log("Move : ", event);
|
||||||
|
// Is it the edit vertex (Middle) moving?
|
||||||
|
follow(event.target.id, event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var runwayNode = function (n, layerGroup) {
|
||||||
|
//console.log(n.attr('lat') + " " + n.attr('lon'));
|
||||||
|
var latlon = convert(n.attr('lat') + " " + n.attr('lon'));
|
||||||
|
//console.log(latlon.decimalLatitude);
|
||||||
|
//console.log(convert(n.attr('lat') + " " + n.attr('lon')).decimalLongitude);
|
||||||
|
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([latlon.decimalLatitude, latlon.decimalLongitude], { icon: icon });
|
||||||
|
node.id = n.attr('index');
|
||||||
|
node.addTo(layerGroup);
|
||||||
|
node.addListeners();
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = runwayNode;
|
@ -12,10 +12,14 @@ L.TaxiwaySegment = L.Polyline.extend({
|
|||||||
bidirectional: Boolean,
|
bidirectional: Boolean,
|
||||||
|
|
||||||
updateBeginVertex : function (latlng) {
|
updateBeginVertex : function (latlng) {
|
||||||
this._latlngs[0].__vertex.setLatLng(latlng);
|
if (this._latlngs[0].__vertex) {
|
||||||
|
this._latlngs[0].__vertex.setLatLng(latlng);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
updateEndVertex : function (latlng) {
|
updateEndVertex : function (latlng) {
|
||||||
this._latlngs[1].__vertex.setLatLng(latlng);
|
if(this._latlngs[1].__vertex){
|
||||||
|
this._latlngs[1].__vertex.setLatLng(latlng);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
updateMiddle: function () {
|
updateMiddle: function () {
|
||||||
|
@ -8,6 +8,7 @@ const markers = require('./MagneticVertex');
|
|||||||
const TaxiwaySegment = require('./TaxiwaySegment');
|
const TaxiwaySegment = require('./TaxiwaySegment');
|
||||||
|
|
||||||
const parkingSpot = require('./ParkingSpot.js');
|
const parkingSpot = require('./ParkingSpot.js');
|
||||||
|
const runwayNode = require('./RunwayNode.js');
|
||||||
|
|
||||||
const store = require('../store');
|
const store = require('../store');
|
||||||
|
|
||||||
@ -68,6 +69,13 @@ exports.readGroundnetXML = function (fDir, icao) {
|
|||||||
|
|
||||||
layerGroup.maxId = Math.max(layerGroup.maxId, Number(n.attr('index')))
|
layerGroup.maxId = Math.max(layerGroup.maxId, Number(n.attr('index')))
|
||||||
nodesLookup[n.attr('index')] = n;
|
nodesLookup[n.attr('index')] = n;
|
||||||
|
if (n.attr('isOnRunway') === '1') {
|
||||||
|
var rNode = runwayNode(n, layerGroup);
|
||||||
|
if(featureLookup[rNode.id] === undefined) {
|
||||||
|
featureLookup[rNode.id] = [];
|
||||||
|
}
|
||||||
|
featureLookup[rNode.id].push(rNode);
|
||||||
|
}
|
||||||
}).sort();
|
}).sort();
|
||||||
|
|
||||||
|
|
||||||
@ -194,7 +202,10 @@ exports.readGroundnetXML = function (fDir, icao) {
|
|||||||
follow = function (dragIndex, event) {
|
follow = function (dragIndex, event) {
|
||||||
featureLookup[dragIndex].forEach(element => {
|
featureLookup[dragIndex].forEach(element => {
|
||||||
if(element !== event.target){
|
if(element !== event.target){
|
||||||
if (element instanceof L.ParkingSpot) {
|
if (element instanceof L.RunwayNode) {
|
||||||
|
element.setLatLng(event.latlng);
|
||||||
|
}
|
||||||
|
else if (element instanceof L.ParkingSpot) {
|
||||||
// element.disableEdit();
|
// element.disableEdit();
|
||||||
element.setLatLng(event.latlng);
|
element.setLatLng(event.latlng);
|
||||||
// element.enableEdit();
|
// element.enableEdit();
|
||||||
|
134
src/renderer/loaders/groundnet_writer.js
Normal file
134
src/renderer/loaders/groundnet_writer.js
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const markers = require('./MagneticVertex');
|
||||||
|
const TaxiwaySegment = require('./TaxiwaySegment');
|
||||||
|
|
||||||
|
const parkingSpot = require('./ParkingSpot.js');
|
||||||
|
|
||||||
|
const store = require('../store');
|
||||||
|
|
||||||
|
const util = require('util');
|
||||||
|
|
||||||
|
const mathjs = require('mathjs');
|
||||||
|
|
||||||
|
var builder = require('xmlbuilder');
|
||||||
|
|
||||||
|
|
||||||
|
exports.writeGroundnetXML = function (fDir, icao, featureList) {
|
||||||
|
try {
|
||||||
|
var f = path.join(fDir, icao[0], icao[1], icao[2], icao + '.groundnet.new.xml');
|
||||||
|
|
||||||
|
if (f == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
console.log(featureList);
|
||||||
|
|
||||||
|
var parkings = featureList.map(mapParkings).filter(n => n);
|
||||||
|
|
||||||
|
var nodes = [];
|
||||||
|
featureList.filter(o => o instanceof L.TaxiwaySegment).filter(n => n).forEach(element => {
|
||||||
|
var begin = mapBeginNode(element);
|
||||||
|
nodes[begin['@index']] = begin;
|
||||||
|
var end = mapEndNode(element);
|
||||||
|
nodes[end['@index']] = end;
|
||||||
|
});
|
||||||
|
|
||||||
|
// delete the parkings
|
||||||
|
parkings.forEach( n => {
|
||||||
|
nodes[n['@index']] = null;
|
||||||
|
} );
|
||||||
|
nodes = nodes.filter(n => n);
|
||||||
|
|
||||||
|
nodes.sort((p, p2) => {return p['@index']- p2['@index'] });
|
||||||
|
var uniqueNodes = nodes.filter( (v, i, a) => a.indexOf(v) === i );
|
||||||
|
|
||||||
|
var maxId = uniqueNodes.slice(-1)[0]['@index'];
|
||||||
|
|
||||||
|
var arcList = [];
|
||||||
|
featureList.filter(o => o instanceof L.TaxiwaySegment).filter(n => n).forEach(element => {
|
||||||
|
|
||||||
|
if (element.getLatLngs().length > 2) {
|
||||||
|
let middlePoints = element.getLatLngs().slice(1,-1);
|
||||||
|
let startIndex = element.begin;
|
||||||
|
middlePoints.forEach(latlng => {
|
||||||
|
uniqueNodes.push({'@index': String(++maxId), '@lat': convertLat(latlng), '@lon': convertLon(latlng)});
|
||||||
|
arc = {'@begin': startIndex, '@end': String(maxId)};
|
||||||
|
arcList.push(arc);
|
||||||
|
arc = {'@begin': String(maxId), '@end': startIndex};
|
||||||
|
arcList.push(arc);
|
||||||
|
startIndex = maxId;
|
||||||
|
});
|
||||||
|
arc = {'@begin': String(startIndex), '@end': element.end};
|
||||||
|
arcList.push(arc);
|
||||||
|
arc = {'@begin': element.end, '@end': String(startIndex)};
|
||||||
|
arcList.push(arc);
|
||||||
|
console.log('We have a edited line');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
arc = {'@begin': element.begin, '@end': element.end };
|
||||||
|
arcList.push(arc);
|
||||||
|
if (element.bidirectional) {
|
||||||
|
arc = {'@begin': element.end, '@end': element.begin };
|
||||||
|
arcList.push(arc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// <arc begin="0" end="161" isPushBackRoute="1" name="" />
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var xmlObj = {groundnet: {version:1, parkingList:{ Parking: parkings }, TaxiNodes: { node: uniqueNodes}, TaxiWaySegments: { arc: arcList}}};
|
||||||
|
|
||||||
|
xmlString = builder.create(xmlObj).end({ pretty: true});
|
||||||
|
fs.writeFileSync(f,xmlString);
|
||||||
|
console.log(xmlString);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
return layerGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
var mapParkings = function( o ) {
|
||||||
|
console.log(o);
|
||||||
|
if (o instanceof L.ParkingSpot) {
|
||||||
|
var lat = convertLat(o.getLatLng());
|
||||||
|
var lon = convertLon(o.getLatLng());
|
||||||
|
// <Parking index="0" type="gate" name="GA_Parking" lat="S9 25.739923" lon="E160 2.927602" heading="67" radius="44" airlineCodes="" />
|
||||||
|
return {'@index': String(o['id']), '@type': o.options.attributes.type, '@name': o.options.attributes.name, '@lat': lat, '@lon': lon, '@heading': Number(o.options.attributes.heading), '@radius': String(o.options.radius)};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var mapBeginNode = function( o ) {
|
||||||
|
if (o instanceof L.TaxiwaySegment) {
|
||||||
|
console.log(o);
|
||||||
|
// <Parking index="0" type="gate" name="GA_Parking" lat="S9 25.739923" lon="E160 2.927602" heading="67" radius="44" airlineCodes="" />
|
||||||
|
return {'@index': String(o['begin']), '@lat': convertLat(o._latlngs[0]), '@lon': convertLon(o._latlngs[0])};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var mapEndNode = function( o ) {
|
||||||
|
if (o instanceof L.TaxiwaySegment) {
|
||||||
|
console.log(o);
|
||||||
|
// <Parking index="0" type="gate" name="GA_Parking" lat="S9 25.739923" lon="E160 2.927602" heading="67" radius="44" airlineCodes="" />
|
||||||
|
return {'@index': String(o['end']), '@lat': convertLat(o._latlngs[1]), '@lon': convertLon(o._latlngs[1])};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var convertLat = function( latlng ) {
|
||||||
|
console.log(latlng.lat);
|
||||||
|
var NS = latlng.lat>0?'N':'S';
|
||||||
|
var deg = mathjs.abs(mathjs.floor(latlng.lat));
|
||||||
|
var min = (mathjs.abs(latlng.lat) - deg) * 60;
|
||||||
|
// console.log(NS + deg + " " + min);
|
||||||
|
return NS + String(deg).padStart(2, '0') + " " + mathjs.round( min, 3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
var convertLon = function( latlng ) {
|
||||||
|
console.log(latlng.lng);
|
||||||
|
var NS = latlng.lat<0?'E':'W';
|
||||||
|
var deg = mathjs.floor(mathjs.abs(latlng.lng));
|
||||||
|
var min = (mathjs.abs(latlng.lng) - deg) * 60;
|
||||||
|
// console.log(NS + deg + " " + min);
|
||||||
|
return NS + String(deg).padStart(2, '0') + " " + mathjs.round( min, 3 );
|
||||||
|
}
|
@ -2,6 +2,7 @@ import Vue from 'vue'
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import ElementUI from 'element-ui'
|
import ElementUI from 'element-ui'
|
||||||
import 'element-ui/lib/theme-chalk/index.css'
|
import 'element-ui/lib/theme-chalk/index.css'
|
||||||
|
import '@/assets/global.css'
|
||||||
|
|
||||||
import App from './App'
|
import App from './App'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
|
Loading…
Reference in New Issue
Block a user