This commit is contained in:
Keith Paterson 2021-06-23 15:59:25 +02:00
parent 8a4820d23c
commit 8b0afa9fcb
9 changed files with 125 additions and 27 deletions

17
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "flightgear-airports",
"version": "0.0.32",
"version": "0.0.33",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -12349,6 +12349,21 @@
"resolved": "https://registry.npmjs.org/leaflet-textpath/-/leaflet-textpath-1.2.0.tgz",
"integrity": "sha512-anLGWptWb916MhEXi4WewYe08YKCawRvEXsMGj9fuYnUGd+irV3VG4UXcdW1l+Oa/TZoCTLQsg3LNwvFcroVog=="
},
"leaflet.pattern": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/leaflet.pattern/-/leaflet.pattern-0.1.0.tgz",
"integrity": "sha512-E4sxvvK0XHi1EhE1yUTG1bzafXZoXUPqWPjHz5fSpv/pOcT4CtS0qR1lhFSRtSUYios8OwlZmUGB9n91zQEgcw==",
"requires": {
"leaflet": "~0.7.1"
},
"dependencies": {
"leaflet": {
"version": "0.7.7",
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-0.7.7.tgz",
"integrity": "sha1-HjUrpU5j0HZFH6NjyQCJDLLPde4="
}
}
},
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",

View File

@ -109,6 +109,7 @@
"leaflet-search": "^2.9.9",
"leaflet-sidebar-v2": "^3.2.1",
"leaflet-textpath": "^1.2.0",
"leaflet.pattern": "^0.1.0",
"lokijs": "^1.5.8",
"mathjs": "^6.2.5",
"path": "^0.12.7",

View File

@ -41,6 +41,11 @@ export function checkMapper(o) {
'type': 'runway_poly',
'pavement': o.getLatLngs()
}
} else if (o instanceof L.TakeoffPolygon) {
return {
'type': 'takeoffpad_poly',
'pavement': o.getLatLngs()
}
} else if (o instanceof L.Polyline) {
console.log(o)
var latLngs = o.getLatLngs().map(l => ({ lat: l.lat, lng: l.lng, index: l.glueindex }));

View File

@ -302,9 +302,16 @@ You should have received a copy of the GNU General Public License along with FG
console.log(l)
pavement.push(l)
})
var features2 = pavement.map(mapper.checkMapper).filter(n => n)
var thresholds = []
this.$parent.$parent.$refs.thresholdLayer.getLayer().eachLayer(l => {
console.log(l)
thresholds.push(l)
})
var pavementFeatures = pavement.map(mapper.checkMapper).filter(n => n)
//TODO
var thresholdFeatures = thresholds.map(mapper.checkMapper).filter(n => n)
worker.postMessage(['check', features.concat(features2) ] )
worker.postMessage(['check', features.concat(pavementFeatures).concat(thresholdFeatures) ] )
this.pollData()
// the reply
var store = this.$store

View File

@ -3,6 +3,7 @@
<script lang="js">
import { LMap, LMarker } from 'vue2-leaflet'
import L from 'leaflet'
import leafletPattern from 'leaflet.pattern'
import LEdit from 'leaflet-editable/src/Leaflet.Editable.js'
import {readThresholdXML} from '../loaders/threshold_loader'
import {writeThresholdXML} from '../loaders/threshold_writer'
@ -13,7 +14,7 @@
created () {
},
mounted () {
console.debug(LMap, LMarker, L, LEdit)
console.debug(LMap, LMarker, L, LEdit, leafletPattern)
this.$store.watch(
function (state) {
return state.Editable.data.threshold
@ -24,6 +25,8 @@
deep: true
}
)
var stripes = new L.StripePattern({color: 'yellow'})
stripes.addTo(this.$parent.mapObject)
},
beforeDestroy () {
this.remove()
@ -55,8 +58,11 @@
if (this.layerGroup) {
this.layerGroup.removeFrom(this.$parent.mapObject)
}
var stripes = new L.StripePattern({color: 'yellow'})
stripes.addTo(this.$parent.mapObject)
// Callback for add
this.layerGroup = readThresholdXML(this.$store.state.Settings.settings.airportsDirectory, icao, this.read)
this.layerGroup = readThresholdXML(this.$store.state.Settings.settings.airportsDirectory, icao, this.read, stripes)
if (!this.layerGroup) {
console.warn('Threshold for ICAO not loaded ' + icao)
return

View File

@ -0,0 +1,41 @@
/*
Copyright 2021 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 turf = require('@turf/turf')
L.TakeoffPolygon = L.Polygon.extend({
turfyRunway: [],
setTurfy: function (padPoints) {
var latLngs = padPoints.map(this.turfToLatLng);
latLngs.push(latLngs[0]);
this.turfyRunway = turf.polygon([latLngs]);
},
turfToLatLng: function (turfPoint) {
return [turfPoint.lng, turfPoint.lat];
}
});
var takeoffPadPoly = function (padPoints) {
var takeoffPadPoly = new L.TakeoffPolygon(padPoints);
takeoffPadPoly.setStyle({ color: 'black', fillColor: '', opacity: 1.0, fillOpacity: 0.0, interactive: false });
takeoffPadPoly.setTurfy(padPoints);
console.debug(padPoints);
return takeoffPadPoly;
}
module.exports = takeoffPadPoly;

View File

@ -1,19 +1,22 @@
/* eslint-disable */
const fs = require('fs');
const path = require('path');
var xamel = require('xamel');
const xamel = require('xamel');
const convert = require('geo-coordinates-parser');
const LatLonEllipsoidal = require('geodesy/latlon-ellipsoidal-vincenty.js').default;
const store = require('../store');
const util = require('util');
const takeoffPadPoly = require('../leaflet/TakeoffPad.js');
const threshold = require('./Threshold.js');
var $ = require('jquery');
exports.readThresholdXML = function (fDir, icao, force) {
exports.readThresholdXML = function (fDir, icao, force, stripes) {
try {
var layerGroup = L.layerGroup();
layerGroup.maxId = 0;
@ -48,12 +51,30 @@ exports.readThresholdXML = function (fDir, icao, force) {
var index = 0;
runwayNodes.map(r => {
var thresholds = r.find('threshold');
thresholds.map(t => {
var icon = threshold(t);
thresholds.map(n => {
var icon = threshold(n);
icon.index = index;
icon.addTo(layerGroup);
// Width in m
var runwayWidth = 20;
var latlon = convert(n.find('lat/text()').text() + " " + n.find('lon/text()').text());
var displ_m = Number(n.find('displ-m/text()').text());
var pointMiddle = new LatLonEllipsoidal(latlon.decimalLatitude, latlon.decimalLongitude);
var heading = Number(n.find('hdg-deg/text()').text());
var point1 = pointMiddle.destinationPoint(displ_m, heading);
var point2 = pointMiddle.destinationPoint(displ_m + 80, heading);
var runwayPoints = [];
runwayPoints.push(point1.destinationPoint(runwayWidth / 2, (heading + 90)));
runwayPoints.push(point2.destinationPoint(runwayWidth / 2, (heading + 90)));
runwayPoints.push(point2.destinationPoint(runwayWidth / 2, (heading - 90)));
runwayPoints.push(point1.destinationPoint(runwayWidth / 2, (heading - 90)));
var runwayPoly = takeoffPadPoly(runwayPoints);
runwayPoly.addTo(layerGroup);
}
)
index+=1;
}).sort();

View File

@ -70,7 +70,7 @@ async function checkGroundnet(data) {
var normalNodes = data.map(mapEdges).filter(n => n !== undefined)
.flatMap(m => m.latLngs).filter(n => runwayNodeIDs.indexOf(Number(n.index)) < 0);
var runways = data.map(mapRunways).filter(n => n !== undefined);
var takeoffPads = data.map(mapTakeoffPads).filter(n => n !== undefined);
this.max = 30;
this.postMessage(['max', this.max]);
@ -104,7 +104,8 @@ async function checkGroundnet(data) {
resolve([{ id: -1, message: check_msg.NO_EDGES }]);
}
this.postMessage(['progress', 1]);
if (runways.length === 0) {
//debugger;
if (takeoffPads.length === 0) {
resolve([{ id: -1, message: check_msg.NO_RUNWAYS }]);
}
this.postMessage(['progress', 1]);
@ -297,7 +298,7 @@ async function checkGroundnet(data) {
var notOkNodesRunways = runwayNodeIDs.filter(
(v, i) => okNodes.indexOf(v) < 0
).map(
id => { return { id: id, message: check_msg.NO_RUNWAY_ROUTE } }
id => { return { id: id, message: check_msg.NO_PARKING_ROUTE } }
);
this.postMessage(['progress', 1]);
@ -382,7 +383,8 @@ async function checkGroundnet(data) {
this.postMessage(['progress', 1]);
//Check if runwaynodes are on runway
runwayNodes.forEach(runwayNode => {
if (runways.filter(r => turf.booleanContains(r, latToTurf(runwayNode))).length === 0) {
// debugger;
if (takeoffPads.filter(r => turf.booleanContains(r, latToTurf(runwayNode))).length === 0) {
notOkNodes.push({ id: runwayNode.index, message: check_msg.RUNWAY_NODE_NOT_ON_RUNWAY });
}
});
@ -391,7 +393,7 @@ async function checkGroundnet(data) {
//Check if nodes no normal nodes are on runway
normalNodes.forEach(normalNode => {
//debugger;
if (runways.filter(r => turf.booleanContains(r, latToTurf(normalNode))).length > 0) {
if (takeoffPads.filter(r => turf.booleanContains(r, latToTurf(normalNode))).length > 0) {
notOkNodes.push({ id: normalNode.index, message: check_msg.NON_RUNWAYNODE_ON_RUNWAY });
}
});
@ -514,8 +516,8 @@ var mapRunwayNode = function (o) {
}
}
var mapRunways = function (o) {
if (o.type === 'runway_poly') {
var mapTakeoffPads = function (o) {
if (o.type === 'takeoffpad_poly') {
var pts = o.pavement[0].map(latLngToArray);
pts.push(pts[0]);
return turf.polygon([pts]);

View File

@ -2,8 +2,8 @@
"LONG_ROUTE_START" : ["Start of long route", "Route segments of >2km are Taxidraw artefacts"],
"LONG_ROUTE_END": ["End of long route", "Route segments of >2km are Taxidraw artefacts"],
"EDGE_MISSING_DIRECTION": ["Edge missing direction", "Each edge must have a direction (forward, backward, bi-directional)"],
"NO_RUNWAY_ROUTE": ["No way from parking to each runway", ""],
"NO_PARKING_ROUTE": ["No way from runway to each parking", ""],
"NO_RUNWAY_ROUTE": ["No way from parking to each runway", "There must be a route from each parking to each runway."],
"NO_PARKING_ROUTE": ["No way from runway to each parking", "There must be a route from each runway to each parking."],
"NO_PARKINGS": ["No parkings", ""],
"NO_RUNWAY_NODES": ["No Runwaynodes", "Fine for parking only"],
"NOT_LEGIT_END": ["Node not a legimate end", "Taxiroutes must end either at a parking or on a runway"],
@ -13,19 +13,19 @@
"TYPE_EMPTY" :["Parking type empty", "The parking type must not be empty"],
"PARKING_TYPE_INVALID" :["Parking type not valid", "The type of parking must be one of ()"],
"DUAL_PUSHBACK": ["Dual runway/ pushback node", "A runway node can not be a hold node at the same time"],
"RUNWAY_NODE_NOT_ON_RUNWAY" : ["Runwaynode not on runway", ""],
"NON_RUNWAYNODE_ON_RUNWAY": ["Non Runwaynode on runway", ""],
"RUNWAY_NODE_NOT_ON_RUNWAY" : ["Runwaynode not in takeoff pad", ""],
"NON_RUNWAYNODE_ON_RUNWAY": ["Non Runwaynode in takeoff pad", ""],
"PARKINGS_VALID": ["Parkings valid", "All Ok"],
"NO_OVERLAPPING_PARKINGS": ["No parkings overlapping", ""],
"NO_OVERLAPPING_PARKINGS": ["No parkings overlapping", "Parking positions may not overlap. Reduce the radius or move."],
"NO_INVALID_ENDS": ["No invalid ends", ""],
"ROUTES_FROM_PARKINGS_OK": ["Routes from parkings OK", ""],
"ROUTES_FROM_RUNWAYS_OK": ["Routes from runways OK", ""],
"PUSHBACK_ROUTES_OK": ["Pushback routes OK", ""],
"UNCONNECTED_PUSHBACK": ["Unconnected Pushbacknode", ""],
"NO_WAY_TO_HOLDPOINT":["No way to pushback holdpoint", "There is no route to the pushback hold point"],
"NO_WAY_TO_HOLDPOINT":["No way to pushback holdpoint", "There is no route from the parking to the pushback hold point-"],
"MULTIPLE_PUSHBACK": ["Multiple connected pushback points", "There are more than one possible pushback holdpoint routes."],
"PUSHBACK_NOT_CONNECTED": ["Pushback Holding Point not Connected to Pushback Route", ""],
"TO_MANY_PUSHBACK_TAXI_ROUTES": ["Too many Taxi routes from Pushback Holding Point", ""],
"TO_MANY_PUSHBACK_TAXI_ROUTES": ["Too many Taxi routes from Pushback Holding Point", "There must be only one pushback point reachable from the parking."],
"PUSHBACK_EXIT_NOT_BIDRECTIONAL": ["Pushback Holding Point Exit route is not bidirectional", ""],
"NO_EDGES": ["No Edges", "No checks are run if there are no edges present"],
"NO_RUNWAYS": ["No Runways", "No checks are run if there are no runways present. APT layer visible?"],