Files
flightgear-airports-old/src/renderer/utils/check.js
T
2021-06-23 15:59:25 +02:00

548 lines
22 KiB
JavaScript

/* eslint-disable */
const winURL = process.env.NODE_ENV === 'development'
? `http://localhost:9080/src/renderer/utils/`
: `file://${process.resourcesPath}/workers/`
var path = require('path');
const fs = require('fs');
//debugger;
var turf;
var check_msg;
if (process.env.NODE_ENV === 'development') {
importScripts('../../../node_modules/dijkstrajs/dijkstra.js');
turf = require('./node_modules/@turf/turf');
} else if (process.env.NODE_ENV === 'mocha') {
importScripts('../../../node_modules/dijkstrajs/dijkstra.js');
turf = require('../../../node_modules/@turf/turf')
} else {
importScripts('dijkstra.js');
turf = require('@turf/turf')
}
const homedir = require('os').homedir();
importScripts('logger.js');
importScripts('haversine.js');
function errorReceiver(event) {
throw event.data;
}
onmessage = function (event) {
postMessage('checkStarted');
logger('info', 'Check Started');
console.log(event.data);
if (event.data[0] === 'check') {
checkGroundnet(event.data[1]).then(result => {
console.log("DONE Checking");
postMessage(['DONE', result]);
// event.origin.webContents.send('scanFinished');
}
).catch(result => {
console.error('Crashed');
console.error(result);
postMessage(['DONE', [{ id: -1, message: ['Crashed', result] }]]);
});
}
};
/**
* Implements the checks of the groundnet
* @param {*} data
*/
async function checkGroundnet(data) {
var promise = new Promise(function (resolve, reject) {
try {
const fName = process.env.NODE_ENV === 'development'
? './src/renderer/utils/check_msg.json'
: path.join(`${process.resourcesPath}`, 'workers', 'check_msg.json');
check_msg = JSON.parse(fs.readFileSync(fName, 'utf8').toString());
//debugger;
var parkings = data.map(mapParkings).filter(n => n !== undefined);
var runwayNodeIDs = data.map(mapRunwayNodeId).filter(n => n !== undefined);
var runwayNodes = data.map(mapRunwayNode).filter(n => n !== undefined);
var pushbackNodes = data.map(mapPushbackNodes).filter(n => n !== undefined);
var edges = data.map(mapEdges).filter(n => n !== undefined);
var normalNodes = data.map(mapEdges).filter(n => n !== undefined)
.flatMap(m => m.latLngs).filter(n => runwayNodeIDs.indexOf(Number(n.index)) < 0);
var takeoffPads = data.map(mapTakeoffPads).filter(n => n !== undefined);
this.max = 30;
this.postMessage(['max', this.max]);
var boxes = {};
//debugger;
data.forEach(element => {
//debugger;
if (element.box !== undefined && element.box !== null) {
boxes[element.index] = element.box[0].map(latlng => [latlng.lat, latlng.lng]);
boxes[element.index].push(boxes[element.index][0]);
}
});
var directionalGraph = {};
var bidirectionalGraph = {};
console.debug(parkings);
parkings.forEach(element => {
directionalGraph[element] = {};
bidirectionalGraph[element] = {};
});
runwayNodeIDs.forEach(element => {
directionalGraph[element] = {};
bidirectionalGraph[element] = {};
});
var notOkNodes = [];
//debugger;
console.debug(edges);
if (edges === undefined) {
resolve([{ id: -1, message: check_msg.NO_EDGES }]);
}
this.postMessage(['progress', 1]);
//debugger;
if (takeoffPads.length === 0) {
resolve([{ id: -1, message: check_msg.NO_RUNWAYS }]);
}
this.postMessage(['progress', 1]);
edges.forEach(edge => {
directionalGraph[edge.start] = {};
bidirectionalGraph[edge.start] = {};
directionalGraph[edge.end] = {};
bidirectionalGraph[edge.end] = {};
if (edge.latLngs !== undefined) {
// Check if there are segments > 2km
edge.latLngs.forEach((latLng, index, arr) => {
if (index > 0) {
var d = distance([arr[index - 1].lng, arr[index - 1].lat], [latLng.lng, latLng.lat]);
if (d > 2000) {
notOkNodes.push({ id: Number(arr[index - 1].index), message: check_msg.LONG_ROUTE_START });
notOkNodes.push({ id: Number(arr[index].index), message: check_msg.LONG_ROUTE_END });
}
//console.log(d);
}
});
}
});
this.postMessage(['progress', 1]);
this.postMessage(['progress', 1]);
// Add edges to graphs
edges.forEach(element => {
var node1 = directionalGraph[element.start];
var node2 = directionalGraph[element.end];
if (element.direction === undefined) {
notOkNodes.push({ id: Number(element._leaflet_id), message: check_msg.EDGE_MISSING_DIRECTION });
}
if (element.direction === 'bi-directional' || element.direction === 'forward') {
node1[Number(element.end)] = 1;
}
if (element.direction === 'bi-directional' || element.direction === 'backward') {
node2[Number(element.start)] = 1;
}
var node3 = bidirectionalGraph[element.start];
var node4 = bidirectionalGraph[element.end];
node3[Number(element.end)] = 1;
node4[Number(element.start)] = 1;
});
this.postMessage(['progress', 1]);
var isLegitEnd = function (v) {
if (bidirectionalGraph[v] === undefined) {
debugger;
}
if (Object.keys(bidirectionalGraph[v]).length <= 1) {
return true;
}
return Object.keys(bidirectionalGraph[v]).filter(v => runwayNodeIDs[v]).length === 0;
}
runwayNodeIDs = runwayNodeIDs.filter(
(v, i) => isLegitEnd(v)
);
// Check if there is a route from every parking to every runway node
var okNodes = [];
logger('info', directionalGraph);
parkings.forEach(parkingNode => {
runwayNodeIDs.forEach(runwayNode => {
var ok = checkRoute(directionalGraph, parkingNode, runwayNode);
if (ok) {
okNodes.push(parkingNode);
okNodes.push(runwayNode);
} else {
console.log(`No route from Parking ${parkingNode} to Runwaynode ${runwayNode}`);
}
});
});
// Build pushback directionalGraph
var noPushbackGraph = {};
parkings.forEach(element => {
noPushbackGraph[element] = {};
});
pushbackNodes.forEach(element => {
noPushbackGraph[element] = {};
});
edges.filter(element => element.isPushBackRoute).forEach(element => {
noPushbackGraph[element.start] = {};
noPushbackGraph[element.end] = {};
});
// add all pushback edges
edges.filter(element => element.isPushBackRoute).forEach(element => {
var node1 = noPushbackGraph[Number(element.start)];
node1[Number(element.end)] = 1;
var node2 = noPushbackGraph[Number(element.end)];
node2[Number(element.start)] = 1;
});
var okPushbacks = [];
// Check pushback
var multiplePushbackRoutes = {};
parkings.forEach(parkingNode => {
pushbackNodes.forEach(pushbackNode => {
var numRoutes = checkRoute(noPushbackGraph, parkingNode, pushbackNode);
if (numRoutes === 0) {
if (multiplePushbackRoutes[parkingNode] === undefined &&
Object.keys(noPushbackGraph[parkingNode]) > 0) {
// Only when there is a edge leaving
multiplePushbackRoutes[parkingNode] = [];
}
} else if (numRoutes === 1) {
if (multiplePushbackRoutes[parkingNode] === undefined) {
multiplePushbackRoutes[parkingNode] = [pushbackNode];
} else {
multiplePushbackRoutes[parkingNode].push(pushbackNode);
}
} else if (numRoutes > 1) {
if (multiplePushbackRoutes[parkingNode] === undefined) {
multiplePushbackRoutes[parkingNode] = [pushbackNode];
} else {
multiplePushbackRoutes[parkingNode].push(pushbackNode);
}
}
});
});
var notConnectedToPushback = pushbackNodes.map(
id => {
var normalRoutes = bidirectionalGraph[id];
var pushbackRoutes = noPushbackGraph[id];
if (Object.keys(pushbackRoutes).length < 1)
return { id: id, message: check_msg.PUSHBACK_NOT_CONNECTED }
}).filter(n => n !== undefined);
this.postMessage(['progress', 1]);
var multipleTaxiRoutes = pushbackNodes.map(
id => {
var normalRoutes = bidirectionalGraph[id];
var pushbackRoutes = noPushbackGraph[id];
if (normalRoutes !== undefined) {
var nonPushbackRoutes = Object.keys(normalRoutes).filter(r => pushbackRoutes[r] === undefined);
if (nonPushbackRoutes.length > 1)
return { id: id, message: check_msg.TO_MANY_PUSHBACK_TAXI_ROUTES }
}
}).filter(n => n !== undefined);
this.postMessage(['progress', 1]);
var pushbackExitNotBidirectional = pushbackNodes.map(
id => {
var normalRoutes = bidirectionalGraph[id];
var pushbackRoutes = noPushbackGraph[id];
if (normalRoutes !== undefined) {
var nonPushbackRoutes = Object.keys(normalRoutes).filter(r => pushbackRoutes[r] === undefined);
if(nonPushbackRoutes.length > 0) {
var returnRoute = Object.keys(bidirectionalGraph[nonPushbackRoutes[0]]).map(id => Number(id)).filter(retId =>id === retId);
if (returnRoute.length === 0)
return { id: id, message: check_msg.PUSHBACK_EXIT_NOT_BIDRECTIONAL }
}
}
}).filter(n => n !== undefined);
this.postMessage(['progress', 1]);
var rogueHoldPoints = pushbackNodes.map(
id => {
var routes = noPushbackGraph[id];
if (Object.keys(routes).length < 1)
return { id: id, message: check_msg.UNCONNECTED_PUSHBACK }
/*
else if(Object.keys(routes).length>1)
return { id: id, message: 'Multiple connected pushback node' }
*/
}
).filter(n => n !== undefined);
this.postMessage(['progress', 1]);
var wrongPushbackRoutes = parkings.filter(
function (e) {
return this[e] != undefined && this[e].length != 1;
}
, multiplePushbackRoutes).map(
id => {
var endPoints = multiplePushbackRoutes[id];
if (endPoints.length < 1)
return { id: id, message: check_msg.NO_WAY_TO_HOLDPOINT }
else
return { id: id, message: check_msg.MULTIPLE_PUSHBACK }
}
);
this.postMessage(['progress', 1]);
okNodes = okNodes.filter((v, i) => okNodes.indexOf(v) === i);
var notOkNodesParkings = parkings.filter(
(v, i) => okNodes.indexOf(v) < 0
).map(
id => { return { id: id, message: check_msg.NO_RUNWAY_ROUTE } }
);
this.postMessage(['progress', 1]);
var notOkNodesRunways = runwayNodeIDs.filter(
(v, i) => okNodes.indexOf(v) < 0
).map(
id => { return { id: id, message: check_msg.NO_PARKING_ROUTE } }
);
this.postMessage(['progress', 1]);
if (parkings.length === 0) {
notOkNodes.push({ id: -2, message: check_msg.NO_PARKINGS });
}
this.postMessage(['progress', 1]);
if (runwayNodeIDs.length === 0) {
notOkNodes.push({ id: -2, message: check_msg.NO_RUNWAY_NODES });
}
this.postMessage(['progress', 1]);
var allEnds = Object.entries(bidirectionalGraph).filter(
(v, i) => Object.keys(v[1]).length <= 1
);
// Ends that are not on Runway and not a Parking or Pushback
var allLegitimateEndNodes = parkings.concat(runwayNodeIDs).concat(pushbackNodes);
var danglingEnds = allEnds.filter(
(v, i) => allLegitimateEndNodes.indexOf(Number(v[0])) < 0
).map(
v => { return { id: Number(v[0]), message: check_msg.NOT_LEGIT_END } }
);
this.postMessage(['progress', 1]);
var parkingNodes = data.map(mapParkingNode).filter(n => n !== undefined);
var overlappingParkings = [];
parkingNodes.forEach(parkingNode => {
if (boxes[parkingNode.index] === undefined) {
overlappingParkings.push({ id: parkingNode.index, message: check_msg.UNKNOWN_RADIUS });
}
});
// Check for intersecting radii
parkingNodes.forEach(parkingNode => {
parkingNodes.forEach(parkingNode1 => {
console.log(parkingNode, parkingNode1);
if (parkingNode.index !== parkingNode1.index) {
var d = distance([parkingNode.lng, parkingNode.lat],
[parkingNode1.lng, parkingNode1.lat]);
if (d < parkingNode.radius + parkingNode1.radius + 10) {
// If bigger circles intersect we should check the boxes
if (boxes[parkingNode.index] !== null && boxes[parkingNode1.index] !== null &&
boxes[parkingNode.index] !== undefined && boxes[parkingNode1.index] !== undefined) {
var poly1 = turf.polygon([boxes[parkingNode.index]]);
var poly2 = turf.polygon([boxes[parkingNode1.index]]);
var intersection = turf.intersect(poly1, poly2);
if (intersection !== null) {
overlappingParkings.push({ id: parkingNode.index, message: check_msg.OVERLAPPING_PARKINGS });
}
}
}
}
});
});
this.postMessage(['progress', 1]);
var invalidParkings = [];
// Check for name
parkingNodes.forEach(parkingNode => {
if (!parkingNode.name || /^\s*$/.test(parkingNode.name)) {
invalidParkings.push({ id: parkingNode.index, message: check_msg.NAME_EMPTY });
}
if (!parkingNode.type) {
invalidParkings.push({ id: parkingNode.index, message: check_msg.TYPE_EMPTY });
}
if (['ga', 'cargo', 'gate', 'mil-fighter', 'mil-cargo'].indexOf(parkingNode.parkingType) < 0) {
invalidParkings.push({ id: parkingNode.index, message: check_msg.PARKING_TYPE_INVALID });
}
});
this.postMessage(['progress', 1]);
this.postMessage(['progress', 1]);
//Check for dual pushback/runway nodes
runwayNodeIDs.forEach(runwayNode => {
if (pushbackNodes.indexOf(runwayNode) >= 0) {
notOkNodes.push({ id: runwayNode, message: check_msg.DUAL_PUSHBACK });
}
});
this.postMessage(['progress', 1]);
//Check if runwaynodes are on runway
runwayNodes.forEach(runwayNode => {
// 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 });
}
});
this.postMessage(['progress', 1]);
//Check if nodes no normal nodes are on runway
normalNodes.forEach(normalNode => {
//debugger;
if (takeoffPads.filter(r => turf.booleanContains(r, latToTurf(normalNode))).length > 0) {
notOkNodes.push({ id: normalNode.index, message: check_msg.NON_RUNWAYNODE_ON_RUNWAY });
}
});
this.postMessage(['progress', 1]);
var doubleEdges = edges.filter((v, i, a) => a.findIndex(t => (t.start === v.start && t.end === v.end) ) !== i);
doubleEdges.forEach(e => {
notOkNodes.push({ id: e.id, message: check_msg.DOUBLE_EDGE });
});
// debugger;
notOkNodes = notOkNodes.concat(invalidParkings);
if (invalidParkings.length === 0) {
notOkNodes.push({ id: -1, message: check_msg.PARKINGS_VALID });
}
notOkNodes = notOkNodes.concat(overlappingParkings);
if (overlappingParkings.length === 0) {
notOkNodes.push({ id: -1, message: check_msg.NO_OVERLAPPING_PARKINGS });
}
notOkNodes = notOkNodes.concat(danglingEnds);
if (danglingEnds.length === 0) {
notOkNodes.push({ id: -1, message: check_msg.NO_INVALID_ENDS });
}
notOkNodes = notOkNodes.concat(notOkNodesParkings).concat(rogueHoldPoints);
if (notOkNodesParkings.length === 0 && rogueHoldPoints === 0) {
notOkNodes.push({ id: -1, message: check_msg.ROUTES_FROM_PARKINGS_OK });
}
notOkNodes = notOkNodes.concat(notOkNodesRunways);
if (notOkNodesRunways.length === 0) {
notOkNodes.push({ id: -1, message: check_msg.ROUTES_FROM_RUNWAYS_OK });
}
notOkNodes = notOkNodes.concat(wrongPushbackRoutes);
notOkNodes = notOkNodes.concat(notConnectedToPushback);
notOkNodes = notOkNodes.concat(multipleTaxiRoutes);
notOkNodes = notOkNodes.concat(pushbackExitNotBidirectional);
if (wrongPushbackRoutes.length === 0 &&
notConnectedToPushback.length === 0 &&
multipleTaxiRoutes.length === 0 &&
pushbackExitNotBidirectional.length === 0
) {
notOkNodes.push({ id: -1, message: check_msg.PUSHBACK_ROUTES_OK });
}
resolve(notOkNodes);
} catch (error) {
reject(error);
}
});
return promise;
}
function checkRoute(directionalGraph, from, to) {
try {
var pathD = this.dijkstra.find_path(directionalGraph, from, to);
if (pathD.length > 0) {
console.log(pathD);
return pathD.length;
}
return 0;
} catch (error) {
// console.error(error);
return 0;
}
}
function check1(directionalGraph) {
var directionalGraph1 = {
a: { b: 1, d: 1 },
b: { a: 1, c: 1, e: 1 },
c: { b: 1, f: 1 },
d: { a: 1, e: 1, g: 1 },
e: { b: 1, d: 1, f: 1, h: 1 },
f: { c: 1, e: 1, i: 1 },
g: { d: 1, h: 1 },
h: { e: 1, g: 1, i: 1 },
i: { f: 1, h: 1 }
};
var path = this.dijkstra.find_path(directionalGraph, 'a', 'i');
console.log(path);
}
function check2(params) {
}
var mapPushbackNodes = function (o) {
if (o.type === 'PushBack') {
return o.index;
}
}
var mapParkings = function (o) {
if (o.type === 'parking')
return o.index;
}
var mapParkingNode = function (o) {
// debugger;
if (o.type === 'parking')
return { index: o.index, lat: o.lat, lng: o.lng, name: o.name, radius: Number(o.radius), type: o.type, parkingType: o.parkingType };
console.debug(o);
}
var mapBoxes = function (o) {
// debugger;
if (o.type === 'parking')
return { index: o.index };
}
var mapRunwayNodeId = function (o) {
if (o.type === 'runway')
return o.index;
console.debug(o);
}
var mapRunwayNode = function (o) {
if (o.type === 'runway') {
return { index: o.index, lat: o.lat, lng: o.lng };
}
}
var mapTakeoffPads = function (o) {
if (o.type === 'takeoffpad_poly') {
var pts = o.pavement[0].map(latLngToArray);
pts.push(pts[0]);
return turf.polygon([pts]);
}
}
var mapEdges = function (o) {
if (o.type === 'poly')
return {
id: o._leaflet_id, start: o.start, end: o.end, isPushBackRoute: o.isPushBackRoute !== undefined &&
o.isPushBackRoute !== 0, direction: o.direction, latLngs: o.latLngs
};
}
var latToTurf = function (turfPoint) {
return turf.point([turfPoint.lng, turfPoint.lat]);
};
var latLngToArray = function (turfPoint) {
//debugger;
return [turfPoint.lng, turfPoint.lat];
};
var turfToLatLng = function (turfPoint) {
return '' + turfPoint.geometry.coordinates[1].toFixed(6) + ',' + turfPoint.geometry.coordinates[0].toFixed(6);
};