UNPKG

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

440 lines (402 loc) 11.3 kB
import Coordinate from '../geom/Coordinate' import GeometryFactory from '../geom/GeometryFactory' const geometryTypes = ['Point', 'MultiPoint', 'LineString', 'MultiLineString', 'Polygon', 'MultiPolygon'] /** * Class for reading and writing Well-Known Text.Create a new parser for GeoJSON * NOTE: Adapted from OpenLayers 2.11 implementation. */ /** * Create a new parser for GeoJSON * * @param {GeometryFactory} geometryFactory * @return An instance of GeoJsonParser. * @constructor * @private */ export default class GeoJSONParser { constructor (geometryFactory) { this.geometryFactory = geometryFactory || new GeometryFactory() } /** * Deserialize a GeoJSON object and return the Geometry or Feature(Collection) with JSTS Geometries * * @param {} * A GeoJSON object. * @return {} A Geometry instance or object representing a Feature(Collection) with Geometry instances. * @private */ read (json) { let obj if (typeof json === 'string') { obj = JSON.parse(json) } else { obj = json } const type = obj.type if (!parse[type]) { throw new Error('Unknown GeoJSON type: ' + obj.type) } if (geometryTypes.indexOf(type) !== -1) { return parse[type].apply(this, [obj.coordinates]) } else if (type === 'GeometryCollection') { return parse[type].apply(this, [obj.geometries]) } // feature or feature collection return parse[type].apply(this, [obj]) } /** * Serialize a Geometry object into GeoJSON * * @param {Geometry} * geometry A Geometry or array of Geometries. * @return {Object} A GeoJSON object represting the input Geometry/Geometries. * @private */ write (geometry) { const type = geometry.getGeometryType() if (!extract[type]) { throw new Error('Geometry is not supported') } return extract[type].apply(this, [geometry]) } } const parse = { /** * Parse a GeoJSON Feature object * * @param {Object} * obj Object to parse. * * @return {Object} Feature with geometry/bbox converted to JSTS Geometries. */ Feature: function (obj) { const feature = {} // copy features for (let key in obj) { feature[key] = obj[key] } // parse geometry if (obj.geometry) { const type = obj.geometry.type if (!parse[type]) { throw new Error('Unknown GeoJSON type: ' + obj.type) } feature.geometry = this.read(obj.geometry) } // bbox if (obj.bbox) { feature.bbox = parse.bbox.apply(this, [obj.bbox]) } return feature }, /** * Parse a GeoJSON FeatureCollection object * * @param {Object} * obj Object to parse. * * @return {Object} FeatureCollection with geometry/bbox converted to JSTS Geometries. */ FeatureCollection: function (obj) { const featureCollection = {} if (obj.features) { featureCollection.features = [] for (let i = 0; i < obj.features.length; ++i) { featureCollection.features.push(this.read(obj.features[i])) } } if (obj.bbox) { featureCollection.bbox = this.parse.bbox.apply(this, [obj.bbox]) } return featureCollection }, /** * Convert the ordinates in an array to an array of Coordinates * * @param {Array} * array Array with {Number}s. * * @return {Array} Array with Coordinates. */ coordinates: function (array) { const coordinates = [] for (let i = 0; i < array.length; ++i) { const sub = array[i] coordinates.push(new Coordinate(sub[0], sub[1])) } return coordinates }, /** * Convert the bbox to a LinearRing * * @param {Array} * array Array with [xMin, yMin, xMax, yMax]. * * @return {Array} Array with Coordinates. */ bbox: function (array) { return this.geometryFactory.createLinearRing([ new Coordinate(array[0], array[1]), new Coordinate(array[2], array[1]), new Coordinate(array[2], array[3]), new Coordinate(array[0], array[3]), new Coordinate(array[0], array[1]) ]) }, /** * Convert an Array with ordinates to a Point * * @param {Array} * array Array with ordinates. * * @return {Point} Point. */ Point: function (array) { const coordinate = new Coordinate(array[0], array[1]) return this.geometryFactory.createPoint(coordinate) }, /** * Convert an Array with coordinates to a MultiPoint * * @param {Array} * array Array with coordinates. * * @return {MultiPoint} MultiPoint. */ MultiPoint: function (array) { const points = [] for (let i = 0; i < array.length; ++i) { points.push(parse.Point.apply(this, [array[i]])) } return this.geometryFactory.createMultiPoint(points) }, /** * Convert an Array with coordinates to a LineString * * @param {Array} * array Array with coordinates. * * @return {LineString} LineString. */ LineString: function (array) { const coordinates = parse.coordinates.apply(this, [array]) return this.geometryFactory.createLineString(coordinates) }, /** * Convert an Array with coordinates to a MultiLineString * * @param {Array} * array Array with coordinates. * * @return {MultiLineString} MultiLineString. */ MultiLineString: function (array) { const lineStrings = [] for (let i = 0; i < array.length; ++i) { lineStrings.push(parse.LineString.apply(this, [array[i]])) } return this.geometryFactory.createMultiLineString(lineStrings) }, /** * Convert an Array to a Polygon * * @param {Array} * array Array with shell and holes. * * @return {Polygon} Polygon. */ Polygon: function (array) { const shellCoordinates = parse.coordinates.apply(this, [array[0]]) const shell = this.geometryFactory.createLinearRing(shellCoordinates) const holes = [] for (let i = 1; i < array.length; ++i) { var hole = array[i] var coordinates = parse.coordinates.apply(this, [hole]) var linearRing = this.geometryFactory.createLinearRing(coordinates) holes.push(linearRing) } return this.geometryFactory.createPolygon(shell, holes) }, /** * Convert an Array to a MultiPolygon * * @param {Array} * array Array of arrays with shell and rings. * * @return {MultiPolygon} MultiPolygon. */ MultiPolygon: function (array) { const polygons = [] for (let i = 0; i < array.length; ++i) { const polygon = array[i] polygons.push(parse.Polygon.apply(this, [polygon])) } return this.geometryFactory.createMultiPolygon(polygons) }, /** * Convert an Array to a GeometryCollection * * @param {Array} * array Array of GeoJSON geometries. * * @return {GeometryCollection} GeometryCollection. */ GeometryCollection: function (array) { const geometries = [] for (let i = 0; i < array.length; ++i) { const geometry = array[i] geometries.push(this.read(geometry)) } return this.geometryFactory.createGeometryCollection(geometries) } } const extract = { /** * Convert a Coordinate to an Array * * @param {Coordinate} * coordinate Coordinate to convert. * * @return {Array} Array of ordinates. */ coordinate: function (coordinate) { return [coordinate.x, coordinate.y] }, /** * Convert a Point to a GeoJSON object * * @param {Point} * point Point to convert. * * @return {Array} Array of 2 ordinates (paired to a coordinate). */ Point: function (point) { const array = extract.coordinate.apply(this, [point.getCoordinate()]) return { type: 'Point', coordinates: array } }, /** * Convert a MultiPoint to a GeoJSON object * * @param {MultiPoint} * multipoint MultiPoint to convert. * * @return {Array} Array of coordinates. */ MultiPoint: function (multipoint) { const array = [] for (let i = 0; i < multipoint._geometries.length; ++i) { const point = multipoint._geometries[i] const geoJson = extract.Point.apply(this, [point]) array.push(geoJson.coordinates) } return { type: 'MultiPoint', coordinates: array } }, /** * Convert a LineString to a GeoJSON object * * @param {LineString} * linestring LineString to convert. * * @return {Array} Array of coordinates. */ LineString: function (linestring) { const array = [] const coordinates = linestring.getCoordinates() for (let i = 0; i < coordinates.length; ++i) { const coordinate = coordinates[i] array.push(extract.coordinate.apply(this, [coordinate])) } return { type: 'LineString', coordinates: array } }, /** * Convert a MultiLineString to a GeoJSON object * * @param {MultiLineString} * multilinestring MultiLineString to convert. * * @return {Array} Array of Array of coordinates. */ MultiLineString: function (multilinestring) { const array = [] for (let i = 0; i < multilinestring._geometries.length; ++i) { const linestring = multilinestring._geometries[i] const geoJson = extract.LineString.apply(this, [linestring]) array.push(geoJson.coordinates) } return { type: 'MultiLineString', coordinates: array } }, /** * Convert a Polygon to a GeoJSON object * * @param {Polygon} * polygon Polygon to convert. * * @return {Array} Array with shell, holes. */ Polygon: function (polygon) { const array = [] const shellGeoJson = extract.LineString.apply(this, [polygon._shell]) array.push(shellGeoJson.coordinates) for (let i = 0; i < polygon._holes.length; ++i) { const hole = polygon._holes[i] const holeGeoJson = extract.LineString.apply(this, [hole]) array.push(holeGeoJson.coordinates) } return { type: 'Polygon', coordinates: array } }, /** * Convert a MultiPolygon to a GeoJSON object * * @param {MultiPolygon} * multipolygon MultiPolygon to convert. * * @return {Array} Array of polygons. */ MultiPolygon: function (multipolygon) { const array = [] for (let i = 0; i < multipolygon._geometries.length; ++i) { const polygon = multipolygon._geometries[i] const geoJson = extract.Polygon.apply(this, [polygon]) array.push(geoJson.coordinates) } return { type: 'MultiPolygon', coordinates: array } }, /** * Convert a GeometryCollection to a GeoJSON object * * @param {GeometryCollection} * collection GeometryCollection to convert. * * @return {Array} Array of geometries. */ GeometryCollection: function (collection) { const array = [] for (let i = 0; i < collection._geometries.length; ++i) { const geometry = collection._geometries[i] const type = geometry.getGeometryType() array.push(extract[type].apply(this, [geometry])) } return { type: 'GeometryCollection', geometries: array } } }