├── .editorconfig ├── .gitignore ├── .jshintignore ├── .jshintrc ├── .nycrc ├── .travis.yml ├── LICENSE.txt ├── README.md ├── build └── update-testdata.js ├── lib ├── binaryreader.js ├── binarywriter.js ├── geometry.js ├── geometrycollection.js ├── linestring.js ├── multilinestring.js ├── multipoint.js ├── multipolygon.js ├── point.js ├── polygon.js ├── types.js ├── wktparser.js ├── wkx.d.ts ├── wkx.js └── zigzag.js ├── package-lock.json ├── package.json └── test ├── .jshintrc ├── binaryreader.js ├── binarywriter.js ├── geojson.js ├── issuetestdata.json ├── testdata.json ├── testdataM.json ├── testdataZ.json ├── testdataZM.json ├── twkb.js ├── wkx.js └── zigzag.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 4 9 | trim_trailing_whitespace = true 10 | 11 | [*.json] 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | coverage 2 | dist 3 | node_modules 4 | .nyc_output -------------------------------------------------------------------------------- /.jshintignore: -------------------------------------------------------------------------------- 1 | coverage 2 | dist 3 | node_modules -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "browser": false, 3 | "node": true, 4 | "strict": false, 5 | "camelcase": true, 6 | "quotmark": "single", 7 | "indent": 4, 8 | "trailing": true, 9 | "white": true, 10 | "smarttabs": false, 11 | "maxlen": 120, 12 | "undef": true, 13 | "unused": true 14 | } -------------------------------------------------------------------------------- /.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "nyc": { 3 | "all": true, 4 | "check-coverage": true 5 | } 6 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - "lts/*" 5 | - "node" 6 | after_script: 7 | - npm run coverage 8 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Christian Schwarz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | wkx [![Build Status](https://travis-ci.org/cschwarz/wkx.svg?branch=master)](https://travis-ci.org/cschwarz/wkx) [![Coverage Status](https://coveralls.io/repos/cschwarz/wkx/badge.svg?branch=master)](https://coveralls.io/r/cschwarz/wkx?branch=master) 2 | ======== 3 | 4 | A WKT/WKB/EWKT/EWKB/TWKB/GeoJSON parser and serializer with support for 5 | 6 | - Point 7 | - LineString 8 | - Polygon 9 | - MultiPoint 10 | - MultiLineString 11 | - MultiPolygon 12 | - GeometryCollection 13 | 14 | Examples 15 | -------- 16 | 17 | The following examples show you how to work with wkx. 18 | 19 | ```javascript 20 | var wkx = require('wkx'); 21 | 22 | //Parsing a WKT string 23 | var geometry = wkx.Geometry.parse('POINT(1 2)'); 24 | 25 | //Parsing an EWKT string 26 | var geometry = wkx.Geometry.parse('SRID=4326;POINT(1 2)'); 27 | 28 | //Parsing a node Buffer containing a WKB object 29 | var geometry = wkx.Geometry.parse(wkbBuffer); 30 | 31 | //Parsing a node Buffer containing an EWKB object 32 | var geometry = wkx.Geometry.parse(ewkbBuffer); 33 | 34 | //Parsing a node Buffer containing a TWKB object 35 | var geometry = wkx.Geometry.parseTwkb(twkbBuffer); 36 | 37 | //Parsing a GeoJSON object 38 | var geometry = wkx.Geometry.parseGeoJSON({ type: 'Point', coordinates: [1, 2] }); 39 | 40 | //Serializing a Point geometry to WKT 41 | var wktString = new wkx.Point(1, 2).toWkt(); 42 | 43 | //Serializing a Point geometry to WKB 44 | var wkbBuffer = new wkx.Point(1, 2).toWkb(); 45 | 46 | //Serializing a Point geometry to EWKT 47 | var ewktString = new wkx.Point(1, 2, undefined, undefined, 4326).toEwkt(); 48 | 49 | //Serializing a Point geometry to EWKB 50 | var ewkbBuffer = new wkx.Point(1, 2, undefined, undefined, 4326).toEwkb(); 51 | 52 | //Serializing a Point geometry to TWKB 53 | var twkbBuffer = new wkx.Point(1, 2).toTwkb(); 54 | 55 | //Serializing a Point geometry to GeoJSON 56 | var geoJSONObject = new wkx.Point(1, 2).toGeoJSON(); 57 | ``` 58 | 59 | Browser 60 | ------- 61 | 62 | To use `wkx` in a webpage, simply copy a built browser version from `dist/` into your project, and use a `script` tag 63 | to include it: 64 | ```html 65 | 66 | ``` 67 | 68 | If you use [browserify][] for your project, you can simply `npm install wkx --save`, and just require `wkx` as usual in 69 | your code. 70 | 71 | ---- 72 | 73 | Regardless of which of the preceeding options you choose, using `wkx` in the browser will look the same: 74 | ```javascript 75 | var wkx = require('wkx'); 76 | 77 | var geometry = wkx.Geometry.parse('POINT(1 2)'); 78 | 79 | console.log(geometry.toGeoJSON()); 80 | ``` 81 | 82 | In addition to the `wkx` module, the browser versions also export `buffer`, which is useful for parsing WKB: 83 | ```javascript 84 | var Buffer = require('buffer').Buffer; 85 | var wkx = require('wkx'); 86 | 87 | var wkbBuffer = new Buffer('0101000000000000000000f03f0000000000000040', 'hex'); 88 | var geometry = wkx.Geometry.parse(wkbBuffer); 89 | 90 | console.log(geometry.toGeoJSON()); 91 | ``` 92 | [browserify]: http://browserify.org/ 93 | -------------------------------------------------------------------------------- /build/update-testdata.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var pg = require('pg'); 3 | var async = require('async'); 4 | var stringify = require('json-stringify-pretty-compact'); 5 | 6 | updateTestData('./test/testdata.json'); 7 | updateTestData('./test/testdataZ.json'); 8 | updateTestData('./test/testdataM.json'); 9 | updateTestData('./test/testdataZM.json'); 10 | 11 | function updateTestData(file) { 12 | var testdata = JSON.parse(fs.readFileSync(file, { encoding: 'utf8' })); 13 | 14 | var connectionString = 'postgres://postgres:postgres@localhost/postgres'; 15 | 16 | var client = new pg.Client(connectionString); 17 | client.connect(function(err) { 18 | if (err) { 19 | console.log(err); 20 | return; 21 | } 22 | 23 | async.forEachOf(testdata, function (value, key, callback) { 24 | client.query('SELECT encode(ST_AsBinary(ST_GeomFromText($1)), \'hex\') wkb, ' + 25 | 'encode(ST_AsEWKB(ST_GeomFromText($1, 4326)), \'hex\') ewkb, ' + 26 | 'encode(ST_AsBinary(ST_GeomFromText($1), \'xdr\'), \'hex\') wkbxdr, ' + 27 | 'encode(ST_AsEWKB(ST_GeomFromText($1, 4326), \'xdr\'), \'hex\') ewkbxdr, ' + 28 | 'encode(ST_AsEWKB(ST_GeomFromText($1)), \'hex\') ewkbnosrid, ' + 29 | 'encode(ST_AsEWKB(ST_GeomFromText($1), \'xdr\'), \'hex\') ewkbxdrnosrid, ' + 30 | 'encode(ST_AsTWKB(ST_GeomFromText($1, 4326)), \'hex\') twkb, ' + 31 | 'ST_AsGeoJSON(ST_GeomFromText($1, 4326)) geojson', [value.wkt], function (err, result) { 32 | 33 | value.wkb = result.rows[0].wkb; 34 | value.ewkb = result.rows[0].ewkb; 35 | value.wkbXdr = result.rows[0].wkbxdr; 36 | value.ewkbXdr = result.rows[0].ewkbxdr; 37 | value.ewkbNoSrid = result.rows[0].ewkbnosrid; 38 | value.ewkbXdrNoSrid = result.rows[0].ewkbxdrnosrid; 39 | value.twkb = result.rows[0].twkb; 40 | value.geoJSON = JSON.parse(result.rows[0].geojson); 41 | 42 | callback(); 43 | }); 44 | }, function () { 45 | client.end(); 46 | fs.writeFileSync(file, stringify(testdata)); 47 | }); 48 | }); 49 | } 50 | -------------------------------------------------------------------------------- /lib/binaryreader.js: -------------------------------------------------------------------------------- 1 | module.exports = BinaryReader; 2 | 3 | function BinaryReader(buffer, isBigEndian) { 4 | this.buffer = buffer; 5 | this.position = 0; 6 | this.isBigEndian = isBigEndian || false; 7 | } 8 | 9 | function _read(readLE, readBE, size) { 10 | return function () { 11 | var value; 12 | 13 | if (this.isBigEndian) 14 | value = readBE.call(this.buffer, this.position); 15 | else 16 | value = readLE.call(this.buffer, this.position); 17 | 18 | this.position += size; 19 | 20 | return value; 21 | }; 22 | } 23 | 24 | BinaryReader.prototype.readUInt8 = _read(Buffer.prototype.readUInt8, Buffer.prototype.readUInt8, 1); 25 | BinaryReader.prototype.readUInt16 = _read(Buffer.prototype.readUInt16LE, Buffer.prototype.readUInt16BE, 2); 26 | BinaryReader.prototype.readUInt32 = _read(Buffer.prototype.readUInt32LE, Buffer.prototype.readUInt32BE, 4); 27 | BinaryReader.prototype.readInt8 = _read(Buffer.prototype.readInt8, Buffer.prototype.readInt8, 1); 28 | BinaryReader.prototype.readInt16 = _read(Buffer.prototype.readInt16LE, Buffer.prototype.readInt16BE, 2); 29 | BinaryReader.prototype.readInt32 = _read(Buffer.prototype.readInt32LE, Buffer.prototype.readInt32BE, 4); 30 | BinaryReader.prototype.readFloat = _read(Buffer.prototype.readFloatLE, Buffer.prototype.readFloatBE, 4); 31 | BinaryReader.prototype.readDouble = _read(Buffer.prototype.readDoubleLE, Buffer.prototype.readDoubleBE, 8); 32 | 33 | BinaryReader.prototype.readVarInt = function () { 34 | var nextByte, 35 | result = 0, 36 | bytesRead = 0; 37 | 38 | do { 39 | nextByte = this.buffer[this.position + bytesRead]; 40 | result += (nextByte & 0x7F) << (7 * bytesRead); 41 | bytesRead++; 42 | } while (nextByte >= 0x80); 43 | 44 | this.position += bytesRead; 45 | 46 | return result; 47 | }; 48 | -------------------------------------------------------------------------------- /lib/binarywriter.js: -------------------------------------------------------------------------------- 1 | module.exports = BinaryWriter; 2 | 3 | function BinaryWriter(size, allowResize) { 4 | this.buffer = new Buffer(size); 5 | this.position = 0; 6 | this.allowResize = allowResize; 7 | } 8 | 9 | function _write(write, size) { 10 | return function (value, noAssert) { 11 | this.ensureSize(size); 12 | 13 | write.call(this.buffer, value, this.position, noAssert); 14 | this.position += size; 15 | }; 16 | } 17 | 18 | BinaryWriter.prototype.writeUInt8 = _write(Buffer.prototype.writeUInt8, 1); 19 | BinaryWriter.prototype.writeUInt16LE = _write(Buffer.prototype.writeUInt16LE, 2); 20 | BinaryWriter.prototype.writeUInt16BE = _write(Buffer.prototype.writeUInt16BE, 2); 21 | BinaryWriter.prototype.writeUInt32LE = _write(Buffer.prototype.writeUInt32LE, 4); 22 | BinaryWriter.prototype.writeUInt32BE = _write(Buffer.prototype.writeUInt32BE, 4); 23 | BinaryWriter.prototype.writeInt8 = _write(Buffer.prototype.writeInt8, 1); 24 | BinaryWriter.prototype.writeInt16LE = _write(Buffer.prototype.writeInt16LE, 2); 25 | BinaryWriter.prototype.writeInt16BE = _write(Buffer.prototype.writeInt16BE, 2); 26 | BinaryWriter.prototype.writeInt32LE = _write(Buffer.prototype.writeInt32LE, 4); 27 | BinaryWriter.prototype.writeInt32BE = _write(Buffer.prototype.writeInt32BE, 4); 28 | BinaryWriter.prototype.writeFloatLE = _write(Buffer.prototype.writeFloatLE, 4); 29 | BinaryWriter.prototype.writeFloatBE = _write(Buffer.prototype.writeFloatBE, 4); 30 | BinaryWriter.prototype.writeDoubleLE = _write(Buffer.prototype.writeDoubleLE, 8); 31 | BinaryWriter.prototype.writeDoubleBE = _write(Buffer.prototype.writeDoubleBE, 8); 32 | 33 | BinaryWriter.prototype.writeBuffer = function (buffer) { 34 | this.ensureSize(buffer.length); 35 | 36 | buffer.copy(this.buffer, this.position, 0, buffer.length); 37 | this.position += buffer.length; 38 | }; 39 | 40 | BinaryWriter.prototype.writeVarInt = function (value) { 41 | var length = 1; 42 | 43 | while ((value & 0xFFFFFF80) !== 0) { 44 | this.writeUInt8((value & 0x7F) | 0x80); 45 | value >>>= 7; 46 | length++; 47 | } 48 | 49 | this.writeUInt8(value & 0x7F); 50 | 51 | return length; 52 | }; 53 | 54 | BinaryWriter.prototype.ensureSize = function (size) { 55 | if (this.buffer.length < this.position + size) { 56 | if (this.allowResize) { 57 | var tempBuffer = new Buffer(this.position + size); 58 | this.buffer.copy(tempBuffer, 0, 0, this.buffer.length); 59 | this.buffer = tempBuffer; 60 | } 61 | else { 62 | throw new RangeError('index out of range'); 63 | } 64 | } 65 | }; 66 | -------------------------------------------------------------------------------- /lib/geometry.js: -------------------------------------------------------------------------------- 1 | module.exports = Geometry; 2 | 3 | var Types = require('./types'); 4 | var Point = require('./point'); 5 | var LineString = require('./linestring'); 6 | var Polygon = require('./polygon'); 7 | var MultiPoint = require('./multipoint'); 8 | var MultiLineString = require('./multilinestring'); 9 | var MultiPolygon = require('./multipolygon'); 10 | var GeometryCollection = require('./geometrycollection'); 11 | var BinaryReader = require('./binaryreader'); 12 | var BinaryWriter = require('./binarywriter'); 13 | var WktParser = require('./wktparser'); 14 | var ZigZag = require('./zigzag.js'); 15 | 16 | function Geometry() { 17 | this.srid = undefined; 18 | this.hasZ = false; 19 | this.hasM = false; 20 | } 21 | 22 | Geometry.parse = function (value, options) { 23 | var valueType = typeof value; 24 | 25 | if (valueType === 'string' || value instanceof WktParser) 26 | return Geometry._parseWkt(value); 27 | else if (Buffer.isBuffer(value) || value instanceof BinaryReader) 28 | return Geometry._parseWkb(value, options); 29 | else 30 | throw new Error('first argument must be a string or Buffer'); 31 | }; 32 | 33 | Geometry._parseWkt = function (value) { 34 | var wktParser, 35 | srid; 36 | 37 | if (value instanceof WktParser) 38 | wktParser = value; 39 | else 40 | wktParser = new WktParser(value); 41 | 42 | var match = wktParser.matchRegex([/^SRID=(\d+);/]); 43 | if (match) 44 | srid = parseInt(match[1], 10); 45 | 46 | var geometryType = wktParser.matchType(); 47 | var dimension = wktParser.matchDimension(); 48 | 49 | var options = { 50 | srid: srid, 51 | hasZ: dimension.hasZ, 52 | hasM: dimension.hasM 53 | }; 54 | 55 | switch (geometryType) { 56 | case Types.wkt.Point: 57 | return Point._parseWkt(wktParser, options); 58 | case Types.wkt.LineString: 59 | return LineString._parseWkt(wktParser, options); 60 | case Types.wkt.Polygon: 61 | return Polygon._parseWkt(wktParser, options); 62 | case Types.wkt.MultiPoint: 63 | return MultiPoint._parseWkt(wktParser, options); 64 | case Types.wkt.MultiLineString: 65 | return MultiLineString._parseWkt(wktParser, options); 66 | case Types.wkt.MultiPolygon: 67 | return MultiPolygon._parseWkt(wktParser, options); 68 | case Types.wkt.GeometryCollection: 69 | return GeometryCollection._parseWkt(wktParser, options); 70 | } 71 | }; 72 | 73 | Geometry._parseWkb = function (value, parentOptions) { 74 | var binaryReader, 75 | wkbType, 76 | geometryType, 77 | options = {}; 78 | 79 | if (value instanceof BinaryReader) 80 | binaryReader = value; 81 | else 82 | binaryReader = new BinaryReader(value); 83 | 84 | binaryReader.isBigEndian = !binaryReader.readInt8(); 85 | 86 | wkbType = binaryReader.readUInt32(); 87 | 88 | options.hasSrid = (wkbType & 0x20000000) === 0x20000000; 89 | options.isEwkb = (wkbType & 0x20000000) || (wkbType & 0x40000000) || (wkbType & 0x80000000); 90 | 91 | if (options.hasSrid) 92 | options.srid = binaryReader.readUInt32(); 93 | 94 | options.hasZ = false; 95 | options.hasM = false; 96 | 97 | if (!options.isEwkb && (!parentOptions || !parentOptions.isEwkb)) { 98 | if (wkbType >= 1000 && wkbType < 2000) { 99 | options.hasZ = true; 100 | geometryType = wkbType - 1000; 101 | } 102 | else if (wkbType >= 2000 && wkbType < 3000) { 103 | options.hasM = true; 104 | geometryType = wkbType - 2000; 105 | } 106 | else if (wkbType >= 3000 && wkbType < 4000) { 107 | options.hasZ = true; 108 | options.hasM = true; 109 | geometryType = wkbType - 3000; 110 | } 111 | else { 112 | geometryType = wkbType; 113 | } 114 | } 115 | else { 116 | if (wkbType & 0x80000000) 117 | options.hasZ = true; 118 | if (wkbType & 0x40000000) 119 | options.hasM = true; 120 | 121 | geometryType = wkbType & 0xF; 122 | } 123 | 124 | switch (geometryType) { 125 | case Types.wkb.Point: 126 | return Point._parseWkb(binaryReader, options); 127 | case Types.wkb.LineString: 128 | return LineString._parseWkb(binaryReader, options); 129 | case Types.wkb.Polygon: 130 | return Polygon._parseWkb(binaryReader, options); 131 | case Types.wkb.MultiPoint: 132 | return MultiPoint._parseWkb(binaryReader, options); 133 | case Types.wkb.MultiLineString: 134 | return MultiLineString._parseWkb(binaryReader, options); 135 | case Types.wkb.MultiPolygon: 136 | return MultiPolygon._parseWkb(binaryReader, options); 137 | case Types.wkb.GeometryCollection: 138 | return GeometryCollection._parseWkb(binaryReader, options); 139 | default: 140 | throw new Error('GeometryType ' + geometryType + ' not supported'); 141 | } 142 | }; 143 | 144 | Geometry.parseTwkb = function (value) { 145 | var binaryReader, 146 | options = {}; 147 | 148 | if (value instanceof BinaryReader) 149 | binaryReader = value; 150 | else 151 | binaryReader = new BinaryReader(value); 152 | 153 | var type = binaryReader.readUInt8(); 154 | var metadataHeader = binaryReader.readUInt8(); 155 | 156 | var geometryType = type & 0x0F; 157 | options.precision = ZigZag.decode(type >> 4); 158 | options.precisionFactor = Math.pow(10, options.precision); 159 | 160 | options.hasBoundingBox = metadataHeader >> 0 & 1; 161 | options.hasSizeAttribute = metadataHeader >> 1 & 1; 162 | options.hasIdList = metadataHeader >> 2 & 1; 163 | options.hasExtendedPrecision = metadataHeader >> 3 & 1; 164 | options.isEmpty = metadataHeader >> 4 & 1; 165 | 166 | if (options.hasExtendedPrecision) { 167 | var extendedPrecision = binaryReader.readUInt8(); 168 | options.hasZ = (extendedPrecision & 0x01) === 0x01; 169 | options.hasM = (extendedPrecision & 0x02) === 0x02; 170 | 171 | options.zPrecision = ZigZag.decode((extendedPrecision & 0x1C) >> 2); 172 | options.zPrecisionFactor = Math.pow(10, options.zPrecision); 173 | 174 | options.mPrecision = ZigZag.decode((extendedPrecision & 0xE0) >> 5); 175 | options.mPrecisionFactor = Math.pow(10, options.mPrecision); 176 | } 177 | else { 178 | options.hasZ = false; 179 | options.hasM = false; 180 | } 181 | 182 | if (options.hasSizeAttribute) 183 | binaryReader.readVarInt(); 184 | if (options.hasBoundingBox) { 185 | var dimensions = 2; 186 | 187 | if (options.hasZ) 188 | dimensions++; 189 | if (options.hasM) 190 | dimensions++; 191 | 192 | for (var i = 0; i < dimensions; i++) { 193 | binaryReader.readVarInt(); 194 | binaryReader.readVarInt(); 195 | } 196 | } 197 | 198 | switch (geometryType) { 199 | case Types.wkb.Point: 200 | return Point._parseTwkb(binaryReader, options); 201 | case Types.wkb.LineString: 202 | return LineString._parseTwkb(binaryReader, options); 203 | case Types.wkb.Polygon: 204 | return Polygon._parseTwkb(binaryReader, options); 205 | case Types.wkb.MultiPoint: 206 | return MultiPoint._parseTwkb(binaryReader, options); 207 | case Types.wkb.MultiLineString: 208 | return MultiLineString._parseTwkb(binaryReader, options); 209 | case Types.wkb.MultiPolygon: 210 | return MultiPolygon._parseTwkb(binaryReader, options); 211 | case Types.wkb.GeometryCollection: 212 | return GeometryCollection._parseTwkb(binaryReader, options); 213 | default: 214 | throw new Error('GeometryType ' + geometryType + ' not supported'); 215 | } 216 | }; 217 | 218 | Geometry.parseGeoJSON = function (value) { 219 | return Geometry._parseGeoJSON(value); 220 | }; 221 | 222 | Geometry._parseGeoJSON = function (value, isSubGeometry) { 223 | var geometry; 224 | 225 | switch (value.type) { 226 | case Types.geoJSON.Point: 227 | geometry = Point._parseGeoJSON(value); break; 228 | case Types.geoJSON.LineString: 229 | geometry = LineString._parseGeoJSON(value); break; 230 | case Types.geoJSON.Polygon: 231 | geometry = Polygon._parseGeoJSON(value); break; 232 | case Types.geoJSON.MultiPoint: 233 | geometry = MultiPoint._parseGeoJSON(value); break; 234 | case Types.geoJSON.MultiLineString: 235 | geometry = MultiLineString._parseGeoJSON(value); break; 236 | case Types.geoJSON.MultiPolygon: 237 | geometry = MultiPolygon._parseGeoJSON(value); break; 238 | case Types.geoJSON.GeometryCollection: 239 | geometry = GeometryCollection._parseGeoJSON(value); break; 240 | default: 241 | throw new Error('GeometryType ' + value.type + ' not supported'); 242 | } 243 | 244 | if (value.crs && value.crs.type && value.crs.type === 'name' && value.crs.properties && value.crs.properties.name) { 245 | var crs = value.crs.properties.name; 246 | 247 | if (crs.indexOf('EPSG:') === 0) 248 | geometry.srid = parseInt(crs.substring(5)); 249 | else if (crs.indexOf('urn:ogc:def:crs:EPSG::') === 0) 250 | geometry.srid = parseInt(crs.substring(22)); 251 | else 252 | throw new Error('Unsupported crs: ' + crs); 253 | } 254 | else if (!isSubGeometry) { 255 | geometry.srid = 4326; 256 | } 257 | 258 | return geometry; 259 | }; 260 | 261 | Geometry.prototype.toEwkt = function () { 262 | return 'SRID=' + this.srid + ';' + this.toWkt(); 263 | }; 264 | 265 | Geometry.prototype.toEwkb = function () { 266 | var ewkb = new BinaryWriter(this._getWkbSize() + 4); 267 | var wkb = this.toWkb(); 268 | 269 | ewkb.writeInt8(1); 270 | ewkb.writeUInt32LE((wkb.slice(1, 5).readUInt32LE(0) | 0x20000000) >>> 0, true); 271 | ewkb.writeUInt32LE(this.srid); 272 | 273 | ewkb.writeBuffer(wkb.slice(5)); 274 | 275 | return ewkb.buffer; 276 | }; 277 | 278 | Geometry.prototype._getWktType = function (wktType, isEmpty) { 279 | var wkt = wktType; 280 | 281 | if (this.hasZ && this.hasM) 282 | wkt += ' ZM '; 283 | else if (this.hasZ) 284 | wkt += ' Z '; 285 | else if (this.hasM) 286 | wkt += ' M '; 287 | 288 | if (isEmpty && !this.hasZ && !this.hasM) 289 | wkt += ' '; 290 | 291 | if (isEmpty) 292 | wkt += 'EMPTY'; 293 | 294 | return wkt; 295 | }; 296 | 297 | Geometry.prototype._getWktCoordinate = function (point) { 298 | var coordinates = point.x + ' ' + point.y; 299 | 300 | if (this.hasZ) 301 | coordinates += ' ' + point.z; 302 | if (this.hasM) 303 | coordinates += ' ' + point.m; 304 | 305 | return coordinates; 306 | }; 307 | 308 | Geometry.prototype._writeWkbType = function (wkb, geometryType, parentOptions) { 309 | var dimensionType = 0; 310 | 311 | if (typeof this.srid === 'undefined' && (!parentOptions || typeof parentOptions.srid === 'undefined')) { 312 | if (this.hasZ && this.hasM) 313 | dimensionType += 3000; 314 | else if (this.hasZ) 315 | dimensionType += 1000; 316 | else if (this.hasM) 317 | dimensionType += 2000; 318 | } 319 | else { 320 | if (this.hasZ) 321 | dimensionType |= 0x80000000; 322 | if (this.hasM) 323 | dimensionType |= 0x40000000; 324 | } 325 | 326 | wkb.writeUInt32LE((dimensionType + geometryType) >>> 0, true); 327 | }; 328 | 329 | Geometry.getTwkbPrecision = function (xyPrecision, zPrecision, mPrecision) { 330 | return { 331 | xy: xyPrecision, 332 | z: zPrecision, 333 | m: mPrecision, 334 | xyFactor: Math.pow(10, xyPrecision), 335 | zFactor: Math.pow(10, zPrecision), 336 | mFactor: Math.pow(10, mPrecision) 337 | }; 338 | }; 339 | 340 | Geometry.prototype._writeTwkbHeader = function (twkb, geometryType, precision, isEmpty) { 341 | var type = (ZigZag.encode(precision.xy) << 4) + geometryType; 342 | var metadataHeader = (this.hasZ || this.hasM) << 3; 343 | metadataHeader += isEmpty << 4; 344 | 345 | twkb.writeUInt8(type); 346 | twkb.writeUInt8(metadataHeader); 347 | 348 | if (this.hasZ || this.hasM) { 349 | var extendedPrecision = 0; 350 | if (this.hasZ) 351 | extendedPrecision |= 0x1; 352 | if (this.hasM) 353 | extendedPrecision |= 0x2; 354 | 355 | twkb.writeUInt8(extendedPrecision); 356 | } 357 | }; 358 | 359 | Geometry.prototype.toGeoJSON = function (options) { 360 | var geoJSON = {}; 361 | 362 | if (this.srid) { 363 | if (options) { 364 | if (options.shortCrs) { 365 | geoJSON.crs = { 366 | type: 'name', 367 | properties: { 368 | name: 'EPSG:' + this.srid 369 | } 370 | }; 371 | } 372 | else if (options.longCrs) { 373 | geoJSON.crs = { 374 | type: 'name', 375 | properties: { 376 | name: 'urn:ogc:def:crs:EPSG::' + this.srid 377 | } 378 | }; 379 | } 380 | } 381 | } 382 | 383 | return geoJSON; 384 | }; 385 | -------------------------------------------------------------------------------- /lib/geometrycollection.js: -------------------------------------------------------------------------------- 1 | module.exports = GeometryCollection; 2 | 3 | var util = require('util'); 4 | 5 | var Types = require('./types'); 6 | var Geometry = require('./geometry'); 7 | var BinaryWriter = require('./binarywriter'); 8 | 9 | function GeometryCollection(geometries, srid) { 10 | Geometry.call(this); 11 | 12 | this.geometries = geometries || []; 13 | this.srid = srid; 14 | 15 | if (this.geometries.length > 0) { 16 | this.hasZ = this.geometries[0].hasZ; 17 | this.hasM = this.geometries[0].hasM; 18 | } 19 | } 20 | 21 | util.inherits(GeometryCollection, Geometry); 22 | 23 | GeometryCollection.Z = function (geometries, srid) { 24 | var geometryCollection = new GeometryCollection(geometries, srid); 25 | geometryCollection.hasZ = true; 26 | return geometryCollection; 27 | }; 28 | 29 | GeometryCollection.M = function (geometries, srid) { 30 | var geometryCollection = new GeometryCollection(geometries, srid); 31 | geometryCollection.hasM = true; 32 | return geometryCollection; 33 | }; 34 | 35 | GeometryCollection.ZM = function (geometries, srid) { 36 | var geometryCollection = new GeometryCollection(geometries, srid); 37 | geometryCollection.hasZ = true; 38 | geometryCollection.hasM = true; 39 | return geometryCollection; 40 | }; 41 | 42 | GeometryCollection._parseWkt = function (value, options) { 43 | var geometryCollection = new GeometryCollection(); 44 | geometryCollection.srid = options.srid; 45 | geometryCollection.hasZ = options.hasZ; 46 | geometryCollection.hasM = options.hasM; 47 | 48 | if (value.isMatch(['EMPTY'])) 49 | return geometryCollection; 50 | 51 | value.expectGroupStart(); 52 | 53 | do { 54 | geometryCollection.geometries.push(Geometry.parse(value)); 55 | } while (value.isMatch([','])); 56 | 57 | value.expectGroupEnd(); 58 | 59 | return geometryCollection; 60 | }; 61 | 62 | GeometryCollection._parseWkb = function (value, options) { 63 | var geometryCollection = new GeometryCollection(); 64 | geometryCollection.srid = options.srid; 65 | geometryCollection.hasZ = options.hasZ; 66 | geometryCollection.hasM = options.hasM; 67 | 68 | var geometryCount = value.readUInt32(); 69 | 70 | for (var i = 0; i < geometryCount; i++) 71 | geometryCollection.geometries.push(Geometry.parse(value, options)); 72 | 73 | return geometryCollection; 74 | }; 75 | 76 | GeometryCollection._parseTwkb = function (value, options) { 77 | var geometryCollection = new GeometryCollection(); 78 | geometryCollection.hasZ = options.hasZ; 79 | geometryCollection.hasM = options.hasM; 80 | 81 | if (options.isEmpty) 82 | return geometryCollection; 83 | 84 | var geometryCount = value.readVarInt(); 85 | 86 | for (var i = 0; i < geometryCount; i++) 87 | geometryCollection.geometries.push(Geometry.parseTwkb(value)); 88 | 89 | return geometryCollection; 90 | }; 91 | 92 | GeometryCollection._parseGeoJSON = function (value) { 93 | var geometryCollection = new GeometryCollection(); 94 | 95 | for (var i = 0; i < value.geometries.length; i++) 96 | geometryCollection.geometries.push(Geometry._parseGeoJSON(value.geometries[i], true)); 97 | 98 | if (geometryCollection.geometries.length > 0) 99 | geometryCollection.hasZ = geometryCollection.geometries[0].hasZ; 100 | 101 | return geometryCollection; 102 | }; 103 | 104 | GeometryCollection.prototype.toWkt = function () { 105 | if (this.geometries.length === 0) 106 | return this._getWktType(Types.wkt.GeometryCollection, true); 107 | 108 | var wkt = this._getWktType(Types.wkt.GeometryCollection, false) + '('; 109 | 110 | for (var i = 0; i < this.geometries.length; i++) 111 | wkt += this.geometries[i].toWkt() + ','; 112 | 113 | wkt = wkt.slice(0, -1); 114 | wkt += ')'; 115 | 116 | return wkt; 117 | }; 118 | 119 | GeometryCollection.prototype.toWkb = function () { 120 | var wkb = new BinaryWriter(this._getWkbSize()); 121 | 122 | wkb.writeInt8(1); 123 | 124 | this._writeWkbType(wkb, Types.wkb.GeometryCollection); 125 | wkb.writeUInt32LE(this.geometries.length); 126 | 127 | for (var i = 0; i < this.geometries.length; i++) 128 | wkb.writeBuffer(this.geometries[i].toWkb({ srid: this.srid })); 129 | 130 | return wkb.buffer; 131 | }; 132 | 133 | GeometryCollection.prototype.toTwkb = function () { 134 | var twkb = new BinaryWriter(0, true); 135 | 136 | var precision = Geometry.getTwkbPrecision(5, 0, 0); 137 | var isEmpty = this.geometries.length === 0; 138 | 139 | this._writeTwkbHeader(twkb, Types.wkb.GeometryCollection, precision, isEmpty); 140 | 141 | if (this.geometries.length > 0) { 142 | twkb.writeVarInt(this.geometries.length); 143 | 144 | for (var i = 0; i < this.geometries.length; i++) 145 | twkb.writeBuffer(this.geometries[i].toTwkb()); 146 | } 147 | 148 | return twkb.buffer; 149 | }; 150 | 151 | GeometryCollection.prototype._getWkbSize = function () { 152 | var size = 1 + 4 + 4; 153 | 154 | for (var i = 0; i < this.geometries.length; i++) 155 | size += this.geometries[i]._getWkbSize(); 156 | 157 | return size; 158 | }; 159 | 160 | GeometryCollection.prototype.toGeoJSON = function (options) { 161 | var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); 162 | geoJSON.type = Types.geoJSON.GeometryCollection; 163 | geoJSON.geometries = []; 164 | 165 | for (var i = 0; i < this.geometries.length; i++) 166 | geoJSON.geometries.push(this.geometries[i].toGeoJSON()); 167 | 168 | return geoJSON; 169 | }; 170 | -------------------------------------------------------------------------------- /lib/linestring.js: -------------------------------------------------------------------------------- 1 | module.exports = LineString; 2 | 3 | var util = require('util'); 4 | 5 | var Geometry = require('./geometry'); 6 | var Types = require('./types'); 7 | var Point = require('./point'); 8 | var BinaryWriter = require('./binarywriter'); 9 | 10 | function LineString(points, srid) { 11 | Geometry.call(this); 12 | 13 | this.points = points || []; 14 | this.srid = srid; 15 | 16 | if (this.points.length > 0) { 17 | this.hasZ = this.points[0].hasZ; 18 | this.hasM = this.points[0].hasM; 19 | } 20 | } 21 | 22 | util.inherits(LineString, Geometry); 23 | 24 | LineString.Z = function (points, srid) { 25 | var lineString = new LineString(points, srid); 26 | lineString.hasZ = true; 27 | return lineString; 28 | }; 29 | 30 | LineString.M = function (points, srid) { 31 | var lineString = new LineString(points, srid); 32 | lineString.hasM = true; 33 | return lineString; 34 | }; 35 | 36 | LineString.ZM = function (points, srid) { 37 | var lineString = new LineString(points, srid); 38 | lineString.hasZ = true; 39 | lineString.hasM = true; 40 | return lineString; 41 | }; 42 | 43 | LineString._parseWkt = function (value, options) { 44 | var lineString = new LineString(); 45 | lineString.srid = options.srid; 46 | lineString.hasZ = options.hasZ; 47 | lineString.hasM = options.hasM; 48 | 49 | if (value.isMatch(['EMPTY'])) 50 | return lineString; 51 | 52 | value.expectGroupStart(); 53 | lineString.points.push.apply(lineString.points, value.matchCoordinates(options)); 54 | value.expectGroupEnd(); 55 | 56 | return lineString; 57 | }; 58 | 59 | LineString._parseWkb = function (value, options) { 60 | var lineString = new LineString(); 61 | lineString.srid = options.srid; 62 | lineString.hasZ = options.hasZ; 63 | lineString.hasM = options.hasM; 64 | 65 | var pointCount = value.readUInt32(); 66 | 67 | for (var i = 0; i < pointCount; i++) 68 | lineString.points.push(Point._readWkbPoint(value, options)); 69 | 70 | return lineString; 71 | }; 72 | 73 | LineString._parseTwkb = function (value, options) { 74 | var lineString = new LineString(); 75 | lineString.hasZ = options.hasZ; 76 | lineString.hasM = options.hasM; 77 | 78 | if (options.isEmpty) 79 | return lineString; 80 | 81 | var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); 82 | var pointCount = value.readVarInt(); 83 | 84 | for (var i = 0; i < pointCount; i++) 85 | lineString.points.push(Point._readTwkbPoint(value, options, previousPoint)); 86 | 87 | return lineString; 88 | }; 89 | 90 | LineString._parseGeoJSON = function (value) { 91 | var lineString = new LineString(); 92 | 93 | if (value.coordinates.length > 0) 94 | lineString.hasZ = value.coordinates[0].length > 2; 95 | 96 | for (var i = 0; i < value.coordinates.length; i++) 97 | lineString.points.push(Point._readGeoJSONPoint(value.coordinates[i])); 98 | 99 | return lineString; 100 | }; 101 | 102 | LineString.prototype.toWkt = function () { 103 | if (this.points.length === 0) 104 | return this._getWktType(Types.wkt.LineString, true); 105 | 106 | return this._getWktType(Types.wkt.LineString, false) + this._toInnerWkt(); 107 | }; 108 | 109 | LineString.prototype._toInnerWkt = function () { 110 | var innerWkt = '('; 111 | 112 | for (var i = 0; i < this.points.length; i++) 113 | innerWkt += this._getWktCoordinate(this.points[i]) + ','; 114 | 115 | innerWkt = innerWkt.slice(0, -1); 116 | innerWkt += ')'; 117 | 118 | return innerWkt; 119 | }; 120 | 121 | LineString.prototype.toWkb = function (parentOptions) { 122 | var wkb = new BinaryWriter(this._getWkbSize()); 123 | 124 | wkb.writeInt8(1); 125 | 126 | this._writeWkbType(wkb, Types.wkb.LineString, parentOptions); 127 | wkb.writeUInt32LE(this.points.length); 128 | 129 | for (var i = 0; i < this.points.length; i++) 130 | this.points[i]._writeWkbPoint(wkb); 131 | 132 | return wkb.buffer; 133 | }; 134 | 135 | LineString.prototype.toTwkb = function () { 136 | var twkb = new BinaryWriter(0, true); 137 | 138 | var precision = Geometry.getTwkbPrecision(5, 0, 0); 139 | var isEmpty = this.points.length === 0; 140 | 141 | this._writeTwkbHeader(twkb, Types.wkb.LineString, precision, isEmpty); 142 | 143 | if (this.points.length > 0) { 144 | twkb.writeVarInt(this.points.length); 145 | 146 | var previousPoint = new Point(0, 0, 0, 0); 147 | for (var i = 0; i < this.points.length; i++) 148 | this.points[i]._writeTwkbPoint(twkb, precision, previousPoint); 149 | } 150 | 151 | return twkb.buffer; 152 | }; 153 | 154 | LineString.prototype._getWkbSize = function () { 155 | var coordinateSize = 16; 156 | 157 | if (this.hasZ) 158 | coordinateSize += 8; 159 | if (this.hasM) 160 | coordinateSize += 8; 161 | 162 | return 1 + 4 + 4 + (this.points.length * coordinateSize); 163 | }; 164 | 165 | LineString.prototype.toGeoJSON = function (options) { 166 | var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); 167 | geoJSON.type = Types.geoJSON.LineString; 168 | geoJSON.coordinates = []; 169 | 170 | for (var i = 0; i < this.points.length; i++) { 171 | if (this.hasZ) 172 | geoJSON.coordinates.push([this.points[i].x, this.points[i].y, this.points[i].z]); 173 | else 174 | geoJSON.coordinates.push([this.points[i].x, this.points[i].y]); 175 | } 176 | 177 | return geoJSON; 178 | }; 179 | -------------------------------------------------------------------------------- /lib/multilinestring.js: -------------------------------------------------------------------------------- 1 | module.exports = MultiLineString; 2 | 3 | var util = require('util'); 4 | 5 | var Types = require('./types'); 6 | var Geometry = require('./geometry'); 7 | var Point = require('./point'); 8 | var LineString = require('./linestring'); 9 | var BinaryWriter = require('./binarywriter'); 10 | 11 | function MultiLineString(lineStrings, srid) { 12 | Geometry.call(this); 13 | 14 | this.lineStrings = lineStrings || []; 15 | this.srid = srid; 16 | 17 | if (this.lineStrings.length > 0) { 18 | this.hasZ = this.lineStrings[0].hasZ; 19 | this.hasM = this.lineStrings[0].hasM; 20 | } 21 | } 22 | 23 | util.inherits(MultiLineString, Geometry); 24 | 25 | MultiLineString.Z = function (lineStrings, srid) { 26 | var multiLineString = new MultiLineString(lineStrings, srid); 27 | multiLineString.hasZ = true; 28 | return multiLineString; 29 | }; 30 | 31 | MultiLineString.M = function (lineStrings, srid) { 32 | var multiLineString = new MultiLineString(lineStrings, srid); 33 | multiLineString.hasM = true; 34 | return multiLineString; 35 | }; 36 | 37 | MultiLineString.ZM = function (lineStrings, srid) { 38 | var multiLineString = new MultiLineString(lineStrings, srid); 39 | multiLineString.hasZ = true; 40 | multiLineString.hasM = true; 41 | return multiLineString; 42 | }; 43 | 44 | MultiLineString._parseWkt = function (value, options) { 45 | var multiLineString = new MultiLineString(); 46 | multiLineString.srid = options.srid; 47 | multiLineString.hasZ = options.hasZ; 48 | multiLineString.hasM = options.hasM; 49 | 50 | if (value.isMatch(['EMPTY'])) 51 | return multiLineString; 52 | 53 | value.expectGroupStart(); 54 | 55 | do { 56 | value.expectGroupStart(); 57 | multiLineString.lineStrings.push(new LineString(value.matchCoordinates(options))); 58 | value.expectGroupEnd(); 59 | } while (value.isMatch([','])); 60 | 61 | value.expectGroupEnd(); 62 | 63 | return multiLineString; 64 | }; 65 | 66 | MultiLineString._parseWkb = function (value, options) { 67 | var multiLineString = new MultiLineString(); 68 | multiLineString.srid = options.srid; 69 | multiLineString.hasZ = options.hasZ; 70 | multiLineString.hasM = options.hasM; 71 | 72 | var lineStringCount = value.readUInt32(); 73 | 74 | for (var i = 0; i < lineStringCount; i++) 75 | multiLineString.lineStrings.push(Geometry.parse(value, options)); 76 | 77 | return multiLineString; 78 | }; 79 | 80 | MultiLineString._parseTwkb = function (value, options) { 81 | var multiLineString = new MultiLineString(); 82 | multiLineString.hasZ = options.hasZ; 83 | multiLineString.hasM = options.hasM; 84 | 85 | if (options.isEmpty) 86 | return multiLineString; 87 | 88 | var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); 89 | var lineStringCount = value.readVarInt(); 90 | 91 | for (var i = 0; i < lineStringCount; i++) { 92 | var lineString = new LineString(); 93 | lineString.hasZ = options.hasZ; 94 | lineString.hasM = options.hasM; 95 | 96 | var pointCount = value.readVarInt(); 97 | 98 | for (var j = 0; j < pointCount; j++) 99 | lineString.points.push(Point._readTwkbPoint(value, options, previousPoint)); 100 | 101 | multiLineString.lineStrings.push(lineString); 102 | } 103 | 104 | return multiLineString; 105 | }; 106 | 107 | MultiLineString._parseGeoJSON = function (value) { 108 | var multiLineString = new MultiLineString(); 109 | 110 | if (value.coordinates.length > 0 && value.coordinates[0].length > 0) 111 | multiLineString.hasZ = value.coordinates[0][0].length > 2; 112 | 113 | for (var i = 0; i < value.coordinates.length; i++) 114 | multiLineString.lineStrings.push(LineString._parseGeoJSON({ coordinates: value.coordinates[i] })); 115 | 116 | return multiLineString; 117 | }; 118 | 119 | MultiLineString.prototype.toWkt = function () { 120 | if (this.lineStrings.length === 0) 121 | return this._getWktType(Types.wkt.MultiLineString, true); 122 | 123 | var wkt = this._getWktType(Types.wkt.MultiLineString, false) + '('; 124 | 125 | for (var i = 0; i < this.lineStrings.length; i++) 126 | wkt += this.lineStrings[i]._toInnerWkt() + ','; 127 | 128 | wkt = wkt.slice(0, -1); 129 | wkt += ')'; 130 | 131 | return wkt; 132 | }; 133 | 134 | MultiLineString.prototype.toWkb = function () { 135 | var wkb = new BinaryWriter(this._getWkbSize()); 136 | 137 | wkb.writeInt8(1); 138 | 139 | this._writeWkbType(wkb, Types.wkb.MultiLineString); 140 | wkb.writeUInt32LE(this.lineStrings.length); 141 | 142 | for (var i = 0; i < this.lineStrings.length; i++) 143 | wkb.writeBuffer(this.lineStrings[i].toWkb({ srid: this.srid })); 144 | 145 | return wkb.buffer; 146 | }; 147 | 148 | MultiLineString.prototype.toTwkb = function () { 149 | var twkb = new BinaryWriter(0, true); 150 | 151 | var precision = Geometry.getTwkbPrecision(5, 0, 0); 152 | var isEmpty = this.lineStrings.length === 0; 153 | 154 | this._writeTwkbHeader(twkb, Types.wkb.MultiLineString, precision, isEmpty); 155 | 156 | if (this.lineStrings.length > 0) { 157 | twkb.writeVarInt(this.lineStrings.length); 158 | 159 | var previousPoint = new Point(0, 0, 0, 0); 160 | for (var i = 0; i < this.lineStrings.length; i++) { 161 | twkb.writeVarInt(this.lineStrings[i].points.length); 162 | 163 | for (var j = 0; j < this.lineStrings[i].points.length; j++) 164 | this.lineStrings[i].points[j]._writeTwkbPoint(twkb, precision, previousPoint); 165 | } 166 | } 167 | 168 | return twkb.buffer; 169 | }; 170 | 171 | MultiLineString.prototype._getWkbSize = function () { 172 | var size = 1 + 4 + 4; 173 | 174 | for (var i = 0; i < this.lineStrings.length; i++) 175 | size += this.lineStrings[i]._getWkbSize(); 176 | 177 | return size; 178 | }; 179 | 180 | MultiLineString.prototype.toGeoJSON = function (options) { 181 | var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); 182 | geoJSON.type = Types.geoJSON.MultiLineString; 183 | geoJSON.coordinates = []; 184 | 185 | for (var i = 0; i < this.lineStrings.length; i++) 186 | geoJSON.coordinates.push(this.lineStrings[i].toGeoJSON().coordinates); 187 | 188 | return geoJSON; 189 | }; 190 | -------------------------------------------------------------------------------- /lib/multipoint.js: -------------------------------------------------------------------------------- 1 | module.exports = MultiPoint; 2 | 3 | var util = require('util'); 4 | 5 | var Types = require('./types'); 6 | var Geometry = require('./geometry'); 7 | var Point = require('./point'); 8 | var BinaryWriter = require('./binarywriter'); 9 | 10 | function MultiPoint(points, srid) { 11 | Geometry.call(this); 12 | 13 | this.points = points || []; 14 | this.srid = srid; 15 | 16 | if (this.points.length > 0) { 17 | this.hasZ = this.points[0].hasZ; 18 | this.hasM = this.points[0].hasM; 19 | } 20 | } 21 | 22 | util.inherits(MultiPoint, Geometry); 23 | 24 | MultiPoint.Z = function (points, srid) { 25 | var multiPoint = new MultiPoint(points, srid); 26 | multiPoint.hasZ = true; 27 | return multiPoint; 28 | }; 29 | 30 | MultiPoint.M = function (points, srid) { 31 | var multiPoint = new MultiPoint(points, srid); 32 | multiPoint.hasM = true; 33 | return multiPoint; 34 | }; 35 | 36 | MultiPoint.ZM = function (points, srid) { 37 | var multiPoint = new MultiPoint(points, srid); 38 | multiPoint.hasZ = true; 39 | multiPoint.hasM = true; 40 | return multiPoint; 41 | }; 42 | 43 | MultiPoint._parseWkt = function (value, options) { 44 | var multiPoint = new MultiPoint(); 45 | multiPoint.srid = options.srid; 46 | multiPoint.hasZ = options.hasZ; 47 | multiPoint.hasM = options.hasM; 48 | 49 | if (value.isMatch(['EMPTY'])) 50 | return multiPoint; 51 | 52 | value.expectGroupStart(); 53 | multiPoint.points.push.apply(multiPoint.points, value.matchCoordinates(options)); 54 | value.expectGroupEnd(); 55 | 56 | return multiPoint; 57 | }; 58 | 59 | MultiPoint._parseWkb = function (value, options) { 60 | var multiPoint = new MultiPoint(); 61 | multiPoint.srid = options.srid; 62 | multiPoint.hasZ = options.hasZ; 63 | multiPoint.hasM = options.hasM; 64 | 65 | var pointCount = value.readUInt32(); 66 | 67 | for (var i = 0; i < pointCount; i++) 68 | multiPoint.points.push(Geometry.parse(value, options)); 69 | 70 | return multiPoint; 71 | }; 72 | 73 | MultiPoint._parseTwkb = function (value, options) { 74 | var multiPoint = new MultiPoint(); 75 | multiPoint.hasZ = options.hasZ; 76 | multiPoint.hasM = options.hasM; 77 | 78 | if (options.isEmpty) 79 | return multiPoint; 80 | 81 | var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); 82 | var pointCount = value.readVarInt(); 83 | 84 | for (var i = 0; i < pointCount; i++) 85 | multiPoint.points.push(Point._readTwkbPoint(value, options, previousPoint)); 86 | 87 | return multiPoint; 88 | }; 89 | 90 | MultiPoint._parseGeoJSON = function (value) { 91 | var multiPoint = new MultiPoint(); 92 | 93 | if (value.coordinates.length > 0) 94 | multiPoint.hasZ = value.coordinates[0].length > 2; 95 | 96 | for (var i = 0; i < value.coordinates.length; i++) 97 | multiPoint.points.push(Point._parseGeoJSON({ coordinates: value.coordinates[i] })); 98 | 99 | return multiPoint; 100 | }; 101 | 102 | MultiPoint.prototype.toWkt = function () { 103 | if (this.points.length === 0) 104 | return this._getWktType(Types.wkt.MultiPoint, true); 105 | 106 | var wkt = this._getWktType(Types.wkt.MultiPoint, false) + '('; 107 | 108 | for (var i = 0; i < this.points.length; i++) 109 | wkt += this._getWktCoordinate(this.points[i]) + ','; 110 | 111 | wkt = wkt.slice(0, -1); 112 | wkt += ')'; 113 | 114 | return wkt; 115 | }; 116 | 117 | MultiPoint.prototype.toWkb = function () { 118 | var wkb = new BinaryWriter(this._getWkbSize()); 119 | 120 | wkb.writeInt8(1); 121 | 122 | this._writeWkbType(wkb, Types.wkb.MultiPoint); 123 | wkb.writeUInt32LE(this.points.length); 124 | 125 | for (var i = 0; i < this.points.length; i++) 126 | wkb.writeBuffer(this.points[i].toWkb({ srid: this.srid })); 127 | 128 | return wkb.buffer; 129 | }; 130 | 131 | MultiPoint.prototype.toTwkb = function () { 132 | var twkb = new BinaryWriter(0, true); 133 | 134 | var precision = Geometry.getTwkbPrecision(5, 0, 0); 135 | var isEmpty = this.points.length === 0; 136 | 137 | this._writeTwkbHeader(twkb, Types.wkb.MultiPoint, precision, isEmpty); 138 | 139 | if (this.points.length > 0) { 140 | twkb.writeVarInt(this.points.length); 141 | 142 | var previousPoint = new Point(0, 0, 0, 0); 143 | for (var i = 0; i < this.points.length; i++) 144 | this.points[i]._writeTwkbPoint(twkb, precision, previousPoint); 145 | } 146 | 147 | return twkb.buffer; 148 | }; 149 | 150 | MultiPoint.prototype._getWkbSize = function () { 151 | var coordinateSize = 16; 152 | 153 | if (this.hasZ) 154 | coordinateSize += 8; 155 | if (this.hasM) 156 | coordinateSize += 8; 157 | 158 | coordinateSize += 5; 159 | 160 | return 1 + 4 + 4 + (this.points.length * coordinateSize); 161 | }; 162 | 163 | MultiPoint.prototype.toGeoJSON = function (options) { 164 | var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); 165 | geoJSON.type = Types.geoJSON.MultiPoint; 166 | geoJSON.coordinates = []; 167 | 168 | for (var i = 0; i < this.points.length; i++) 169 | geoJSON.coordinates.push(this.points[i].toGeoJSON().coordinates); 170 | 171 | return geoJSON; 172 | }; 173 | -------------------------------------------------------------------------------- /lib/multipolygon.js: -------------------------------------------------------------------------------- 1 | module.exports = MultiPolygon; 2 | 3 | var util = require('util'); 4 | 5 | var Types = require('./types'); 6 | var Geometry = require('./geometry'); 7 | var Point = require('./point'); 8 | var Polygon = require('./polygon'); 9 | var BinaryWriter = require('./binarywriter'); 10 | 11 | function MultiPolygon(polygons, srid) { 12 | Geometry.call(this); 13 | 14 | this.polygons = polygons || []; 15 | this.srid = srid; 16 | 17 | if (this.polygons.length > 0) { 18 | this.hasZ = this.polygons[0].hasZ; 19 | this.hasM = this.polygons[0].hasM; 20 | } 21 | } 22 | 23 | util.inherits(MultiPolygon, Geometry); 24 | 25 | MultiPolygon.Z = function (polygons, srid) { 26 | var multiPolygon = new MultiPolygon(polygons, srid); 27 | multiPolygon.hasZ = true; 28 | return multiPolygon; 29 | }; 30 | 31 | MultiPolygon.M = function (polygons, srid) { 32 | var multiPolygon = new MultiPolygon(polygons, srid); 33 | multiPolygon.hasM = true; 34 | return multiPolygon; 35 | }; 36 | 37 | MultiPolygon.ZM = function (polygons, srid) { 38 | var multiPolygon = new MultiPolygon(polygons, srid); 39 | multiPolygon.hasZ = true; 40 | multiPolygon.hasM = true; 41 | return multiPolygon; 42 | }; 43 | 44 | MultiPolygon._parseWkt = function (value, options) { 45 | var multiPolygon = new MultiPolygon(); 46 | multiPolygon.srid = options.srid; 47 | multiPolygon.hasZ = options.hasZ; 48 | multiPolygon.hasM = options.hasM; 49 | 50 | if (value.isMatch(['EMPTY'])) 51 | return multiPolygon; 52 | 53 | value.expectGroupStart(); 54 | 55 | do { 56 | value.expectGroupStart(); 57 | 58 | var exteriorRing = []; 59 | var interiorRings = []; 60 | 61 | value.expectGroupStart(); 62 | exteriorRing.push.apply(exteriorRing, value.matchCoordinates(options)); 63 | value.expectGroupEnd(); 64 | 65 | while (value.isMatch([','])) { 66 | value.expectGroupStart(); 67 | interiorRings.push(value.matchCoordinates(options)); 68 | value.expectGroupEnd(); 69 | } 70 | 71 | multiPolygon.polygons.push(new Polygon(exteriorRing, interiorRings)); 72 | 73 | value.expectGroupEnd(); 74 | 75 | } while (value.isMatch([','])); 76 | 77 | value.expectGroupEnd(); 78 | 79 | return multiPolygon; 80 | }; 81 | 82 | MultiPolygon._parseWkb = function (value, options) { 83 | var multiPolygon = new MultiPolygon(); 84 | multiPolygon.srid = options.srid; 85 | multiPolygon.hasZ = options.hasZ; 86 | multiPolygon.hasM = options.hasM; 87 | 88 | var polygonCount = value.readUInt32(); 89 | 90 | for (var i = 0; i < polygonCount; i++) 91 | multiPolygon.polygons.push(Geometry.parse(value, options)); 92 | 93 | return multiPolygon; 94 | }; 95 | 96 | MultiPolygon._parseTwkb = function (value, options) { 97 | var multiPolygon = new MultiPolygon(); 98 | multiPolygon.hasZ = options.hasZ; 99 | multiPolygon.hasM = options.hasM; 100 | 101 | if (options.isEmpty) 102 | return multiPolygon; 103 | 104 | var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); 105 | var polygonCount = value.readVarInt(); 106 | 107 | for (var i = 0; i < polygonCount; i++) { 108 | var polygon = new Polygon(); 109 | polygon.hasZ = options.hasZ; 110 | polygon.hasM = options.hasM; 111 | 112 | var ringCount = value.readVarInt(); 113 | var exteriorRingCount = value.readVarInt(); 114 | 115 | for (var j = 0; j < exteriorRingCount; j++) 116 | polygon.exteriorRing.push(Point._readTwkbPoint(value, options, previousPoint)); 117 | 118 | for (j = 1; j < ringCount; j++) { 119 | var interiorRing = []; 120 | 121 | var interiorRingCount = value.readVarInt(); 122 | 123 | for (var k = 0; k < interiorRingCount; k++) 124 | interiorRing.push(Point._readTwkbPoint(value, options, previousPoint)); 125 | 126 | polygon.interiorRings.push(interiorRing); 127 | } 128 | 129 | multiPolygon.polygons.push(polygon); 130 | } 131 | 132 | return multiPolygon; 133 | }; 134 | 135 | MultiPolygon._parseGeoJSON = function (value) { 136 | var multiPolygon = new MultiPolygon(); 137 | 138 | if (value.coordinates.length > 0 && value.coordinates[0].length > 0 && value.coordinates[0][0].length > 0) 139 | multiPolygon.hasZ = value.coordinates[0][0][0].length > 2; 140 | 141 | for (var i = 0; i < value.coordinates.length; i++) 142 | multiPolygon.polygons.push(Polygon._parseGeoJSON({ coordinates: value.coordinates[i] })); 143 | 144 | return multiPolygon; 145 | }; 146 | 147 | MultiPolygon.prototype.toWkt = function () { 148 | if (this.polygons.length === 0) 149 | return this._getWktType(Types.wkt.MultiPolygon, true); 150 | 151 | var wkt = this._getWktType(Types.wkt.MultiPolygon, false) + '('; 152 | 153 | for (var i = 0; i < this.polygons.length; i++) 154 | wkt += this.polygons[i]._toInnerWkt() + ','; 155 | 156 | wkt = wkt.slice(0, -1); 157 | wkt += ')'; 158 | 159 | return wkt; 160 | }; 161 | 162 | MultiPolygon.prototype.toWkb = function () { 163 | var wkb = new BinaryWriter(this._getWkbSize()); 164 | 165 | wkb.writeInt8(1); 166 | 167 | this._writeWkbType(wkb, Types.wkb.MultiPolygon); 168 | wkb.writeUInt32LE(this.polygons.length); 169 | 170 | for (var i = 0; i < this.polygons.length; i++) 171 | wkb.writeBuffer(this.polygons[i].toWkb({ srid: this.srid })); 172 | 173 | return wkb.buffer; 174 | }; 175 | 176 | MultiPolygon.prototype.toTwkb = function () { 177 | var twkb = new BinaryWriter(0, true); 178 | 179 | var precision = Geometry.getTwkbPrecision(5, 0, 0); 180 | var isEmpty = this.polygons.length === 0; 181 | 182 | this._writeTwkbHeader(twkb, Types.wkb.MultiPolygon, precision, isEmpty); 183 | 184 | if (this.polygons.length > 0) { 185 | twkb.writeVarInt(this.polygons.length); 186 | 187 | var previousPoint = new Point(0, 0, 0, 0); 188 | for (var i = 0; i < this.polygons.length; i++) { 189 | twkb.writeVarInt(1 + this.polygons[i].interiorRings.length); 190 | 191 | twkb.writeVarInt(this.polygons[i].exteriorRing.length); 192 | 193 | for (var j = 0; j < this.polygons[i].exteriorRing.length; j++) 194 | this.polygons[i].exteriorRing[j]._writeTwkbPoint(twkb, precision, previousPoint); 195 | 196 | for (j = 0; j < this.polygons[i].interiorRings.length; j++) { 197 | twkb.writeVarInt(this.polygons[i].interiorRings[j].length); 198 | 199 | for (var k = 0; k < this.polygons[i].interiorRings[j].length; k++) 200 | this.polygons[i].interiorRings[j][k]._writeTwkbPoint(twkb, precision, previousPoint); 201 | } 202 | } 203 | } 204 | 205 | return twkb.buffer; 206 | }; 207 | 208 | MultiPolygon.prototype._getWkbSize = function () { 209 | var size = 1 + 4 + 4; 210 | 211 | for (var i = 0; i < this.polygons.length; i++) 212 | size += this.polygons[i]._getWkbSize(); 213 | 214 | return size; 215 | }; 216 | 217 | MultiPolygon.prototype.toGeoJSON = function (options) { 218 | var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); 219 | geoJSON.type = Types.geoJSON.MultiPolygon; 220 | geoJSON.coordinates = []; 221 | 222 | for (var i = 0; i < this.polygons.length; i++) 223 | geoJSON.coordinates.push(this.polygons[i].toGeoJSON().coordinates); 224 | 225 | return geoJSON; 226 | }; 227 | -------------------------------------------------------------------------------- /lib/point.js: -------------------------------------------------------------------------------- 1 | module.exports = Point; 2 | 3 | var util = require('util'); 4 | 5 | var Geometry = require('./geometry'); 6 | var Types = require('./types'); 7 | var BinaryWriter = require('./binarywriter'); 8 | var ZigZag = require('./zigzag.js'); 9 | 10 | function Point(x, y, z, m, srid) { 11 | Geometry.call(this); 12 | 13 | this.x = x; 14 | this.y = y; 15 | this.z = z; 16 | this.m = m; 17 | this.srid = srid; 18 | 19 | this.hasZ = typeof this.z !== 'undefined'; 20 | this.hasM = typeof this.m !== 'undefined'; 21 | } 22 | 23 | util.inherits(Point, Geometry); 24 | 25 | Point.Z = function (x, y, z, srid) { 26 | var point = new Point(x, y, z, undefined, srid); 27 | point.hasZ = true; 28 | return point; 29 | }; 30 | 31 | Point.M = function (x, y, m, srid) { 32 | var point = new Point(x, y, undefined, m, srid); 33 | point.hasM = true; 34 | return point; 35 | }; 36 | 37 | Point.ZM = function (x, y, z, m, srid) { 38 | var point = new Point(x, y, z, m, srid); 39 | point.hasZ = true; 40 | point.hasM = true; 41 | return point; 42 | }; 43 | 44 | Point._parseWkt = function (value, options) { 45 | var point = new Point(); 46 | point.srid = options.srid; 47 | point.hasZ = options.hasZ; 48 | point.hasM = options.hasM; 49 | 50 | if (value.isMatch(['EMPTY'])) 51 | return point; 52 | 53 | value.expectGroupStart(); 54 | 55 | var coordinate = value.matchCoordinate(options); 56 | 57 | point.x = coordinate.x; 58 | point.y = coordinate.y; 59 | point.z = coordinate.z; 60 | point.m = coordinate.m; 61 | 62 | value.expectGroupEnd(); 63 | 64 | return point; 65 | }; 66 | 67 | Point._parseWkb = function (value, options) { 68 | var point = Point._readWkbPoint(value, options); 69 | point.srid = options.srid; 70 | return point; 71 | }; 72 | 73 | Point._readWkbPoint = function (value, options) { 74 | return new Point(value.readDouble(), value.readDouble(), 75 | options.hasZ ? value.readDouble() : undefined, 76 | options.hasM ? value.readDouble() : undefined); 77 | }; 78 | 79 | Point._parseTwkb = function (value, options) { 80 | var point = new Point(); 81 | point.hasZ = options.hasZ; 82 | point.hasM = options.hasM; 83 | 84 | if (options.isEmpty) 85 | return point; 86 | 87 | point.x = ZigZag.decode(value.readVarInt()) / options.precisionFactor; 88 | point.y = ZigZag.decode(value.readVarInt()) / options.precisionFactor; 89 | point.z = options.hasZ ? ZigZag.decode(value.readVarInt()) / options.zPrecisionFactor : undefined; 90 | point.m = options.hasM ? ZigZag.decode(value.readVarInt()) / options.mPrecisionFactor : undefined; 91 | 92 | return point; 93 | }; 94 | 95 | Point._readTwkbPoint = function (value, options, previousPoint) { 96 | previousPoint.x += ZigZag.decode(value.readVarInt()) / options.precisionFactor; 97 | previousPoint.y += ZigZag.decode(value.readVarInt()) / options.precisionFactor; 98 | 99 | if (options.hasZ) 100 | previousPoint.z += ZigZag.decode(value.readVarInt()) / options.zPrecisionFactor; 101 | if (options.hasM) 102 | previousPoint.m += ZigZag.decode(value.readVarInt()) / options.mPrecisionFactor; 103 | 104 | return new Point(previousPoint.x, previousPoint.y, previousPoint.z, previousPoint.m); 105 | }; 106 | 107 | Point._parseGeoJSON = function (value) { 108 | return Point._readGeoJSONPoint(value.coordinates); 109 | }; 110 | 111 | Point._readGeoJSONPoint = function (coordinates) { 112 | if (coordinates.length === 0) 113 | return new Point(); 114 | 115 | if (coordinates.length > 2) 116 | return new Point(coordinates[0], coordinates[1], coordinates[2]); 117 | 118 | return new Point(coordinates[0], coordinates[1]); 119 | }; 120 | 121 | Point.prototype.toWkt = function () { 122 | if (typeof this.x === 'undefined' && typeof this.y === 'undefined' && 123 | typeof this.z === 'undefined' && typeof this.m === 'undefined') 124 | return this._getWktType(Types.wkt.Point, true); 125 | 126 | return this._getWktType(Types.wkt.Point, false) + '(' + this._getWktCoordinate(this) + ')'; 127 | }; 128 | 129 | Point.prototype.toWkb = function (parentOptions) { 130 | var wkb = new BinaryWriter(this._getWkbSize()); 131 | 132 | wkb.writeInt8(1); 133 | this._writeWkbType(wkb, Types.wkb.Point, parentOptions); 134 | 135 | if (typeof this.x === 'undefined' && typeof this.y === 'undefined') { 136 | wkb.writeDoubleLE(NaN); 137 | wkb.writeDoubleLE(NaN); 138 | 139 | if (this.hasZ) 140 | wkb.writeDoubleLE(NaN); 141 | if (this.hasM) 142 | wkb.writeDoubleLE(NaN); 143 | } 144 | else { 145 | this._writeWkbPoint(wkb); 146 | } 147 | 148 | return wkb.buffer; 149 | }; 150 | 151 | Point.prototype._writeWkbPoint = function (wkb) { 152 | wkb.writeDoubleLE(this.x); 153 | wkb.writeDoubleLE(this.y); 154 | 155 | if (this.hasZ) 156 | wkb.writeDoubleLE(this.z); 157 | if (this.hasM) 158 | wkb.writeDoubleLE(this.m); 159 | }; 160 | 161 | Point.prototype.toTwkb = function () { 162 | var twkb = new BinaryWriter(0, true); 163 | 164 | var precision = Geometry.getTwkbPrecision(5, 0, 0); 165 | var isEmpty = typeof this.x === 'undefined' && typeof this.y === 'undefined'; 166 | 167 | this._writeTwkbHeader(twkb, Types.wkb.Point, precision, isEmpty); 168 | 169 | if (!isEmpty) 170 | this._writeTwkbPoint(twkb, precision, new Point(0, 0, 0, 0)); 171 | 172 | return twkb.buffer; 173 | }; 174 | 175 | Point.prototype._writeTwkbPoint = function (twkb, precision, previousPoint) { 176 | var x = this.x * precision.xyFactor; 177 | var y = this.y * precision.xyFactor; 178 | var z = this.z * precision.zFactor; 179 | var m = this.m * precision.mFactor; 180 | 181 | twkb.writeVarInt(ZigZag.encode(x - previousPoint.x)); 182 | twkb.writeVarInt(ZigZag.encode(y - previousPoint.y)); 183 | if (this.hasZ) 184 | twkb.writeVarInt(ZigZag.encode(z - previousPoint.z)); 185 | if (this.hasM) 186 | twkb.writeVarInt(ZigZag.encode(m - previousPoint.m)); 187 | 188 | previousPoint.x = x; 189 | previousPoint.y = y; 190 | previousPoint.z = z; 191 | previousPoint.m = m; 192 | }; 193 | 194 | Point.prototype._getWkbSize = function () { 195 | var size = 1 + 4 + 8 + 8; 196 | 197 | if (this.hasZ) 198 | size += 8; 199 | if (this.hasM) 200 | size += 8; 201 | 202 | return size; 203 | }; 204 | 205 | Point.prototype.toGeoJSON = function (options) { 206 | var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); 207 | geoJSON.type = Types.geoJSON.Point; 208 | 209 | if (typeof this.x === 'undefined' && typeof this.y === 'undefined') 210 | geoJSON.coordinates = []; 211 | else if (typeof this.z !== 'undefined') 212 | geoJSON.coordinates = [this.x, this.y, this.z]; 213 | else 214 | geoJSON.coordinates = [this.x, this.y]; 215 | 216 | return geoJSON; 217 | }; 218 | -------------------------------------------------------------------------------- /lib/polygon.js: -------------------------------------------------------------------------------- 1 | module.exports = Polygon; 2 | 3 | var util = require('util'); 4 | 5 | var Geometry = require('./geometry'); 6 | var Types = require('./types'); 7 | var Point = require('./point'); 8 | var BinaryWriter = require('./binarywriter'); 9 | 10 | function Polygon(exteriorRing, interiorRings, srid) { 11 | Geometry.call(this); 12 | 13 | this.exteriorRing = exteriorRing || []; 14 | this.interiorRings = interiorRings || []; 15 | this.srid = srid; 16 | 17 | if (this.exteriorRing.length > 0) { 18 | this.hasZ = this.exteriorRing[0].hasZ; 19 | this.hasM = this.exteriorRing[0].hasM; 20 | } 21 | } 22 | 23 | util.inherits(Polygon, Geometry); 24 | 25 | Polygon.Z = function (exteriorRing, interiorRings, srid) { 26 | var polygon = new Polygon(exteriorRing, interiorRings, srid); 27 | polygon.hasZ = true; 28 | return polygon; 29 | }; 30 | 31 | Polygon.M = function (exteriorRing, interiorRings, srid) { 32 | var polygon = new Polygon(exteriorRing, interiorRings, srid); 33 | polygon.hasM = true; 34 | return polygon; 35 | }; 36 | 37 | Polygon.ZM = function (exteriorRing, interiorRings, srid) { 38 | var polygon = new Polygon(exteriorRing, interiorRings, srid); 39 | polygon.hasZ = true; 40 | polygon.hasM = true; 41 | return polygon; 42 | }; 43 | 44 | Polygon._parseWkt = function (value, options) { 45 | var polygon = new Polygon(); 46 | polygon.srid = options.srid; 47 | polygon.hasZ = options.hasZ; 48 | polygon.hasM = options.hasM; 49 | 50 | if (value.isMatch(['EMPTY'])) 51 | return polygon; 52 | 53 | value.expectGroupStart(); 54 | 55 | value.expectGroupStart(); 56 | polygon.exteriorRing.push.apply(polygon.exteriorRing, value.matchCoordinates(options)); 57 | value.expectGroupEnd(); 58 | 59 | while (value.isMatch([','])) { 60 | value.expectGroupStart(); 61 | polygon.interiorRings.push(value.matchCoordinates(options)); 62 | value.expectGroupEnd(); 63 | } 64 | 65 | value.expectGroupEnd(); 66 | 67 | return polygon; 68 | }; 69 | 70 | Polygon._parseWkb = function (value, options) { 71 | var polygon = new Polygon(); 72 | polygon.srid = options.srid; 73 | polygon.hasZ = options.hasZ; 74 | polygon.hasM = options.hasM; 75 | 76 | var ringCount = value.readUInt32(); 77 | 78 | if (ringCount > 0) { 79 | var exteriorRingCount = value.readUInt32(); 80 | 81 | for (var i = 0; i < exteriorRingCount; i++) 82 | polygon.exteriorRing.push(Point._readWkbPoint(value, options)); 83 | 84 | for (i = 1; i < ringCount; i++) { 85 | var interiorRing = []; 86 | 87 | var interiorRingCount = value.readUInt32(); 88 | 89 | for (var j = 0; j < interiorRingCount; j++) 90 | interiorRing.push(Point._readWkbPoint(value, options)); 91 | 92 | polygon.interiorRings.push(interiorRing); 93 | } 94 | } 95 | 96 | return polygon; 97 | }; 98 | 99 | Polygon._parseTwkb = function (value, options) { 100 | var polygon = new Polygon(); 101 | polygon.hasZ = options.hasZ; 102 | polygon.hasM = options.hasM; 103 | 104 | if (options.isEmpty) 105 | return polygon; 106 | 107 | var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); 108 | var ringCount = value.readVarInt(); 109 | var exteriorRingCount = value.readVarInt(); 110 | 111 | for (var i = 0; i < exteriorRingCount; i++) 112 | polygon.exteriorRing.push(Point._readTwkbPoint(value, options, previousPoint)); 113 | 114 | for (i = 1; i < ringCount; i++) { 115 | var interiorRing = []; 116 | 117 | var interiorRingCount = value.readVarInt(); 118 | 119 | for (var j = 0; j < interiorRingCount; j++) 120 | interiorRing.push(Point._readTwkbPoint(value, options, previousPoint)); 121 | 122 | polygon.interiorRings.push(interiorRing); 123 | } 124 | 125 | return polygon; 126 | }; 127 | 128 | Polygon._parseGeoJSON = function (value) { 129 | var polygon = new Polygon(); 130 | 131 | if (value.coordinates.length > 0 && value.coordinates[0].length > 0) 132 | polygon.hasZ = value.coordinates[0][0].length > 2; 133 | 134 | for (var i = 0; i < value.coordinates.length; i++) { 135 | if (i > 0) 136 | polygon.interiorRings.push([]); 137 | 138 | for (var j = 0; j < value.coordinates[i].length; j++) { 139 | if (i === 0) 140 | polygon.exteriorRing.push(Point._readGeoJSONPoint(value.coordinates[i][j])); 141 | else 142 | polygon.interiorRings[i - 1].push(Point._readGeoJSONPoint(value.coordinates[i][j])); 143 | } 144 | } 145 | 146 | return polygon; 147 | }; 148 | 149 | Polygon.prototype.toWkt = function () { 150 | if (this.exteriorRing.length === 0) 151 | return this._getWktType(Types.wkt.Polygon, true); 152 | 153 | return this._getWktType(Types.wkt.Polygon, false) + this._toInnerWkt(); 154 | }; 155 | 156 | Polygon.prototype._toInnerWkt = function () { 157 | var innerWkt = '(('; 158 | 159 | for (var i = 0; i < this.exteriorRing.length; i++) 160 | innerWkt += this._getWktCoordinate(this.exteriorRing[i]) + ','; 161 | 162 | innerWkt = innerWkt.slice(0, -1); 163 | innerWkt += ')'; 164 | 165 | for (i = 0; i < this.interiorRings.length; i++) { 166 | innerWkt += ',('; 167 | 168 | for (var j = 0; j < this.interiorRings[i].length; j++) { 169 | innerWkt += this._getWktCoordinate(this.interiorRings[i][j]) + ','; 170 | } 171 | 172 | innerWkt = innerWkt.slice(0, -1); 173 | innerWkt += ')'; 174 | } 175 | 176 | innerWkt += ')'; 177 | 178 | return innerWkt; 179 | }; 180 | 181 | Polygon.prototype.toWkb = function (parentOptions) { 182 | var wkb = new BinaryWriter(this._getWkbSize()); 183 | 184 | wkb.writeInt8(1); 185 | 186 | this._writeWkbType(wkb, Types.wkb.Polygon, parentOptions); 187 | 188 | if (this.exteriorRing.length > 0) { 189 | wkb.writeUInt32LE(1 + this.interiorRings.length); 190 | wkb.writeUInt32LE(this.exteriorRing.length); 191 | } 192 | else { 193 | wkb.writeUInt32LE(0); 194 | } 195 | 196 | for (var i = 0; i < this.exteriorRing.length; i++) 197 | this.exteriorRing[i]._writeWkbPoint(wkb); 198 | 199 | for (i = 0; i < this.interiorRings.length; i++) { 200 | wkb.writeUInt32LE(this.interiorRings[i].length); 201 | 202 | for (var j = 0; j < this.interiorRings[i].length; j++) 203 | this.interiorRings[i][j]._writeWkbPoint(wkb); 204 | } 205 | 206 | return wkb.buffer; 207 | }; 208 | 209 | Polygon.prototype.toTwkb = function () { 210 | var twkb = new BinaryWriter(0, true); 211 | 212 | var precision = Geometry.getTwkbPrecision(5, 0, 0); 213 | var isEmpty = this.exteriorRing.length === 0; 214 | 215 | this._writeTwkbHeader(twkb, Types.wkb.Polygon, precision, isEmpty); 216 | 217 | if (this.exteriorRing.length > 0) { 218 | twkb.writeVarInt(1 + this.interiorRings.length); 219 | 220 | twkb.writeVarInt(this.exteriorRing.length); 221 | 222 | var previousPoint = new Point(0, 0, 0, 0); 223 | for (var i = 0; i < this.exteriorRing.length; i++) 224 | this.exteriorRing[i]._writeTwkbPoint(twkb, precision, previousPoint); 225 | 226 | for (i = 0; i < this.interiorRings.length; i++) { 227 | twkb.writeVarInt(this.interiorRings[i].length); 228 | 229 | for (var j = 0; j < this.interiorRings[i].length; j++) 230 | this.interiorRings[i][j]._writeTwkbPoint(twkb, precision, previousPoint); 231 | } 232 | } 233 | 234 | return twkb.buffer; 235 | }; 236 | 237 | Polygon.prototype._getWkbSize = function () { 238 | var coordinateSize = 16; 239 | 240 | if (this.hasZ) 241 | coordinateSize += 8; 242 | if (this.hasM) 243 | coordinateSize += 8; 244 | 245 | var size = 1 + 4 + 4; 246 | 247 | if (this.exteriorRing.length > 0) 248 | size += 4 + (this.exteriorRing.length * coordinateSize); 249 | 250 | for (var i = 0; i < this.interiorRings.length; i++) 251 | size += 4 + (this.interiorRings[i].length * coordinateSize); 252 | 253 | return size; 254 | }; 255 | 256 | Polygon.prototype.toGeoJSON = function (options) { 257 | var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); 258 | geoJSON.type = Types.geoJSON.Polygon; 259 | geoJSON.coordinates = []; 260 | 261 | if (this.exteriorRing.length > 0) { 262 | var exteriorRing = []; 263 | 264 | for (var i = 0; i < this.exteriorRing.length; i++) { 265 | if (this.hasZ) 266 | exteriorRing.push([this.exteriorRing[i].x, this.exteriorRing[i].y, this.exteriorRing[i].z]); 267 | else 268 | exteriorRing.push([this.exteriorRing[i].x, this.exteriorRing[i].y]); 269 | } 270 | 271 | geoJSON.coordinates.push(exteriorRing); 272 | } 273 | 274 | for (var j = 0; j < this.interiorRings.length; j++) { 275 | var interiorRing = []; 276 | 277 | for (var k = 0; k < this.interiorRings[j].length; k++) { 278 | if (this.hasZ) 279 | interiorRing.push([this.interiorRings[j][k].x, this.interiorRings[j][k].y, this.interiorRings[j][k].z]); 280 | else 281 | interiorRing.push([this.interiorRings[j][k].x, this.interiorRings[j][k].y]); 282 | } 283 | 284 | geoJSON.coordinates.push(interiorRing); 285 | } 286 | 287 | return geoJSON; 288 | }; 289 | -------------------------------------------------------------------------------- /lib/types.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | wkt: { 3 | Point: 'POINT', 4 | LineString: 'LINESTRING', 5 | Polygon: 'POLYGON', 6 | MultiPoint: 'MULTIPOINT', 7 | MultiLineString: 'MULTILINESTRING', 8 | MultiPolygon: 'MULTIPOLYGON', 9 | GeometryCollection: 'GEOMETRYCOLLECTION' 10 | }, 11 | wkb: { 12 | Point: 1, 13 | LineString: 2, 14 | Polygon: 3, 15 | MultiPoint: 4, 16 | MultiLineString: 5, 17 | MultiPolygon: 6, 18 | GeometryCollection: 7 19 | }, 20 | geoJSON: { 21 | Point: 'Point', 22 | LineString: 'LineString', 23 | Polygon: 'Polygon', 24 | MultiPoint: 'MultiPoint', 25 | MultiLineString: 'MultiLineString', 26 | MultiPolygon: 'MultiPolygon', 27 | GeometryCollection: 'GeometryCollection' 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /lib/wktparser.js: -------------------------------------------------------------------------------- 1 | module.exports = WktParser; 2 | 3 | var Types = require('./types'); 4 | var Point = require('./point'); 5 | 6 | function WktParser(value) { 7 | this.value = value; 8 | this.position = 0; 9 | } 10 | 11 | WktParser.prototype.match = function (tokens) { 12 | this.skipWhitespaces(); 13 | 14 | for (var i = 0; i < tokens.length; i++) { 15 | if (this.value.substring(this.position).indexOf(tokens[i]) === 0) { 16 | this.position += tokens[i].length; 17 | return tokens[i]; 18 | } 19 | } 20 | 21 | return null; 22 | }; 23 | 24 | WktParser.prototype.matchRegex = function (tokens) { 25 | this.skipWhitespaces(); 26 | 27 | for (var i = 0; i < tokens.length; i++) { 28 | var match = this.value.substring(this.position).match(tokens[i]); 29 | 30 | if (match) { 31 | this.position += match[0].length; 32 | return match; 33 | } 34 | } 35 | 36 | return null; 37 | }; 38 | 39 | WktParser.prototype.isMatch = function (tokens) { 40 | this.skipWhitespaces(); 41 | 42 | for (var i = 0; i < tokens.length; i++) { 43 | if (this.value.substring(this.position).indexOf(tokens[i]) === 0) { 44 | this.position += tokens[i].length; 45 | return true; 46 | } 47 | } 48 | 49 | return false; 50 | }; 51 | 52 | WktParser.prototype.matchType = function () { 53 | var geometryType = this.match([Types.wkt.Point, Types.wkt.LineString, Types.wkt.Polygon, Types.wkt.MultiPoint, 54 | Types.wkt.MultiLineString, Types.wkt.MultiPolygon, Types.wkt.GeometryCollection]); 55 | 56 | if (!geometryType) 57 | throw new Error('Expected geometry type'); 58 | 59 | return geometryType; 60 | }; 61 | 62 | WktParser.prototype.matchDimension = function () { 63 | var dimension = this.match(['ZM', 'Z', 'M']); 64 | 65 | switch (dimension) { 66 | case 'ZM': return { hasZ: true, hasM: true }; 67 | case 'Z': return { hasZ: true, hasM: false }; 68 | case 'M': return { hasZ: false, hasM: true }; 69 | default: return { hasZ: false, hasM: false }; 70 | } 71 | }; 72 | 73 | WktParser.prototype.expectGroupStart = function () { 74 | if (!this.isMatch(['('])) 75 | throw new Error('Expected group start'); 76 | }; 77 | 78 | WktParser.prototype.expectGroupEnd = function () { 79 | if (!this.isMatch([')'])) 80 | throw new Error('Expected group end'); 81 | }; 82 | 83 | WktParser.prototype.matchCoordinate = function (options) { 84 | var match; 85 | 86 | if (options.hasZ && options.hasM) 87 | match = this.matchRegex([/^(\S*)\s+(\S*)\s+(\S*)\s+([^\s,)]*)/]); 88 | else if (options.hasZ || options.hasM) 89 | match = this.matchRegex([/^(\S*)\s+(\S*)\s+([^\s,)]*)/]); 90 | else 91 | match = this.matchRegex([/^(\S*)\s+([^\s,)]*)/]); 92 | 93 | if (!match) 94 | throw new Error('Expected coordinates'); 95 | 96 | if (options.hasZ && options.hasM) 97 | return new Point(parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3]), parseFloat(match[4])); 98 | else if (options.hasZ) 99 | return new Point(parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3])); 100 | else if (options.hasM) 101 | return new Point(parseFloat(match[1]), parseFloat(match[2]), undefined, parseFloat(match[3])); 102 | else 103 | return new Point(parseFloat(match[1]), parseFloat(match[2])); 104 | }; 105 | 106 | WktParser.prototype.matchCoordinates = function (options) { 107 | var coordinates = []; 108 | 109 | do { 110 | var startsWithBracket = this.isMatch(['(']); 111 | 112 | coordinates.push(this.matchCoordinate(options)); 113 | 114 | if (startsWithBracket) 115 | this.expectGroupEnd(); 116 | } while (this.isMatch([','])); 117 | 118 | return coordinates; 119 | }; 120 | 121 | WktParser.prototype.skipWhitespaces = function () { 122 | while (this.position < this.value.length && this.value[this.position] === ' ') 123 | this.position++; 124 | }; 125 | -------------------------------------------------------------------------------- /lib/wkx.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module "wkx" { 4 | 5 | export class Geometry { 6 | srid: number; 7 | hasZ: boolean; 8 | hasM: boolean; 9 | 10 | static parse(value: string | Buffer): Geometry; 11 | static parseTwkb(value: Buffer): Geometry; 12 | static parseGeoJSON(value: {}): Geometry; 13 | 14 | toWkt(): string; 15 | toEwkt(): string; 16 | toWkb(): Buffer; 17 | toEwkb(): Buffer; 18 | toTwkb(): Buffer; 19 | toGeoJSON(options?: GeoJSONOptions): {}; 20 | } 21 | 22 | export interface GeoJSONOptions { 23 | shortCrs?: boolean; 24 | longCrs?: boolean; 25 | } 26 | 27 | export class Point extends Geometry { 28 | x: number; 29 | y: number; 30 | z: number; 31 | m: number; 32 | 33 | constructor(x?: number, y?: number, z?: number, m?: number, srid?: number); 34 | 35 | static Z(x: number, y: number, z: number, srid?: number): Point; 36 | static M(x: number, y: number, m: number, srid?: number): Point; 37 | static ZM(x: number, y: number, z: number, m: number, srid?: number): Point; 38 | } 39 | 40 | export class LineString extends Geometry { 41 | points: Point[]; 42 | 43 | constructor(points?: Point[], srid?: number); 44 | 45 | static Z(points?: Point[], srid?: number): LineString; 46 | static M(points?: Point[], srid?: number): LineString; 47 | static ZM(points?: Point[], srid?: number): LineString; 48 | } 49 | 50 | export class Polygon extends Geometry { 51 | exteriorRing: Point[]; 52 | interiorRings: Point[][]; 53 | 54 | constructor(exteriorRing?: Point[], interiorRings?: Point[][], srid?: number); 55 | 56 | static Z(exteriorRing?: Point[], interiorRings?: Point[][], srid?: number): Polygon; 57 | static M(exteriorRing?: Point[], interiorRings?: Point[][], srid?: number): Polygon; 58 | static ZM(exteriorRing?: Point[], interiorRings?: Point[][], srid?: number): Polygon; 59 | } 60 | 61 | export class MultiPoint extends Geometry { 62 | points: Point[]; 63 | 64 | constructor(points?: Point[], srid?: number); 65 | 66 | static Z(points?: Point[], srid?: number): MultiPoint; 67 | static M(points?: Point[], srid?: number): MultiPoint; 68 | static ZM(points?: Point[], srid?: number): MultiPoint; 69 | } 70 | 71 | export class MultiLineString extends Geometry { 72 | lineStrings: LineString[]; 73 | 74 | constructor(lineStrings?: LineString[], srid?: number); 75 | 76 | static Z(lineStrings?: LineString[], srid?: number): MultiLineString; 77 | static M(lineStrings?: LineString[], srid?: number): MultiLineString; 78 | static ZM(lineStrings?: LineString[], srid?: number): MultiLineString; 79 | } 80 | 81 | export class MultiPolygon extends Geometry { 82 | polygons: Polygon[]; 83 | 84 | constructor(polygons?: Polygon[], srid?: number); 85 | 86 | static Z(polygons?: Polygon[], srid?: number): MultiPolygon; 87 | static M(polygons?: Polygon[], srid?: number): MultiPolygon; 88 | static ZM(polygons?: Polygon[], srid?: number): MultiPolygon; 89 | } 90 | 91 | export class GeometryCollection extends Geometry { 92 | geometries: Geometry[]; 93 | 94 | constructor(geometries?: Geometry[], srid?: number); 95 | 96 | static Z(geometries?: Geometry[], srid?: number): GeometryCollection; 97 | static M(geometries?: Geometry[], srid?: number): GeometryCollection; 98 | static ZM(geometries?: Geometry[], srid?: number): GeometryCollection; 99 | } 100 | } -------------------------------------------------------------------------------- /lib/wkx.js: -------------------------------------------------------------------------------- 1 | exports.Types = require('./types'); 2 | exports.Geometry = require('./geometry'); 3 | exports.Point = require('./point'); 4 | exports.LineString = require('./linestring'); 5 | exports.Polygon = require('./polygon'); 6 | exports.MultiPoint = require('./multipoint'); 7 | exports.MultiLineString = require('./multilinestring'); 8 | exports.MultiPolygon = require('./multipolygon'); 9 | exports.GeometryCollection = require('./geometrycollection'); -------------------------------------------------------------------------------- /lib/zigzag.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | encode: function (value) { 3 | return (value << 1) ^ (value >> 31); 4 | }, 5 | decode: function (value) { 6 | return (value >> 1) ^ (-(value & 1)); 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wkx", 3 | "version": "0.5.0", 4 | "description": "A WKT/WKB/EWKT/EWKB/TWKB/GeoJSON parser and serializer", 5 | "main": "lib/wkx.js", 6 | "types": "lib/wkx.d.ts", 7 | "files": [ 8 | "dist/", 9 | "lib/" 10 | ], 11 | "scripts": { 12 | "test": "jshint . && nyc mocha", 13 | "build": "mkdirp ./dist && browserify -r buffer -r ./lib/wkx.js:wkx ./lib/wkx.js > ./dist/wkx.js && uglifyjs -c -m -- ./dist/wkx.js > ./dist/wkx.min.js", 14 | "coverage": "nyc report --reporter=text-lcov | coveralls" 15 | }, 16 | "author": "Christian Schwarz", 17 | "license": "MIT", 18 | "devDependencies": { 19 | "async": "^3.2.0", 20 | "browserify": "^16.5.0", 21 | "coveralls": "^3.0.11", 22 | "deep-eql": "^4.0.0", 23 | "jshint": "^2.11.0", 24 | "json-stringify-pretty-compact": "^2.0.0", 25 | "mkdirp": "^1.0.3", 26 | "mocha": "^7.1.1", 27 | "nyc": "^15.0.0", 28 | "pg": "^7.18.2", 29 | "uglify-js": "^3.8.0" 30 | }, 31 | "repository": { 32 | "type": "git", 33 | "url": "http://github.com/cschwarz/wkx.git" 34 | }, 35 | "keywords": [ 36 | "wkt", 37 | "wkb", 38 | "ewkt", 39 | "ewkb", 40 | "twkb", 41 | "geojson", 42 | "ogc", 43 | "geometry", 44 | "geography", 45 | "spatial" 46 | ], 47 | "dependencies": { 48 | "@types/node": "*" 49 | } 50 | } -------------------------------------------------------------------------------- /test/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.jshintrc", 3 | "mocha": true 4 | } -------------------------------------------------------------------------------- /test/binaryreader.js: -------------------------------------------------------------------------------- 1 | var BinaryReader = require('../lib/binaryreader'); 2 | 3 | var assert = require('assert'); 4 | 5 | describe('wkx', function () { 6 | describe('BinaryReader', function () { 7 | it('readVarInt', function () { 8 | assert.equal(new BinaryReader(new Buffer('01', 'hex')).readVarInt(), 1); 9 | assert.equal(new BinaryReader(new Buffer('ac02', 'hex')).readVarInt(), 300); 10 | }); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /test/binarywriter.js: -------------------------------------------------------------------------------- 1 | var BinaryWriter = require('../lib/binarywriter'); 2 | 3 | var assert = require('assert'); 4 | 5 | describe('wkx', function () { 6 | describe('BinaryWriter', function () { 7 | it('writeVarInt - 1', function () { 8 | var binaryWriter = new BinaryWriter(1); 9 | var length = binaryWriter.writeVarInt(1); 10 | 11 | assert.equal(binaryWriter.buffer.toString('hex'), '01'); 12 | assert.equal(length, 1); 13 | }); 14 | it('writeVarInt - 300', function () { 15 | var binaryWriter = new BinaryWriter(2); 16 | var length = binaryWriter.writeVarInt(300); 17 | 18 | assert.equal(binaryWriter.buffer.toString('hex'), 'ac02'); 19 | assert.equal(length, 2); 20 | }); 21 | it('writeUInt8 - enough space', function () { 22 | var binaryWriter = new BinaryWriter(1); 23 | binaryWriter.writeUInt8(1); 24 | assert.equal(binaryWriter.buffer.length, 1); 25 | assert.equal(binaryWriter.position, 1); 26 | }); 27 | it('writeUInt16LE - not enough space', function () { 28 | var binaryWriter = new BinaryWriter(1); 29 | assert.throws(function () { binaryWriter.writeUInt16LE(1); }, /RangeError: index out of range/); 30 | }); 31 | it('writeUInt8 - enough space / allow resize', function () { 32 | var binaryWriter = new BinaryWriter(1, true); 33 | binaryWriter.writeUInt8(1); 34 | assert.equal(binaryWriter.buffer.length, 1); 35 | assert.equal(binaryWriter.position, 1); 36 | }); 37 | it('writeUInt16LE - not enough space / allow resize', function () { 38 | var binaryWriter = new BinaryWriter(1, true); 39 | binaryWriter.writeUInt16LE(1); 40 | assert.equal(binaryWriter.buffer.length, 2); 41 | assert.equal(binaryWriter.position, 2); 42 | }); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /test/geojson.js: -------------------------------------------------------------------------------- 1 | var Geometry = require('../lib/geometry'); 2 | var Point = require('../lib/point'); 3 | 4 | var assert = require('assert'); 5 | 6 | describe('wkx', function () { 7 | describe('parseGeoJSON', function () { 8 | it('includes short CRS', function () { 9 | var point = new Point(1, 2); 10 | point.srid = 4326; 11 | 12 | assert.deepEqual(Geometry.parseGeoJSON({ 13 | type: 'Point', 14 | crs: { 15 | type: 'name', 16 | properties: { 17 | name: 'EPSG:4326' 18 | } 19 | }, 20 | coordinates: [1, 2] 21 | }), point); 22 | }); 23 | it('includes long CRS', function () { 24 | var point = new Point(1, 2); 25 | point.srid = 4326; 26 | 27 | assert.deepEqual(Geometry.parseGeoJSON({ 28 | type: 'Point', 29 | crs: { 30 | type: 'name', 31 | properties: { 32 | name: 'urn:ogc:def:crs:EPSG::4326' 33 | } 34 | }, 35 | coordinates: [1, 2] 36 | }), point); 37 | }); 38 | it('includes invalid CRS', function () { 39 | assert.throws(function () { Geometry.parseGeoJSON({ 40 | type: 'Point', 41 | crs: { 42 | type: 'name', 43 | properties: { 44 | name: 'TEST' 45 | } 46 | }, 47 | coordinates: [1, 2] 48 | }); 49 | }, /Unsupported crs: TEST/); 50 | }); 51 | }); 52 | describe('toGeoJSON', function () { 53 | it('include short CRS', function () { 54 | var point = new Point(1, 2); 55 | point.srid = 4326; 56 | 57 | assert.deepEqual(point.toGeoJSON({ shortCrs: true }), { 58 | type: 'Point', 59 | crs: { 60 | type: 'name', 61 | properties: { 62 | name: 'EPSG:4326' 63 | } 64 | }, 65 | coordinates: [1, 2] 66 | }); 67 | }); 68 | it('include long CRS', function () { 69 | var point = new Point(1, 2); 70 | point.srid = 4326; 71 | 72 | assert.deepEqual(point.toGeoJSON({ longCrs: true }), { 73 | type: 'Point', 74 | crs: { 75 | type: 'name', 76 | properties: { 77 | name: 'urn:ogc:def:crs:EPSG::4326' 78 | } 79 | }, 80 | coordinates: [1, 2] 81 | }); 82 | }); 83 | it('geometry with SRID - without options', function () { 84 | var point = new Point(1, 2); 85 | point.srid = 4326; 86 | 87 | assert.deepEqual(point.toGeoJSON(), { 88 | type: 'Point', 89 | coordinates: [1, 2] 90 | }); 91 | }); 92 | it('geometry with SRID - with empty options', function () { 93 | var point = new Point(1, 2); 94 | point.srid = 4326; 95 | 96 | assert.deepEqual(point.toGeoJSON({}), { 97 | type: 'Point', 98 | coordinates: [1, 2] 99 | }); 100 | }); 101 | }); 102 | }); 103 | -------------------------------------------------------------------------------- /test/issuetestdata.json: -------------------------------------------------------------------------------- 1 | { 2 | "#31": { 3 | "geometry": "new Polygon([new Point(-89.31029407, 38.72017071), new Point(-89.30548017, 38.72017071), new Point(-89.30421905, 38.72418814), new Point(-89.31029407, 38.72376013), new Point(-89.31029407, 38.72017071)])", 4 | "wkt": "POLYGON((-89.31029407 38.72017071,-89.30548017 38.72017071,-89.30421905 38.72418814,-89.31029407 38.72376013,-89.31029407 38.72017071))" 5 | } 6 | } -------------------------------------------------------------------------------- /test/testdata.json: -------------------------------------------------------------------------------- 1 | { 2 | "emptyPoint": { 3 | "geometry": "new Point()", 4 | "wkbGeometry": "new Point(NaN, NaN)", 5 | "wkt": "POINT EMPTY", 6 | "wkb": "0101000000000000000000f87f000000000000f87f", 7 | "ewkb": "0101000020e6100000000000000000f87f000000000000f87f", 8 | "wkbXdr": "00000000017ff80000000000007ff8000000000000", 9 | "ewkbXdr": "0020000001000010e67ff80000000000007ff8000000000000", 10 | "twkb": "a110", 11 | "geoJSON": {"type": "Point", "coordinates": []}, 12 | "ewkbNoSrid": "0101000000000000000000f87f000000000000f87f", 13 | "ewkbXdrNoSrid": "00000000017ff80000000000007ff8000000000000" 14 | }, 15 | "point": { 16 | "geometry": "new Point(1, 2)", 17 | "wkt": "POINT(1 2)", 18 | "wkb": "0101000000000000000000f03f0000000000000040", 19 | "ewkb": "0101000020e6100000000000000000f03f0000000000000040", 20 | "wkbXdr": "00000000013ff00000000000004000000000000000", 21 | "ewkbXdr": "0020000001000010e63ff00000000000004000000000000000", 22 | "twkb": "a100c09a0c80b518", 23 | "geoJSON": {"type": "Point", "coordinates": [1, 2]}, 24 | "ewkbNoSrid": "0101000000000000000000f03f0000000000000040", 25 | "ewkbXdrNoSrid": "00000000013ff00000000000004000000000000000" 26 | }, 27 | "emptyLineString": { 28 | "geometry": "new LineString()", 29 | "wkt": "LINESTRING EMPTY", 30 | "wkb": "010200000000000000", 31 | "ewkb": "0102000020e610000000000000", 32 | "wkbXdr": "000000000200000000", 33 | "ewkbXdr": "0020000002000010e600000000", 34 | "twkb": "a210", 35 | "geoJSON": {"type": "LineString", "coordinates": []}, 36 | "ewkbNoSrid": "010200000000000000", 37 | "ewkbXdrNoSrid": "000000000200000000" 38 | }, 39 | "lineString": { 40 | "geometry": "new LineString([new Point(1, 2), new Point(3, 4)])", 41 | "wkt": "LINESTRING(1 2,3 4)", 42 | "wkb": "010200000002000000000000000000f03f000000000000004000000000000008400000000000001040", 43 | "ewkb": "0102000020e610000002000000000000000000f03f000000000000004000000000000008400000000000001040", 44 | "wkbXdr": "0000000002000000023ff0000000000000400000000000000040080000000000004010000000000000", 45 | "ewkbXdr": "0020000002000010e6000000023ff0000000000000400000000000000040080000000000004010000000000000", 46 | "twkb": "a20002c09a0c80b51880b51880b518", 47 | "geoJSON": {"type": "LineString", "coordinates": [[1, 2], [3, 4]]}, 48 | "ewkbNoSrid": "010200000002000000000000000000f03f000000000000004000000000000008400000000000001040", 49 | "ewkbXdrNoSrid": "0000000002000000023ff0000000000000400000000000000040080000000000004010000000000000" 50 | }, 51 | "emptyPolygon": { 52 | "geometry": "new Polygon()", 53 | "wkt": "POLYGON EMPTY", 54 | "wkb": "010300000000000000", 55 | "ewkb": "0103000020e610000000000000", 56 | "wkbXdr": "000000000300000000", 57 | "ewkbXdr": "0020000003000010e600000000", 58 | "twkb": "a310", 59 | "geoJSON": {"type": "Polygon", "coordinates": []}, 60 | "ewkbNoSrid": "010300000000000000", 61 | "ewkbXdrNoSrid": "000000000300000000" 62 | }, 63 | "polygon": { 64 | "geometry": "new Polygon([new Point(1, 2), new Point(3, 4), new Point(5, 6), new Point(1, 2)])", 65 | "wkt": "POLYGON((1 2,3 4,5 6,1 2))", 66 | "wkb": "01030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f0000000000000040", 67 | "ewkb": "0103000020e61000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f0000000000000040", 68 | "wkbXdr": "000000000300000001000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff00000000000004000000000000000", 69 | "ewkbXdr": "0020000003000010e600000001000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff00000000000004000000000000000", 70 | "twkb": "a3000104c09a0c80b51880b51880b51880b51880b518ffe930ffe930", 71 | "geoJSON": { 72 | "type": "Polygon", 73 | "coordinates": [[[1, 2], [3, 4], [5, 6], [1, 2]]] 74 | }, 75 | "ewkbNoSrid": "01030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f0000000000000040", 76 | "ewkbXdrNoSrid": "000000000300000001000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff00000000000004000000000000000" 77 | }, 78 | "polygonWithOneInteriorRing": { 79 | "geometry": "new Polygon([new Point(1, 2), new Point(3, 4), new Point(5, 6), new Point(1, 2)], [[new Point(11, 12), new Point(13, 14), new Point(15, 16), new Point(11, 12)]])", 80 | "wkt": "POLYGON((1 2,3 4,5 6,1 2),(11 12,13 14,15 16,11 12))", 81 | "wkb": "01030000000200000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e40000000000000304000000000000026400000000000002840", 82 | "ewkb": "0103000020e61000000200000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e40000000000000304000000000000026400000000000002840", 83 | "wkbXdr": "000000000300000002000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff000000000000040000000000000000000000440260000000000004028000000000000402a000000000000402c000000000000402e000000000000403000000000000040260000000000004028000000000000", 84 | "ewkbXdr": "0020000003000010e600000002000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff000000000000040000000000000000000000440260000000000004028000000000000402a000000000000402c000000000000402e000000000000403000000000000040260000000000004028000000000000", 85 | "twkb": "a3000204c09a0c80b51880b51880b51880b51880b518ffe930ffe9300480897a80897a80b51880b51880b51880b518ffe930ffe930", 86 | "geoJSON": { 87 | "type": "Polygon", 88 | "coordinates": [ 89 | [[1, 2], [3, 4], [5, 6], [1, 2]], 90 | [[11, 12], [13, 14], [15, 16], [11, 12]] 91 | ] 92 | }, 93 | "ewkbNoSrid": "01030000000200000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e40000000000000304000000000000026400000000000002840", 94 | "ewkbXdrNoSrid": "000000000300000002000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff000000000000040000000000000000000000440260000000000004028000000000000402a000000000000402c000000000000402e000000000000403000000000000040260000000000004028000000000000" 95 | }, 96 | "polygonWithTwoInteriorRings": { 97 | "geometry": "new Polygon([new Point(1, 2), new Point(3, 4), new Point(5, 6), new Point(1, 2)], [[new Point(11, 12), new Point(13, 14), new Point(15, 16), new Point(11, 12)], [new Point(21, 22), new Point(23, 24), new Point(25, 26), new Point(21, 22)]])", 98 | "wkt": "POLYGON((1 2,3 4,5 6,1 2),(11 12,13 14,15 16,11 12),(21 22,23 24,25 26,21 22))", 99 | "wkb": "01030000000300000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e4000000000000030400000000000002640000000000000284004000000000000000000354000000000000036400000000000003740000000000000384000000000000039400000000000003a4000000000000035400000000000003640", 100 | "ewkb": "0103000020e61000000300000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e4000000000000030400000000000002640000000000000284004000000000000000000354000000000000036400000000000003740000000000000384000000000000039400000000000003a4000000000000035400000000000003640", 101 | "wkbXdr": "000000000300000003000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff000000000000040000000000000000000000440260000000000004028000000000000402a000000000000402c000000000000402e0000000000004030000000000000402600000000000040280000000000000000000440350000000000004036000000000000403700000000000040380000000000004039000000000000403a00000000000040350000000000004036000000000000", 102 | "ewkbXdr": "0020000003000010e600000003000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff000000000000040000000000000000000000440260000000000004028000000000000402a000000000000402c000000000000402e0000000000004030000000000000402600000000000040280000000000000000000440350000000000004036000000000000403700000000000040380000000000004039000000000000403a00000000000040350000000000004036000000000000", 103 | "twkb": "a3000304c09a0c80b51880b51880b51880b51880b518ffe930ffe9300480897a80897a80b51880b51880b51880b518ffe930ffe9300480897a80897a80b51880b51880b51880b518ffe930ffe930", 104 | "geoJSON": { 105 | "type": "Polygon", 106 | "coordinates": [ 107 | [[1, 2], [3, 4], [5, 6], [1, 2]], 108 | [[11, 12], [13, 14], [15, 16], [11, 12]], 109 | [[21, 22], [23, 24], [25, 26], [21, 22]] 110 | ] 111 | }, 112 | "ewkbNoSrid": "01030000000300000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e4000000000000030400000000000002640000000000000284004000000000000000000354000000000000036400000000000003740000000000000384000000000000039400000000000003a4000000000000035400000000000003640", 113 | "ewkbXdrNoSrid": "000000000300000003000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff000000000000040000000000000000000000440260000000000004028000000000000402a000000000000402c000000000000402e0000000000004030000000000000402600000000000040280000000000000000000440350000000000004036000000000000403700000000000040380000000000004039000000000000403a00000000000040350000000000004036000000000000" 114 | }, 115 | "emptyMultiPoint": { 116 | "geometry": "new MultiPoint()", 117 | "wkt": "MULTIPOINT EMPTY", 118 | "wkb": "010400000000000000", 119 | "ewkb": "0104000020e610000000000000", 120 | "wkbXdr": "000000000400000000", 121 | "ewkbXdr": "0020000004000010e600000000", 122 | "twkb": "a410", 123 | "geoJSON": {"type": "MultiPoint", "coordinates": []}, 124 | "ewkbNoSrid": "010400000000000000", 125 | "ewkbXdrNoSrid": "000000000400000000" 126 | }, 127 | "multiPointWithOnePoint": { 128 | "geometry": "new MultiPoint([new Point(1, 2)])", 129 | "wkt": "MULTIPOINT(1 2)", 130 | "wkb": "0104000000010000000101000000000000000000f03f0000000000000040", 131 | "ewkb": "0104000020e6100000010000000101000000000000000000f03f0000000000000040", 132 | "wkbXdr": "00000000040000000100000000013ff00000000000004000000000000000", 133 | "ewkbXdr": "0020000004000010e60000000100000000013ff00000000000004000000000000000", 134 | "twkb": "a40001c09a0c80b518", 135 | "geoJSON": {"type": "MultiPoint", "coordinates": [[1, 2]]}, 136 | "ewkbNoSrid": "0104000000010000000101000000000000000000f03f0000000000000040", 137 | "ewkbXdrNoSrid": "00000000040000000100000000013ff00000000000004000000000000000" 138 | }, 139 | "multiPointWithTwoPoints": { 140 | "geometry": "new MultiPoint([new Point(1, 2), new Point(3, 4)])", 141 | "wkt": "MULTIPOINT(1 2,3 4)", 142 | "wkb": "0104000000020000000101000000000000000000f03f0000000000000040010100000000000000000008400000000000001040", 143 | "ewkb": "0104000020e6100000020000000101000000000000000000f03f0000000000000040010100000000000000000008400000000000001040", 144 | "wkbXdr": "00000000040000000200000000013ff00000000000004000000000000000000000000140080000000000004010000000000000", 145 | "ewkbXdr": "0020000004000010e60000000200000000013ff00000000000004000000000000000000000000140080000000000004010000000000000", 146 | "twkb": "a40002c09a0c80b51880b51880b518", 147 | "geoJSON": {"type": "MultiPoint", "coordinates": [[1, 2], [3, 4]]}, 148 | "ewkbNoSrid": "0104000000020000000101000000000000000000f03f0000000000000040010100000000000000000008400000000000001040", 149 | "ewkbXdrNoSrid": "00000000040000000200000000013ff00000000000004000000000000000000000000140080000000000004010000000000000" 150 | }, 151 | "emptyMultiLineString": { 152 | "geometry": "new MultiLineString()", 153 | "wkt": "MULTILINESTRING EMPTY", 154 | "wkb": "010500000000000000", 155 | "ewkb": "0105000020e610000000000000", 156 | "wkbXdr": "000000000500000000", 157 | "ewkbXdr": "0020000005000010e600000000", 158 | "twkb": "a510", 159 | "geoJSON": {"type": "MultiLineString", "coordinates": []}, 160 | "ewkbNoSrid": "010500000000000000", 161 | "ewkbXdrNoSrid": "000000000500000000" 162 | }, 163 | "multiLineStringWithOneLineString": { 164 | "geometry": "new MultiLineString([new LineString([new Point(1, 2), new Point(3, 4)])])", 165 | "wkt": "MULTILINESTRING((1 2,3 4))", 166 | "wkb": "010500000001000000010200000002000000000000000000f03f000000000000004000000000000008400000000000001040", 167 | "ewkb": "0105000020e610000001000000010200000002000000000000000000f03f000000000000004000000000000008400000000000001040", 168 | "wkbXdr": "0000000005000000010000000002000000023ff0000000000000400000000000000040080000000000004010000000000000", 169 | "ewkbXdr": "0020000005000010e6000000010000000002000000023ff0000000000000400000000000000040080000000000004010000000000000", 170 | "twkb": "a5000102c09a0c80b51880b51880b518", 171 | "geoJSON": {"type": "MultiLineString", "coordinates": [[[1, 2], [3, 4]]]}, 172 | "ewkbNoSrid": "010500000001000000010200000002000000000000000000f03f000000000000004000000000000008400000000000001040", 173 | "ewkbXdrNoSrid": "0000000005000000010000000002000000023ff0000000000000400000000000000040080000000000004010000000000000" 174 | }, 175 | "multiLineStringWithTwoLineStrings": { 176 | "geometry": "new MultiLineString([new LineString([new Point(1, 2), new Point(3, 4)]), new LineString([new Point(5, 6), new Point(7, 8)])])", 177 | "wkt": "MULTILINESTRING((1 2,3 4),(5 6,7 8))", 178 | "wkb": "010500000002000000010200000002000000000000000000f03f000000000000004000000000000008400000000000001040010200000002000000000000000000144000000000000018400000000000001c400000000000002040", 179 | "ewkb": "0105000020e610000002000000010200000002000000000000000000f03f000000000000004000000000000008400000000000001040010200000002000000000000000000144000000000000018400000000000001c400000000000002040", 180 | "wkbXdr": "0000000005000000020000000002000000023ff000000000000040000000000000004008000000000000401000000000000000000000020000000240140000000000004018000000000000401c0000000000004020000000000000", 181 | "ewkbXdr": "0020000005000010e6000000020000000002000000023ff000000000000040000000000000004008000000000000401000000000000000000000020000000240140000000000004018000000000000401c0000000000004020000000000000", 182 | "twkb": "a5000202c09a0c80b51880b51880b5180280b51880b51880b51880b518", 183 | "geoJSON": { 184 | "type": "MultiLineString", 185 | "coordinates": [[[1, 2], [3, 4]], [[5, 6], [7, 8]]] 186 | }, 187 | "ewkbNoSrid": "010500000002000000010200000002000000000000000000f03f000000000000004000000000000008400000000000001040010200000002000000000000000000144000000000000018400000000000001c400000000000002040", 188 | "ewkbXdrNoSrid": "0000000005000000020000000002000000023ff000000000000040000000000000004008000000000000401000000000000000000000020000000240140000000000004018000000000000401c0000000000004020000000000000" 189 | }, 190 | "emptyMultiPolygon": { 191 | "geometry": "new MultiPolygon()", 192 | "wkt": "MULTIPOLYGON EMPTY", 193 | "wkb": "010600000000000000", 194 | "ewkb": "0106000020e610000000000000", 195 | "wkbXdr": "000000000600000000", 196 | "ewkbXdr": "0020000006000010e600000000", 197 | "twkb": "a610", 198 | "geoJSON": {"type": "MultiPolygon", "coordinates": []}, 199 | "ewkbNoSrid": "010600000000000000", 200 | "ewkbXdrNoSrid": "000000000600000000" 201 | }, 202 | "multiPolygonWithOnePolygon": { 203 | "geometry": "new MultiPolygon([new Polygon([new Point(1, 2), new Point(3, 4), new Point(5, 6), new Point(1, 2)])])", 204 | "wkt": "MULTIPOLYGON(((1 2,3 4,5 6,1 2)))", 205 | "wkb": "01060000000100000001030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f0000000000000040", 206 | "ewkb": "0106000020e61000000100000001030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f0000000000000040", 207 | "wkbXdr": "000000000600000001000000000300000001000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff00000000000004000000000000000", 208 | "ewkbXdr": "0020000006000010e600000001000000000300000001000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff00000000000004000000000000000", 209 | "twkb": "a600010104c09a0c80b51880b51880b51880b51880b518ffe930ffe930", 210 | "geoJSON": { 211 | "type": "MultiPolygon", 212 | "coordinates": [[[[1, 2], [3, 4], [5, 6], [1, 2]]]] 213 | }, 214 | "ewkbNoSrid": "01060000000100000001030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f0000000000000040", 215 | "ewkbXdrNoSrid": "000000000600000001000000000300000001000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff00000000000004000000000000000" 216 | }, 217 | "multiPolygonWithTwoPolygons": { 218 | "geometry": "new MultiPolygon([new Polygon([new Point(1, 2), new Point(3, 4), new Point(5, 6), new Point(1, 2)]), new Polygon([new Point(1, 2), new Point(3, 4), new Point(5, 6), new Point(1, 2)], [[new Point(11, 12), new Point(13, 14), new Point(15, 16), new Point(11, 12)], [new Point(21, 22), new Point(23, 24), new Point(25, 26), new Point(21,22)]])])", 219 | "wkt": "MULTIPOLYGON(((1 2,3 4,5 6,1 2)),((1 2,3 4,5 6,1 2),(11 12,13 14,15 16,11 12),(21 22,23 24,25 26,21 22)))", 220 | "wkb": "01060000000200000001030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004001030000000300000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e4000000000000030400000000000002640000000000000284004000000000000000000354000000000000036400000000000003740000000000000384000000000000039400000000000003a4000000000000035400000000000003640", 221 | "ewkb": "0106000020e61000000200000001030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004001030000000300000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e4000000000000030400000000000002640000000000000284004000000000000000000354000000000000036400000000000003740000000000000384000000000000039400000000000003a4000000000000035400000000000003640", 222 | "wkbXdr": "000000000600000002000000000300000001000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff00000000000004000000000000000000000000300000003000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff000000000000040000000000000000000000440260000000000004028000000000000402a000000000000402c000000000000402e0000000000004030000000000000402600000000000040280000000000000000000440350000000000004036000000000000403700000000000040380000000000004039000000000000403a00000000000040350000000000004036000000000000", 223 | "ewkbXdr": "0020000006000010e600000002000000000300000001000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff00000000000004000000000000000000000000300000003000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff000000000000040000000000000000000000440260000000000004028000000000000402a000000000000402c000000000000402e0000000000004030000000000000402600000000000040280000000000000000000440350000000000004036000000000000403700000000000040380000000000004039000000000000403a00000000000040350000000000004036000000000000", 224 | "twkb": "a600020104c09a0c80b51880b51880b51880b51880b518ffe930ffe9300304000080b51880b51880b51880b518ffe930ffe9300480897a80897a80b51880b51880b51880b518ffe930ffe9300480897a80897a80b51880b51880b51880b518ffe930ffe930", 225 | "geoJSON": { 226 | "type": "MultiPolygon", 227 | "coordinates": [ 228 | [[[1, 2], [3, 4], [5, 6], [1, 2]]], 229 | [ 230 | [[1, 2], [3, 4], [5, 6], [1, 2]], 231 | [[11, 12], [13, 14], [15, 16], [11, 12]], 232 | [[21, 22], [23, 24], [25, 26], [21, 22]] 233 | ] 234 | ] 235 | }, 236 | "ewkbNoSrid": "01060000000200000001030000000100000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004001030000000300000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e4000000000000030400000000000002640000000000000284004000000000000000000354000000000000036400000000000003740000000000000384000000000000039400000000000003a4000000000000035400000000000003640", 237 | "ewkbXdrNoSrid": "000000000600000002000000000300000001000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff00000000000004000000000000000000000000300000003000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff000000000000040000000000000000000000440260000000000004028000000000000402a000000000000402c000000000000402e0000000000004030000000000000402600000000000040280000000000000000000440350000000000004036000000000000403700000000000040380000000000004039000000000000403a00000000000040350000000000004036000000000000" 238 | }, 239 | "emptyGeometryCollection": { 240 | "geometry": "new GeometryCollection()", 241 | "wkt": "GEOMETRYCOLLECTION EMPTY", 242 | "wkb": "010700000000000000", 243 | "ewkb": "0107000020e610000000000000", 244 | "wkbXdr": "000000000700000000", 245 | "ewkbXdr": "0020000007000010e600000000", 246 | "twkb": "a710", 247 | "geoJSON": {"type": "GeometryCollection", "geometries": []}, 248 | "ewkbNoSrid": "010700000000000000", 249 | "ewkbXdrNoSrid": "000000000700000000" 250 | }, 251 | "geometryCollectionWithPoint": { 252 | "geometry": "new GeometryCollection([new Point(1, 2)])", 253 | "wkt": "GEOMETRYCOLLECTION(POINT(1 2))", 254 | "wkb": "0107000000010000000101000000000000000000f03f0000000000000040", 255 | "ewkb": "0107000020e6100000010000000101000000000000000000f03f0000000000000040", 256 | "wkbXdr": "00000000070000000100000000013ff00000000000004000000000000000", 257 | "ewkbXdr": "0020000007000010e60000000100000000013ff00000000000004000000000000000", 258 | "twkb": "a70001a100c09a0c80b518", 259 | "geoJSON": { 260 | "type": "GeometryCollection", 261 | "geometries": [{"type": "Point", "coordinates": [1, 2]}] 262 | }, 263 | "ewkbNoSrid": "0107000000010000000101000000000000000000f03f0000000000000040", 264 | "ewkbXdrNoSrid": "00000000070000000100000000013ff00000000000004000000000000000" 265 | }, 266 | "geometryCollectionWithPointAndLineString": { 267 | "geometry": "new GeometryCollection([new Point(1, 2), new LineString([new Point(1, 2), new Point(3, 4)])])", 268 | "wkt": "GEOMETRYCOLLECTION(POINT(1 2),LINESTRING(1 2,3 4))", 269 | "wkb": "0107000000020000000101000000000000000000f03f0000000000000040010200000002000000000000000000f03f000000000000004000000000000008400000000000001040", 270 | "ewkb": "0107000020e6100000020000000101000000000000000000f03f0000000000000040010200000002000000000000000000f03f000000000000004000000000000008400000000000001040", 271 | "wkbXdr": "00000000070000000200000000013ff000000000000040000000000000000000000002000000023ff0000000000000400000000000000040080000000000004010000000000000", 272 | "ewkbXdr": "0020000007000010e60000000200000000013ff000000000000040000000000000000000000002000000023ff0000000000000400000000000000040080000000000004010000000000000", 273 | "twkb": "a70002a100c09a0c80b518a20002c09a0c80b51880b51880b518", 274 | "geoJSON": { 275 | "type": "GeometryCollection", 276 | "geometries": [ 277 | {"type": "Point", "coordinates": [1, 2]}, 278 | {"type": "LineString", "coordinates": [[1, 2], [3, 4]]} 279 | ] 280 | }, 281 | "ewkbNoSrid": "0107000000020000000101000000000000000000f03f0000000000000040010200000002000000000000000000f03f000000000000004000000000000008400000000000001040", 282 | "ewkbXdrNoSrid": "00000000070000000200000000013ff000000000000040000000000000000000000002000000023ff0000000000000400000000000000040080000000000004010000000000000" 283 | }, 284 | "geometryCollectionWithPointAndLineStringAndPolygon": { 285 | "geometry": "new GeometryCollection([new Point(1, 2), new LineString([new Point(1, 2), new Point(3, 4)]), new Polygon([new Point(1, 2), new Point(3,4),new Point(5, 6), new Point(1, 2)], [[new Point(11, 12), new Point(13, 14), new Point(15, 16), new Point(11, 12)], [new Point(21, 22), new Point(23, 24), new Point(25, 26), new Point(21, 22)]])])", 286 | "wkt": "GEOMETRYCOLLECTION(POINT(1 2),LINESTRING(1 2,3 4),POLYGON((1 2,3 4,5 6,1 2),(11 12,13 14,15 16,11 12),(21 22,23 24,25 26,21 22)))", 287 | "wkb": "0107000000030000000101000000000000000000f03f0000000000000040010200000002000000000000000000f03f00000000000000400000000000000840000000000000104001030000000300000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e4000000000000030400000000000002640000000000000284004000000000000000000354000000000000036400000000000003740000000000000384000000000000039400000000000003a4000000000000035400000000000003640", 288 | "ewkb": "0107000020e6100000030000000101000000000000000000f03f0000000000000040010200000002000000000000000000f03f00000000000000400000000000000840000000000000104001030000000300000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e4000000000000030400000000000002640000000000000284004000000000000000000354000000000000036400000000000003740000000000000384000000000000039400000000000003a4000000000000035400000000000003640", 289 | "wkbXdr": "00000000070000000300000000013ff000000000000040000000000000000000000002000000023ff0000000000000400000000000000040080000000000004010000000000000000000000300000003000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff000000000000040000000000000000000000440260000000000004028000000000000402a000000000000402c000000000000402e0000000000004030000000000000402600000000000040280000000000000000000440350000000000004036000000000000403700000000000040380000000000004039000000000000403a00000000000040350000000000004036000000000000", 290 | "ewkbXdr": "0020000007000010e60000000300000000013ff000000000000040000000000000000000000002000000023ff0000000000000400000000000000040080000000000004010000000000000000000000300000003000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff000000000000040000000000000000000000440260000000000004028000000000000402a000000000000402c000000000000402e0000000000004030000000000000402600000000000040280000000000000000000440350000000000004036000000000000403700000000000040380000000000004039000000000000403a00000000000040350000000000004036000000000000", 291 | "twkb": "a70003a100c09a0c80b518a20002c09a0c80b51880b51880b518a3000304c09a0c80b51880b51880b51880b51880b518ffe930ffe9300480897a80897a80b51880b51880b51880b518ffe930ffe9300480897a80897a80b51880b51880b51880b518ffe930ffe930", 292 | "geoJSON": { 293 | "type": "GeometryCollection", 294 | "geometries": [ 295 | {"type": "Point", "coordinates": [1, 2]}, 296 | {"type": "LineString", "coordinates": [[1, 2], [3, 4]]}, 297 | { 298 | "type": "Polygon", 299 | "coordinates": [ 300 | [[1, 2], [3, 4], [5, 6], [1, 2]], 301 | [[11, 12], [13, 14], [15, 16], [11, 12]], 302 | [[21, 22], [23, 24], [25, 26], [21, 22]] 303 | ] 304 | } 305 | ] 306 | }, 307 | "ewkbNoSrid": "0107000000030000000101000000000000000000f03f0000000000000040010200000002000000000000000000f03f00000000000000400000000000000840000000000000104001030000000300000004000000000000000000f03f00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000f03f000000000000004004000000000000000000264000000000000028400000000000002a400000000000002c400000000000002e4000000000000030400000000000002640000000000000284004000000000000000000354000000000000036400000000000003740000000000000384000000000000039400000000000003a4000000000000035400000000000003640", 308 | "ewkbXdrNoSrid": "00000000070000000300000000013ff000000000000040000000000000000000000002000000023ff0000000000000400000000000000040080000000000004010000000000000000000000300000003000000043ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000003ff000000000000040000000000000000000000440260000000000004028000000000000402a000000000000402c000000000000402e0000000000004030000000000000402600000000000040280000000000000000000440350000000000004036000000000000403700000000000040380000000000004039000000000000403a00000000000040350000000000004036000000000000" 309 | } 310 | } -------------------------------------------------------------------------------- /test/testdataM.json: -------------------------------------------------------------------------------- 1 | { 2 | "emptyPoint": { 3 | "geometry": "new Point.M()", 4 | "wkbGeometry": "new Point.M(NaN, NaN, NaN)", 5 | "geoJSONGeometry": "new Point()", 6 | "wkt": "POINT M EMPTY", 7 | "wkb": "01d1070000000000000000f87f000000000000f87f000000000000f87f", 8 | "ewkb": "0101000060e6100000000000000000f87f000000000000f87f000000000000f87f", 9 | "wkbXdr": "00000007d17ff80000000000007ff80000000000007ff8000000000000", 10 | "ewkbXdr": "0060000001000010e67ff80000000000007ff80000000000007ff8000000000000", 11 | "twkb": "a11802", 12 | "geoJSON": {"type": "Point", "coordinates": []}, 13 | "ewkbNoSrid": "0101000040000000000000f87f000000000000f87f000000000000f87f", 14 | "ewkbXdrNoSrid": "00400000017ff80000000000007ff80000000000007ff8000000000000" 15 | }, 16 | "point": { 17 | "geometry": "new Point.M(1, 2, 3)", 18 | "geoJSONGeometry": "new Point(1, 2)", 19 | "wkt": "POINT M (1 2 3)", 20 | "wkb": "01d1070000000000000000f03f00000000000000400000000000000840", 21 | "ewkb": "0101000060e6100000000000000000f03f00000000000000400000000000000840", 22 | "wkbXdr": "00000007d13ff000000000000040000000000000004008000000000000", 23 | "ewkbXdr": "0060000001000010e63ff000000000000040000000000000004008000000000000", 24 | "twkb": "a10802c09a0c80b51806", 25 | "geoJSON": {"type": "Point", "coordinates": [1, 2]}, 26 | "ewkbNoSrid": "0101000040000000000000f03f00000000000000400000000000000840", 27 | "ewkbXdrNoSrid": "00400000013ff000000000000040000000000000004008000000000000" 28 | }, 29 | "emptyLineString": { 30 | "geometry": "new LineString.M()", 31 | "geoJSONGeometry": "new LineString()", 32 | "wkt": "LINESTRING M EMPTY", 33 | "wkb": "01d207000000000000", 34 | "ewkb": "0102000060e610000000000000", 35 | "wkbXdr": "00000007d200000000", 36 | "ewkbXdr": "0060000002000010e600000000", 37 | "twkb": "a21802", 38 | "geoJSON": {"type": "LineString", "coordinates": []}, 39 | "ewkbNoSrid": "010200004000000000", 40 | "ewkbXdrNoSrid": "004000000200000000" 41 | }, 42 | "lineString": { 43 | "geometry": "new LineString.M([new Point.M(1, 2, 1), new Point.M(3, 4, 2)])", 44 | "geoJSONGeometry": "new LineString([new Point(1, 2), new Point(3, 4)])", 45 | "wkt": "LINESTRING M (1 2 1,3 4 2)", 46 | "wkb": "01d207000002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 47 | "ewkb": "0102000060e610000002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 48 | "wkbXdr": "00000007d2000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000", 49 | "ewkbXdr": "0060000002000010e6000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000", 50 | "twkb": "a2080202c09a0c80b5180280b51880b51802", 51 | "geoJSON": {"type": "LineString", "coordinates": [[1, 2], [3, 4]]}, 52 | "ewkbNoSrid": "010200004002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 53 | "ewkbXdrNoSrid": "0040000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000" 54 | }, 55 | "emptyPolygon": { 56 | "geometry": "new Polygon.M()", 57 | "geoJSONGeometry": "new Polygon()", 58 | "wkt": "POLYGON M EMPTY", 59 | "wkb": "01d307000000000000", 60 | "ewkb": "0103000060e610000000000000", 61 | "wkbXdr": "00000007d300000000", 62 | "ewkbXdr": "0060000003000010e600000000", 63 | "twkb": "a31802", 64 | "geoJSON": {"type": "Polygon", "coordinates": []}, 65 | "ewkbNoSrid": "010300004000000000", 66 | "ewkbXdrNoSrid": "004000000300000000" 67 | }, 68 | "polygon": { 69 | "geometry": "new Polygon.M([new Point.M(1, 2, 1), new Point.M(3, 4, 2), new Point.M(5, 6, 3), new Point.M(1, 2, 1)])", 70 | "geoJSONGeometry": "new Polygon([new Point(1, 2), new Point(3, 4), new Point(5, 6), new Point(1, 2)])", 71 | "wkt": "POLYGON M ((1 2 1,3 4 2,5 6 3,1 2 1))", 72 | "wkb": "01d30700000100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f", 73 | "ewkb": "0103000060e61000000100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f", 74 | "wkbXdr": "00000007d300000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000", 75 | "ewkbXdr": "0060000003000010e600000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000", 76 | "twkb": "a308020104c09a0c80b5180280b51880b5180280b51880b51802ffe930ffe93003", 77 | "geoJSON": { 78 | "type": "Polygon", 79 | "coordinates": [[[1, 2], [3, 4], [5, 6], [1, 2]]] 80 | }, 81 | "ewkbNoSrid": "01030000400100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f", 82 | "ewkbXdrNoSrid": "004000000300000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000" 83 | }, 84 | "polygonWithOneInteriorRing": { 85 | "geometry": "new Polygon.M([new Point.M(1, 2, 1), new Point.M(3, 4, 2), new Point.M(5, 6, 3), new Point.M(1, 2, 1)], [[new Point.M(11, 12, 4), new Point.M(13, 14, 5), new Point.M(15, 16, 6), new Point.M(11, 12, 4)]])", 86 | "geoJSONGeometry": "new Polygon([new Point(1, 2), new Point(3, 4), new Point(5, 6), new Point(1, 2)], [[new Point(11, 12), new Point(13, 14), new Point(15, 16), new Point(11, 12)]])", 87 | "wkt": "POLYGON M ((1 2 1,3 4 2,5 6 3,1 2 1),(11 12 4,13 14 5,15 16 6,11 12 4))", 88 | "wkb": "01d30700000200000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e4000000000000030400000000000001840000000000000264000000000000028400000000000001040", 89 | "ewkb": "0103000060e61000000200000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e4000000000000030400000000000001840000000000000264000000000000028400000000000001040", 90 | "wkbXdr": "00000007d300000002000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e00000000000040300000000000004018000000000000402600000000000040280000000000004010000000000000", 91 | "ewkbXdr": "0060000003000010e600000002000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e00000000000040300000000000004018000000000000402600000000000040280000000000004010000000000000", 92 | "twkb": "a308020204c09a0c80b5180280b51880b5180280b51880b51802ffe930ffe930030480897a80897a0680b51880b5180280b51880b51802ffe930ffe93003", 93 | "geoJSON": { 94 | "type": "Polygon", 95 | "coordinates": [ 96 | [[1, 2], [3, 4], [5, 6], [1, 2]], 97 | [[11, 12], [13, 14], [15, 16], [11, 12]] 98 | ] 99 | }, 100 | "ewkbNoSrid": "01030000400200000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e4000000000000030400000000000001840000000000000264000000000000028400000000000001040", 101 | "ewkbXdrNoSrid": "004000000300000002000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e00000000000040300000000000004018000000000000402600000000000040280000000000004010000000000000" 102 | }, 103 | "polygonWithTwoInteriorRings": { 104 | "geometry": "new Polygon.M([new Point.M(1, 2, 1), new Point.M(3, 4, 2), new Point.M(5, 6, 3), new Point.M(1, 2, 1)], [[new Point.M(11, 12, 4), new Point.M(13, 14, 5), new Point.M(15, 16, 6), new Point.M(11, 12, 4)], [new Point.M(21, 22, 7), new Point.M(23, 24, 8), new Point.M(25, 26, 9), new Point.M(21, 22, 7)]])", 105 | "geoJSONGeometry": "new Polygon([new Point(1, 2), new Point(3, 4), new Point(5, 6), new Point(1, 2)], [[new Point(11, 12), new Point(13, 14), new Point(15, 16), new Point(11, 12)], [new Point(21, 22), new Point(23, 24), new Point(25, 26), new Point(21, 22)]])", 106 | "wkt": "POLYGON M ((1 2 1,3 4 2,5 6 3,1 2 1),(11 12 4,13 14 5,15 16 6,11 12 4),(21 22 7,23 24 8,25 26 9,21 22 7))", 107 | "wkb": "01d30700000300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 108 | "ewkb": "0103000060e61000000300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 109 | "wkbXdr": "00000007d300000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000", 110 | "ewkbXdr": "0060000003000010e600000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000", 111 | "twkb": "a308020304c09a0c80b5180280b51880b5180280b51880b51802ffe930ffe930030480897a80897a0680b51880b5180280b51880b51802ffe930ffe930030480897a80897a0680b51880b5180280b51880b51802ffe930ffe93003", 112 | "geoJSON": { 113 | "type": "Polygon", 114 | "coordinates": [ 115 | [[1, 2], [3, 4], [5, 6], [1, 2]], 116 | [[11, 12], [13, 14], [15, 16], [11, 12]], 117 | [[21, 22], [23, 24], [25, 26], [21, 22]] 118 | ] 119 | }, 120 | "ewkbNoSrid": "01030000400300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 121 | "ewkbXdrNoSrid": "004000000300000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000" 122 | }, 123 | "emptyMultiPoint": { 124 | "geometry": "new MultiPoint.M()", 125 | "geoJSONGeometry": "new MultiPoint()", 126 | "wkt": "MULTIPOINT M EMPTY", 127 | "wkb": "01d407000000000000", 128 | "ewkb": "0104000060e610000000000000", 129 | "wkbXdr": "00000007d400000000", 130 | "ewkbXdr": "0060000004000010e600000000", 131 | "twkb": "a41802", 132 | "geoJSON": {"type": "MultiPoint", "coordinates": []}, 133 | "ewkbNoSrid": "010400004000000000", 134 | "ewkbXdrNoSrid": "004000000400000000" 135 | }, 136 | "multiPointWithOnePoint": { 137 | "geometry": "new MultiPoint.M([new Point.M(1, 2, 1)])", 138 | "geoJSONGeometry": "new MultiPoint([new Point(1, 2)])", 139 | "wkt": "MULTIPOINT M (1 2 1)", 140 | "wkb": "01d40700000100000001d1070000000000000000f03f0000000000000040000000000000f03f", 141 | "ewkb": "0104000060e6100000010000000101000040000000000000f03f0000000000000040000000000000f03f", 142 | "wkbXdr": "00000007d40000000100000007d13ff000000000000040000000000000003ff0000000000000", 143 | "ewkbXdr": "0060000004000010e60000000100400000013ff000000000000040000000000000003ff0000000000000", 144 | "twkb": "a4080201c09a0c80b51802", 145 | "geoJSON": {"type": "MultiPoint", "coordinates": [[1, 2]]}, 146 | "ewkbNoSrid": "0104000040010000000101000040000000000000f03f0000000000000040000000000000f03f", 147 | "ewkbXdrNoSrid": "00400000040000000100400000013ff000000000000040000000000000003ff0000000000000" 148 | }, 149 | "multiPointWithTwoPoints": { 150 | "geometry": "new MultiPoint.M([new Point.M(1, 2, 1), new Point.M(3, 4, 2)])", 151 | "geoJSONGeometry": "new MultiPoint([new Point(1, 2), new Point(3, 4)])", 152 | "wkt": "MULTIPOINT M (1 2 1,3 4 2)", 153 | "wkb": "01d40700000200000001d1070000000000000000f03f0000000000000040000000000000f03f01d1070000000000000000084000000000000010400000000000000040", 154 | "ewkb": "0104000060e6100000020000000101000040000000000000f03f0000000000000040000000000000f03f0101000040000000000000084000000000000010400000000000000040", 155 | "wkbXdr": "00000007d40000000200000007d13ff000000000000040000000000000003ff000000000000000000007d1400800000000000040100000000000004000000000000000", 156 | "ewkbXdr": "0060000004000010e60000000200400000013ff000000000000040000000000000003ff00000000000000040000001400800000000000040100000000000004000000000000000", 157 | "twkb": "a4080202c09a0c80b5180280b51880b51802", 158 | "geoJSON": {"type": "MultiPoint", "coordinates": [[1, 2], [3, 4]]}, 159 | "ewkbNoSrid": "0104000040020000000101000040000000000000f03f0000000000000040000000000000f03f0101000040000000000000084000000000000010400000000000000040", 160 | "ewkbXdrNoSrid": "00400000040000000200400000013ff000000000000040000000000000003ff00000000000000040000001400800000000000040100000000000004000000000000000" 161 | }, 162 | "emptyMultiLineString": { 163 | "geometry": "new MultiLineString.M()", 164 | "geoJSONGeometry": "new MultiLineString()", 165 | "wkt": "MULTILINESTRING M EMPTY", 166 | "wkb": "01d507000000000000", 167 | "ewkb": "0105000060e610000000000000", 168 | "wkbXdr": "00000007d500000000", 169 | "ewkbXdr": "0060000005000010e600000000", 170 | "twkb": "a51802", 171 | "geoJSON": {"type": "MultiLineString", "coordinates": []}, 172 | "ewkbNoSrid": "010500004000000000", 173 | "ewkbXdrNoSrid": "004000000500000000" 174 | }, 175 | "multiLineStringWithOneLineString": { 176 | "geometry": "new MultiLineString.M([new LineString.M([new Point.M(1, 2, 1), new Point.M(3, 4, 2)])])", 177 | "geoJSONGeometry": "new MultiLineString([new LineString([new Point(1, 2), new Point(3, 4)])])", 178 | "wkt": "MULTILINESTRING M ((1 2 1,3 4 2))", 179 | "wkb": "01d50700000100000001d207000002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 180 | "ewkb": "0105000060e610000001000000010200004002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 181 | "wkbXdr": "00000007d50000000100000007d2000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000", 182 | "ewkbXdr": "0060000005000010e6000000010040000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000", 183 | "twkb": "a508020102c09a0c80b5180280b51880b51802", 184 | "geoJSON": {"type": "MultiLineString", "coordinates": [[[1, 2], [3, 4]]]}, 185 | "ewkbNoSrid": "010500004001000000010200004002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 186 | "ewkbXdrNoSrid": "0040000005000000010040000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000" 187 | }, 188 | "multiLineStringWithTwoLineStrings": { 189 | "geometry": "new MultiLineString.M([new LineString.M([new Point.M(1, 2, 1), new Point.M(3, 4, 2)]), new LineString.M([new Point.M(5, 6, 3), new Point.M(7, 8, 4)])])", 190 | "geoJSONGeometry": "new MultiLineString([new LineString([new Point(1, 2), new Point(3, 4)]), new LineString([new Point(5, 6), new Point(7, 8)])])", 191 | "wkt": "MULTILINESTRING M ((1 2 1,3 4 2),(5 6 3,7 8 4))", 192 | "wkb": "01d50700000200000001d207000002000000000000000000f03f0000000000000040000000000000f03f00000000000008400000000000001040000000000000004001d2070000020000000000000000001440000000000000184000000000000008400000000000001c4000000000000020400000000000001040", 193 | "ewkb": "0105000060e610000002000000010200004002000000000000000000f03f0000000000000040000000000000f03f0000000000000840000000000000104000000000000000400102000040020000000000000000001440000000000000184000000000000008400000000000001c4000000000000020400000000000001040", 194 | "wkbXdr": "00000007d50000000200000007d2000000023ff000000000000040000000000000003ff000000000000040080000000000004010000000000000400000000000000000000007d200000002401400000000000040180000000000004008000000000000401c00000000000040200000000000004010000000000000", 195 | "ewkbXdr": "0060000005000010e6000000020040000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000004000000200000002401400000000000040180000000000004008000000000000401c00000000000040200000000000004010000000000000", 196 | "twkb": "a508020202c09a0c80b5180280b51880b518020280b51880b5180280b51880b51802", 197 | "geoJSON": { 198 | "type": "MultiLineString", 199 | "coordinates": [[[1, 2], [3, 4]], [[5, 6], [7, 8]]] 200 | }, 201 | "ewkbNoSrid": "010500004002000000010200004002000000000000000000f03f0000000000000040000000000000f03f0000000000000840000000000000104000000000000000400102000040020000000000000000001440000000000000184000000000000008400000000000001c4000000000000020400000000000001040", 202 | "ewkbXdrNoSrid": "0040000005000000020040000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000004000000200000002401400000000000040180000000000004008000000000000401c00000000000040200000000000004010000000000000" 203 | }, 204 | "emptyMultiPolygon": { 205 | "geometry": "new MultiPolygon.M()", 206 | "geoJSONGeometry": "new MultiPolygon()", 207 | "wkt": "MULTIPOLYGON M EMPTY", 208 | "wkb": "01d607000000000000", 209 | "ewkb": "0106000060e610000000000000", 210 | "wkbXdr": "00000007d600000000", 211 | "ewkbXdr": "0060000006000010e600000000", 212 | "twkb": "a61802", 213 | "geoJSON": {"type": "MultiPolygon", "coordinates": []}, 214 | "ewkbNoSrid": "010600004000000000", 215 | "ewkbXdrNoSrid": "004000000600000000" 216 | }, 217 | "multiPolygonWithOnePolygon": { 218 | "geometry": "new MultiPolygon.M([new Polygon.M([new Point.M(1, 2, 1), new Point.M(3, 4, 2), new Point.M(5, 6, 3), new Point.M(1, 2, 1)])])", 219 | "geoJSONGeometry": "new MultiPolygon([new Polygon([new Point(1, 2), new Point(3, 4), new Point(5, 6), new Point(1, 2)])])", 220 | "wkt": "MULTIPOLYGON M (((1 2 1,3 4 2,5 6 3,1 2 1)))", 221 | "wkb": "01d60700000100000001d30700000100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f", 222 | "ewkb": "0106000060e61000000100000001030000400100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f", 223 | "wkbXdr": "00000007d60000000100000007d300000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000", 224 | "ewkbXdr": "0060000006000010e600000001004000000300000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000", 225 | "twkb": "a60802010104c09a0c80b5180280b51880b5180280b51880b51802ffe930ffe93003", 226 | "geoJSON": { 227 | "type": "MultiPolygon", 228 | "coordinates": [[[[1, 2], [3, 4], [5, 6], [1, 2]]]] 229 | }, 230 | "ewkbNoSrid": "01060000400100000001030000400100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f", 231 | "ewkbXdrNoSrid": "004000000600000001004000000300000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000" 232 | }, 233 | "multiPolygonWithTwoPolygons": { 234 | "geometry": "new MultiPolygon.M([new Polygon.M([new Point.M(1, 2, 1), new Point.M(3, 4, 2), new Point.M(5, 6, 3), new Point.M(1, 2, 1)]), new Polygon.M([new Point.M(1, 2, 1), new Point.M(3, 4, 2), new Point.M(5, 6, 3), new Point.M(1, 2, 1)], [[new Point.M(11, 12, 4), new Point.M(13, 14, 5), new Point.M(15, 16, 6), new Point.M(11, 12, 4)], [new Point.M(21, 22, 7), new Point.M(23, 24, 8), new Point.M(25, 26, 9), new Point.M(21,22, 7)]])])", 235 | "geoJSONGeometry": "new MultiPolygon([new Polygon([new Point(1, 2), new Point(3, 4), new Point(5, 6), new Point(1, 2)]), new Polygon([new Point(1, 2), new Point(3, 4), new Point(5, 6), new Point(1, 2)], [[new Point(11, 12), new Point(13, 14), new Point(15, 16), new Point(11, 12)], [new Point(21, 22), new Point(23, 24), new Point(25, 26), new Point(21,22)]])])", 236 | "wkt": "MULTIPOLYGON M (((1 2 1,3 4 2,5 6 3,1 2 1)),((1 2 1,3 4 2,5 6 3,1 2 1),(11 12 4,13 14 5,15 16 6,11 12 4),(21 22 7,23 24 8,25 26 9,21 22 7)))", 237 | "wkb": "01d60700000200000001d30700000100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f01d30700000300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 238 | "ewkb": "0106000060e61000000200000001030000400100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f01030000400300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 239 | "wkbXdr": "00000007d60000000200000007d300000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000007d300000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000", 240 | "ewkbXdr": "0060000006000010e600000002004000000300000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000004000000300000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000", 241 | "twkb": "a60802020104c09a0c80b5180280b51880b5180280b51880b51802ffe930ffe93003030400000080b51880b5180280b51880b51802ffe930ffe930030480897a80897a0680b51880b5180280b51880b51802ffe930ffe930030480897a80897a0680b51880b5180280b51880b51802ffe930ffe93003", 242 | "geoJSON": { 243 | "type": "MultiPolygon", 244 | "coordinates": [ 245 | [[[1, 2], [3, 4], [5, 6], [1, 2]]], 246 | [ 247 | [[1, 2], [3, 4], [5, 6], [1, 2]], 248 | [[11, 12], [13, 14], [15, 16], [11, 12]], 249 | [[21, 22], [23, 24], [25, 26], [21, 22]] 250 | ] 251 | ] 252 | }, 253 | "ewkbNoSrid": "01060000400200000001030000400100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f01030000400300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 254 | "ewkbXdrNoSrid": "004000000600000002004000000300000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000004000000300000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000" 255 | }, 256 | "emptyGeometryCollection": { 257 | "geometry": "new GeometryCollection.M()", 258 | "geoJSONGeometry": "new GeometryCollection()", 259 | "wkt": "GEOMETRYCOLLECTION M EMPTY", 260 | "wkb": "01d707000000000000", 261 | "ewkb": "0107000060e610000000000000", 262 | "wkbXdr": "00000007d700000000", 263 | "ewkbXdr": "0060000007000010e600000000", 264 | "twkb": "a71802", 265 | "geoJSON": {"type": "GeometryCollection", "geometries": []}, 266 | "ewkbNoSrid": "010700004000000000", 267 | "ewkbXdrNoSrid": "004000000700000000" 268 | }, 269 | "geometryCollectionWithPoint": { 270 | "geometry": "new GeometryCollection.M([new Point.M(1, 2, 1)])", 271 | "geoJSONGeometry": "new GeometryCollection([new Point(1, 2)])", 272 | "wkt": "GEOMETRYCOLLECTION M (POINT M (1 2 1))", 273 | "wkb": "01d70700000100000001d1070000000000000000f03f0000000000000040000000000000f03f", 274 | "ewkb": "0107000060e6100000010000000101000040000000000000f03f0000000000000040000000000000f03f", 275 | "wkbXdr": "00000007d70000000100000007d13ff000000000000040000000000000003ff0000000000000", 276 | "ewkbXdr": "0060000007000010e60000000100400000013ff000000000000040000000000000003ff0000000000000", 277 | "twkb": "a7080201a10802c09a0c80b51802", 278 | "geoJSON": { 279 | "type": "GeometryCollection", 280 | "geometries": [{"type": "Point", "coordinates": [1, 2]}] 281 | }, 282 | "ewkbNoSrid": "0107000040010000000101000040000000000000f03f0000000000000040000000000000f03f", 283 | "ewkbXdrNoSrid": "00400000070000000100400000013ff000000000000040000000000000003ff0000000000000" 284 | }, 285 | "geometryCollectionWithPointAndLineString": { 286 | "geometry": "new GeometryCollection.M([new Point.M(1, 2, 1), new LineString.M([new Point.M(1, 2, 1), new Point.M(3, 4, 2)])])", 287 | "geoJSONGeometry": "new GeometryCollection([new Point(1, 2), new LineString([new Point(1, 2), new Point(3, 4)])])", 288 | "wkt": "GEOMETRYCOLLECTION M (POINT M (1 2 1),LINESTRING M (1 2 1,3 4 2))", 289 | "wkb": "01d70700000200000001d1070000000000000000f03f0000000000000040000000000000f03f01d207000002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 290 | "ewkb": "0107000060e6100000020000000101000040000000000000f03f0000000000000040000000000000f03f010200004002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 291 | "wkbXdr": "00000007d70000000200000007d13ff000000000000040000000000000003ff000000000000000000007d2000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000", 292 | "ewkbXdr": "0060000007000010e60000000200400000013ff000000000000040000000000000003ff00000000000000040000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000", 293 | "twkb": "a7080202a10802c09a0c80b51802a2080202c09a0c80b5180280b51880b51802", 294 | "geoJSON": { 295 | "type": "GeometryCollection", 296 | "geometries": [ 297 | {"type": "Point", "coordinates": [1, 2]}, 298 | {"type": "LineString", "coordinates": [[1, 2], [3, 4]]} 299 | ] 300 | }, 301 | "ewkbNoSrid": "0107000040020000000101000040000000000000f03f0000000000000040000000000000f03f010200004002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 302 | "ewkbXdrNoSrid": "00400000070000000200400000013ff000000000000040000000000000003ff00000000000000040000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000" 303 | }, 304 | "geometryCollectionWithPointAndLineStringAndPolygon": { 305 | "geometry": "new GeometryCollection.M([new Point.M(1, 2, 1), new LineString.M([new Point.M(1, 2, 1), new Point.M(3, 4, 2)]), new Polygon.M([new Point.M(1, 2, 1), new Point.M(3, 4, 2), new Point.M(5, 6, 3), new Point.M(1, 2, 1)], [[new Point.M(11, 12, 4), new Point.M(13, 14, 5), new Point.M(15, 16, 6), new Point.M(11, 12, 4)], [new Point.M(21, 22, 7), new Point.M(23, 24, 8), new Point.M(25, 26, 9), new Point.M(21, 22, 7)]])])", 306 | "geoJSONGeometry": "new GeometryCollection([new Point(1, 2), new LineString([new Point(1, 2), new Point(3, 4)]), new Polygon([new Point(1, 2), new Point(3, 4), new Point(5, 6), new Point(1, 2)], [[new Point(11, 12), new Point(13, 14), new Point(15, 16), new Point(11, 12)], [new Point(21, 22), new Point(23, 24), new Point(25, 26), new Point(21, 22)]])])", 307 | "wkt": "GEOMETRYCOLLECTION M (POINT M (1 2 1),LINESTRING M (1 2 1,3 4 2),POLYGON M ((1 2 1,3 4 2,5 6 3,1 2 1),(11 12 4,13 14 5,15 16 6,11 12 4),(21 22 7,23 24 8,25 26 9,21 22 7)))", 308 | "wkb": "01d70700000300000001d1070000000000000000f03f0000000000000040000000000000f03f01d207000002000000000000000000f03f0000000000000040000000000000f03f00000000000008400000000000001040000000000000004001d30700000300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 309 | "ewkb": "0107000060e6100000030000000101000040000000000000f03f0000000000000040000000000000f03f010200004002000000000000000000f03f0000000000000040000000000000f03f00000000000008400000000000001040000000000000004001030000400300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 310 | "wkbXdr": "00000007d70000000300000007d13ff000000000000040000000000000003ff000000000000000000007d2000000023ff000000000000040000000000000003ff000000000000040080000000000004010000000000000400000000000000000000007d300000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000", 311 | "ewkbXdr": "0060000007000010e60000000300400000013ff000000000000040000000000000003ff00000000000000040000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000004000000300000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000", 312 | "twkb": "a7080203a10802c09a0c80b51802a2080202c09a0c80b5180280b51880b51802a308020304c09a0c80b5180280b51880b5180280b51880b51802ffe930ffe930030480897a80897a0680b51880b5180280b51880b51802ffe930ffe930030480897a80897a0680b51880b5180280b51880b51802ffe930ffe93003", 313 | "geoJSON": { 314 | "type": "GeometryCollection", 315 | "geometries": [ 316 | {"type": "Point", "coordinates": [1, 2]}, 317 | {"type": "LineString", "coordinates": [[1, 2], [3, 4]]}, 318 | { 319 | "type": "Polygon", 320 | "coordinates": [ 321 | [[1, 2], [3, 4], [5, 6], [1, 2]], 322 | [[11, 12], [13, 14], [15, 16], [11, 12]], 323 | [[21, 22], [23, 24], [25, 26], [21, 22]] 324 | ] 325 | } 326 | ] 327 | }, 328 | "ewkbNoSrid": "0107000040030000000101000040000000000000f03f0000000000000040000000000000f03f010200004002000000000000000000f03f0000000000000040000000000000f03f00000000000008400000000000001040000000000000004001030000400300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 329 | "ewkbXdrNoSrid": "00400000070000000300400000013ff000000000000040000000000000003ff00000000000000040000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000004000000300000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000" 330 | } 331 | } -------------------------------------------------------------------------------- /test/testdataZ.json: -------------------------------------------------------------------------------- 1 | { 2 | "emptyPoint": { 3 | "geometry": "new Point.Z()", 4 | "wkbGeometry": "new Point.Z(NaN, NaN, NaN)", 5 | "geoJSONGeometry": "new Point()", 6 | "wkt": "POINT Z EMPTY", 7 | "wkb": "01e9030000000000000000f87f000000000000f87f000000000000f87f", 8 | "ewkb": "01010000a0e6100000000000000000f87f000000000000f87f000000000000f87f", 9 | "wkbXdr": "00000003e97ff80000000000007ff80000000000007ff8000000000000", 10 | "ewkbXdr": "00a0000001000010e67ff80000000000007ff80000000000007ff8000000000000", 11 | "twkb": "a11801", 12 | "geoJSON": {"type": "Point", "coordinates": []}, 13 | "ewkbNoSrid": "0101000080000000000000f87f000000000000f87f000000000000f87f", 14 | "ewkbXdrNoSrid": "00800000017ff80000000000007ff80000000000007ff8000000000000" 15 | }, 16 | "point": { 17 | "geometry": "new Point.Z(1, 2, 3)", 18 | "wkt": "POINT Z (1 2 3)", 19 | "wkb": "01e9030000000000000000f03f00000000000000400000000000000840", 20 | "ewkb": "01010000a0e6100000000000000000f03f00000000000000400000000000000840", 21 | "wkbXdr": "00000003e93ff000000000000040000000000000004008000000000000", 22 | "ewkbXdr": "00a0000001000010e63ff000000000000040000000000000004008000000000000", 23 | "twkb": "a10801c09a0c80b51806", 24 | "geoJSON": {"type": "Point", "coordinates": [1, 2, 3]}, 25 | "ewkbNoSrid": "0101000080000000000000f03f00000000000000400000000000000840", 26 | "ewkbXdrNoSrid": "00800000013ff000000000000040000000000000004008000000000000" 27 | }, 28 | "emptyLineString": { 29 | "geometry": "new LineString.Z()", 30 | "geoJSONGeometry": "new LineString()", 31 | "wkt": "LINESTRING Z EMPTY", 32 | "wkb": "01ea03000000000000", 33 | "ewkb": "01020000a0e610000000000000", 34 | "wkbXdr": "00000003ea00000000", 35 | "ewkbXdr": "00a0000002000010e600000000", 36 | "twkb": "a21801", 37 | "geoJSON": {"type": "LineString", "coordinates": []}, 38 | "ewkbNoSrid": "010200008000000000", 39 | "ewkbXdrNoSrid": "008000000200000000" 40 | }, 41 | "lineString": { 42 | "geometry": "new LineString.Z([new Point(1, 2, 1), new Point(3, 4, 2)])", 43 | "wkt": "LINESTRING Z (1 2 1,3 4 2)", 44 | "wkb": "01ea03000002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 45 | "ewkb": "01020000a0e610000002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 46 | "wkbXdr": "00000003ea000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000", 47 | "ewkbXdr": "00a0000002000010e6000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000", 48 | "twkb": "a2080102c09a0c80b5180280b51880b51802", 49 | "geoJSON": {"type": "LineString", "coordinates": [[1, 2, 1], [3, 4, 2]]}, 50 | "ewkbNoSrid": "010200008002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 51 | "ewkbXdrNoSrid": "0080000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000" 52 | }, 53 | "emptyPolygon": { 54 | "geometry": "new Polygon.Z()", 55 | "geoJSONGeometry": "new Polygon()", 56 | "wkt": "POLYGON Z EMPTY", 57 | "wkb": "01eb03000000000000", 58 | "ewkb": "01030000a0e610000000000000", 59 | "wkbXdr": "00000003eb00000000", 60 | "ewkbXdr": "00a0000003000010e600000000", 61 | "twkb": "a31801", 62 | "geoJSON": {"type": "Polygon", "coordinates": []}, 63 | "ewkbNoSrid": "010300008000000000", 64 | "ewkbXdrNoSrid": "008000000300000000" 65 | }, 66 | "polygon": { 67 | "geometry": "new Polygon.Z([new Point(1, 2, 1), new Point(3, 4, 2), new Point(5, 6, 3), new Point(1, 2, 1)])", 68 | "wkt": "POLYGON Z ((1 2 1,3 4 2,5 6 3,1 2 1))", 69 | "wkb": "01eb0300000100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f", 70 | "ewkb": "01030000a0e61000000100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f", 71 | "wkbXdr": "00000003eb00000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000", 72 | "ewkbXdr": "00a0000003000010e600000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000", 73 | "twkb": "a308010104c09a0c80b5180280b51880b5180280b51880b51802ffe930ffe93003", 74 | "geoJSON": { 75 | "type": "Polygon", 76 | "coordinates": [[[1, 2, 1], [3, 4, 2], [5, 6, 3], [1, 2, 1]]] 77 | }, 78 | "ewkbNoSrid": "01030000800100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f", 79 | "ewkbXdrNoSrid": "008000000300000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000" 80 | }, 81 | "polygonWithOneInteriorRing": { 82 | "geometry": "new Polygon.Z([new Point(1, 2, 1), new Point(3, 4, 2), new Point(5, 6, 3), new Point(1, 2, 1)], [[new Point(11, 12, 4), new Point(13, 14, 5), new Point(15, 16, 6), new Point(11, 12, 4)]])", 83 | "wkt": "POLYGON Z ((1 2 1,3 4 2,5 6 3,1 2 1),(11 12 4,13 14 5,15 16 6,11 12 4))", 84 | "wkb": "01eb0300000200000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e4000000000000030400000000000001840000000000000264000000000000028400000000000001040", 85 | "ewkb": "01030000a0e61000000200000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e4000000000000030400000000000001840000000000000264000000000000028400000000000001040", 86 | "wkbXdr": "00000003eb00000002000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e00000000000040300000000000004018000000000000402600000000000040280000000000004010000000000000", 87 | "ewkbXdr": "00a0000003000010e600000002000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e00000000000040300000000000004018000000000000402600000000000040280000000000004010000000000000", 88 | "twkb": "a308010204c09a0c80b5180280b51880b5180280b51880b51802ffe930ffe930030480897a80897a0680b51880b5180280b51880b51802ffe930ffe93003", 89 | "geoJSON": { 90 | "type": "Polygon", 91 | "coordinates": [ 92 | [[1, 2, 1], [3, 4, 2], [5, 6, 3], [1, 2, 1]], 93 | [[11, 12, 4], [13, 14, 5], [15, 16, 6], [11, 12, 4]] 94 | ] 95 | }, 96 | "ewkbNoSrid": "01030000800200000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e4000000000000030400000000000001840000000000000264000000000000028400000000000001040", 97 | "ewkbXdrNoSrid": "008000000300000002000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e00000000000040300000000000004018000000000000402600000000000040280000000000004010000000000000" 98 | }, 99 | "polygonWithTwoInteriorRings": { 100 | "geometry": "new Polygon.Z([new Point(1, 2, 1), new Point(3, 4, 2), new Point(5, 6, 3), new Point(1, 2, 1)], [[new Point(11, 12, 4), new Point(13, 14, 5), new Point(15, 16, 6), new Point(11, 12, 4)], [new Point(21, 22, 7), new Point(23, 24, 8), new Point(25, 26, 9), new Point(21, 22, 7)]])", 101 | "wkt": "POLYGON Z ((1 2 1,3 4 2,5 6 3,1 2 1),(11 12 4,13 14 5,15 16 6,11 12 4),(21 22 7,23 24 8,25 26 9,21 22 7))", 102 | "wkb": "01eb0300000300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 103 | "ewkb": "01030000a0e61000000300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 104 | "wkbXdr": "00000003eb00000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000", 105 | "ewkbXdr": "00a0000003000010e600000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000", 106 | "twkb": "a308010304c09a0c80b5180280b51880b5180280b51880b51802ffe930ffe930030480897a80897a0680b51880b5180280b51880b51802ffe930ffe930030480897a80897a0680b51880b5180280b51880b51802ffe930ffe93003", 107 | "geoJSON": { 108 | "type": "Polygon", 109 | "coordinates": [ 110 | [[1, 2, 1], [3, 4, 2], [5, 6, 3], [1, 2, 1]], 111 | [[11, 12, 4], [13, 14, 5], [15, 16, 6], [11, 12, 4]], 112 | [[21, 22, 7], [23, 24, 8], [25, 26, 9], [21, 22, 7]] 113 | ] 114 | }, 115 | "ewkbNoSrid": "01030000800300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 116 | "ewkbXdrNoSrid": "008000000300000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000" 117 | }, 118 | "emptyMultiPoint": { 119 | "geometry": "new MultiPoint.Z()", 120 | "geoJSONGeometry": "new MultiPoint()", 121 | "wkt": "MULTIPOINT Z EMPTY", 122 | "wkb": "01ec03000000000000", 123 | "ewkb": "01040000a0e610000000000000", 124 | "wkbXdr": "00000003ec00000000", 125 | "ewkbXdr": "00a0000004000010e600000000", 126 | "twkb": "a41801", 127 | "geoJSON": {"type": "MultiPoint", "coordinates": []}, 128 | "ewkbNoSrid": "010400008000000000", 129 | "ewkbXdrNoSrid": "008000000400000000" 130 | }, 131 | "multiPointWithOnePoint": { 132 | "geometry": "new MultiPoint.Z([new Point(1, 2, 1)])", 133 | "wkt": "MULTIPOINT Z (1 2 1)", 134 | "wkb": "01ec0300000100000001e9030000000000000000f03f0000000000000040000000000000f03f", 135 | "ewkb": "01040000a0e6100000010000000101000080000000000000f03f0000000000000040000000000000f03f", 136 | "wkbXdr": "00000003ec0000000100000003e93ff000000000000040000000000000003ff0000000000000", 137 | "ewkbXdr": "00a0000004000010e60000000100800000013ff000000000000040000000000000003ff0000000000000", 138 | "twkb": "a4080101c09a0c80b51802", 139 | "geoJSON": {"type": "MultiPoint", "coordinates": [[1, 2, 1]]}, 140 | "ewkbNoSrid": "0104000080010000000101000080000000000000f03f0000000000000040000000000000f03f", 141 | "ewkbXdrNoSrid": "00800000040000000100800000013ff000000000000040000000000000003ff0000000000000" 142 | }, 143 | "multiPointWithTwoPoints": { 144 | "geometry": "new MultiPoint.Z([new Point(1, 2, 1), new Point(3, 4, 2)])", 145 | "wkt": "MULTIPOINT Z (1 2 1,3 4 2)", 146 | "wkb": "01ec0300000200000001e9030000000000000000f03f0000000000000040000000000000f03f01e9030000000000000000084000000000000010400000000000000040", 147 | "ewkb": "01040000a0e6100000020000000101000080000000000000f03f0000000000000040000000000000f03f0101000080000000000000084000000000000010400000000000000040", 148 | "wkbXdr": "00000003ec0000000200000003e93ff000000000000040000000000000003ff000000000000000000003e9400800000000000040100000000000004000000000000000", 149 | "ewkbXdr": "00a0000004000010e60000000200800000013ff000000000000040000000000000003ff00000000000000080000001400800000000000040100000000000004000000000000000", 150 | "twkb": "a4080102c09a0c80b5180280b51880b51802", 151 | "geoJSON": {"type": "MultiPoint", "coordinates": [[1, 2, 1], [3, 4, 2]]}, 152 | "ewkbNoSrid": "0104000080020000000101000080000000000000f03f0000000000000040000000000000f03f0101000080000000000000084000000000000010400000000000000040", 153 | "ewkbXdrNoSrid": "00800000040000000200800000013ff000000000000040000000000000003ff00000000000000080000001400800000000000040100000000000004000000000000000" 154 | }, 155 | "emptyMultiLineString": { 156 | "geometry": "new MultiLineString.Z()", 157 | "geoJSONGeometry": "new MultiLineString()", 158 | "wkt": "MULTILINESTRING Z EMPTY", 159 | "wkb": "01ed03000000000000", 160 | "ewkb": "01050000a0e610000000000000", 161 | "wkbXdr": "00000003ed00000000", 162 | "ewkbXdr": "00a0000005000010e600000000", 163 | "twkb": "a51801", 164 | "geoJSON": {"type": "MultiLineString", "coordinates": []}, 165 | "ewkbNoSrid": "010500008000000000", 166 | "ewkbXdrNoSrid": "008000000500000000" 167 | }, 168 | "multiLineStringWithOneLineString": { 169 | "geometry": "new MultiLineString.Z([new LineString.Z([new Point(1, 2, 1), new Point(3, 4, 2)])])", 170 | "wkt": "MULTILINESTRING Z ((1 2 1,3 4 2))", 171 | "wkb": "01ed0300000100000001ea03000002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 172 | "ewkb": "01050000a0e610000001000000010200008002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 173 | "wkbXdr": "00000003ed0000000100000003ea000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000", 174 | "ewkbXdr": "00a0000005000010e6000000010080000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000", 175 | "twkb": "a508010102c09a0c80b5180280b51880b51802", 176 | "geoJSON": { 177 | "type": "MultiLineString", 178 | "coordinates": [[[1, 2, 1], [3, 4, 2]]] 179 | }, 180 | "ewkbNoSrid": "010500008001000000010200008002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 181 | "ewkbXdrNoSrid": "0080000005000000010080000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000" 182 | }, 183 | "multiLineStringWithTwoLineStrings": { 184 | "geometry": "new MultiLineString.Z([new LineString.Z([new Point(1, 2, 1), new Point(3, 4, 2)]), new LineString.Z([new Point(5, 6, 3), new Point(7, 8, 4)])])", 185 | "wkt": "MULTILINESTRING Z ((1 2 1,3 4 2),(5 6 3,7 8 4))", 186 | "wkb": "01ed0300000200000001ea03000002000000000000000000f03f0000000000000040000000000000f03f00000000000008400000000000001040000000000000004001ea030000020000000000000000001440000000000000184000000000000008400000000000001c4000000000000020400000000000001040", 187 | "ewkb": "01050000a0e610000002000000010200008002000000000000000000f03f0000000000000040000000000000f03f0000000000000840000000000000104000000000000000400102000080020000000000000000001440000000000000184000000000000008400000000000001c4000000000000020400000000000001040", 188 | "wkbXdr": "00000003ed0000000200000003ea000000023ff000000000000040000000000000003ff000000000000040080000000000004010000000000000400000000000000000000003ea00000002401400000000000040180000000000004008000000000000401c00000000000040200000000000004010000000000000", 189 | "ewkbXdr": "00a0000005000010e6000000020080000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000008000000200000002401400000000000040180000000000004008000000000000401c00000000000040200000000000004010000000000000", 190 | "twkb": "a508010202c09a0c80b5180280b51880b518020280b51880b5180280b51880b51802", 191 | "geoJSON": { 192 | "type": "MultiLineString", 193 | "coordinates": [[[1, 2, 1], [3, 4, 2]], [[5, 6, 3], [7, 8, 4]]] 194 | }, 195 | "ewkbNoSrid": "010500008002000000010200008002000000000000000000f03f0000000000000040000000000000f03f0000000000000840000000000000104000000000000000400102000080020000000000000000001440000000000000184000000000000008400000000000001c4000000000000020400000000000001040", 196 | "ewkbXdrNoSrid": "0080000005000000020080000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000008000000200000002401400000000000040180000000000004008000000000000401c00000000000040200000000000004010000000000000" 197 | }, 198 | "emptyMultiPolygon": { 199 | "geometry": "new MultiPolygon.Z()", 200 | "geoJSONGeometry": "new MultiPolygon()", 201 | "wkt": "MULTIPOLYGON Z EMPTY", 202 | "wkb": "01ee03000000000000", 203 | "ewkb": "01060000a0e610000000000000", 204 | "wkbXdr": "00000003ee00000000", 205 | "ewkbXdr": "00a0000006000010e600000000", 206 | "twkb": "a61801", 207 | "geoJSON": {"type": "MultiPolygon", "coordinates": []}, 208 | "ewkbNoSrid": "010600008000000000", 209 | "ewkbXdrNoSrid": "008000000600000000" 210 | }, 211 | "multiPolygonWithOnePolygon": { 212 | "geometry": "new MultiPolygon.Z([new Polygon.Z([new Point(1, 2, 1), new Point(3, 4, 2), new Point(5, 6, 3), new Point(1, 2, 1)])])", 213 | "wkt": "MULTIPOLYGON Z (((1 2 1,3 4 2,5 6 3,1 2 1)))", 214 | "wkb": "01ee0300000100000001eb0300000100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f", 215 | "ewkb": "01060000a0e61000000100000001030000800100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f", 216 | "wkbXdr": "00000003ee0000000100000003eb00000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000", 217 | "ewkbXdr": "00a0000006000010e600000001008000000300000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000", 218 | "twkb": "a60801010104c09a0c80b5180280b51880b5180280b51880b51802ffe930ffe93003", 219 | "geoJSON": { 220 | "type": "MultiPolygon", 221 | "coordinates": [[[[1, 2, 1], [3, 4, 2], [5, 6, 3], [1, 2, 1]]]] 222 | }, 223 | "ewkbNoSrid": "01060000800100000001030000800100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f", 224 | "ewkbXdrNoSrid": "008000000600000001008000000300000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000" 225 | }, 226 | "multiPolygonWithTwoPolygons": { 227 | "geometry": "new MultiPolygon.Z([new Polygon.Z([new Point(1, 2, 1), new Point(3, 4, 2), new Point(5, 6, 3), new Point(1, 2, 1)]), new Polygon.Z([new Point(1, 2, 1), new Point(3, 4, 2), new Point(5, 6, 3), new Point(1, 2, 1)], [[new Point(11, 12, 4), new Point(13, 14, 5), new Point(15, 16, 6), new Point(11, 12, 4)], [new Point(21, 22, 7), new Point(23, 24, 8), new Point(25, 26, 9), new Point(21,22, 7)]])])", 228 | "wkt": "MULTIPOLYGON Z (((1 2 1,3 4 2,5 6 3,1 2 1)),((1 2 1,3 4 2,5 6 3,1 2 1),(11 12 4,13 14 5,15 16 6,11 12 4),(21 22 7,23 24 8,25 26 9,21 22 7)))", 229 | "wkb": "01ee0300000200000001eb0300000100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f01eb0300000300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 230 | "ewkb": "01060000a0e61000000200000001030000800100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f01030000800300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 231 | "wkbXdr": "00000003ee0000000200000003eb00000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000003eb00000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000", 232 | "ewkbXdr": "00a0000006000010e600000002008000000300000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000008000000300000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000", 233 | "twkb": "a60801020104c09a0c80b5180280b51880b5180280b51880b51802ffe930ffe93003030400000080b51880b5180280b51880b51802ffe930ffe930030480897a80897a0680b51880b5180280b51880b51802ffe930ffe930030480897a80897a0680b51880b5180280b51880b51802ffe930ffe93003", 234 | "geoJSON": { 235 | "type": "MultiPolygon", 236 | "coordinates": [ 237 | [[[1, 2, 1], [3, 4, 2], [5, 6, 3], [1, 2, 1]]], 238 | [ 239 | [[1, 2, 1], [3, 4, 2], [5, 6, 3], [1, 2, 1]], 240 | [[11, 12, 4], [13, 14, 5], [15, 16, 6], [11, 12, 4]], 241 | [[21, 22, 7], [23, 24, 8], [25, 26, 9], [21, 22, 7]] 242 | ] 243 | ] 244 | }, 245 | "ewkbNoSrid": "01060000800200000001030000800100000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f01030000800300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 246 | "ewkbXdrNoSrid": "008000000600000002008000000300000001000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff0000000000000008000000300000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000" 247 | }, 248 | "emptyGeometryCollection": { 249 | "geometry": "new GeometryCollection.Z()", 250 | "geoJSONGeometry": "new GeometryCollection()", 251 | "wkt": "GEOMETRYCOLLECTION Z EMPTY", 252 | "wkb": "01ef03000000000000", 253 | "ewkb": "01070000a0e610000000000000", 254 | "wkbXdr": "00000003ef00000000", 255 | "ewkbXdr": "00a0000007000010e600000000", 256 | "twkb": "a71801", 257 | "geoJSON": {"type": "GeometryCollection", "geometries": []}, 258 | "ewkbNoSrid": "010700008000000000", 259 | "ewkbXdrNoSrid": "008000000700000000" 260 | }, 261 | "geometryCollectionWithPoint": { 262 | "geometry": "new GeometryCollection.Z([new Point(1, 2, 1)])", 263 | "wkt": "GEOMETRYCOLLECTION Z (POINT Z (1 2 1))", 264 | "wkb": "01ef0300000100000001e9030000000000000000f03f0000000000000040000000000000f03f", 265 | "ewkb": "01070000a0e6100000010000000101000080000000000000f03f0000000000000040000000000000f03f", 266 | "wkbXdr": "00000003ef0000000100000003e93ff000000000000040000000000000003ff0000000000000", 267 | "ewkbXdr": "00a0000007000010e60000000100800000013ff000000000000040000000000000003ff0000000000000", 268 | "twkb": "a7080101a10801c09a0c80b51802", 269 | "geoJSON": { 270 | "type": "GeometryCollection", 271 | "geometries": [{"type": "Point", "coordinates": [1, 2, 1]}] 272 | }, 273 | "ewkbNoSrid": "0107000080010000000101000080000000000000f03f0000000000000040000000000000f03f", 274 | "ewkbXdrNoSrid": "00800000070000000100800000013ff000000000000040000000000000003ff0000000000000" 275 | }, 276 | "geometryCollectionWithPointAndLineString": { 277 | "geometry": "new GeometryCollection.Z([new Point(1, 2, 1), new LineString.Z([new Point(1, 2, 1), new Point(3, 4, 2)])])", 278 | "wkt": "GEOMETRYCOLLECTION Z (POINT Z (1 2 1),LINESTRING Z (1 2 1,3 4 2))", 279 | "wkb": "01ef0300000200000001e9030000000000000000f03f0000000000000040000000000000f03f01ea03000002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 280 | "ewkb": "01070000a0e6100000020000000101000080000000000000f03f0000000000000040000000000000f03f010200008002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 281 | "wkbXdr": "00000003ef0000000200000003e93ff000000000000040000000000000003ff000000000000000000003ea000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000", 282 | "ewkbXdr": "00a0000007000010e60000000200800000013ff000000000000040000000000000003ff00000000000000080000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000", 283 | "twkb": "a7080102a10801c09a0c80b51802a2080102c09a0c80b5180280b51880b51802", 284 | "geoJSON": { 285 | "type": "GeometryCollection", 286 | "geometries": [ 287 | {"type": "Point", "coordinates": [1, 2, 1]}, 288 | {"type": "LineString", "coordinates": [[1, 2, 1], [3, 4, 2]]} 289 | ] 290 | }, 291 | "ewkbNoSrid": "0107000080020000000101000080000000000000f03f0000000000000040000000000000f03f010200008002000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040", 292 | "ewkbXdrNoSrid": "00800000070000000200800000013ff000000000000040000000000000003ff00000000000000080000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000" 293 | }, 294 | "geometryCollectionWithPointAndLineStringAndPolygon": { 295 | "geometry": "new GeometryCollection.Z([new Point(1, 2, 1), new LineString.Z([new Point(1, 2, 1), new Point(3, 4, 2)]), new Polygon.Z([new Point(1, 2, 1), new Point(3, 4, 2),new Point(5, 6, 3), new Point(1, 2, 1)], [[new Point(11, 12, 4), new Point(13, 14, 5), new Point(15, 16, 6), new Point(11, 12, 4)], [new Point(21, 22, 7), new Point(23, 24, 8), new Point(25, 26, 9), new Point(21, 22, 7)]])])", 296 | "wkt": "GEOMETRYCOLLECTION Z (POINT Z (1 2 1),LINESTRING Z (1 2 1,3 4 2),POLYGON Z ((1 2 1,3 4 2,5 6 3,1 2 1),(11 12 4,13 14 5,15 16 6,11 12 4),(21 22 7,23 24 8,25 26 9,21 22 7)))", 297 | "wkb": "01ef0300000300000001e9030000000000000000f03f0000000000000040000000000000f03f01ea03000002000000000000000000f03f0000000000000040000000000000f03f00000000000008400000000000001040000000000000004001eb0300000300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 298 | "ewkb": "01070000a0e6100000030000000101000080000000000000f03f0000000000000040000000000000f03f010200008002000000000000000000f03f0000000000000040000000000000f03f00000000000008400000000000001040000000000000004001030000800300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 299 | "wkbXdr": "00000003ef0000000300000003e93ff000000000000040000000000000003ff000000000000000000003ea000000023ff000000000000040000000000000003ff000000000000040080000000000004010000000000000400000000000000000000003eb00000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000", 300 | "ewkbXdr": "00a0000007000010e60000000300800000013ff000000000000040000000000000003ff00000000000000080000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000008000000300000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000", 301 | "twkb": "a7080103a10801c09a0c80b51802a2080102c09a0c80b5180280b51880b51802a308010304c09a0c80b5180280b51880b5180280b51880b51802ffe930ffe930030480897a80897a0680b51880b5180280b51880b51802ffe930ffe930030480897a80897a0680b51880b5180280b51880b51802ffe930ffe93003", 302 | "geoJSON": { 303 | "type": "GeometryCollection", 304 | "geometries": [ 305 | {"type": "Point", "coordinates": [1, 2, 1]}, 306 | {"type": "LineString", "coordinates": [[1, 2, 1], [3, 4, 2]]}, 307 | { 308 | "type": "Polygon", 309 | "coordinates": [ 310 | [[1, 2, 1], [3, 4, 2], [5, 6, 3], [1, 2, 1]], 311 | [[11, 12, 4], [13, 14, 5], [15, 16, 6], [11, 12, 4]], 312 | [[21, 22, 7], [23, 24, 8], [25, 26, 9], [21, 22, 7]] 313 | ] 314 | } 315 | ] 316 | }, 317 | "ewkbNoSrid": "0107000080030000000101000080000000000000f03f0000000000000040000000000000f03f010200008002000000000000000000f03f0000000000000040000000000000f03f00000000000008400000000000001040000000000000004001030000800300000004000000000000000000f03f0000000000000040000000000000f03f000000000000084000000000000010400000000000000040000000000000144000000000000018400000000000000840000000000000f03f0000000000000040000000000000f03f040000000000000000002640000000000000284000000000000010400000000000002a400000000000002c4000000000000014400000000000002e400000000000003040000000000000184000000000000026400000000000002840000000000000104004000000000000000000354000000000000036400000000000001c4000000000000037400000000000003840000000000000204000000000000039400000000000003a400000000000002240000000000000354000000000000036400000000000001c40", 318 | "ewkbXdrNoSrid": "00800000070000000300800000013ff000000000000040000000000000003ff00000000000000080000002000000023ff000000000000040000000000000003ff0000000000000400800000000000040100000000000004000000000000000008000000300000003000000043ff000000000000040000000000000003ff00000000000004008000000000000401000000000000040000000000000004014000000000000401800000000000040080000000000003ff000000000000040000000000000003ff000000000000000000004402600000000000040280000000000004010000000000000402a000000000000402c0000000000004014000000000000402e000000000000403000000000000040180000000000004026000000000000402800000000000040100000000000000000000440350000000000004036000000000000401c0000000000004037000000000000403800000000000040200000000000004039000000000000403a000000000000402200000000000040350000000000004036000000000000401c000000000000" 319 | } 320 | } -------------------------------------------------------------------------------- /test/twkb.js: -------------------------------------------------------------------------------- 1 | var Geometry = require('../lib/geometry'); 2 | var Point = require('../lib/point'); 3 | 4 | var assert = require('assert'); 5 | 6 | describe('wkx', function () { 7 | describe('parseTwkb', function () { 8 | it('includes size', function () { 9 | assert.deepEqual(Geometry.parseTwkb( 10 | new Buffer('0102020204', 'hex')), 11 | new Point(1, 2)); 12 | }); 13 | it('includes bounding box', function () { 14 | assert.deepEqual(Geometry.parseTwkb( 15 | new Buffer('0101020004000204', 'hex')), 16 | new Point(1, 2)); 17 | }); 18 | it('includes extended precision', function () { 19 | assert.deepEqual(Geometry.parseTwkb( 20 | new Buffer('01080302040608', 'hex')), 21 | new Point(1, 2, 3, 4)); 22 | }); 23 | it('includes extended precision and bounding box', function () { 24 | assert.deepEqual(Geometry.parseTwkb( 25 | new Buffer('010903020004000600080002040608', 'hex')), 26 | new Point(1, 2, 3, 4)); 27 | }); 28 | }); 29 | describe('toTwkb', function () { 30 | it('Point small', function () { 31 | assert.equal(new Point(1, 2).toTwkb().toString('hex'), 'a100c09a0c80b518'); 32 | }); 33 | it('Point large', function () { 34 | assert.equal(new Point(10000, 20000).toTwkb().toString('hex'), 'a10080a8d6b90780d0acf30e'); 35 | }); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /test/wkx.js: -------------------------------------------------------------------------------- 1 | /* jshint evil: true, unused: false */ 2 | 3 | var eql = require('deep-eql'); 4 | 5 | var Geometry = require('../lib/geometry'); 6 | var Point = require('../lib/point'); 7 | var LineString = require('../lib/linestring'); 8 | var Polygon = require('../lib/polygon'); 9 | var MultiPoint = require('../lib/multipoint'); 10 | var MultiLineString = require('../lib/multilinestring'); 11 | var MultiPolygon = require('../lib/multipolygon'); 12 | var GeometryCollection = require('../lib/geometrycollection'); 13 | 14 | var tests = { 15 | '2D': require('./testdata.json'), 16 | 'Z': require('./testdataZ.json'), 17 | 'M': require('./testdataM.json'), 18 | 'ZM': require('./testdataZM.json') 19 | }; 20 | 21 | var issueTests = require('./issuetestdata.json'); 22 | 23 | var assert = require('assert'); 24 | 25 | function assertParseWkt(data) { 26 | assert(eql(Geometry.parse(data.wkt), eval(data.geometry))); 27 | } 28 | 29 | function assertParseWkb(data) { 30 | var geometry = data.wkbGeometry ? data.wkbGeometry : data.geometry; 31 | geometry = eval(geometry); 32 | geometry.srid = undefined; 33 | assert(eql(Geometry.parse(new Buffer(data.wkb, 'hex')), geometry)); 34 | } 35 | 36 | function assertParseWkbXdr(data) { 37 | var geometry = data.wkbGeometry ? data.wkbGeometry : data.geometry; 38 | geometry = eval(geometry); 39 | geometry.srid = undefined; 40 | assert(eql(Geometry.parse(new Buffer(data.wkbXdr, 'hex')), geometry)); 41 | } 42 | 43 | function assertParseEwkt(data) { 44 | var geometry = eval(data.geometry); 45 | geometry.srid = 4326; 46 | assert(eql(Geometry.parse('SRID=4326;' + data.wkt), geometry)); 47 | } 48 | 49 | function assertParseEwkb(data) { 50 | var geometry = data.wkbGeometry ? data.wkbGeometry : data.geometry; 51 | geometry = eval(geometry); 52 | geometry.srid = 4326; 53 | assert(eql(Geometry.parse(new Buffer(data.ewkb, 'hex')), geometry)); 54 | } 55 | 56 | function assertParseEwkbXdr(data) { 57 | var geometry = data.wkbGeometry ? data.wkbGeometry : data.geometry; 58 | geometry = eval(geometry); 59 | geometry.srid = 4326; 60 | assert(eql(Geometry.parse(new Buffer(data.ewkbXdr, 'hex')), geometry)); 61 | } 62 | 63 | function assertParseEwkbNoSrid(data) { 64 | var geometry = data.wkbGeometry ? data.wkbGeometry : data.geometry; 65 | geometry = eval(geometry); 66 | assert(eql(Geometry.parse(new Buffer(data.ewkbNoSrid, 'hex')), geometry)); 67 | } 68 | 69 | function assertParseEwkbXdrNoSrid(data) { 70 | var geometry = data.wkbGeometry ? data.wkbGeometry : data.geometry; 71 | geometry = eval(geometry); 72 | assert(eql(Geometry.parse(new Buffer(data.ewkbXdrNoSrid, 'hex')), geometry)); 73 | } 74 | 75 | function assertParseTwkb(data) { 76 | var geometry = eval(data.geometry); 77 | geometry.srid = undefined; 78 | assert(eql(Geometry.parseTwkb(new Buffer(data.twkb, 'hex')), geometry)); 79 | } 80 | 81 | function assertParseGeoJSON(data) { 82 | var geometry = data.geoJSONGeometry ? data.geoJSONGeometry : data.geometry; 83 | geometry = eval(geometry); 84 | geometry.srid = 4326; 85 | assert(eql(Geometry.parseGeoJSON(data.geoJSON), geometry)); 86 | } 87 | 88 | function assertToWkt(data) { 89 | assert.equal(eval(data.geometry).toWkt(), data.wkt); 90 | } 91 | 92 | function assertToWkb(data) { 93 | assert.equal(eval(data.geometry).toWkb().toString('hex'), data.wkb); 94 | } 95 | 96 | function assertToEwkt(data) { 97 | var geometry = eval(data.geometry); 98 | geometry.srid = 4326; 99 | assert.equal(geometry.toEwkt(), 'SRID=4326;' + data.wkt); 100 | } 101 | 102 | function assertToEwkb(data) { 103 | var geometry = eval(data.geometry); 104 | geometry.srid = 4326; 105 | assert.equal(geometry.toEwkb().toString('hex'), data.ewkb); 106 | } 107 | 108 | function assertToTwkb(data) { 109 | assert.equal(eval(data.geometry).toTwkb().toString('hex'), data.twkb); 110 | } 111 | 112 | function assertToGeoJSON(data) { 113 | assert(eql(eval(data.geometry).toGeoJSON(), data.geoJSON)); 114 | } 115 | 116 | describe('wkx', function () { 117 | describe('Geometry', function () { 118 | it('parse(wkt) - coordinate', function () { 119 | assert.deepEqual(Geometry.parse('POINT(1 2)'), new Point(1, 2)); 120 | assert.deepEqual(Geometry.parse('POINT(1.2 3.4)'), new Point(1.2, 3.4)); 121 | assert.deepEqual(Geometry.parse('POINT(1 3.4)'), new Point(1, 3.4)); 122 | assert.deepEqual(Geometry.parse('POINT(1.2 3)'), new Point(1.2, 3)); 123 | 124 | assert.deepEqual(Geometry.parse('POINT(-1 -2)'), new Point(-1, -2)); 125 | assert.deepEqual(Geometry.parse('POINT(-1 2)'), new Point(-1, 2)); 126 | assert.deepEqual(Geometry.parse('POINT(1 -2)'), new Point(1, -2)); 127 | 128 | assert.deepEqual(Geometry.parse('POINT(-1.2 -3.4)'), new Point(-1.2, -3.4)); 129 | assert.deepEqual(Geometry.parse('POINT(-1.2 3.4)'), new Point(-1.2, 3.4)); 130 | assert.deepEqual(Geometry.parse('POINT(1.2 -3.4)'), new Point(1.2, -3.4)); 131 | 132 | assert.deepEqual(Geometry.parse('POINT(1.2e1 3.4e1)'), new Point(12, 34)); 133 | assert.deepEqual(Geometry.parse('POINT(1.2e-1 3.4e-1)'), new Point(0.12, 0.34)); 134 | assert.deepEqual(Geometry.parse('POINT(-1.2e1 -3.4e1)'), new Point(-12, -34)); 135 | assert.deepEqual(Geometry.parse('POINT(-1.2e-1 -3.4e-1)'), new Point(-0.12, -0.34)); 136 | 137 | assert.deepEqual(Geometry.parse('MULTIPOINT(1 2,3 4)'), 138 | new MultiPoint([new Point(1, 2), new Point(3, 4)])); 139 | assert.deepEqual(Geometry.parse('MULTIPOINT(1 2, 3 4)'), 140 | new MultiPoint([new Point(1, 2), new Point(3, 4)])); 141 | assert.deepEqual(Geometry.parse('MULTIPOINT((1 2),(3 4))'), 142 | new MultiPoint([new Point(1, 2), new Point(3, 4)])); 143 | assert.deepEqual(Geometry.parse('MULTIPOINT((1 2), (3 4))'), 144 | new MultiPoint([new Point(1, 2), new Point(3, 4)])); 145 | }); 146 | it('parse() - invalid input', function () { 147 | assert.throws(Geometry.parse, /first argument must be a string or Buffer/); 148 | assert.throws(function () { Geometry.parse('TEST'); }, /Expected geometry type/); 149 | assert.throws(function () { Geometry.parse('POINT)'); }, /Expected group start/); 150 | assert.throws(function () { Geometry.parse('POINT(1 2'); }, /Expected group end/); 151 | assert.throws(function () { Geometry.parse('POINT(1)'); }, /Expected coordinates/); 152 | assert.throws(function () { Geometry.parse('TEST'); }, /Expected geometry type/); 153 | assert.throws(function () { 154 | Geometry.parse(new Buffer('010800000000000000', 'hex')); 155 | }, /GeometryType 8 not supported/); 156 | assert.throws(function () { 157 | Geometry.parseTwkb(new Buffer('a800c09a0c80b518', 'hex')); 158 | }, /GeometryType 8 not supported/); 159 | assert.throws(function () { 160 | Geometry.parseGeoJSON({ type: 'TEST' }); 161 | }, /GeometryType TEST not supported/); 162 | }); 163 | it('parse(wkt) - #31', function () { 164 | assert.deepEqual(Geometry.parse(issueTests['#31'].wkt), eval(issueTests['#31'].geometry)); 165 | }); 166 | }); 167 | 168 | function createTest(testKey, testData) { 169 | describe(testKey, function () { 170 | it('parse(wkt)', function () { 171 | assertParseWkt(testData[testKey]); 172 | }); 173 | it('parse(wkb)', function () { 174 | assertParseWkb(testData[testKey]); 175 | }); 176 | it('parse(wkb xdr)', function () { 177 | assertParseWkbXdr(testData[testKey]); 178 | }); 179 | it('parse(ewkt)', function () { 180 | assertParseEwkt(testData[testKey]); 181 | }); 182 | it('parse(ewkb)', function () { 183 | assertParseEwkb(testData[testKey]); 184 | }); 185 | it('parse(ewkb xdr)', function () { 186 | assertParseEwkbXdr(testData[testKey]); 187 | }); 188 | it('parse(ewkb no srid)', function () { 189 | assertParseEwkbNoSrid(testData[testKey]); 190 | }); 191 | it('parse(ewkb xdr no srid)', function () { 192 | assertParseEwkbXdrNoSrid(testData[testKey]); 193 | }); 194 | it('parseTwkb()', function () { 195 | assertParseTwkb(testData[testKey]); 196 | }); 197 | it('parseGeoJSON()', function () { 198 | assertParseGeoJSON(testData[testKey]); 199 | }); 200 | it('toWkt()', function () { 201 | assertToWkt(testData[testKey]); 202 | }); 203 | it('toWkb()', function () { 204 | assertToWkb(testData[testKey]); 205 | }); 206 | it('toEwkt()', function () { 207 | assertToEwkt(testData[testKey]); 208 | }); 209 | it('toEwkb()', function () { 210 | assertToEwkb(testData[testKey]); 211 | }); 212 | it('toTwkb()', function () { 213 | assertToTwkb(testData[testKey]); 214 | }); 215 | it('toGeoJSON()', function () { 216 | assertToGeoJSON(testData[testKey]); 217 | }); 218 | }); 219 | } 220 | 221 | function createTests(testKey, testData) { 222 | describe(testKey, function () { 223 | for (var testDataKey in testData) { 224 | createTest(testDataKey, testData); 225 | } 226 | }); 227 | } 228 | 229 | for (var testKey in tests) { 230 | createTests(testKey, tests[testKey]); 231 | } 232 | }); 233 | -------------------------------------------------------------------------------- /test/zigzag.js: -------------------------------------------------------------------------------- 1 | var ZigZag = require('../lib/zigzag'); 2 | 3 | var assert = require('assert'); 4 | 5 | describe('wkx', function () { 6 | describe('ZigZag', function () { 7 | it('encode', function () { 8 | assert.equal(ZigZag.encode(-1), 1); 9 | assert.equal(ZigZag.encode(1), 2); 10 | assert.equal(ZigZag.encode(-2), 3); 11 | assert.equal(ZigZag.encode(2), 4); 12 | }); 13 | it('decode', function () { 14 | assert.equal(ZigZag.decode(1), -1); 15 | assert.equal(ZigZag.decode(2), 1); 16 | assert.equal(ZigZag.decode(3), -2); 17 | assert.equal(ZigZag.decode(4), 2); 18 | }); 19 | }); 20 | }); 21 | --------------------------------------------------------------------------------