node-red-contrib-tak-registration
Version:
A Node-RED node to register to TAK and to help wrap files as datapackages to send to TAK
209 lines (196 loc) • 7.07 kB
JavaScript
var rbush = require('rbush');
var helpers = require('@turf/helpers');
var meta = require('@turf/meta');
var turfBBox = require('@turf/bbox').default;
var featureEach = meta.featureEach;
var coordEach = meta.coordEach;
var polygon = helpers.polygon;
var featureCollection = helpers.featureCollection;
/**
* GeoJSON implementation of [RBush](https://github.com/mourner/rbush#rbush) spatial index.
*
* @name rbush
* @param {number} [maxEntries=9] defines the maximum number of entries in a tree node. 9 (used by default) is a
* reasonable choice for most applications. Higher value means faster insertion and slower search, and vice versa.
* @returns {RBush} GeoJSON RBush
* @example
* var geojsonRbush = require('geojson-rbush').default;
* var tree = geojsonRbush();
*/
function geojsonRbush(maxEntries) {
var tree = new rbush(maxEntries);
/**
* [insert](https://github.com/mourner/rbush#data-format)
*
* @param {Feature} feature insert single GeoJSON Feature
* @returns {RBush} GeoJSON RBush
* @example
* var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]);
* tree.insert(poly)
*/
tree.insert = function (feature) {
if (feature.type !== 'Feature') throw new Error('invalid feature');
feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);
return rbush.prototype.insert.call(this, feature);
};
/**
* [load](https://github.com/mourner/rbush#bulk-inserting-data)
*
* @param {FeatureCollection|Array<Feature>} features load entire GeoJSON FeatureCollection
* @returns {RBush} GeoJSON RBush
* @example
* var polys = turf.polygons([
* [[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]],
* [[[-93, 32], [-83, 32], [-83, 39], [-93, 39], [-93, 32]]]
* ]);
* tree.load(polys);
*/
tree.load = function (features) {
var load = [];
// Load an Array of Features
if (Array.isArray(features)) {
features.forEach(function (feature) {
if (feature.type !== 'Feature') throw new Error('invalid features');
feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);
load.push(feature);
});
} else {
// Load a FeatureCollection
featureEach(features, function (feature) {
if (feature.type !== 'Feature') throw new Error('invalid features');
feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);
load.push(feature);
});
}
return rbush.prototype.load.call(this, load);
};
/**
* [remove](https://github.com/mourner/rbush#removing-data)
*
* @param {Feature} feature remove single GeoJSON Feature
* @param {Function} equals Pass a custom equals function to compare by value for removal.
* @returns {RBush} GeoJSON RBush
* @example
* var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]);
*
* tree.remove(poly);
*/
tree.remove = function (feature, equals) {
if (feature.type !== 'Feature') throw new Error('invalid feature');
feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);
return rbush.prototype.remove.call(this, feature, equals);
};
/**
* [clear](https://github.com/mourner/rbush#removing-data)
*
* @returns {RBush} GeoJSON Rbush
* @example
* tree.clear()
*/
tree.clear = function () {
return rbush.prototype.clear.call(this);
};
/**
* [search](https://github.com/mourner/rbush#search)
*
* @param {BBox|FeatureCollection|Feature} geojson search with GeoJSON
* @returns {FeatureCollection} all features that intersects with the given GeoJSON.
* @example
* var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]);
*
* tree.search(poly);
*/
tree.search = function (geojson) {
var features = rbush.prototype.search.call(this, this.toBBox(geojson));
return featureCollection(features);
};
/**
* [collides](https://github.com/mourner/rbush#collisions)
*
* @param {BBox|FeatureCollection|Feature} geojson collides with GeoJSON
* @returns {boolean} true if there are any items intersecting the given GeoJSON, otherwise false.
* @example
* var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]);
*
* tree.collides(poly);
*/
tree.collides = function (geojson) {
return rbush.prototype.collides.call(this, this.toBBox(geojson));
};
/**
* [all](https://github.com/mourner/rbush#search)
*
* @returns {FeatureCollection} all the features in RBush
* @example
* tree.all()
*/
tree.all = function () {
var features = rbush.prototype.all.call(this);
return featureCollection(features);
};
/**
* [toJSON](https://github.com/mourner/rbush#export-and-import)
*
* @returns {any} export data as JSON object
* @example
* var exported = tree.toJSON()
*/
tree.toJSON = function () {
return rbush.prototype.toJSON.call(this);
};
/**
* [fromJSON](https://github.com/mourner/rbush#export-and-import)
*
* @param {any} json import previously exported data
* @returns {RBush} GeoJSON RBush
* @example
* var exported = {
* "children": [
* {
* "type": "Feature",
* "geometry": {
* "type": "Point",
* "coordinates": [110, 50]
* },
* "properties": {},
* "bbox": [110, 50, 110, 50]
* }
* ],
* "height": 1,
* "leaf": true,
* "minX": 110,
* "minY": 50,
* "maxX": 110,
* "maxY": 50
* }
* tree.fromJSON(exported)
*/
tree.fromJSON = function (json) {
return rbush.prototype.fromJSON.call(this, json);
};
/**
* Converts GeoJSON to {minX, minY, maxX, maxY} schema
*
* @private
* @param {BBox|FeatureCollection|Feature} geojson feature(s) to retrieve BBox from
* @returns {Object} converted to {minX, minY, maxX, maxY}
*/
tree.toBBox = function (geojson) {
var bbox;
if (geojson.bbox) bbox = geojson.bbox;
else if (Array.isArray(geojson) && geojson.length === 4) bbox = geojson;
else if (Array.isArray(geojson) && geojson.length === 6) bbox = [geojson[0], geojson[1], geojson[3], geojson[4]];
else if (geojson.type === 'Feature') bbox = turfBBox(geojson);
else if (geojson.type === 'FeatureCollection') bbox = turfBBox(geojson);
else throw new Error('invalid geojson')
return {
minX: bbox[0],
minY: bbox[1],
maxX: bbox[2],
maxY: bbox[3]
};
};
return tree;
}
module.exports = geojsonRbush;
module.exports.default = geojsonRbush;