@signalk/resources-provider
Version:
Resources provider plugin for Signal K server.
174 lines (173 loc) • 6.69 kB
JavaScript
;
/* 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;