UNPKG

@signalk/resources-provider

Version:

Resources provider plugin for Signal K server.

174 lines (173 loc) 6.69 kB
"use strict"; /* eslint-disable @typescript-eslint/no-explicit-any */ // utility library functions var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.toPolygon = exports.processParameters = exports.passFilter = exports.inBounds = void 0; const geolib_1 = require("geolib"); const ngeohash_1 = __importDefault(require("ngeohash")); // check geometry is in bounds const inBounds = (val, type, polygon) => { var _a, _b, _c, _d; let ok = false; switch (type) { case 'notes': case 'waypoints': if ((_b = (_a = val === null || val === void 0 ? void 0 : val.feature) === null || _a === void 0 ? void 0 : _a.geometry) === null || _b === void 0 ? void 0 : _b.coordinates) { ok = (0, geolib_1.isPointInPolygon)((_d = (_c = val === null || val === void 0 ? void 0 : val.feature) === null || _c === void 0 ? void 0 : _c.geometry) === null || _d === void 0 ? void 0 : _d.coordinates, polygon); } if (val.position) { ok = (0, geolib_1.isPointInPolygon)(val.position, polygon); } if (val.geohash) { const bar = ngeohash_1.default.decode_bbox(val.geohash); const bounds = (0, exports.toPolygon)([bar[1], bar[0], bar[3], bar[2]]); const center = (0, geolib_1.getCenterOfBounds)(bounds); ok = (0, geolib_1.isPointInPolygon)(center, polygon); } break; case 'routes': if (val.feature.geometry.coordinates) { val.feature.geometry.coordinates.forEach((pt) => { ok = ok || (0, geolib_1.isPointInPolygon)(pt, polygon); }); } break; case 'regions': if (val.feature.geometry.coordinates && val.feature.geometry.coordinates.length > 0) { if (val.feature.geometry.type == 'Polygon') { val.feature.geometry.coordinates.forEach((ls) => { ls.forEach((pt) => { ok = ok || (0, geolib_1.isPointInPolygon)(pt, polygon); }); }); } else if (val.feature.geometry.type == 'MultiPolygon') { val.feature.geometry.coordinates.forEach((polygon) => { polygon.forEach((ls) => { ls.forEach((pt) => { ok = ok || (0, geolib_1.isPointInPolygon)(pt, polygon); }); }); }); } } break; } return ok; }; exports.inBounds = inBounds; /** Apply filters to Resource entry * returns: true if entry should be included in results **/ const passFilter = (res, type, params) => { let ok = true; if (params.href) { // check is attached to another resource if (typeof res.href === 'undefined' || !res.href) { ok = ok && false; } else { // deconstruct resource href value const ha = res.href.split('/'); const hType = ha.length === 1 ? 'regions' : ha.length > 2 ? ha[ha.length - 2] : 'regions'; const hId = ha.length === 1 ? ha[0] : ha[ha.length - 1]; // deconstruct param.href value const pa = params.href.split('/'); const pType = pa.length === 1 ? 'regions' : pa.length > 2 ? pa[pa.length - 2] : 'regions'; const pId = pa.length === 1 ? pa[0] : pa[pa.length - 1]; ok = ok && hType === pType && hId === pId; } } if (params.group) { // check is attached to group if (typeof res.group === 'undefined') { ok = ok && false; } else { ok = ok && res.group == params.group; } } if (params.geobounds) { // check is within bounds ok = ok && (0, exports.inBounds)(res, type, params.geobounds); } return ok; }; exports.passFilter = passFilter; const checkForNumberArray = (param) => { if (!Array.isArray(param)) { throw new Error(`Supplied value is not valid! (Array<number>) (${param})`); } else { param.forEach((i) => { if (typeof i !== 'number') { throw new Error(`Supplied value is not a number array! (Array<number>) (${param})`); } }); return param; } }; const checkForNumber = (param) => { if (isNaN(param)) { throw new Error(`Supplied value is not a number! (${param})`); } else { return param; } }; // process query parameters const processParameters = (params) => { if (typeof params.limit !== 'undefined') { params.limit = checkForNumber(params.limit); } if (typeof params.bbox !== 'undefined') { params.bbox = checkForNumberArray(params.bbox); // generate geobounds polygon from bbox params.geobounds = (0, exports.toPolygon)(params.bbox); if (params.geobounds.length !== 5) { params.geobounds = null; throw new Error(`Bounding box contains invalid coordinate value (${params.bbox})`); } } else if (typeof params.distance !== 'undefined' && params.position) { params.distance = checkForNumber(params.distance); params.position = checkForNumberArray(params.position); const sw = (0, geolib_1.computeDestinationPoint)(params.position, params.distance, 225); const ne = (0, geolib_1.computeDestinationPoint)(params.position, params.distance, 45); params.geobounds = (0, exports.toPolygon)([ sw.longitude, sw.latitude, ne.longitude, ne.latitude ]); } return params; }; exports.processParameters = processParameters; // convert bbox string to array of points (polygon) const toPolygon = (bbox) => { const polygon = []; if (bbox.length === 4) { polygon.push([bbox[0], bbox[1]]); polygon.push([bbox[0], bbox[3]]); polygon.push([bbox[2], bbox[3]]); polygon.push([bbox[2], bbox[1]]); polygon.push([bbox[0], bbox[1]]); } else { console.error(`*** Error: Bounding box contains invalid coordinate value (${bbox}) ***`); } return polygon; }; exports.toPolygon = toPolygon;