diff --git a/.eslintignore b/.eslintignore index 52e9daff04..06b1c27aaf 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,8 +2,9 @@ node_modules test test.js bench.js -packages/turf/turf.js -packages/turf/turf.min.js +dist/turf.js +dist/turf.es.js +dist/turf.min.js marchingsquares-isobands.js rollup.config.js simplepolygon.js diff --git a/.eslintrc.js b/.eslintrc.js index c66e8a3744..02c2b82f84 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -9,6 +9,7 @@ module.exports = { 'no-loop-func': [0], 'object-curly-spacing': [0], 'consistent-return': [0], + 'prefer-arrow-callback': [0], 'valid-jsdoc': [2, { prefer: {'return': 'returns'}, requireReturn: false diff --git a/.gitignore b/.gitignore index cb1727ba8b..ddb5e02b61 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,5 @@ .rpt2_cache dist -main.js -main.es.js -main.mjs -main.min.js -index.mjs -*.min.js -*.es5.js .esm-cache package-lock.json env diff --git a/.travis.yml b/.travis.yml index 176bd509b2..8f9c7d9a3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ language: node_js cache: yarn node_js: - - 9 + - 8.14.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6eadb3cc35..edc4f2422d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,9 @@ ### :bug: [How to report a bug](http://polite.technology/reportabug.html) +## Please note + +The high-level structure of Turf is undergoing discussion at [#1428](https://github.com/Turfjs/turf/issues/1428). Currently (June 2018), there is a partial conversion to Typescript, and the contribution documentation does not completely reflect the current status. + ## How To Contribute - Most work happens in sub modules. These are found in the `packages` directory prefixed with "turf-". @@ -85,6 +89,17 @@ it will create a new folder inside `packages` with a simple boilerplate for your [geojson.io](http://geojson.io) to see, visually, if the module is behaving appropriately. +## Running tests +To run tests for a specified module +```bash +$ npm run test-module "module-name" +``` + +To debug tests for a specified module: +```bash +$ node --inspect-brk -r esm scripts/testModule.js "module-name" +``` +and attach with your favorite debugger. ## Publishing diff --git a/lerna.json b/lerna.json deleted file mode 100644 index 36604c8004..0000000000 --- a/lerna.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "lerna": "2.8.0", - "packages": [ - "packages/*" - ], - "version": "independent", - "npmClient": "yarn", - "useWorkspaces": true -} diff --git a/package.json b/package.json index 6d5237b1a4..716e9a1833 100644 --- a/package.json +++ b/package.json @@ -1,40 +1,79 @@ { - "private": true, - "workspaces": [ - "packages/*" + "name": "turf", + "version": "7.0.0-alpha", + "description": "A JavaScript library for performing geospatial operations with GeoJSON", + "main": "dist/turf.js", + "browser": "dist/turf.min.js", + "unpkg": "dist/turf.min.js", + "module": "src/index.js", + "files": [ + "src", + "dist" ], + "types": "index.d.ts", "scripts": { - "prelint": "tsc", - "lint": "echo 'eslint will be moved to TSLint'", - "postlint": "documentation lint packages/turf-*/index.js", - "pretest": "lerna bootstrap --use-workspaces && npm run lint", - "test": "lerna run test --use-workspaces", - "docs": "node ./scripts/generate-readmes", + "benchmark-module": "node -r esm scripts/benchmarkModule.js", + "build": "rollup -c", + "lint": "eslint src/*/index.js", + "prepublish": "npm run build", + "test": "tape -r esm src/*/test.js | faucet", + "test-module": "node -r esm scripts/testModule.js", + "test-module:regen": "cross-env REGEN=true node -r esm scripts/testModule.js", "postinstall": "opencollective postinstall" }, "devDependencies": { + "@mapbox/geojsonhint": "^2.1.0", "@types/geojson": "*", "@types/node": "*", + "benchmark": "^2.1.4", + "boolean-jsts": "0.0.1", + "boolean-shapely": "^0.1.2", "camelcase": "*", + "chromatism": "^3.0.0", + "concaveman": "^1.1.1", + "cross-env": "^5.2.0", "d3-queue": "*", "decamelize": "*", "documentation": "*", "eslint": "*", "eslint-config-mourner": "*", + "esm": "^3.0.84", + "faucet": "0.0.1", "fs-extra": "*", - "lerna": "2.8.0", + "geojson-fixtures": "^1.0.0", "load-json-file": "*", "meow": "*", "progress": "*", + "proj4": "^2.4.4", "rollup": "*", + "rollup-plugin-butternut": "^0.1.0", + "rollup-plugin-commonjs": "^8.4.1", + "rollup-plugin-node-resolve": "^3.3.0", "rollup-plugin-typescript": "*", "tape": "*", "typescript": "*", + "write-json-file": "*", "yamljs": "*" }, "dependencies": { - "opencollective": "^1.0.3" + "d3-voronoi": "^1.1.2", + "opencollective": "^1.0.3", + "polygon-clipping": "^0.14.0", + "skmeans": "^0.9.7", + "turf-jsts": "^1.2.3" }, + "license": "MIT", + "homepage": "http://turfjs.org", + "keywords": [ + "geospatial", + "spatial", + "analysis", + "gis", + "geojson", + "buffer", + "intersect", + "union" + ], "collective": { "type": "opencollective", "url": "https://opencollective.com/turf", diff --git a/packages/turf-along/.gitignore b/packages/turf-along/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-along/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-along/LICENSE b/packages/turf-along/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-along/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-along/README.md b/packages/turf-along/README.md deleted file mode 100644 index e32d03a2fb..0000000000 --- a/packages/turf-along/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# @turf/along - - - -## along - -Takes a [LineString][1] and returns a [Point][2] at a specified distance along the line. - -**Parameters** - -- `line` **[Feature][3]<[LineString][4]>** input line -- `distance` **[number][5]** distance along the line -- `options` **[Object][6]?** Optional parameters - - `options.units` **[string][7]** can be degrees, radians, miles, or kilometers (optional, default `"kilometers"`) - -**Examples** - -```javascript -var line = turf.lineString([[-83, 30], [-84, 36], [-78, 41]]); -var options = {units: 'miles'}; - -var along = turf.along(line, 200, options); - -//addToMap -var addToMap = [along, line] -``` - -Returns **[Feature][3]<[Point][8]>** Point `distance` `units` along the line - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[8]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/along -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-along/bench.js b/packages/turf-along/bench.js deleted file mode 100644 index dbf47ae016..0000000000 --- a/packages/turf-along/bench.js +++ /dev/null @@ -1,64 +0,0 @@ -const fs = require('fs'); -const Benchmark = require('benchmark'); -const along = require('./').default; - -const line = { - type: "Feature", - properties: {}, - geometry: { - type: "LineString", - coordinates: [ - [ - -77.0316696166992, - 38.878605901789236 - ], - [ - -77.02960968017578, - 38.88194668656296 - ], - [ - -77.02033996582031, - 38.88408470638821 - ], - [ - -77.02566146850586, - 38.885821800123196 - ], - [ - -77.02188491821289, - 38.88956308852534 - ], - [ - -77.01982498168944, - 38.89236892551996 - ] - ] - } -}; - -const route = JSON.parse(fs.readFileSync(__dirname + '/test/fixtures/route.geojson')); - -const suite = new Benchmark.Suite('turf-along'); -suite - .add('turf-along',function () { - along(line, 1, 'miles'); - }) - .add('turf-along#route 1 mile',function () { - along(route, 1, 'miles'); - }) - .add('turf-along#route 10 miles',function () { - along(route, 10, 'miles'); - }) - .add('turf-along#route 50 miles',function () { - along(route, 50, 'miles'); - }) - .add('turf-along#route 100 miles',function () { - along(route, 100, 'miles'); - }) - .on('cycle', function (event) { - console.log(String(event.target)); - }) - .on('complete', function () { - - }) - .run(); diff --git a/packages/turf-along/index.d.ts b/packages/turf-along/index.d.ts deleted file mode 100644 index 8132157cc5..0000000000 --- a/packages/turf-along/index.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Feature, LineString, Point, Units } from "@turf/helpers"; -/** - * Takes a {@link LineString} and returns a {@link Point} at a specified distance along the line. - * - * @name along - * @param {Feature} line input line - * @param {number} distance distance along the line - * @param {Object} [options] Optional parameters - * @param {string} [options.units="kilometers"] can be degrees, radians, miles, or kilometers - * @returns {Feature} Point `distance` `units` along the line - * @example - * var line = turf.lineString([[-83, 30], [-84, 36], [-78, 41]]); - * var options = {units: 'miles'}; - * - * var along = turf.along(line, 200, options); - * - * //addToMap - * var addToMap = [along, line] - */ -export default function along(line: Feature | LineString, distance: number, options?: { - units?: Units; -}): Feature; diff --git a/packages/turf-along/index.ts b/packages/turf-along/index.ts deleted file mode 100644 index 8e83f7acb0..0000000000 --- a/packages/turf-along/index.ts +++ /dev/null @@ -1,49 +0,0 @@ -import bearing from "@turf/bearing"; -import destination from "@turf/destination"; -import measureDistance from "@turf/distance"; -import { Feature, LineString, point, Point, Units } from "@turf/helpers"; -import { getGeom } from "@turf/invariant"; - -/** - * Takes a {@link LineString} and returns a {@link Point} at a specified distance along the line. - * - * @name along - * @param {Feature} line input line - * @param {number} distance distance along the line - * @param {Object} [options] Optional parameters - * @param {string} [options.units="kilometers"] can be degrees, radians, miles, or kilometers - * @returns {Feature} Point `distance` `units` along the line - * @example - * var line = turf.lineString([[-83, 30], [-84, 36], [-78, 41]]); - * var options = {units: 'miles'}; - * - * var along = turf.along(line, 200, options); - * - * //addToMap - * var addToMap = [along, line] - */ -export default function along( - line: Feature | LineString, - distance: number, - options: {units?: Units} = {}, -): Feature { - // Get Coords - const geom = getGeom(line); - const coords = geom.coordinates; - let travelled = 0; - for (let i = 0; i < coords.length; i++) { - if (distance >= travelled && i === coords.length - 1) { break; - } else if (travelled >= distance) { - const overshot = distance - travelled; - if (!overshot) { return point(coords[i]); - } else { - const direction = bearing(coords[i], coords[i - 1]) - 180; - const interpolated = destination(coords[i], overshot, direction, options); - return interpolated; - } - } else { - travelled += measureDistance(coords[i], coords[i + 1], options); - } - } - return point(coords[coords.length - 1]); -} diff --git a/packages/turf-along/package.json b/packages/turf-along/package.json deleted file mode 100644 index 1a0c57aa95..0000000000 --- a/packages/turf-along/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@turf/along", - "version": "6.1.0", - "description": "turf along module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "along", - "line", - "linestring", - "turf", - "distance" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@types/tape": "*", - "benchmark": "*", - "load-json-file": "*", - "tape": "*", - "tslint": "*", - "typescript": "*" - }, - "dependencies": { - "@turf/bearing": "6.x", - "@turf/destination": "6.x", - "@turf/distance": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-along/test.js b/packages/turf-along/test.js deleted file mode 100644 index 95476917a9..0000000000 --- a/packages/turf-along/test.js +++ /dev/null @@ -1,31 +0,0 @@ -const path = require('path'); -const test = require('tape'); -const load = require('load-json-file'); -const { featureCollection } = require('@turf/helpers'); -const along = require('./').default; - -const line = load.sync(path.join(__dirname, 'test', 'fixtures', 'dc-line.geojson')); - -test('turf-along', t => { - const options = {units: 'miles'} - const pt1 = along(line, 1, options); - const pt2 = along(line.geometry, 1.2, options); - const pt3 = along(line, 1.4, options); - const pt4 = along(line.geometry, 1.6, options); - const pt5 = along(line, 1.8, options); - const pt6 = along(line.geometry, 2, options); - const pt7 = along(line, 100, options); - const pt8 = along(line.geometry, 0, options); - const fc = featureCollection([pt1, pt2, pt3, pt4, pt5, pt6, pt7, pt8]); - - fc.features.forEach(f => { - t.ok(f); - t.equal(f.type, 'Feature'); - t.equal(f.geometry.type, 'Point'); - }); - t.equal(fc.features.length, 8); - t.equal(fc.features[7].geometry.coordinates[0], pt8.geometry.coordinates[0]); - t.equal(fc.features[7].geometry.coordinates[1], pt8.geometry.coordinates[1]); - - t.end(); -}); diff --git a/packages/turf-along/test/fixtures/dc-points.geojson b/packages/turf-along/test/fixtures/dc-points.geojson deleted file mode 100644 index bd19be8658..0000000000 --- a/packages/turf-along/test/fixtures/dc-points.geojson +++ /dev/null @@ -1,115 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Point", - "coordinates": [ - -77.0316696166992, - 38.87406218243845 - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Point", - "coordinates": [ - -77.02325820922852, - 38.885688179036094 - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Point", - "coordinates": [ - -77.0222282409668, - 38.89744587262311 - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Point", - "coordinates": [ - -77.02377319335936, - 38.910804525446686 - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Point", - "coordinates": [ - -77.02840805053711, - 38.91441093075183 - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Point", - "coordinates": [ - -77.02840805053711, - 38.92402711565758 - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Point", - "coordinates": [ - -77.04008102416992, - 38.932707274379595 - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Point", - "coordinates": [ - -76.99390411376953, - 38.91387666004744 - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Point", - "coordinates": [ - -77.03269958496094, - 38.898648254305215 - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Point", - "coordinates": [ - -77.02342987060545, - 38.870587377511235 - ] - } - } - ] -} \ No newline at end of file diff --git a/packages/turf-along/test/fixtures/route.geojson b/packages/turf-along/test/fixtures/route.geojson deleted file mode 100644 index 8c19389b35..0000000000 --- a/packages/turf-along/test/fixtures/route.geojson +++ /dev/null @@ -1,2 +0,0 @@ - -{ "type": "Feature", "properties": { "name": null, "cmt": null, "desc": null, "src": null, "link1_href": null, "link1_text": null, "link1_type": null, "link2_href": null, "link2_text": null, "link2_type": null, "number": null, "type": null }, "geometry": { "type": "LineString", "coordinates": [ [ -79.254923, 36.98394 ], [ -79.254923, 36.983939 ], [ -79.255326, 36.9838 ], [ -79.255401, 36.983774 ], [ -79.25576, 36.983664 ], [ -79.256795, 36.984137 ], [ -79.257537, 36.984478 ], [ -79.258539, 36.984925 ], [ -79.259498, 36.985353 ], [ -79.260286, 36.985712 ], [ -79.261405, 36.986222 ], [ -79.262933, 36.986928 ], [ -79.263237, 36.987071 ], [ -79.263755, 36.987296 ], [ -79.264086, 36.987423 ], [ -79.264167, 36.987446 ], [ -79.264338, 36.987486 ], [ -79.264414, 36.987501 ], [ -79.264618, 36.987531 ], [ -79.2648, 36.987542 ], [ -79.264982, 36.987537 ], [ -79.265163, 36.987517 ], [ -79.26703, 36.987355 ], [ -79.267952, 36.98726 ], [ -79.268404, 36.987226 ], [ -79.268771, 36.987197 ], [ -79.26955, 36.987117 ], [ -79.271398, 36.986946 ], [ -79.271488, 36.986941 ], [ -79.271698, 36.986925 ], [ -79.271936, 36.986898 ], [ -79.272231, 36.986852 ], [ -79.272474, 36.986785 ], [ -79.272711, 36.986705 ], [ -79.272895, 36.986632 ], [ -79.273059, 36.986552 ], [ -79.273646, 36.986245 ], [ -79.274224, 36.985925 ], [ -79.274887, 36.985592 ], [ -79.275308, 36.985365 ], [ -79.275672, 36.98517 ], [ -79.276249, 36.984876 ], [ -79.277101, 36.984433 ], [ -79.277425, 36.984259 ], [ -79.277918, 36.983982 ], [ -79.27799, 36.98395 ], [ -79.278179, 36.98385 ], [ -79.278261, 36.9838 ], [ -79.278335, 36.983745 ], [ -79.278421, 36.983666 ], [ -79.27844, 36.983647 ], [ -79.278502, 36.983577 ], [ -79.278548, 36.983511 ], [ -79.278614, 36.983381 ], [ -79.278654, 36.983273 ], [ -79.278711, 36.983011 ], [ -79.278763, 36.98269 ], [ -79.278806, 36.982485 ], [ -79.278866, 36.982282 ], [ -79.278952, 36.982101 ], [ -79.279023, 36.981984 ], [ -79.280178, 36.980418 ], [ -79.280259, 36.980319 ], [ -79.280355, 36.980229 ], [ -79.280419, 36.98018 ], [ -79.280578, 36.980082 ], [ -79.280666, 36.980038 ], [ -79.280783, 36.979994 ], [ -79.280908, 36.979963 ], [ -79.281301, 36.979913 ], [ -79.281646, 36.979874 ], [ -79.282145, 36.979835 ], [ -79.282797, 36.97977 ], [ -79.283144, 36.979743 ], [ -79.283618, 36.97972 ], [ -79.28399, 36.979706 ], [ -79.284447, 36.979695 ], [ -79.284904, 36.979697 ], [ -79.286913, 36.979638 ], [ -79.287201, 36.979628 ], [ -79.287954, 36.979612 ], [ -79.288037, 36.979611 ], [ -79.288397, 36.97962 ], [ -79.288697, 36.979643 ], [ -79.289908, 36.979722 ], [ -79.289994, 36.979724 ], [ -79.290136, 36.979716 ], [ -79.290248, 36.979699 ], [ -79.290503, 36.979632 ], [ -79.291043, 36.979454 ], [ -79.291563, 36.979269 ], [ -79.292467, 36.97896 ], [ -79.292759, 36.978877 ], [ -79.292963, 36.978832 ], [ -79.293286, 36.978778 ], [ -79.293549, 36.978746 ], [ -79.293649, 36.978738 ], [ -79.293755, 36.978729 ], [ -79.293858, 36.978731 ], [ -79.294028, 36.978747 ], [ -79.294162, 36.978771 ], [ -79.294243, 36.9788 ], [ -79.294439, 36.978883 ], [ -79.294626, 36.978979 ], [ -79.294782, 36.979072 ], [ -79.294921, 36.979174 ], [ -79.295023, 36.979263 ], [ -79.295281, 36.979534 ], [ -79.295458, 36.979739 ], [ -79.296347, 36.980843 ], [ -79.296549, 36.981064 ], [ -79.296594, 36.981095 ], [ -79.296695, 36.981144 ], [ -79.296788, 36.98117 ], [ -79.296916, 36.981184 ], [ -79.297032, 36.981182 ], [ -79.297147, 36.981165 ], [ -79.297933, 36.980962 ], [ -79.298145, 36.980893 ], [ -79.298401, 36.98079 ], [ -79.298602, 36.980696 ], [ -79.298795, 36.980593 ], [ -79.299134, 36.980402 ], [ -79.299407, 36.980244 ], [ -79.299963, 36.9799 ], [ -79.301767, 36.97881 ], [ -79.301976, 36.978691 ], [ -79.3021, 36.978619 ], [ -79.302508, 36.978369 ], [ -79.302614, 36.978309 ], [ -79.3028, 36.97822 ], [ -79.302995, 36.978145 ], [ -79.303113, 36.978114 ], [ -79.303153, 36.978249 ], [ -79.303232, 36.978565 ], [ -79.303319, 36.978989 ], [ -79.303326, 36.979184 ], [ -79.303313, 36.979346 ], [ -79.30324, 36.979748 ], [ -79.303136, 36.980362 ], [ -79.303088, 36.980609 ], [ -79.302996, 36.981143 ], [ -79.302982, 36.981226 ], [ -79.302977, 36.981321 ], [ -79.302986, 36.98144 ], [ -79.303013, 36.981556 ], [ -79.303057, 36.98167 ], [ -79.303191, 36.9819 ], [ -79.303336, 36.982126 ], [ -79.303702, 36.982652 ], [ -79.304322, 36.983486 ], [ -79.304588, 36.98382 ], [ -79.304756, 36.984051 ], [ -79.304903, 36.984229 ], [ -79.305059, 36.984403 ], [ -79.305145, 36.984487 ], [ -79.305336, 36.984648 ], [ -79.305612, 36.98486 ], [ -79.30569, 36.984915 ], [ -79.305765, 36.984974 ], [ -79.305944, 36.98513 ], [ -79.306108, 36.985295 ], [ -79.306259, 36.985469 ], [ -79.306333, 36.98557 ], [ -79.306437, 36.985737 ], [ -79.306524, 36.985911 ], [ -79.306595, 36.98609 ], [ -79.306677, 36.986365 ], [ -79.306734, 36.98662 ], [ -79.306773, 36.986878 ], [ -79.306759, 36.986998 ], [ -79.306724, 36.987146 ], [ -79.306621, 36.987426 ], [ -79.306591, 36.987545 ], [ -79.306555, 36.987745 ], [ -79.306536, 36.987984 ], [ -79.30653, 36.988172 ], [ -79.306539, 36.988321 ], [ -79.30655, 36.988398 ], [ -79.306566, 36.988507 ], [ -79.306673, 36.988967 ], [ -79.306789, 36.989416 ], [ -79.30681, 36.989518 ], [ -79.306831, 36.98969 ], [ -79.306833, 36.989828 ], [ -79.306822, 36.989888 ], [ -79.306771, 36.990067 ], [ -79.306696, 36.99024 ], [ -79.306569, 36.990463 ], [ -79.306374, 36.99078 ], [ -79.30633, 36.990863 ], [ -79.306292, 36.990972 ], [ -79.306271, 36.991084 ], [ -79.306268, 36.991229 ], [ -79.306282, 36.991421 ], [ -79.306323, 36.991648 ], [ -79.30657, 36.992516 ], [ -79.306601, 36.992703 ], [ -79.306614, 36.992892 ], [ -79.306598, 36.993111 ], [ -79.306569, 36.993287 ], [ -79.306553, 36.993345 ], [ -79.306526, 36.993432 ], [ -79.306466, 36.993574 ], [ -79.306313, 36.993848 ], [ -79.305971, 36.994382 ], [ -79.305826, 36.994647 ], [ -79.305382, 36.995598 ], [ -79.305197, 36.995963 ], [ -79.305065, 36.996284 ], [ -79.304983, 36.996521 ], [ -79.304954, 36.99668 ], [ -79.30495, 36.996815 ], [ -79.304959, 36.996932 ], [ -79.304988, 36.997077 ], [ -79.305024, 36.99719 ], [ -79.305111, 36.99739 ], [ -79.305197, 36.997567 ], [ -79.30532, 36.997782 ], [ -79.305429, 36.997949 ], [ -79.305577, 36.998153 ], [ -79.306017, 36.99873 ], [ -79.306204, 36.998965 ], [ -79.306407, 36.999192 ], [ -79.306624, 36.999411 ], [ -79.30672, 36.999489 ], [ -79.306828, 36.999557 ], [ -79.306922, 36.999602 ], [ -79.307072, 36.999656 ], [ -79.307354, 36.999723 ], [ -79.307628, 36.999778 ], [ -79.308892, 36.999988 ], [ -79.309029, 37.00002 ], [ -79.309135, 37.000056 ], [ -79.30926, 37.000112 ], [ -79.309374, 37.00018 ], [ -79.309478, 37.000259 ], [ -79.30959, 37.000372 ], [ -79.309743, 37.000552 ], [ -79.31029, 37.001344 ], [ -79.31037, 37.001451 ], [ -79.310486, 37.001568 ], [ -79.310598, 37.001654 ], [ -79.310697, 37.001714 ], [ -79.310838, 37.001785 ], [ -79.310991, 37.001844 ], [ -79.31115, 37.001891 ], [ -79.311632, 37.001979 ], [ -79.312359, 37.002135 ], [ -79.312455, 37.002156 ], [ -79.312915, 37.002271 ], [ -79.313026, 37.002296 ], [ -79.313639, 37.002422 ], [ -79.314311, 37.002515 ], [ -79.314769, 37.002553 ], [ -79.315227, 37.002582 ], [ -79.315352, 37.002604 ], [ -79.315472, 37.002641 ], [ -79.315543, 37.002685 ], [ -79.315621, 37.00275 ], [ -79.315685, 37.002824 ], [ -79.315725, 37.002889 ], [ -79.315888, 37.002832 ], [ -79.316221, 37.002733 ], [ -79.316448, 37.002678 ], [ -79.31752, 37.002455 ], [ -79.318524, 37.002275 ], [ -79.319059, 37.002211 ], [ -79.319268, 37.002199 ], [ -79.319435, 37.0022 ], [ -79.319651, 37.002214 ], [ -79.319786, 37.002226 ], [ -79.320258, 37.002279 ], [ -79.320522, 37.002298 ], [ -79.320786, 37.002302 ], [ -79.320953, 37.002288 ], [ -79.321116, 37.002258 ], [ -79.321274, 37.002213 ], [ -79.321381, 37.00217 ], [ -79.321762, 37.002001 ], [ -79.322382, 37.001698 ], [ -79.322844, 37.001466 ], [ -79.323023, 37.001376 ], [ -79.323292, 37.001249 ], [ -79.32357, 37.001134 ], [ -79.323943, 37.001003 ], [ -79.324098, 37.000958 ], [ -79.324162, 37.000945 ], [ -79.32513, 37.000843 ], [ -79.325325, 37.000814 ], [ -79.325517, 37.000777 ], [ -79.325753, 37.000719 ], [ -79.327186, 37.000266 ], [ -79.327482, 37.000173 ], [ -79.327802, 37.00008 ], [ -79.328598, 36.999838 ], [ -79.329158, 36.999654 ], [ -79.329204, 36.999715 ], [ -79.329343, 36.999894 ], [ -79.32942, 36.999975 ], [ -79.329588, 37.000125 ], [ -79.329742, 37.000239 ], [ -79.329777, 37.000256 ], [ -79.329869, 37.000291 ], [ -79.329988, 37.000315 ], [ -79.330091, 37.000318 ], [ -79.33027, 37.000316 ], [ -79.330449, 37.000298 ], [ -79.331035, 37.000223 ], [ -79.331427, 37.000184 ], [ -79.331855, 37.000129 ], [ -79.333009, 37.000023 ], [ -79.334568, 36.999869 ], [ -79.335002, 36.999826 ], [ -79.33552, 36.999806 ], [ -79.33606, 36.999814 ], [ -79.336208, 36.999833 ], [ -79.336352, 36.999866 ], [ -79.33649, 36.999913 ], [ -79.336644, 36.999986 ], [ -79.336856, 37.000123 ], [ -79.336962, 37.000203 ], [ -79.337096, 37.000316 ], [ -79.337325, 37.000539 ], [ -79.337519, 37.000761 ], [ -79.338522, 37.001965 ], [ -79.339126, 37.002688 ], [ -79.339574, 37.003185 ], [ -79.340385, 37.004106 ], [ -79.340479, 37.004212 ], [ -79.340603, 37.004341 ], [ -79.340773, 37.00449 ], [ -79.340929, 37.004602 ], [ -79.341131, 37.004723 ], [ -79.341632, 37.004968 ], [ -79.341875, 37.005087 ], [ -79.342172, 37.005233 ], [ -79.342594, 37.00542 ], [ -79.343189, 37.005708 ], [ -79.343817, 37.006011 ], [ -79.344455, 37.006335 ], [ -79.344712, 37.00647 ], [ -79.345697, 37.006916 ], [ -79.345837, 37.006985 ], [ -79.346006, 37.00708 ], [ -79.346221, 37.007218 ], [ -79.347403, 37.008016 ], [ -79.347493, 37.008071 ], [ -79.347634, 37.008171 ], [ -79.347763, 37.008281 ], [ -79.347971, 37.008497 ], [ -79.348051, 37.008623 ], [ -79.348135, 37.008786 ], [ -79.348201, 37.008954 ], [ -79.34825, 37.009126 ], [ -79.348316, 37.00954 ], [ -79.348397, 37.010196 ], [ -79.34854, 37.01111 ], [ -79.348616, 37.011496 ], [ -79.348778, 37.012266 ], [ -79.349159, 37.013946 ], [ -79.349315, 37.014628 ], [ -79.349636, 37.015919 ], [ -79.349688, 37.016183 ], [ -79.349795, 37.016628 ], [ -79.349854, 37.016827 ], [ -79.349915, 37.01701 ], [ -79.350064, 37.017337 ], [ -79.350135, 37.017464 ], [ -79.350159, 37.017499 ], [ -79.350325, 37.017735 ], [ -79.35042, 37.017865 ], [ -79.350584, 37.018129 ], [ -79.35072, 37.01842 ], [ -79.350808, 37.018683 ], [ -79.35089, 37.018981 ], [ -79.350968, 37.019317 ], [ -79.35119, 37.020219 ], [ -79.351251, 37.020445 ], [ -79.351346, 37.020719 ], [ -79.351414, 37.020888 ], [ -79.351505, 37.021079 ], [ -79.351682, 37.021459 ], [ -79.351825, 37.02176 ], [ -79.352185, 37.022473 ], [ -79.352628, 37.023433 ], [ -79.352751, 37.023743 ], [ -79.35282, 37.023863 ], [ -79.352895, 37.023965 ], [ -79.353012, 37.024078 ], [ -79.353078, 37.024127 ], [ -79.353186, 37.024186 ], [ -79.353325, 37.024244 ], [ -79.353398, 37.024265 ], [ -79.353421, 37.02427 ], [ -79.353621, 37.024315 ], [ -79.353675, 37.024321 ], [ -79.35392, 37.024336 ], [ -79.354286, 37.024379 ], [ -79.354423, 37.024385 ], [ -79.354844, 37.024375 ], [ -79.355058, 37.024359 ], [ -79.355214, 37.024339 ], [ -79.355354, 37.024308 ], [ -79.355614, 37.024238 ], [ -79.355718, 37.024209 ], [ -79.355965, 37.024125 ], [ -79.356147, 37.024057 ], [ -79.356485, 37.02394 ], [ -79.356546, 37.023919 ], [ -79.356797, 37.023824 ], [ -79.356964, 37.023769 ], [ -79.357077, 37.023757 ], [ -79.357196, 37.023767 ], [ -79.357262, 37.023786 ], [ -79.357309, 37.023811 ], [ -79.35735, 37.023849 ], [ -79.357388, 37.023905 ], [ -79.357541, 37.024317 ], [ -79.357583, 37.024391 ], [ -79.357634, 37.024438 ], [ -79.357685, 37.024467 ], [ -79.357747, 37.024487 ], [ -79.35783, 37.024497 ], [ -79.357899, 37.024495 ], [ -79.35801, 37.02448 ], [ -79.358102, 37.02446 ], [ -79.358409, 37.025941 ], [ -79.358471, 37.026316 ], [ -79.358502, 37.026637 ], [ -79.358517, 37.026844 ], [ -79.358519, 37.027185 ], [ -79.358497, 37.027679 ], [ -79.358457, 37.028033 ], [ -79.358398, 37.028378 ], [ -79.358301, 37.028779 ], [ -79.358082, 37.029574 ], [ -79.357957, 37.030026 ], [ -79.357813, 37.030609 ], [ -79.357745, 37.03095 ], [ -79.357685, 37.031344 ], [ -79.357656, 37.031612 ], [ -79.357621, 37.032199 ], [ -79.357619, 37.032445 ], [ -79.357631, 37.032766 ], [ -79.357637, 37.032893 ], [ -79.357666, 37.033258 ], [ -79.357711, 37.033639 ], [ -79.357789, 37.034066 ], [ -79.357875, 37.034441 ], [ -79.357922, 37.034622 ], [ -79.358521, 37.036938 ], [ -79.358613, 37.037315 ], [ -79.358687, 37.037658 ], [ -79.358786, 37.038217 ], [ -79.358856, 37.038791 ], [ -79.358911, 37.039356 ], [ -79.358965, 37.0401 ], [ -79.359051, 37.041306 ], [ -79.359073, 37.041825 ], [ -79.359059, 37.042471 ], [ -79.359012, 37.042954 ], [ -79.35899, 37.04313 ], [ -79.358922, 37.043537 ], [ -79.358829, 37.043973 ], [ -79.358773, 37.044171 ], [ -79.358704, 37.044417 ], [ -79.358541, 37.044914 ], [ -79.358352, 37.045429 ], [ -79.357856, 37.04678 ], [ -79.357794, 37.046961 ], [ -79.357564, 37.047556 ], [ -79.357409, 37.047915 ], [ -79.357338, 37.048062 ], [ -79.357278, 37.048184 ], [ -79.356942, 37.048801 ], [ -79.356841, 37.048967 ], [ -79.356589, 37.049349 ], [ -79.356363, 37.049677 ], [ -79.354212, 37.052783 ], [ -79.353972, 37.053148 ], [ -79.353865, 37.053295 ], [ -79.353452, 37.053889 ], [ -79.352197, 37.055711 ], [ -79.352126, 37.055808 ], [ -79.351983, 37.056023 ], [ -79.351596, 37.056539 ], [ -79.351413, 37.056761 ], [ -79.35122, 37.056979 ], [ -79.351018, 37.057191 ], [ -79.35075, 37.057445 ], [ -79.350603, 37.057584 ], [ -79.35029, 37.057856 ], [ -79.348032, 37.059645 ], [ -79.346954, 37.060488 ], [ -79.345892, 37.06133 ], [ -79.345295, 37.061797 ], [ -79.344778, 37.062208 ], [ -79.344716, 37.062258 ], [ -79.343942, 37.062866 ], [ -79.343259, 37.06342 ], [ -79.342925, 37.063722 ], [ -79.342732, 37.063907 ], [ -79.342302, 37.064351 ], [ -79.342055, 37.06463 ], [ -79.341843, 37.064885 ], [ -79.341424, 37.065452 ], [ -79.341048, 37.066036 ], [ -79.340718, 37.066647 ], [ -79.340066, 37.068047 ], [ -79.338982, 37.070343 ], [ -79.336951, 37.074656 ], [ -79.336672, 37.075265 ], [ -79.335622, 37.077497 ], [ -79.335265, 37.078252 ], [ -79.33489, 37.079062 ], [ -79.334833, 37.079182 ], [ -79.334222, 37.080477 ], [ -79.333262, 37.082521 ], [ -79.333001, 37.083079 ], [ -79.332628, 37.084028 ], [ -79.332548, 37.084278 ], [ -79.332388, 37.08478 ], [ -79.332201, 37.085539 ], [ -79.33204, 37.086421 ], [ -79.33196, 37.086978 ], [ -79.331907, 37.087757 ], [ -79.331871, 37.088536 ], [ -79.33185, 37.089317 ], [ -79.331805, 37.090324 ], [ -79.331772, 37.091338 ], [ -79.331768, 37.092235 ], [ -79.33183, 37.093576 ], [ -79.331943, 37.095022 ], [ -79.332045, 37.096198 ], [ -79.332341, 37.099713 ], [ -79.332397, 37.100421 ], [ -79.332436, 37.101086 ], [ -79.332443, 37.1013 ], [ -79.332438, 37.10199 ], [ -79.332418, 37.102426 ], [ -79.332391, 37.102795 ], [ -79.332337, 37.103324 ], [ -79.332244, 37.103966 ], [ -79.332205, 37.104185 ], [ -79.332175, 37.104355 ], [ -79.332056, 37.104907 ], [ -79.332041, 37.104978 ], [ -79.331903, 37.105494 ], [ -79.331733, 37.106053 ], [ -79.331559, 37.106562 ], [ -79.33131, 37.107195 ], [ -79.331178, 37.107501 ], [ -79.330959, 37.107973 ], [ -79.330748, 37.108399 ], [ -79.330489, 37.108876 ], [ -79.330365, 37.109093 ], [ -79.330155, 37.10944 ], [ -79.329757, 37.110058 ], [ -79.328813, 37.111446 ], [ -79.328701, 37.111611 ], [ -79.327118, 37.113932 ], [ -79.327107, 37.113947 ], [ -79.326498, 37.114802 ], [ -79.326178, 37.115223 ], [ -79.326128, 37.115289 ], [ -79.32568, 37.115855 ], [ -79.325061, 37.116595 ], [ -79.324816, 37.116878 ], [ -79.324497, 37.117235 ], [ -79.324161, 37.117601 ], [ -79.323816, 37.117964 ], [ -79.323589, 37.118194 ], [ -79.323104, 37.118678 ], [ -79.322015, 37.119732 ], [ -79.320826, 37.12089 ], [ -79.320279, 37.121415 ], [ -79.31993, 37.121729 ], [ -79.319276, 37.122271 ], [ -79.318828, 37.122609 ], [ -79.318377, 37.122925 ], [ -79.317535, 37.123462 ], [ -79.316595, 37.123987 ], [ -79.315586, 37.124473 ], [ -79.314958, 37.124742 ], [ -79.311931, 37.125973 ], [ -79.303986, 37.129196 ], [ -79.303177, 37.129555 ], [ -79.302367, 37.129915 ], [ -79.30095, 37.130617 ], [ -79.298871, 37.131691 ], [ -79.298008, 37.132146 ], [ -79.293574, 37.134491 ], [ -79.293108, 37.134749 ], [ -79.292712, 37.134937 ], [ -79.292278, 37.135125 ], [ -79.291836, 37.1353 ], [ -79.291351, 37.135473 ], [ -79.290905, 37.135615 ], [ -79.290365, 37.135772 ], [ -79.289641, 37.135941 ], [ -79.289078, 37.136055 ], [ -79.288222, 37.136184 ], [ -79.287781, 37.136228 ], [ -79.287205, 37.136269 ], [ -79.281895, 37.136526 ], [ -79.280512, 37.136607 ], [ -79.279731, 37.13667 ], [ -79.278968, 37.136747 ], [ -79.277922, 37.136872 ], [ -79.276244, 37.13712 ], [ -79.273494, 37.137624 ], [ -79.272005, 37.137904 ], [ -79.271794, 37.137944 ], [ -79.266159, 37.138985 ], [ -79.265643, 37.139056 ], [ -79.265084, 37.139119 ], [ -79.264404, 37.139177 ], [ -79.263826, 37.139213 ], [ -79.263263, 37.139234 ], [ -79.262666, 37.139241 ], [ -79.262103, 37.139234 ], [ -79.26149, 37.139213 ], [ -79.260895, 37.13918 ], [ -79.260488, 37.139149 ], [ -79.257811, 37.138859 ], [ -79.253283, 37.138354 ], [ -79.251817, 37.138189 ], [ -79.251311, 37.138138 ], [ -79.25082, 37.138104 ], [ -79.250344, 37.138087 ], [ -79.249949, 37.138091 ], [ -79.249141, 37.138125 ], [ -79.248701, 37.138169 ], [ -79.248255, 37.138232 ], [ -79.247815, 37.138303 ], [ -79.247404, 37.138388 ], [ -79.246983, 37.138492 ], [ -79.24619, 37.138741 ], [ -79.246034, 37.138799 ], [ -79.245567, 37.138991 ], [ -79.243639, 37.139795 ], [ -79.242121, 37.140435 ], [ -79.241618, 37.140648 ], [ -79.241125, 37.14089 ], [ -79.240755, 37.141103 ], [ -79.240471, 37.141293 ], [ -79.240237, 37.141475 ], [ -79.240023, 37.141661 ], [ -79.239659, 37.142024 ], [ -79.238717, 37.143115 ], [ -79.238653, 37.143189 ], [ -79.238443, 37.143404 ], [ -79.23822, 37.14361 ], [ -79.237972, 37.143817 ], [ -79.237711, 37.144013 ], [ -79.237424, 37.144206 ], [ -79.237139, 37.144378 ], [ -79.236846, 37.144536 ], [ -79.23672, 37.144599 ], [ -79.235366, 37.145185 ], [ -79.235031, 37.145327 ], [ -79.233118, 37.146139 ], [ -79.232943, 37.146214 ], [ -79.23213, 37.146559 ], [ -79.23159, 37.146789 ], [ -79.231268, 37.146943 ], [ -79.230971, 37.147103 ], [ -79.230723, 37.147248 ], [ -79.230589, 37.147333 ], [ -79.230303, 37.147527 ], [ -79.230067, 37.147704 ], [ -79.229831, 37.147902 ], [ -79.229608, 37.148108 ], [ -79.229398, 37.148324 ], [ -79.229192, 37.148559 ], [ -79.229002, 37.148802 ], [ -79.228823, 37.149065 ], [ -79.228683, 37.149299 ], [ -79.228557, 37.149537 ], [ -79.228436, 37.149807 ], [ -79.228332, 37.15008 ], [ -79.22824, 37.150371 ], [ -79.228165, 37.150679 ], [ -79.228144, 37.150787 ], [ -79.22795, 37.1522 ], [ -79.227939, 37.152282 ], [ -79.227922, 37.152405 ], [ -79.227831, 37.1531 ], [ -79.227768, 37.153577 ], [ -79.22775, 37.153704 ], [ -79.227707, 37.153951 ], [ -79.227614, 37.154338 ], [ -79.227519, 37.154642 ], [ -79.227394, 37.154981 ], [ -79.227259, 37.155289 ], [ -79.227113, 37.155579 ], [ -79.227008, 37.155764 ], [ -79.226979, 37.155814 ], [ -79.226931, 37.155892 ], [ -79.22673, 37.156196 ], [ -79.226531, 37.156466 ], [ -79.226359, 37.156679 ], [ -79.226091, 37.156981 ], [ -79.225836, 37.157239 ], [ -79.225577, 37.157477 ], [ -79.225307, 37.157704 ], [ -79.225033, 37.15791 ], [ -79.224838, 37.158043 ], [ -79.223223, 37.159106 ], [ -79.222625, 37.159494 ], [ -79.222577, 37.159525 ], [ -79.222526, 37.159559 ], [ -79.222269, 37.159725 ], [ -79.221758, 37.160065 ], [ -79.219427, 37.161585 ], [ -79.218294, 37.162324 ], [ -79.218211, 37.162378 ], [ -79.216923, 37.163217 ], [ -79.216426, 37.163539 ], [ -79.215909, 37.16389 ], [ -79.215531, 37.164171 ], [ -79.215221, 37.164425 ], [ -79.214936, 37.164678 ], [ -79.214674, 37.164929 ], [ -79.214292, 37.165324 ], [ -79.214244, 37.165374 ], [ -79.213081, 37.166582 ], [ -79.212642, 37.167038 ], [ -79.212368, 37.167324 ], [ -79.212048, 37.167658 ], [ -79.211768, 37.16795 ], [ -79.211486, 37.168245 ], [ -79.211416, 37.168318 ], [ -79.211008, 37.168744 ], [ -79.210963, 37.168791 ], [ -79.210689, 37.16908 ], [ -79.210304, 37.16953 ], [ -79.2101, 37.169782 ], [ -79.209923, 37.170006 ], [ -79.209526, 37.170538 ], [ -79.209343, 37.170798 ], [ -79.207037, 37.174039 ], [ -79.206764, 37.174435 ], [ -79.206634, 37.174641 ], [ -79.206469, 37.174929 ], [ -79.206273, 37.17532 ], [ -79.20615, 37.175603 ], [ -79.206073, 37.175802 ], [ -79.206026, 37.175929 ], [ -79.205916, 37.176273 ], [ -79.205845, 37.176539 ], [ -79.205757, 37.176917 ], [ -79.205696, 37.177164 ], [ -79.205658, 37.177349 ], [ -79.205603, 37.177589 ], [ -79.205562, 37.177759 ], [ -79.205539, 37.177863 ], [ -79.205487, 37.178091 ], [ -79.205427, 37.178344 ], [ -79.205364, 37.178607 ], [ -79.205297, 37.178889 ], [ -79.205253, 37.179068 ], [ -79.20519, 37.179332 ], [ -79.205122, 37.179618 ], [ -79.205055, 37.179895 ], [ -79.204997, 37.180138 ], [ -79.204614, 37.181773 ], [ -79.204588, 37.181883 ], [ -79.204488, 37.182314 ], [ -79.204319, 37.183043 ], [ -79.204265, 37.183268 ], [ -79.204123, 37.18388 ], [ -79.203924, 37.184747 ], [ -79.203855, 37.185167 ], [ -79.203781, 37.185725 ], [ -79.203767, 37.185869 ], [ -79.203714, 37.186727 ], [ -79.203688, 37.188358 ], [ -79.203665, 37.189574 ], [ -79.203624, 37.192626 ], [ -79.203627, 37.192665 ], [ -79.203588, 37.193792 ], [ -79.203572, 37.194229 ], [ -79.203568, 37.194309 ], [ -79.203559, 37.194539 ], [ -79.203553, 37.194676 ], [ -79.203543, 37.194919 ], [ -79.203531, 37.195199 ], [ -79.203502, 37.195859 ], [ -79.203483, 37.196276 ], [ -79.203468, 37.196579 ], [ -79.203458, 37.196792 ], [ -79.203433, 37.197322 ], [ -79.203422, 37.197563 ], [ -79.20341, 37.197824 ], [ -79.203397, 37.198095 ], [ -79.20339, 37.198254 ], [ -79.203379, 37.19847 ], [ -79.203358, 37.198936 ], [ -79.20334, 37.19935 ], [ -79.203304, 37.200071 ], [ -79.203262, 37.200536 ], [ -79.203244, 37.200686 ], [ -79.203162, 37.201241 ], [ -79.203073, 37.201722 ], [ -79.20306, 37.201793 ], [ -79.203026, 37.201977 ], [ -79.202836, 37.203003 ], [ -79.202752, 37.203459 ], [ -79.202563, 37.204478 ], [ -79.202452, 37.205079 ], [ -79.202395, 37.205385 ], [ -79.201856, 37.208299 ], [ -79.201805, 37.208574 ], [ -79.201702, 37.209126 ], [ -79.201673, 37.209268 ], [ -79.201619, 37.209479 ], [ -79.201573, 37.209638 ], [ -79.201505, 37.209836 ], [ -79.201407, 37.210085 ], [ -79.201284, 37.210341 ], [ -79.201114, 37.21064 ], [ -79.201026, 37.210776 ], [ -79.200882, 37.21098 ], [ -79.200649, 37.211282 ], [ -79.200396, 37.211554 ], [ -79.199727, 37.212167 ], [ -79.199637, 37.212249 ], [ -79.199553, 37.212325 ], [ -79.199391, 37.212473 ], [ -79.199159, 37.212684 ], [ -79.19865, 37.213144 ], [ -79.197756, 37.213946 ], [ -79.197588, 37.214097 ], [ -79.197252, 37.214415 ], [ -79.196922, 37.214731 ], [ -79.196487, 37.215166 ], [ -79.196055, 37.215596 ], [ -79.195714, 37.216042 ], [ -79.195395, 37.216449 ], [ -79.194175, 37.218086 ], [ -79.193942, 37.2184 ], [ -79.193714, 37.218705 ], [ -79.193339, 37.219208 ], [ -79.193103, 37.219523 ], [ -79.192804, 37.219924 ], [ -79.192465, 37.220384 ], [ -79.191972, 37.221056 ], [ -79.191665, 37.221486 ], [ -79.191271, 37.222039 ], [ -79.191066, 37.222328 ], [ -79.190837, 37.222648 ], [ -79.190786, 37.222724 ], [ -79.190591, 37.223024 ], [ -79.190561, 37.223069 ], [ -79.190114, 37.223762 ], [ -79.189976, 37.223994 ], [ -79.189786, 37.224314 ], [ -79.189538, 37.224731 ], [ -79.189441, 37.224896 ], [ -79.189231, 37.225287 ], [ -79.188873, 37.225949 ], [ -79.188647, 37.226369 ], [ -79.188578, 37.226497 ], [ -79.188422, 37.22682 ], [ -79.187747, 37.228226 ], [ -79.187638, 37.228454 ], [ -79.186752, 37.230317 ], [ -79.186236, 37.23142 ], [ -79.186183, 37.231531 ], [ -79.186143, 37.231633 ], [ -79.186012, 37.231905 ], [ -79.185971, 37.232009 ], [ -79.185901, 37.232204 ], [ -79.185821, 37.232467 ], [ -79.185783, 37.232629 ], [ -79.185746, 37.232787 ], [ -79.185712, 37.232989 ], [ -79.185564, 37.234115 ], [ -79.18554, 37.234342 ], [ -79.185535, 37.234388 ], [ -79.185527, 37.234464 ], [ -79.185489, 37.234824 ], [ -79.185459, 37.235133 ], [ -79.185442, 37.235447 ], [ -79.185444, 37.235802 ], [ -79.185467, 37.236157 ], [ -79.185494, 37.236478 ], [ -79.185509, 37.236629 ], [ -79.185568, 37.237037 ], [ -79.185613, 37.237268 ], [ -79.185642, 37.237403 ], [ -79.185719, 37.237706 ], [ -79.185791, 37.237965 ], [ -79.185811, 37.238037 ], [ -79.185899, 37.238345 ], [ -79.185952, 37.238527 ], [ -79.18597, 37.23859 ], [ -79.186042, 37.238834 ], [ -79.186525, 37.240494 ], [ -79.186638, 37.240882 ], [ -79.186786, 37.241392 ], [ -79.186995, 37.242108 ], [ -79.187061, 37.242336 ], [ -79.187075, 37.242384 ], [ -79.187298, 37.243149 ], [ -79.187378, 37.243422 ], [ -79.187527, 37.243936 ], [ -79.187774, 37.244774 ], [ -79.187853, 37.245008 ], [ -79.187949, 37.245331 ], [ -79.187975, 37.245426 ], [ -79.18809, 37.245933 ], [ -79.188158, 37.246339 ], [ -79.188193, 37.246639 ], [ -79.188214, 37.246935 ], [ -79.188219, 37.247189 ], [ -79.188219, 37.247284 ], [ -79.188204, 37.247624 ], [ -79.188173, 37.24795 ], [ -79.188121, 37.248287 ], [ -79.188078, 37.248502 ], [ -79.188012, 37.248777 ], [ -79.187964, 37.248948 ], [ -79.18752, 37.250322 ], [ -79.187502, 37.250377 ], [ -79.187461, 37.250489 ], [ -79.187101, 37.251604 ], [ -79.186977, 37.251986 ], [ -79.186803, 37.252487 ], [ -79.186647, 37.252862 ], [ -79.186473, 37.253233 ], [ -79.1864, 37.253375 ], [ -79.186369, 37.253435 ], [ -79.186196, 37.253727 ], [ -79.186096, 37.253883 ], [ -79.185846, 37.254253 ], [ -79.185619, 37.254587 ], [ -79.184816, 37.255765 ], [ -79.184332, 37.256471 ], [ -79.184251, 37.256583 ], [ -79.183919, 37.257073 ], [ -79.183282, 37.258009 ], [ -79.183273, 37.258023 ], [ -79.182658, 37.258928 ], [ -79.182428, 37.259266 ], [ -79.182236, 37.259548 ], [ -79.182189, 37.259617 ], [ -79.181677, 37.260371 ], [ -79.180889, 37.261527 ], [ -79.180329, 37.262346 ], [ -79.179966, 37.262877 ], [ -79.178561, 37.264935 ], [ -79.177834, 37.265998 ], [ -79.17762, 37.266312 ], [ -79.177577, 37.266375 ], [ -79.177344, 37.266717 ], [ -79.177268, 37.266828 ], [ -79.175738, 37.269066 ], [ -79.175293, 37.269718 ], [ -79.175059, 37.270062 ], [ -79.175024, 37.270113 ], [ -79.174746, 37.27052 ], [ -79.174499, 37.270885 ], [ -79.174225, 37.271286 ], [ -79.17318, 37.27282 ], [ -79.172596, 37.273676 ], [ -79.172062, 37.274457 ], [ -79.17205, 37.274476 ], [ -79.171892, 37.274707 ], [ -79.171746, 37.274919 ], [ -79.170612, 37.276581 ], [ -79.170091, 37.277344 ], [ -79.170074, 37.277368 ], [ -79.169014, 37.27887 ], [ -79.168768, 37.279279 ], [ -79.168446, 37.279751 ], [ -79.168095, 37.28026 ], [ -79.167791, 37.280704 ], [ -79.167004, 37.281854 ], [ -79.166839, 37.282126 ], [ -79.166686, 37.282417 ], [ -79.166553, 37.282715 ], [ -79.166455, 37.282978 ], [ -79.166365, 37.283271 ], [ -79.166331, 37.283406 ], [ -79.166277, 37.283662 ], [ -79.166236, 37.283934 ], [ -79.166211, 37.284233 ], [ -79.166208, 37.284331 ], [ -79.16621, 37.284606 ], [ -79.166232, 37.284894 ], [ -79.166273, 37.28518 ], [ -79.166341, 37.285491 ], [ -79.166394, 37.28568 ], [ -79.166419, 37.28576 ], [ -79.16653, 37.286061 ], [ -79.16656, 37.286133 ], [ -79.166601, 37.286228 ], [ -79.167073, 37.287187 ], [ -79.167342, 37.287727 ], [ -79.167647, 37.288335 ], [ -79.167961, 37.288961 ], [ -79.168213, 37.289466 ], [ -79.168669, 37.290363 ], [ -79.169252, 37.291516 ], [ -79.169707, 37.292425 ], [ -79.170019, 37.293049 ], [ -79.170164, 37.293337 ], [ -79.170762, 37.294525 ], [ -79.171017, 37.295032 ], [ -79.171197, 37.29539 ], [ -79.171228, 37.295451 ], [ -79.171707, 37.296402 ], [ -79.171854, 37.296694 ], [ -79.172057, 37.297099 ], [ -79.172329, 37.297639 ], [ -79.172756, 37.298485 ], [ -79.172921, 37.29877 ], [ -79.173118, 37.299071 ], [ -79.173326, 37.299351 ], [ -79.1734, 37.299443 ], [ -79.173711, 37.299824 ], [ -79.174643, 37.300928 ], [ -79.177789, 37.304649 ], [ -79.17841, 37.305383 ], [ -79.179563, 37.306751 ], [ -79.18128, 37.308787 ], [ -79.181492, 37.309036 ], [ -79.181949, 37.309573 ], [ -79.182599, 37.310336 ], [ -79.183198, 37.311046 ], [ -79.183775, 37.311729 ], [ -79.183964, 37.311947 ], [ -79.18428, 37.312314 ], [ -79.18536, 37.313557 ], [ -79.18553, 37.313753 ], [ -79.18588, 37.314159 ], [ -79.186286, 37.314624 ], [ -79.186592, 37.314975 ], [ -79.186893, 37.31532 ], [ -79.187155, 37.315623 ], [ -79.187287, 37.315796 ], [ -79.187433, 37.315958 ], [ -79.187603, 37.316193 ], [ -79.187705, 37.316348 ], [ -79.187781, 37.316469 ], [ -79.187895, 37.316666 ], [ -79.188063, 37.316995 ], [ -79.188211, 37.31734 ], [ -79.188267, 37.317488 ], [ -79.188574, 37.31828 ], [ -79.18873, 37.318682 ], [ -79.188773, 37.318793 ], [ -79.188818, 37.318907 ], [ -79.188983, 37.319332 ], [ -79.189167, 37.319817 ], [ -79.18919, 37.319881 ], [ -79.189276, 37.320122 ], [ -79.189293, 37.320183 ], [ -79.189372, 37.320484 ], [ -79.189407, 37.320635 ], [ -79.189445, 37.320825 ], [ -79.189477, 37.321015 ], [ -79.189492, 37.321115 ], [ -79.189533, 37.321458 ], [ -79.189536, 37.321492 ], [ -79.189586, 37.322119 ], [ -79.189602, 37.322319 ], [ -79.189637, 37.32275 ], [ -79.189647, 37.322876 ], [ -79.189704, 37.323523 ], [ -79.189737, 37.323892 ], [ -79.189747, 37.323997 ], [ -79.189761, 37.324147 ], [ -79.189781, 37.324375 ], [ -79.189798, 37.324545 ], [ -79.189823, 37.324722 ], [ -79.189861, 37.324935 ], [ -79.189896, 37.325095 ], [ -79.189922, 37.3252 ], [ -79.190034, 37.325593 ], [ -79.190115, 37.325884 ], [ -79.190279, 37.326471 ], [ -79.190558, 37.327468 ], [ -79.190626, 37.327737 ], [ -79.190656, 37.327855 ], [ -79.190719, 37.328102 ], [ -79.190893, 37.328783 ], [ -79.19093, 37.328914 ], [ -79.19114, 37.329665 ], [ -79.191197, 37.329849 ], [ -79.191289, 37.330174 ], [ -79.191411, 37.330604 ], [ -79.191427, 37.330662 ], [ -79.191549, 37.331144 ], [ -79.191612, 37.331407 ], [ -79.191674, 37.33166 ], [ -79.191713, 37.331945 ], [ -79.191731, 37.332216 ], [ -79.191727, 37.3324 ], [ -79.191718, 37.332618 ], [ -79.191688, 37.333114 ], [ -79.191671, 37.333265 ], [ -79.191652, 37.333506 ], [ -79.191625, 37.33369 ], [ -79.191591, 37.333978 ], [ -79.191586, 37.334109 ], [ -79.191605, 37.334336 ], [ -79.19161, 37.334672 ], [ -79.191612, 37.334771 ], [ -79.191619, 37.335165 ], [ -79.191615, 37.335425 ], [ -79.191612, 37.335464 ], [ -79.191591, 37.335798 ], [ -79.191573, 37.33597 ], [ -79.19153, 37.336198 ], [ -79.191511, 37.3363 ], [ -79.191476, 37.336481 ], [ -79.191396, 37.336901 ], [ -79.191254, 37.33724 ], [ -79.191108, 37.337564 ], [ -79.190891, 37.337852 ], [ -79.190707, 37.338004 ], [ -79.190446, 37.338136 ], [ -79.190159, 37.338232 ], [ -79.189809, 37.338303 ], [ -79.189504, 37.338343 ], [ -79.189039, 37.338414 ], [ -79.188663, 37.33847 ], [ -79.188351, 37.338526 ], [ -79.18802, 37.338571 ], [ -79.18767, 37.338617 ], [ -79.187276, 37.338677 ], [ -79.18683, 37.338758 ], [ -79.186448, 37.338854 ], [ -79.186232, 37.338986 ], [ -79.186034, 37.339158 ], [ -79.185913, 37.339381 ], [ -79.185862, 37.339654 ], [ -79.185792, 37.339958 ], [ -79.185735, 37.340246 ], [ -79.185608, 37.340565 ], [ -79.185474, 37.340849 ], [ -79.185264, 37.341152 ], [ -79.185009, 37.341421 ], [ -79.184748, 37.341658 ], [ -79.184399, 37.341989 ], [ -79.184093, 37.342254 ], [ -79.183658, 37.342682 ], [ -79.18294, 37.343536 ], [ -79.182113, 37.344505 ], [ -79.181077, 37.345699 ], [ -79.180004, 37.346871 ], [ -79.178729, 37.348196 ], [ -79.177389, 37.349407 ], [ -79.177129, 37.349621 ], [ -79.176626, 37.350036 ], [ -79.173129, 37.353092 ], [ -79.169752, 37.356318 ], [ -79.169186, 37.356859 ], [ -79.166439, 37.359647 ], [ -79.165165, 37.360856 ], [ -79.164528, 37.361444 ], [ -79.163946, 37.361878 ], [ -79.162943, 37.362614 ], [ -79.161891, 37.363349 ], [ -79.159885, 37.364693 ], [ -79.158866, 37.365389 ], [ -79.157915, 37.36609 ], [ -79.156262, 37.367299 ], [ -79.153378, 37.36939 ], [ -79.1513, 37.370777 ], [ -79.148798, 37.372337 ], [ -79.146813, 37.373529 ], [ -79.146135, 37.37394 ], [ -79.145298, 37.374385 ], [ -79.144399, 37.374808 ], [ -79.143032, 37.375351 ], [ -79.142887, 37.375396 ], [ -79.141407, 37.375861 ], [ -79.13952, 37.376309 ], [ -79.137442, 37.376753 ], [ -79.136385, 37.376976 ], [ -79.135221, 37.37722 ], [ -79.134065, 37.377456 ], [ -79.132756, 37.377733 ], [ -79.131505, 37.377997 ], [ -79.130701, 37.378165 ], [ -79.129655, 37.378385 ], [ -79.128812, 37.378561 ], [ -79.127809, 37.378776 ], [ -79.127166, 37.378891 ], [ -79.124907, 37.379433 ], [ -79.122351, 37.380007 ], [ -79.119924, 37.380555 ], [ -79.118369, 37.380958 ], [ -79.116892, 37.381492 ], [ -79.11429, 37.382508 ], [ -79.111589, 37.383564 ], [ -79.110432, 37.384015 ], [ -79.108723, 37.384663 ], [ -79.107004, 37.385341 ], [ -79.10533, 37.38597 ], [ -79.10529, 37.385969 ], [ -79.104874, 37.386095 ], [ -79.104406, 37.386191 ], [ -79.103958, 37.38624 ], [ -79.103328, 37.386271 ], [ -79.101681, 37.386155 ], [ -79.101144, 37.386117 ], [ -79.100418, 37.386038 ], [ -79.097991, 37.385843 ], [ -79.09636, 37.385744 ], [ -79.095982, 37.385658 ], [ -79.095845, 37.385614 ], [ -79.09571, 37.385555 ], [ -79.095567, 37.38548 ], [ -79.095427, 37.38539 ], [ -79.095308, 37.385296 ], [ -79.09517, 37.385161 ], [ -79.09509, 37.385054 ], [ -79.094998, 37.384905 ], [ -79.094916, 37.384737 ], [ -79.094844, 37.384528 ], [ -79.094656, 37.383845 ], [ -79.094531, 37.38345 ], [ -79.094325, 37.383054 ], [ -79.094038, 37.38276 ], [ -79.093621, 37.382467 ], [ -79.093187, 37.382294 ], [ -79.092689, 37.382201 ], [ -79.092284, 37.382201 ], [ -79.091903, 37.382257 ], [ -79.091551, 37.382364 ], [ -79.091187, 37.382541 ], [ -79.090959, 37.382723 ], [ -79.090789, 37.382882 ], [ -79.090589, 37.383115 ], [ -79.090443, 37.383376 ], [ -79.090284, 37.383744 ], [ -79.090225, 37.384 ], [ -79.090179, 37.384541 ], [ -79.090062, 37.385779 ], [ -79.089925, 37.386644 ], [ -79.089849, 37.387226 ], [ -79.089779, 37.387541 ], [ -79.089689, 37.387836 ], [ -79.0895, 37.38838 ], [ -79.089436, 37.388633 ], [ -79.089405, 37.388841 ], [ -79.089289, 37.389685 ], [ -79.089161, 37.39093 ], [ -79.089008, 37.392008 ], [ -79.08881, 37.394069 ], [ -79.088768, 37.394579 ], [ -79.088645, 37.395885 ], [ -79.088477, 37.397207 ], [ -79.087956, 37.401181 ], [ -79.087825, 37.401823 ], [ -79.087665, 37.402308 ], [ -79.087554, 37.402629 ], [ -79.08736, 37.403142 ], [ -79.087142, 37.403562 ], [ -79.086923, 37.403937 ], [ -79.086762, 37.404195 ], [ -79.086439, 37.404708 ], [ -79.086251, 37.405002 ], [ -79.085982, 37.405393 ], [ -79.085647, 37.405896 ], [ -79.085037, 37.406824 ], [ -79.084691, 37.407346 ], [ -79.084239, 37.407998 ], [ -79.084081, 37.408208 ], [ -79.083969, 37.408376 ], [ -79.083852, 37.408534 ], [ -79.083752, 37.408705 ], [ -79.083641, 37.408893 ], [ -79.08253, 37.41059 ], [ -79.082107, 37.41155 ], [ -79.081937, 37.412163 ], [ -79.081833, 37.412538 ], [ -79.081757, 37.413176 ], [ -79.08171, 37.413903 ], [ -79.081751, 37.414774 ], [ -79.081781, 37.415758 ], [ -79.081777, 37.417393 ], [ -79.081646, 37.41901 ], [ -79.081485, 37.420256 ], [ -79.081292, 37.421219 ], [ -79.081057, 37.422257 ], [ -79.080513, 37.424117 ], [ -79.07951, 37.427155 ], [ -79.078061, 37.431195 ], [ -79.077269, 37.433524 ], [ -79.076993, 37.434391 ], [ -79.076647, 37.435495 ], [ -79.076395, 37.436608 ], [ -79.076304, 37.437254 ], [ -79.076229, 37.438019 ], [ -79.076213, 37.439312 ], [ -79.076213, 37.439413 ], [ -79.076155, 37.442774 ], [ -79.07614, 37.443179 ], [ -79.076116, 37.443841 ], [ -79.076046, 37.446058 ], [ -79.075976, 37.449173 ], [ -79.076002, 37.451689 ], [ -79.076065, 37.4523 ], [ -79.076262, 37.453 ], [ -79.076579, 37.453683 ], [ -79.076982, 37.454312 ], [ -79.077536, 37.45501 ], [ -79.079739, 37.457229 ], [ -79.080689, 37.458217 ], [ -79.081531, 37.459252 ], [ -79.082085, 37.460038 ], [ -79.082441, 37.460738 ], [ -79.082708, 37.461304 ], [ -79.082968, 37.461981 ], [ -79.083137, 37.462694 ], [ -79.083265, 37.463513 ], [ -79.083293, 37.464338 ], [ -79.083287, 37.464745 ], [ -79.083277, 37.465166 ], [ -79.083236, 37.465743 ], [ -79.083136, 37.466259 ], [ -79.082678, 37.468029 ], [ -79.082438, 37.469156 ], [ -79.08215, 37.470371 ], [ -79.081963, 37.471033 ], [ -79.081827, 37.471415 ], [ -79.081408, 37.472342 ], [ -79.081005, 37.47309 ], [ -79.080296, 37.474045 ], [ -79.079641, 37.474751 ], [ -79.078249, 37.476094 ], [ -79.077451, 37.477058 ], [ -79.076776, 37.477863 ], [ -79.076213, 37.478711 ], [ -79.075638, 37.479763 ], [ -79.075274, 37.480624 ], [ -79.074869, 37.481821 ], [ -79.074675, 37.482594 ], [ -79.074634, 37.482892 ], [ -79.074593, 37.483204 ], [ -79.07457, 37.483627 ], [ -79.074448, 37.484732 ], [ -79.074331, 37.485753 ], [ -79.074167, 37.486518 ], [ -79.073888, 37.487326 ], [ -79.073467, 37.488074 ], [ -79.07305, 37.488846 ], [ -79.072616, 37.489619 ], [ -79.072018, 37.490699 ], [ -79.07163, 37.49136 ], [ -79.070791, 37.492896 ], [ -79.070146, 37.494186 ], [ -79.06953, 37.495438 ], [ -79.068703, 37.497026 ], [ -79.067817, 37.498799 ], [ -79.067177, 37.500098 ], [ -79.066497, 37.501471 ], [ -79.066168, 37.502341 ], [ -79.065974, 37.503063 ], [ -79.065895, 37.503746 ], [ -79.065857, 37.504329 ], [ -79.065851, 37.505804 ], [ -79.065851, 37.506847 ], [ -79.065828, 37.508187 ], [ -79.065831, 37.509824 ], [ -79.0658, 37.510657 ], [ -79.065769, 37.511273 ], [ -79.065628, 37.51191 ], [ -79.065455, 37.512506 ], [ -79.065165, 37.513111 ], [ -79.064807, 37.513823 ], [ -79.064426, 37.514512 ], [ -79.063986, 37.515424 ], [ -79.063804, 37.515903 ], [ -79.063545, 37.516788 ], [ -79.063328, 37.51796 ], [ -79.063264, 37.519296 ], [ -79.063311, 37.520208 ], [ -79.063487, 37.521209 ], [ -79.063645, 37.522214 ], [ -79.063845, 37.523275 ], [ -79.06425, 37.525364 ], [ -79.064871, 37.528602 ], [ -79.065376, 37.531264 ], [ -79.066057, 37.534819 ], [ -79.066725, 37.538252 ], [ -79.0674, 37.541904 ], [ -79.06794, 37.544546 ], [ -79.068021, 37.545221 ], [ -79.068093, 37.545891 ], [ -79.068075, 37.546616 ], [ -79.067977, 37.547323 ], [ -79.067805, 37.547989 ], [ -79.06729, 37.549617 ], [ -79.066508, 37.552189 ], [ -79.066203, 37.55312 ], [ -79.065916, 37.554199 ], [ -79.06571, 37.554864 ], [ -79.065358, 37.555901 ], [ -79.06462, 37.558162 ], [ -79.064236, 37.559374 ], [ -79.064086, 37.559848 ], [ -79.063835, 37.560896 ], [ -79.063609, 37.561383 ], [ -79.063256, 37.561986 ], [ -79.062896, 37.562503 ], [ -79.062134, 37.563345 ], [ -79.061625, 37.563753 ], [ -79.06094, 37.564213 ], [ -79.058641, 37.565583 ], [ -79.05758, 37.566208 ], [ -79.056639, 37.566768 ], [ -79.055935, 37.567192 ], [ -79.055742, 37.567302 ], [ -79.055553, 37.567416 ], [ -79.055246, 37.567615 ], [ -79.054927, 37.567838 ], [ -79.054748, 37.567977 ], [ -79.054525, 37.568169 ], [ -79.05429, 37.568391 ], [ -79.054239, 37.568442 ], [ -79.054034, 37.568657 ], [ -79.053873, 37.56885 ], [ -79.053657, 37.569143 ], [ -79.053524, 37.569347 ], [ -79.053368, 37.569618 ], [ -79.053228, 37.569894 ], [ -79.053172, 37.570026 ], [ -79.053043, 37.570358 ], [ -79.05286, 37.57095 ], [ -79.052677, 37.571527 ], [ -79.052485, 37.572133 ], [ -79.052132, 37.573261 ], [ -79.051632, 37.57486 ], [ -79.051348, 37.57574 ], [ -79.051123, 37.576286 ], [ -79.051087, 37.576361 ], [ -79.050788, 37.576916 ], [ -79.050662, 37.577116 ], [ -79.050472, 37.577395 ], [ -79.050278, 37.577652 ], [ -79.050057, 37.577924 ], [ -79.049759, 37.578262 ], [ -79.049412, 37.578608 ], [ -79.049047, 37.578931 ], [ -79.047001, 37.580602 ], [ -79.046515, 37.580994 ], [ -79.046166, 37.58126 ], [ -79.045909, 37.581455 ], [ -79.04561, 37.58167 ], [ -79.045264, 37.581887 ], [ -79.044961, 37.582077 ], [ -79.044149, 37.582573 ], [ -79.04353, 37.582927 ], [ -79.04291, 37.58327 ], [ -79.042129, 37.58371 ], [ -79.041873, 37.583864 ], [ -79.041806, 37.58391 ], [ -79.041621, 37.584017 ], [ -79.041414, 37.584155 ], [ -79.041178, 37.58431 ], [ -79.040635, 37.584689 ], [ -79.039894, 37.585255 ], [ -79.039608, 37.585491 ], [ -79.03912, 37.585904 ], [ -79.038845, 37.586155 ], [ -79.038474, 37.586513 ], [ -79.03781, 37.587198 ], [ -79.037358, 37.587719 ], [ -79.037086, 37.588056 ], [ -79.036877, 37.588331 ], [ -79.036498, 37.588836 ], [ -79.036258, 37.589205 ], [ -79.035926, 37.589739 ], [ -79.034645, 37.591992 ], [ -79.034482, 37.592286 ], [ -79.034097, 37.592957 ], [ -79.033913, 37.593255 ], [ -79.033669, 37.593669 ], [ -79.033006, 37.594819 ], [ -79.032654, 37.595452 ], [ -79.032044, 37.596522 ], [ -79.031678, 37.597159 ], [ -79.031353, 37.597735 ], [ -79.03004, 37.600074 ], [ -79.029644, 37.600763 ], [ -79.028963, 37.601951 ], [ -79.028685, 37.602397 ], [ -79.02851, 37.602662 ], [ -79.028221, 37.603043 ], [ -79.027978, 37.603341 ], [ -79.027692, 37.60368 ], [ -79.027548, 37.60383 ], [ -79.027306, 37.604072 ], [ -79.027105, 37.604269 ], [ -79.02697, 37.604392 ], [ -79.026652, 37.60468 ], [ -79.026083, 37.605207 ], [ -79.026036, 37.60525 ], [ -79.025989, 37.605294 ], [ -79.025872, 37.605402 ], [ -79.02555, 37.605685 ], [ -79.025303, 37.605893 ], [ -79.025239, 37.605951 ], [ -79.025075, 37.606102 ], [ -79.024795, 37.606358 ], [ -79.024408, 37.606702 ], [ -79.024072, 37.607013 ], [ -79.024053, 37.607031 ], [ -79.023787, 37.607264 ], [ -79.023498, 37.607516 ], [ -79.023027, 37.607911 ], [ -79.022811, 37.60807 ], [ -79.022583, 37.608218 ], [ -79.022393, 37.608329 ], [ -79.022103, 37.608478 ], [ -79.021864, 37.608585 ], [ -79.021424, 37.608752 ], [ -79.020855, 37.608965 ], [ -79.020271, 37.609195 ], [ -79.020171, 37.609236 ], [ -79.019921, 37.609348 ], [ -79.019569, 37.609526 ], [ -79.019341, 37.609661 ], [ -79.019134, 37.609801 ], [ -79.018938, 37.609951 ], [ -79.018736, 37.61013 ], [ -79.018557, 37.610318 ], [ -79.018408, 37.6105 ], [ -79.018273, 37.610689 ], [ -79.018177, 37.610845 ], [ -79.018077, 37.611005 ], [ -79.017942, 37.61127 ], [ -79.01775, 37.611733 ], [ -79.017583, 37.612195 ], [ -79.017453, 37.612536 ], [ -79.01736, 37.612779 ], [ -79.017077, 37.613518 ], [ -79.016316, 37.615651 ], [ -79.016211, 37.615921 ], [ -79.015957, 37.616661 ], [ -79.015442, 37.618041 ], [ -79.015171, 37.618767 ], [ -79.015044, 37.619085 ], [ -79.014896, 37.619401 ], [ -79.014725, 37.619699 ], [ -79.014609, 37.619891 ], [ -79.014507, 37.620046 ], [ -79.014326, 37.620291 ], [ -79.014076, 37.620611 ], [ -79.013882, 37.620808 ], [ -79.013583, 37.621079 ], [ -79.012998, 37.621504 ], [ -79.01238, 37.621893 ], [ -79.010646, 37.622959 ], [ -79.01003, 37.623323 ], [ -79.009112, 37.623886 ], [ -79.007841, 37.62468 ], [ -79.007669, 37.624786 ], [ -79.00613, 37.625753 ], [ -79.00574, 37.625992 ], [ -79.004933, 37.626484 ], [ -79.004251, 37.626912 ], [ -79.004139, 37.626981 ], [ -79.003154, 37.627592 ], [ -79.001641, 37.628516 ], [ -79.001111, 37.628835 ], [ -79.00072, 37.62907 ], [ -79.000623, 37.62914 ], [ -79.000217, 37.629394 ], [ -78.998912, 37.630202 ], [ -78.998196, 37.630645 ], [ -78.997598, 37.631025 ], [ -78.997526, 37.631071 ], [ -78.997241, 37.631274 ], [ -78.996875, 37.631534 ], [ -78.996217, 37.63205 ], [ -78.995656, 37.632525 ], [ -78.995017, 37.633129 ], [ -78.994464, 37.633668 ], [ -78.993794, 37.634338 ], [ -78.992582, 37.635539 ], [ -78.99241, 37.635715 ], [ -78.992112, 37.636 ], [ -78.991971, 37.636127 ], [ -78.991598, 37.636454 ], [ -78.991319, 37.636676 ], [ -78.991111, 37.636827 ], [ -78.990724, 37.637089 ], [ -78.990344, 37.637324 ], [ -78.989967, 37.637537 ], [ -78.989578, 37.637737 ], [ -78.988855, 37.638052 ], [ -78.98807, 37.638382 ], [ -78.986736, 37.63892 ], [ -78.986454, 37.639034 ], [ -78.985803, 37.639316 ], [ -78.984897, 37.639687 ], [ -78.98388, 37.640096 ], [ -78.983117, 37.640414 ], [ -78.982726, 37.640573 ], [ -78.981774, 37.640959 ], [ -78.979687, 37.64182 ], [ -78.978231, 37.642417 ], [ -78.977005, 37.64291 ], [ -78.97646, 37.643116 ], [ -78.975777, 37.643333 ], [ -78.975711, 37.643354 ], [ -78.97542, 37.643425 ], [ -78.974834, 37.643551 ], [ -78.974604, 37.64359 ], [ -78.974067, 37.643681 ], [ -78.973393, 37.643752 ], [ -78.972559, 37.643813 ], [ -78.972242, 37.643839 ], [ -78.970006, 37.64399 ], [ -78.96903, 37.64406 ], [ -78.968589, 37.644095 ], [ -78.968224, 37.644136 ], [ -78.967889, 37.644182 ], [ -78.967664, 37.644226 ], [ -78.967387, 37.644293 ], [ -78.967224, 37.644341 ], [ -78.966957, 37.64443 ], [ -78.966688, 37.644536 ], [ -78.966474, 37.644631 ], [ -78.966164, 37.644789 ], [ -78.965983, 37.644902 ], [ -78.965692, 37.645098 ], [ -78.965428, 37.645294 ], [ -78.965238, 37.645456 ], [ -78.965063, 37.645628 ], [ -78.964898, 37.645816 ], [ -78.964762, 37.645992 ], [ -78.964605, 37.646219 ], [ -78.964465, 37.646453 ], [ -78.964354, 37.646672 ], [ -78.96426, 37.646896 ], [ -78.964184, 37.647124 ], [ -78.964105, 37.647472 ], [ -78.964045, 37.647822 ], [ -78.963795, 37.650137 ], [ -78.963771, 37.650446 ], [ -78.963726, 37.650831 ], [ -78.963699, 37.651104 ], [ -78.963637, 37.651545 ], [ -78.963559, 37.651968 ], [ -78.963475, 37.652244 ], [ -78.963403, 37.652439 ], [ -78.963343, 37.65259 ], [ -78.963259, 37.652771 ], [ -78.963211, 37.652855 ], [ -78.963159, 37.652948 ], [ -78.963044, 37.653119 ], [ -78.962876, 37.65334 ], [ -78.962692, 37.653554 ], [ -78.961989, 37.654258 ], [ -78.961507, 37.654728 ], [ -78.961039, 37.655181 ], [ -78.960337, 37.655875 ], [ -78.96023, 37.655972 ], [ -78.960126, 37.656071 ], [ -78.959777, 37.656385 ], [ -78.959596, 37.656559 ], [ -78.959428, 37.656733 ], [ -78.95894, 37.657212 ], [ -78.958347, 37.65781 ], [ -78.957955, 37.658265 ], [ -78.957902, 37.65834 ], [ -78.957703, 37.658582 ], [ -78.956957, 37.659613 ], [ -78.956, 37.660952 ], [ -78.95555, 37.661601 ], [ -78.95521, 37.662149 ], [ -78.955078, 37.662367 ], [ -78.954742, 37.662988 ], [ -78.954584, 37.663297 ], [ -78.954305, 37.663917 ], [ -78.954148, 37.6643 ], [ -78.953981, 37.664751 ], [ -78.953842, 37.665162 ], [ -78.953791, 37.665348 ], [ -78.953693, 37.665702 ], [ -78.953658, 37.665836 ], [ -78.953519, 37.666441 ], [ -78.953449, 37.666806 ], [ -78.953407, 37.667104 ], [ -78.953324, 37.667763 ], [ -78.953292, 37.668183 ], [ -78.953221, 37.669156 ], [ -78.953153, 37.670098 ], [ -78.953142, 37.670264 ], [ -78.953141, 37.6704 ], [ -78.953072, 37.671177 ], [ -78.95304, 37.671615 ], [ -78.952995, 37.672174 ], [ -78.952947, 37.672942 ], [ -78.95292, 37.673225 ], [ -78.952878, 37.673819 ], [ -78.952829, 37.674339 ], [ -78.952797, 37.674686 ], [ -78.952784, 37.674804 ], [ -78.952747, 37.675024 ], [ -78.952692, 37.675301 ], [ -78.952624, 37.675578 ], [ -78.952561, 37.675784 ], [ -78.952486, 37.675985 ], [ -78.952442, 37.676122 ], [ -78.952386, 37.676257 ], [ -78.95232, 37.676433 ], [ -78.952115, 37.676852 ], [ -78.952045, 37.676981 ], [ -78.951895, 37.677259 ], [ -78.951765, 37.677478 ], [ -78.951015, 37.678688 ], [ -78.950642, 37.679294 ], [ -78.950106, 37.680167 ], [ -78.949932, 37.680439 ], [ -78.949555, 37.681057 ], [ -78.948514, 37.682749 ], [ -78.948346, 37.683014 ], [ -78.94819, 37.68327 ], [ -78.947933, 37.683687 ], [ -78.947735, 37.683997 ], [ -78.946949, 37.685284 ], [ -78.946763, 37.685577 ], [ -78.946171, 37.686544 ], [ -78.946077, 37.686718 ], [ -78.945972, 37.686928 ], [ -78.945848, 37.687201 ], [ -78.945794, 37.687349 ], [ -78.945689, 37.687661 ], [ -78.945632, 37.687901 ], [ -78.945568, 37.688266 ], [ -78.945541, 37.688542 ], [ -78.945537, 37.688659 ], [ -78.945545, 37.689126 ], [ -78.945579, 37.689434 ], [ -78.945664, 37.689907 ], [ -78.945683, 37.68999 ], [ -78.945776, 37.690456 ], [ -78.945835, 37.69071 ], [ -78.945961, 37.691323 ], [ -78.946182, 37.69241 ], [ -78.946237, 37.692788 ], [ -78.946274, 37.693085 ], [ -78.946296, 37.693491 ], [ -78.946303, 37.694022 ], [ -78.946301, 37.694057 ], [ -78.946287, 37.694387 ], [ -78.946261, 37.694709 ], [ -78.946249, 37.694805 ], [ -78.946182, 37.695293 ], [ -78.946055, 37.695876 ], [ -78.945864, 37.696567 ], [ -78.945405, 37.698162 ], [ -78.945298, 37.698548 ], [ -78.944826, 37.700186 ], [ -78.944719, 37.700501 ], [ -78.94458, 37.700835 ], [ -78.944457, 37.701074 ], [ -78.944324, 37.701307 ], [ -78.944135, 37.701595 ], [ -78.944026, 37.701738 ], [ -78.943778, 37.70202 ], [ -78.943504, 37.702305 ], [ -78.943214, 37.702564 ], [ -78.94302, 37.702719 ], [ -78.942935, 37.702779 ], [ -78.942809, 37.702868 ], [ -78.942485, 37.703077 ], [ -78.942218, 37.703232 ], [ -78.9405, 37.704132 ], [ -78.940455, 37.704155 ], [ -78.940006, 37.704381 ], [ -78.938227, 37.705302 ], [ -78.93698, 37.705948 ], [ -78.93647, 37.706225 ], [ -78.93488, 37.707122 ], [ -78.934646, 37.707256 ], [ -78.93388, 37.707679 ], [ -78.933448, 37.707924 ], [ -78.932774, 37.708305 ], [ -78.931107, 37.709235 ], [ -78.929365, 37.710215 ], [ -78.928987, 37.710423 ], [ -78.928188, 37.710873 ], [ -78.927848, 37.711058 ], [ -78.927739, 37.711117 ], [ -78.927286, 37.71134 ], [ -78.927035, 37.711449 ], [ -78.926705, 37.711572 ], [ -78.926357, 37.711684 ], [ -78.926015, 37.711773 ], [ -78.925764, 37.711831 ], [ -78.925742, 37.711836 ], [ -78.925395, 37.711899 ], [ -78.925098, 37.711943 ], [ -78.92463, 37.712006 ], [ -78.924358, 37.71204 ], [ -78.9241, 37.712072 ], [ -78.923317, 37.712168 ], [ -78.922673, 37.712257 ], [ -78.921644, 37.712386 ], [ -78.920771, 37.712503 ], [ -78.91879, 37.712755 ], [ -78.917763, 37.712894 ], [ -78.916758, 37.713029 ], [ -78.916316, 37.713107 ], [ -78.915891, 37.713204 ], [ -78.915614, 37.71328 ], [ -78.915324, 37.713372 ], [ -78.915274, 37.713388 ], [ -78.914912, 37.71352 ], [ -78.91455, 37.71367 ], [ -78.914179, 37.713842 ], [ -78.913675, 37.714085 ], [ -78.912967, 37.714415 ], [ -78.910226, 37.715714 ], [ -78.90939, 37.716116 ], [ -78.908844, 37.716378 ], [ -78.908565, 37.716525 ], [ -78.908344, 37.716654 ], [ -78.908223, 37.716733 ], [ -78.907898, 37.716972 ], [ -78.907709, 37.71712 ], [ -78.907284, 37.717479 ], [ -78.905705, 37.718784 ], [ -78.905314, 37.719084 ], [ -78.90491, 37.719372 ], [ -78.904525, 37.719604 ], [ -78.904033, 37.719882 ], [ -78.903337, 37.720265 ], [ -78.902528, 37.720722 ], [ -78.902455, 37.720766 ], [ -78.902055, 37.720998 ], [ -78.901704, 37.721237 ], [ -78.901372, 37.721492 ], [ -78.901207, 37.721632 ], [ -78.901102, 37.721732 ], [ -78.90093, 37.721897 ], [ -78.900791, 37.722043 ], [ -78.900736, 37.722103 ], [ -78.900601, 37.722261 ], [ -78.900394, 37.722523 ], [ -78.900222, 37.722764 ], [ -78.900079, 37.722992 ], [ -78.900004, 37.723131 ], [ -78.899716, 37.723665 ], [ -78.899467, 37.724145 ], [ -78.899406, 37.724274 ], [ -78.89922, 37.72461 ], [ -78.899008, 37.725016 ], [ -78.898838, 37.725322 ], [ -78.898749, 37.725462 ], [ -78.898619, 37.725684 ], [ -78.898501, 37.725886 ], [ -78.898424, 37.726009 ], [ -78.898396, 37.726054 ], [ -78.89823, 37.726333 ], [ -78.897785, 37.72702 ], [ -78.897326, 37.727687 ], [ -78.897029, 37.728104 ], [ -78.896755, 37.72847 ], [ -78.896087, 37.729327 ], [ -78.895376, 37.730223 ], [ -78.89492, 37.73078 ], [ -78.894224, 37.731648 ], [ -78.893951, 37.731982 ], [ -78.893208, 37.732922 ], [ -78.893101, 37.733073 ], [ -78.892951, 37.733284 ], [ -78.892829, 37.733486 ], [ -78.892725, 37.733694 ], [ -78.892653, 37.733852 ], [ -78.892395, 37.734583 ], [ -78.892264, 37.735006 ], [ -78.891874, 37.73617 ], [ -78.891809, 37.736394 ], [ -78.891615, 37.736972 ], [ -78.891508, 37.737307 ], [ -78.891316, 37.737819 ], [ -78.891154, 37.738191 ], [ -78.891075, 37.738356 ], [ -78.891011, 37.738485 ], [ -78.890701, 37.739024 ], [ -78.890539, 37.739262 ], [ -78.890353, 37.739521 ], [ -78.890119, 37.739847 ], [ -78.889796, 37.740253 ], [ -78.889491, 37.740645 ], [ -78.889217, 37.740996 ], [ -78.888944, 37.74133 ], [ -78.888623, 37.741743 ], [ -78.888513, 37.741886 ], [ -78.888267, 37.742188 ], [ -78.887876, 37.742653 ], [ -78.887675, 37.74287 ], [ -78.887504, 37.743037 ], [ -78.887277, 37.743237 ], [ -78.887216, 37.743287 ], [ -78.887135, 37.743353 ], [ -78.886534, 37.743824 ], [ -78.886162, 37.744125 ], [ -78.8861, 37.744182 ], [ -78.885899, 37.744355 ], [ -78.885622, 37.744575 ], [ -78.885356, 37.74478 ], [ -78.884605, 37.745388 ], [ -78.884042, 37.74585 ], [ -78.882882, 37.746752 ], [ -78.882051, 37.747417 ], [ -78.880834, 37.748391 ], [ -78.88003, 37.749038 ], [ -78.879751, 37.749271 ], [ -78.879568, 37.74942 ], [ -78.879376, 37.749569 ], [ -78.878419, 37.750353 ], [ -78.877854, 37.750804 ], [ -78.877584, 37.751037 ], [ -78.877286, 37.751315 ], [ -78.877004, 37.751598 ], [ -78.876844, 37.751774 ], [ -78.876626, 37.752042 ], [ -78.876378, 37.752385 ], [ -78.876192, 37.752665 ], [ -78.876061, 37.752882 ], [ -78.875814, 37.753345 ], [ -78.875209, 37.754691 ], [ -78.874619, 37.756931 ], [ -78.874501, 37.757307 ], [ -78.874339, 37.757855 ], [ -78.873994, 37.758979 ], [ -78.873789, 37.759637 ], [ -78.873696, 37.75991 ], [ -78.873541, 37.760318 ], [ -78.873332, 37.760834 ], [ -78.873094, 37.761337 ], [ -78.872847, 37.761808 ], [ -78.872451, 37.762468 ], [ -78.872257, 37.76277 ], [ -78.871993, 37.763172 ], [ -78.871574, 37.763799 ], [ -78.871327, 37.764167 ], [ -78.871012, 37.764642 ], [ -78.870469, 37.765468 ], [ -78.870316, 37.765702 ], [ -78.870042, 37.766126 ], [ -78.869873, 37.766412 ], [ -78.869781, 37.766589 ], [ -78.869687, 37.766814 ], [ -78.869585, 37.76708 ], [ -78.869516, 37.767314 ], [ -78.869424, 37.767698 ], [ -78.869391, 37.767942 ], [ -78.86938, 37.768238 ], [ -78.869389, 37.768459 ], [ -78.869415, 37.768673 ], [ -78.869485, 37.768991 ], [ -78.869567, 37.769255 ], [ -78.86966, 37.769515 ], [ -78.869743, 37.769714 ], [ -78.869793, 37.769822 ], [ -78.870127, 37.770634 ], [ -78.870244, 37.770938 ], [ -78.870299, 37.771157 ], [ -78.870337, 37.771378 ], [ -78.870379, 37.771605 ], [ -78.870392, 37.771879 ], [ -78.870378, 37.772127 ], [ -78.870337, 37.772397 ], [ -78.870272, 37.77267 ], [ -78.870248, 37.772764 ], [ -78.87004, 37.773562 ], [ -78.869728, 37.774718 ], [ -78.869574, 37.775264 ], [ -78.869411, 37.775864 ], [ -78.869234, 37.776522 ], [ -78.869061, 37.777151 ], [ -78.868889, 37.777735 ], [ -78.868643, 37.778648 ], [ -78.868399, 37.779571 ], [ -78.868224, 37.780198 ], [ -78.868067, 37.780782 ], [ -78.867497, 37.782893 ], [ -78.867434, 37.783141 ], [ -78.867364, 37.783414 ], [ -78.867185, 37.784047 ], [ -78.867156, 37.784152 ], [ -78.867042, 37.784562 ], [ -78.866921, 37.785054 ], [ -78.866779, 37.785508 ], [ -78.866518, 37.786333 ], [ -78.866458, 37.786501 ], [ -78.866348, 37.786832 ], [ -78.866066, 37.787709 ], [ -78.865703, 37.788816 ], [ -78.865457, 37.789659 ], [ -78.865164, 37.790592 ], [ -78.864927, 37.791345 ], [ -78.864619, 37.792175 ], [ -78.864507, 37.792484 ], [ -78.864363, 37.792792 ], [ -78.864228, 37.793041 ], [ -78.864067, 37.7933 ], [ -78.863882, 37.793548 ], [ -78.863684, 37.793797 ], [ -78.863319, 37.794211 ], [ -78.863117, 37.794344 ], [ -78.86295, 37.794541 ], [ -78.862701, 37.794857 ], [ -78.86248, 37.795184 ], [ -78.862275, 37.795518 ], [ -78.862199, 37.795651 ], [ -78.862007, 37.796159 ], [ -78.861989, 37.79622 ], [ -78.861909, 37.796548 ], [ -78.861883, 37.796687 ], [ -78.861846, 37.796942 ], [ -78.861828, 37.797235 ], [ -78.861827, 37.797529 ], [ -78.861837, 37.797754 ], [ -78.861844, 37.797901 ], [ -78.861878, 37.798631 ], [ -78.861919, 37.799738 ], [ -78.861971, 37.800826 ], [ -78.862007, 37.801869 ], [ -78.862081, 37.803303 ], [ -78.862104, 37.80423 ], [ -78.86209, 37.804437 ], [ -78.862063, 37.804642 ], [ -78.862038, 37.804754 ], [ -78.862023, 37.804816 ], [ -78.861947, 37.805046 ], [ -78.861861, 37.805246 ], [ -78.861771, 37.805437 ], [ -78.86165, 37.805634 ], [ -78.861512, 37.805817 ], [ -78.861343, 37.806004 ], [ -78.860353, 37.806994 ], [ -78.859848, 37.807481 ], [ -78.858512, 37.808821 ], [ -78.858367, 37.808958 ], [ -78.858079, 37.809211 ], [ -78.857729, 37.809505 ], [ -78.857293, 37.80986 ], [ -78.856987, 37.81009 ], [ -78.856658, 37.810338 ], [ -78.855693, 37.81105 ], [ -78.85561, 37.811115 ], [ -78.855262, 37.811371 ], [ -78.854965, 37.811605 ], [ -78.853694, 37.812587 ], [ -78.853389, 37.812818 ], [ -78.852362, 37.813637 ], [ -78.851981, 37.813912 ], [ -78.851517, 37.814266 ], [ -78.851057, 37.81462 ], [ -78.85085, 37.814768 ], [ -78.850729, 37.814859 ], [ -78.850652, 37.81492 ], [ -78.850085, 37.815369 ], [ -78.848637, 37.81648 ], [ -78.846503, 37.818117 ], [ -78.846263, 37.818303 ], [ -78.845641, 37.818784 ], [ -78.845198, 37.81912 ], [ -78.844287, 37.819835 ], [ -78.843809, 37.820229 ], [ -78.841255, 37.822413 ], [ -78.840635, 37.822925 ], [ -78.840114, 37.823377 ], [ -78.839772, 37.823685 ], [ -78.839408, 37.824047 ], [ -78.839049, 37.824425 ], [ -78.838766, 37.824737 ], [ -78.838386, 37.825182 ], [ -78.838147, 37.825481 ], [ -78.837849, 37.82588 ], [ -78.837407, 37.826506 ], [ -78.837204, 37.826823 ], [ -78.837053, 37.827081 ], [ -78.836731, 37.827595 ], [ -78.836452, 37.828104 ], [ -78.836275, 37.828399 ], [ -78.836111, 37.828667 ], [ -78.835849, 37.82912 ], [ -78.835504, 37.829691 ], [ -78.835352, 37.829945 ], [ -78.83498, 37.830568 ], [ -78.834935, 37.830642 ], [ -78.834826, 37.830821 ], [ -78.834646, 37.831137 ], [ -78.834377, 37.831577 ], [ -78.833853, 37.832462 ], [ -78.833724, 37.832692 ], [ -78.833217, 37.833546 ], [ -78.831919, 37.835713 ], [ -78.831568, 37.836263 ], [ -78.831293, 37.836637 ], [ -78.831013, 37.836981 ], [ -78.83077, 37.837252 ], [ -78.829687, 37.838434 ], [ -78.829526, 37.8386 ], [ -78.829353, 37.838766 ], [ -78.828845, 37.839208 ], [ -78.828553, 37.839442 ], [ -78.828248, 37.839665 ], [ -78.827736, 37.840071 ], [ -78.82744, 37.840316 ], [ -78.827359, 37.840393 ], [ -78.827219, 37.840526 ], [ -78.827033, 37.840723 ], [ -78.82681, 37.840985 ], [ -78.826636, 37.841213 ], [ -78.826324, 37.841668 ], [ -78.825848, 37.842321 ], [ -78.825635, 37.842569 ], [ -78.825481, 37.842727 ], [ -78.825276, 37.842917 ], [ -78.825211, 37.842971 ], [ -78.825103, 37.843062 ], [ -78.824902, 37.843225 ], [ -78.824735, 37.84334 ], [ -78.824467, 37.843502 ], [ -78.824206, 37.843652 ], [ -78.82312, 37.844198 ], [ -78.822611, 37.844456 ], [ -78.821878, 37.84482 ], [ -78.820981, 37.845244 ], [ -78.82067, 37.845389 ], [ -78.820264, 37.845536 ], [ -78.820038, 37.845598 ], [ -78.819873, 37.845635 ], [ -78.81967, 37.845683 ], [ -78.819501, 37.845707 ], [ -78.819221, 37.845735 ], [ -78.818871, 37.845752 ], [ -78.818684, 37.845746 ], [ -78.818377, 37.845729 ], [ -78.818065, 37.845689 ], [ -78.817748, 37.845635 ], [ -78.817461, 37.845563 ], [ -78.817089, 37.845456 ], [ -78.81664, 37.845308 ], [ -78.816094, 37.845137 ], [ -78.815801, 37.845042 ], [ -78.815106, 37.844835 ], [ -78.814203, 37.844545 ], [ -78.813661, 37.844372 ], [ -78.813194, 37.844227 ], [ -78.812793, 37.844119 ], [ -78.812466, 37.844059 ], [ -78.812161, 37.844015 ], [ -78.811899, 37.843994 ], [ -78.811692, 37.843985 ], [ -78.81145, 37.844002 ], [ -78.811288, 37.844022 ], [ -78.810966, 37.84409 ], [ -78.810704, 37.844162 ], [ -78.810498, 37.844229 ], [ -78.810246, 37.844336 ], [ -78.80993, 37.84449 ], [ -78.809727, 37.844605 ], [ -78.809573, 37.844705 ], [ -78.809276, 37.84492 ], [ -78.809029, 37.845076 ], [ -78.808807, 37.845199 ], [ -78.808527, 37.845332 ], [ -78.808311, 37.845419 ], [ -78.808089, 37.845498 ], [ -78.807811, 37.845579 ], [ -78.807589, 37.845643 ], [ -78.807297, 37.845708 ], [ -78.807, 37.845759 ], [ -78.806691, 37.845797 ], [ -78.806302, 37.845837 ], [ -78.805184, 37.845933 ], [ -78.80503, 37.845945 ], [ -78.804012, 37.846026 ], [ -78.800837, 37.846324 ], [ -78.800537, 37.846339 ], [ -78.800237, 37.846355 ], [ -78.800014, 37.846352 ], [ -78.79976, 37.846345 ], [ -78.799425, 37.846321 ], [ -78.799048, 37.846276 ], [ -78.79881, 37.846227 ], [ -78.798587, 37.846183 ], [ -78.798334, 37.846121 ], [ -78.798127, 37.846044 ], [ -78.797833, 37.845932 ], [ -78.797473, 37.845765 ], [ -78.797183, 37.845617 ], [ -78.796923, 37.845465 ], [ -78.796357, 37.845082 ], [ -78.795818, 37.844712 ], [ -78.795607, 37.84458 ], [ -78.795352, 37.844427 ], [ -78.795147, 37.84431 ], [ -78.794915, 37.844201 ], [ -78.794645, 37.844085 ], [ -78.794419, 37.843996 ], [ -78.794095, 37.843903 ], [ -78.793805, 37.843828 ], [ -78.793467, 37.843774 ], [ -78.793125, 37.84374 ], [ -78.792933, 37.843732 ], [ -78.792722, 37.843723 ], [ -78.792238, 37.84372 ], [ -78.791688, 37.843732 ], [ -78.791137, 37.843731 ], [ -78.790713, 37.843712 ], [ -78.790444, 37.843693 ], [ -78.79016, 37.843657 ], [ -78.78988, 37.843607 ], [ -78.789604, 37.843542 ], [ -78.789363, 37.843478 ], [ -78.789067, 37.843389 ], [ -78.788706, 37.843253 ], [ -78.78839, 37.843125 ], [ -78.788101, 37.843016 ], [ -78.78765, 37.842857 ], [ -78.787324, 37.842748 ], [ -78.787056, 37.84268 ], [ -78.786677, 37.842606 ], [ -78.786459, 37.842568 ], [ -78.786292, 37.842537 ], [ -78.785994, 37.842501 ], [ -78.785649, 37.842467 ], [ -78.785267, 37.842457 ], [ -78.784945, 37.842456 ], [ -78.784589, 37.842468 ], [ -78.782212, 37.842633 ], [ -78.780497, 37.842776 ], [ -78.779987, 37.842814 ], [ -78.778924, 37.842896 ], [ -78.77812, 37.842986 ], [ -78.777773, 37.843042 ], [ -78.777066, 37.843144 ], [ -78.776444, 37.84325 ], [ -78.775647, 37.843402 ], [ -78.774632, 37.843601 ], [ -78.773646, 37.843786 ], [ -78.773282, 37.843855 ], [ -78.772981, 37.843912 ], [ -78.772128, 37.844091 ], [ -78.771161, 37.844316 ], [ -78.770651, 37.844441 ], [ -78.769991, 37.844616 ], [ -78.768859, 37.844941 ], [ -78.768162, 37.845142 ], [ -78.767015, 37.845472 ], [ -78.76637, 37.845658 ], [ -78.765119, 37.846012 ], [ -78.761663, 37.84701 ], [ -78.760903, 37.847224 ], [ -78.760298, 37.847402 ], [ -78.75996, 37.847506 ], [ -78.7597, 37.847596 ], [ -78.759532, 37.84765 ], [ -78.759113, 37.847806 ], [ -78.758783, 37.847948 ], [ -78.758412, 37.84812 ], [ -78.758057, 37.848288 ], [ -78.757154, 37.848747 ], [ -78.756986, 37.848829 ], [ -78.756546, 37.849062 ], [ -78.756115, 37.849306 ], [ -78.755862, 37.849458 ], [ -78.755244, 37.849843 ], [ -78.754769, 37.85013 ], [ -78.754377, 37.85038 ], [ -78.753945, 37.850672 ], [ -78.753673, 37.850873 ], [ -78.753364, 37.851127 ], [ -78.753217, 37.851259 ], [ -78.752739, 37.851715 ], [ -78.752046, 37.852374 ], [ -78.75166, 37.852719 ], [ -78.751401, 37.852929 ], [ -78.751134, 37.853132 ], [ -78.750789, 37.853376 ], [ -78.750504, 37.853564 ], [ -78.750081, 37.853824 ], [ -78.74973, 37.854021 ], [ -78.749369, 37.854207 ], [ -78.748998, 37.85438 ], [ -78.748624, 37.854531 ], [ -78.748053, 37.854743 ], [ -78.747045, 37.85508 ], [ -78.746537, 37.855262 ], [ -78.746473, 37.855285 ], [ -78.745985, 37.855474 ], [ -78.7456, 37.855635 ], [ -78.744986, 37.855911 ], [ -78.744673, 37.856064 ], [ -78.744246, 37.856299 ], [ -78.743761, 37.856591 ], [ -78.743416, 37.856817 ], [ -78.742954, 37.857145 ], [ -78.742639, 37.857387 ], [ -78.742337, 37.85764 ], [ -78.742294, 37.85768 ], [ -78.741896, 37.858045 ], [ -78.741503, 37.85843 ], [ -78.741291, 37.858648 ], [ -78.741254, 37.858686 ], [ -78.740963, 37.859027 ], [ -78.740705, 37.859351 ], [ -78.740668, 37.859398 ], [ -78.740453, 37.85968 ], [ -78.739901, 37.860385 ], [ -78.739675, 37.860647 ], [ -78.739434, 37.860902 ], [ -78.739176, 37.861151 ], [ -78.73895, 37.861357 ], [ -78.738655, 37.861604 ], [ -78.738411, 37.861795 ], [ -78.738094, 37.862025 ], [ -78.737733, 37.862262 ], [ -78.737429, 37.862445 ], [ -78.73708, 37.862638 ], [ -78.73657, 37.862893 ], [ -78.736186, 37.863088 ], [ -78.735435, 37.86348 ], [ -78.734529, 37.863942 ], [ -78.733874, 37.864271 ], [ -78.733562, 37.864427 ], [ -78.733042, 37.864704 ], [ -78.732039, 37.865214 ], [ -78.731948, 37.865258 ], [ -78.731785, 37.865335 ], [ -78.731411, 37.86553 ], [ -78.730148, 37.866169 ], [ -78.729986, 37.866254 ], [ -78.729722, 37.866391 ], [ -78.728688, 37.866913 ], [ -78.727888, 37.86733 ], [ -78.727529, 37.86751 ], [ -78.726765, 37.867904 ], [ -78.726166, 37.868202 ], [ -78.725869, 37.868361 ], [ -78.725428, 37.868579 ], [ -78.725084, 37.868757 ], [ -78.724518, 37.869049 ], [ -78.723898, 37.869354 ], [ -78.722779, 37.869945 ], [ -78.721592, 37.870542 ], [ -78.720481, 37.87111 ], [ -78.719958, 37.871373 ], [ -78.719701, 37.871497 ], [ -78.719365, 37.871672 ], [ -78.718719, 37.872028 ], [ -78.71847, 37.872183 ], [ -78.718164, 37.872388 ], [ -78.717945, 37.872553 ], [ -78.717592, 37.872851 ], [ -78.717285, 37.873139 ], [ -78.717049, 37.873363 ], [ -78.716739, 37.873728 ], [ -78.716536, 37.874002 ], [ -78.716395, 37.874221 ], [ -78.716144, 37.874657 ], [ -78.71604, 37.87487 ], [ -78.715888, 37.875212 ], [ -78.715814, 37.875401 ], [ -78.715694, 37.87571 ], [ -78.715495, 37.876238 ], [ -78.715377, 37.876548 ], [ -78.715275, 37.876817 ], [ -78.71521, 37.877013 ], [ -78.715136, 37.877211 ], [ -78.715081, 37.877371 ], [ -78.714995, 37.877587 ], [ -78.71492, 37.877787 ], [ -78.7148, 37.878131 ], [ -78.714687, 37.878428 ], [ -78.714533, 37.878796 ], [ -78.714454, 37.879009 ], [ -78.714417, 37.879116 ], [ -78.714256, 37.879549 ], [ -78.714141, 37.879854 ], [ -78.713896, 37.880594 ], [ -78.713756, 37.881038 ], [ -78.713682, 37.88126 ], [ -78.713617, 37.881457 ], [ -78.713533, 37.881697 ], [ -78.713446, 37.881943 ], [ -78.713394, 37.882108 ], [ -78.713314, 37.882336 ], [ -78.713184, 37.882655 ], [ -78.713006, 37.883053 ], [ -78.712892, 37.883274 ], [ -78.712733, 37.88355 ], [ -78.712558, 37.88384 ], [ -78.712369, 37.884119 ], [ -78.712275, 37.884257 ], [ -78.712136, 37.884449 ], [ -78.711974, 37.884667 ], [ -78.711814, 37.884876 ], [ -78.711641, 37.885085 ], [ -78.711418, 37.885345 ], [ -78.711139, 37.885644 ], [ -78.710798, 37.88599 ], [ -78.710465, 37.886309 ], [ -78.710195, 37.886555 ], [ -78.709928, 37.886781 ], [ -78.709577, 37.88706 ], [ -78.709406, 37.887199 ], [ -78.709211, 37.887345 ], [ -78.708778, 37.887648 ], [ -78.707968, 37.888179 ], [ -78.707642, 37.888399 ], [ -78.707473, 37.88851 ], [ -78.707244, 37.888663 ], [ -78.706965, 37.888843 ], [ -78.706601, 37.889083 ], [ -78.706088, 37.889425 ], [ -78.705712, 37.889669 ], [ -78.705189, 37.890019 ], [ -78.704893, 37.890211 ], [ -78.703445, 37.891162 ], [ -78.703041, 37.891429 ], [ -78.702721, 37.891638 ], [ -78.702327, 37.891905 ], [ -78.70184, 37.892223 ], [ -78.701163, 37.892662 ], [ -78.700778, 37.892933 ], [ -78.70071, 37.892981 ], [ -78.700622, 37.893046 ], [ -78.700337, 37.893272 ], [ -78.69999, 37.89357 ], [ -78.699755, 37.8938 ], [ -78.699482, 37.894099 ], [ -78.699289, 37.894329 ], [ -78.698787, 37.894984 ], [ -78.698558, 37.895284 ], [ -78.69837, 37.895519 ], [ -78.698116, 37.895851 ], [ -78.697966, 37.896055 ], [ -78.697696, 37.896407 ], [ -78.697057, 37.897242 ], [ -78.696439, 37.898041 ], [ -78.695681, 37.899035 ], [ -78.695049, 37.899863 ], [ -78.694658, 37.900403 ], [ -78.694519, 37.900599 ], [ -78.694429, 37.900733 ], [ -78.693954, 37.901464 ], [ -78.693721, 37.901862 ], [ -78.693473, 37.902275 ], [ -78.693102, 37.902981 ], [ -78.692879, 37.903439 ], [ -78.692797, 37.903623 ], [ -78.692129, 37.905105 ], [ -78.691808, 37.905817 ], [ -78.691268, 37.906984 ], [ -78.690987, 37.907549 ], [ -78.690814, 37.907874 ], [ -78.690688, 37.908089 ], [ -78.690521, 37.908372 ], [ -78.690275, 37.908767 ], [ -78.689663, 37.909657 ], [ -78.689078, 37.910492 ], [ -78.685485, 37.915666 ], [ -78.684467, 37.917131 ], [ -78.682047, 37.920608 ], [ -78.681785, 37.92095 ], [ -78.681517, 37.921272 ], [ -78.681241, 37.921578 ], [ -78.68101, 37.921818 ], [ -78.680605, 37.922194 ], [ -78.68013, 37.922617 ], [ -78.679566, 37.923137 ], [ -78.679307, 37.923403 ], [ -78.678986, 37.92374 ], [ -78.678605, 37.924203 ], [ -78.678345, 37.924561 ], [ -78.678124, 37.924891 ], [ -78.677903, 37.925227 ], [ -78.677688, 37.925589 ], [ -78.677544, 37.925878 ], [ -78.67731, 37.926442 ], [ -78.676551, 37.928284 ], [ -78.676404, 37.928595 ], [ -78.676242, 37.928949 ], [ -78.676148, 37.929122 ], [ -78.675977, 37.929377 ], [ -78.675612, 37.929807 ], [ -78.675385, 37.930086 ], [ -78.675213, 37.930312 ], [ -78.675004, 37.930559 ], [ -78.674617, 37.931044 ], [ -78.67407, 37.931702 ], [ -78.673673, 37.932201 ], [ -78.673281, 37.9327 ], [ -78.672994, 37.933082 ], [ -78.672166, 37.934227 ], [ -78.671112, 37.935771 ], [ -78.670762, 37.936281 ], [ -78.670385, 37.936817 ], [ -78.669877, 37.937599 ], [ -78.668999, 37.93886 ], [ -78.667671, 37.940789 ], [ -78.666721, 37.942158 ], [ -78.666126, 37.943118 ], [ -78.665597, 37.944014 ], [ -78.665125, 37.944827 ], [ -78.664642, 37.945633 ], [ -78.664087, 37.946602 ], [ -78.663665, 37.947366 ], [ -78.663523, 37.947648 ], [ -78.663363, 37.948007 ], [ -78.66312, 37.948581 ], [ -78.662992, 37.948919 ], [ -78.662788, 37.949511 ], [ -78.662392, 37.950794 ], [ -78.662127, 37.951686 ], [ -78.661907, 37.952368 ], [ -78.6618, 37.952667 ], [ -78.661673, 37.952964 ], [ -78.661549, 37.953229 ], [ -78.661377, 37.953546 ], [ -78.661172, 37.953875 ], [ -78.660975, 37.954168 ], [ -78.660712, 37.954527 ], [ -78.660589, 37.954686 ], [ -78.660525, 37.954768 ], [ -78.660204, 37.955161 ], [ -78.659899, 37.955515 ], [ -78.65946, 37.956045 ], [ -78.659107, 37.956472 ], [ -78.658939, 37.95668 ], [ -78.658404, 37.957325 ], [ -78.658185, 37.957583 ], [ -78.657413, 37.958505 ], [ -78.65713, 37.958855 ], [ -78.65677, 37.959264 ], [ -78.656612, 37.959431 ], [ -78.656439, 37.95959 ], [ -78.656251, 37.959739 ], [ -78.656068, 37.959867 ], [ -78.655989, 37.959917 ], [ -78.655752, 37.960052 ], [ -78.655575, 37.96015 ], [ -78.655228, 37.960289 ], [ -78.654931, 37.960405 ], [ -78.653275, 37.960978 ], [ -78.652399, 37.961277 ], [ -78.651659, 37.961545 ], [ -78.651372, 37.96167 ], [ -78.651131, 37.961788 ], [ -78.650953, 37.961888 ], [ -78.65077, 37.962003 ], [ -78.650655, 37.962074 ], [ -78.650545, 37.96215 ], [ -78.650369, 37.962277 ], [ -78.650124, 37.962492 ], [ -78.649827, 37.962781 ], [ -78.649528, 37.963082 ], [ -78.649157, 37.963468 ], [ -78.648771, 37.96385 ], [ -78.648569, 37.964042 ], [ -78.648236, 37.964318 ], [ -78.647928, 37.964546 ], [ -78.647355, 37.964951 ], [ -78.646421, 37.965624 ], [ -78.646034, 37.965897 ], [ -78.645591, 37.966218 ], [ -78.645351, 37.966376 ], [ -78.645051, 37.966569 ], [ -78.644735, 37.966754 ], [ -78.644581, 37.96684 ], [ -78.6444, 37.966936 ], [ -78.643915, 37.967163 ], [ -78.643555, 37.967319 ], [ -78.643147, 37.967465 ], [ -78.642853, 37.967561 ], [ -78.642519, 37.96766 ], [ -78.642395, 37.967695 ], [ -78.642095, 37.967768 ], [ -78.641871, 37.967823 ], [ -78.641449, 37.967916 ], [ -78.640993, 37.967991 ], [ -78.640408, 37.968066 ], [ -78.639997, 37.968103 ], [ -78.639496, 37.96813 ], [ -78.638995, 37.968136 ], [ -78.638434, 37.968125 ], [ -78.637944, 37.9681 ], [ -78.63612, 37.967958 ], [ -78.635136, 37.967873 ], [ -78.633802, 37.96777 ], [ -78.632073, 37.967631 ], [ -78.631801, 37.967611 ], [ -78.630935, 37.967546 ], [ -78.630424, 37.967503 ], [ -78.629697, 37.967442 ], [ -78.628686, 37.967361 ], [ -78.626167, 37.967159 ], [ -78.623282, 37.966927 ], [ -78.622258, 37.96685 ], [ -78.621932, 37.966824 ], [ -78.620819, 37.966736 ], [ -78.620381, 37.966716 ], [ -78.620004, 37.966712 ], [ -78.619679, 37.966717 ], [ -78.61937, 37.966745 ], [ -78.619064, 37.966787 ], [ -78.618761, 37.966844 ], [ -78.618523, 37.9669 ], [ -78.618222, 37.966977 ], [ -78.617837, 37.967103 ], [ -78.617525, 37.967224 ], [ -78.617264, 37.967333 ], [ -78.616866, 37.967526 ], [ -78.61666, 37.96764 ], [ -78.616487, 37.967735 ], [ -78.616266, 37.967872 ], [ -78.615844, 37.968137 ], [ -78.615555, 37.968338 ], [ -78.615229, 37.968577 ], [ -78.614931, 37.968831 ], [ -78.614607, 37.969142 ], [ -78.614381, 37.96937 ], [ -78.614151, 37.969646 ], [ -78.613964, 37.96988 ], [ -78.613494, 37.970554 ], [ -78.61301, 37.971246 ], [ -78.612831, 37.971512 ], [ -78.612279, 37.972333 ], [ -78.611229, 37.97389 ], [ -78.610819, 37.974494 ], [ -78.610719, 37.974624 ], [ -78.610499, 37.974897 ], [ -78.610319, 37.975118 ], [ -78.610116, 37.975331 ], [ -78.609966, 37.975469 ], [ -78.609796, 37.975624 ], [ -78.609591, 37.975796 ], [ -78.609317, 37.976004 ], [ -78.609071, 37.976176 ], [ -78.608849, 37.976327 ], [ -78.608744, 37.97639 ], [ -78.608365, 37.976619 ], [ -78.608101, 37.976752 ], [ -78.607845, 37.976869 ], [ -78.607584, 37.976978 ], [ -78.60725, 37.977103 ], [ -78.606977, 37.977192 ], [ -78.606625, 37.977297 ], [ -78.606266, 37.977388 ], [ -78.606123, 37.977418 ], [ -78.605902, 37.977465 ], [ -78.605646, 37.97752 ], [ -78.605621, 37.977522 ], [ -78.605549, 37.977538 ], [ -78.60423, 37.977756 ], [ -78.602588, 37.978034 ], [ -78.602162, 37.978122 ], [ -78.601825, 37.978203 ], [ -78.601492, 37.978293 ], [ -78.601094, 37.978414 ], [ -78.60071, 37.978547 ], [ -78.600334, 37.978694 ], [ -78.599967, 37.978854 ], [ -78.599486, 37.979083 ], [ -78.599163, 37.979252 ], [ -78.598789, 37.97947 ], [ -78.598549, 37.979624 ], [ -78.597946, 37.980033 ], [ -78.596889, 37.98075 ], [ -78.595137, 37.981939 ], [ -78.593704, 37.982911 ], [ -78.592376, 37.98382 ], [ -78.590854, 37.984906 ], [ -78.590225, 37.985373 ], [ -78.588999, 37.98631 ], [ -78.588012, 37.9871 ], [ -78.587089, 37.987859 ], [ -78.586722, 37.988171 ], [ -78.586183, 37.988631 ], [ -78.585023, 37.989655 ], [ -78.583908, 37.990662 ], [ -78.583686, 37.990885 ], [ -78.583478, 37.991116 ], [ -78.583203, 37.991447 ], [ -78.583057, 37.991641 ], [ -78.582889, 37.99189 ], [ -78.582734, 37.992152 ], [ -78.582584, 37.992445 ], [ -78.582451, 37.992743 ], [ -78.582318, 37.993104 ], [ -78.582229, 37.993396 ], [ -78.582158, 37.993692 ], [ -78.582061, 37.994255 ], [ -78.581989, 37.994788 ], [ -78.581919, 37.9952 ], [ -78.581831, 37.99573 ], [ -78.581596, 37.997239 ], [ -78.581525, 37.997665 ], [ -78.58147, 37.998088 ], [ -78.581083, 38.000517 ], [ -78.580993, 38.001016 ], [ -78.580912, 38.001332 ], [ -78.580857, 38.001514 ], [ -78.580851, 38.001532 ], [ -78.580827, 38.001607 ], [ -78.580788, 38.001711 ], [ -78.580764, 38.001783 ], [ -78.580638, 38.002087 ], [ -78.580501, 38.002397 ], [ -78.580338, 38.002682 ], [ -78.580176, 38.002939 ], [ -78.580026, 38.003155 ], [ -78.57984, 38.003394 ], [ -78.579631, 38.003641 ], [ -78.579528, 38.003748 ], [ -78.579258, 38.004014 ], [ -78.578985, 38.00426 ], [ -78.578784, 38.004426 ], [ -78.578575, 38.004584 ], [ -78.578379, 38.004723 ], [ -78.578122, 38.004899 ], [ -78.577709, 38.005151 ], [ -78.577431, 38.005306 ], [ -78.577141, 38.005444 ], [ -78.576923, 38.005542 ], [ -78.576628, 38.005666 ], [ -78.576327, 38.005766 ], [ -78.576154, 38.005828 ], [ -78.575371, 38.006031 ], [ -78.574274, 38.006313 ], [ -78.573929, 38.006397 ], [ -78.573678, 38.006459 ], [ -78.5731, 38.006602 ], [ -78.572544, 38.006742 ], [ -78.570845, 38.007165 ], [ -78.570536, 38.007245 ], [ -78.570147, 38.007346 ], [ -78.569511, 38.007502 ], [ -78.568866, 38.007677 ], [ -78.568449, 38.007795 ], [ -78.568216, 38.007865 ], [ -78.567861, 38.007984 ], [ -78.567483, 38.008116 ], [ -78.567008, 38.00831 ], [ -78.566642, 38.008471 ], [ -78.566222, 38.008672 ], [ -78.565813, 38.008887 ], [ -78.565381, 38.009126 ], [ -78.564818, 38.009422 ], [ -78.564544, 38.009563 ], [ -78.564196, 38.009735 ], [ -78.564075, 38.009787 ], [ -78.56369, 38.009944 ], [ -78.56326, 38.010103 ], [ -78.562849, 38.010238 ], [ -78.562529, 38.010332 ], [ -78.562124, 38.010438 ], [ -78.561805, 38.010515 ], [ -78.561564, 38.010564 ], [ -78.56093, 38.010675 ], [ -78.560028, 38.010845 ], [ -78.558824, 38.011064 ], [ -78.558024, 38.011219 ], [ -78.557648, 38.011286 ], [ -78.557386, 38.011333 ], [ -78.557058, 38.011387 ], [ -78.555118, 38.011755 ], [ -78.554112, 38.011931 ], [ -78.552878, 38.012156 ], [ -78.552449, 38.01225 ], [ -78.552186, 38.012316 ], [ -78.551829, 38.012417 ], [ -78.551365, 38.012562 ], [ -78.55109, 38.012655 ], [ -78.550658, 38.012829 ], [ -78.550236, 38.013017 ], [ -78.549599, 38.013364 ], [ -78.549376, 38.013492 ], [ -78.549058, 38.013698 ], [ -78.548469, 38.01411 ], [ -78.547659, 38.014674 ], [ -78.547468, 38.014808 ], [ -78.54736, 38.014884 ], [ -78.547042, 38.015096 ], [ -78.546611, 38.015362 ], [ -78.546269, 38.015559 ], [ -78.54592, 38.01574 ], [ -78.545223, 38.016069 ], [ -78.544841, 38.016247 ], [ -78.543906, 38.016682 ], [ -78.543654, 38.016806 ], [ -78.54333, 38.016982 ], [ -78.542733, 38.017318 ], [ -78.542466, 38.017467 ], [ -78.539711, 38.018979 ], [ -78.536725, 38.020664 ], [ -78.535885, 38.021132 ], [ -78.535518, 38.021335 ], [ -78.534742, 38.021766 ], [ -78.534188, 38.022073 ], [ -78.532955, 38.02276 ], [ -78.532173, 38.023196 ], [ -78.531193, 38.023747 ], [ -78.531125, 38.023792 ], [ -78.53075, 38.024045 ], [ -78.530445, 38.024274 ], [ -78.530203, 38.024476 ], [ -78.530016, 38.024649 ], [ -78.529931, 38.024733 ], [ -78.52985, 38.024806 ], [ -78.529798, 38.024854 ], [ -78.529758, 38.024894 ], [ -78.529598, 38.025065 ], [ -78.529327, 38.025386 ], [ -78.52916, 38.025608 ], [ -78.528945, 38.025933 ], [ -78.5288, 38.026176 ], [ -78.528672, 38.026426 ], [ -78.52861, 38.026566 ], [ -78.528405, 38.027066 ], [ -78.52833, 38.027311 ], [ -78.528283, 38.02751 ], [ -78.528235, 38.027689 ], [ -78.528151, 38.028145 ], [ -78.527582, 38.03105 ], [ -78.527126, 38.033402 ], [ -78.52703, 38.033972 ], [ -78.526914, 38.034782 ], [ -78.526868, 38.035166 ], [ -78.52679, 38.036035 ], [ -78.526753, 38.036647 ], [ -78.526715, 38.03781 ], [ -78.526642, 38.040878 ], [ -78.526607, 38.042081 ], [ -78.526584, 38.042473 ], [ -78.526544, 38.042863 ], [ -78.52645, 38.043462 ], [ -78.526353, 38.043907 ], [ -78.526306, 38.044099 ], [ -78.526225, 38.044382 ], [ -78.526103, 38.044762 ], [ -78.525978, 38.045116 ], [ -78.52595, 38.045183 ], [ -78.525619, 38.045973 ], [ -78.525226, 38.046882 ], [ -78.524837, 38.047794 ], [ -78.524807, 38.047861 ], [ -78.524712, 38.048073 ], [ -78.523664, 38.050524 ], [ -78.523608, 38.050633 ], [ -78.523449, 38.050945 ], [ -78.523194, 38.051371 ], [ -78.522992, 38.051667 ], [ -78.522896, 38.051793 ], [ -78.522708, 38.052033 ], [ -78.522379, 38.052403 ], [ -78.522049, 38.052728 ], [ -78.521736, 38.053004 ], [ -78.521375, 38.053289 ], [ -78.521061, 38.053512 ], [ -78.520792, 38.053687 ], [ -78.520433, 38.053898 ], [ -78.5202, 38.054028 ], [ -78.519924, 38.054166 ], [ -78.519561, 38.054329 ], [ -78.519179, 38.054486 ], [ -78.518827, 38.054612 ], [ -78.518437, 38.054736 ], [ -78.518106, 38.054829 ], [ -78.517883, 38.054877 ], [ -78.517638, 38.05494 ], [ -78.517298, 38.055006 ], [ -78.51674, 38.055093 ], [ -78.515503, 38.055228 ], [ -78.513125, 38.055506 ], [ -78.51298, 38.05552 ], [ -78.511721, 38.055664 ], [ -78.510089, 38.05585 ], [ -78.509444, 38.055931 ], [ -78.508892, 38.056018 ], [ -78.508324, 38.056121 ], [ -78.50762, 38.056269 ], [ -78.507101, 38.056364 ], [ -78.5063, 38.056529 ], [ -78.504207, 38.056975 ], [ -78.503544, 38.057129 ], [ -78.50332, 38.057173 ], [ -78.50218, 38.05739 ], [ -78.501769, 38.057476 ], [ -78.501588, 38.057518 ], [ -78.501288, 38.05758 ], [ -78.500918, 38.057644 ], [ -78.50053, 38.057699 ], [ -78.50025, 38.057721 ], [ -78.49999, 38.057731 ], [ -78.4996, 38.057738 ], [ -78.499258, 38.057729 ], [ -78.499228, 38.057727 ], [ -78.498789, 38.057695 ], [ -78.498509, 38.057667 ], [ -78.498249, 38.05764 ], [ -78.497868, 38.057604 ], [ -78.497658, 38.057584 ], [ -78.497235, 38.057537 ], [ -78.496848, 38.057489 ], [ -78.495893, 38.057371 ], [ -78.494978, 38.057279 ], [ -78.49472, 38.057173 ], [ -78.494659, 38.057142 ], [ -78.494592, 38.057093 ], [ -78.494549, 38.057047 ], [ -78.494516, 38.056995 ], [ -78.494502, 38.05695 ], [ -78.494493, 38.056874 ], [ -78.494502, 38.056798 ], [ -78.494522, 38.056739 ], [ -78.494562, 38.056669 ], [ -78.494623, 38.05661 ], [ -78.494697, 38.056562 ], [ -78.494781, 38.056525 ], [ -78.494872, 38.056502 ], [ -78.49496, 38.056493 ], [ -78.495044, 38.0565 ], [ -78.495109, 38.056516 ], [ -78.495169, 38.056541 ], [ -78.495238, 38.056584 ], [ -78.49528, 38.056617 ], [ -78.495339, 38.05668 ], [ -78.495381, 38.056751 ], [ -78.495402, 38.056811 ], [ -78.495415, 38.056894 ], [ -78.495413, 38.056998 ], [ -78.495388, 38.057116 ], [ -78.49528, 38.057239 ], [ -78.495007, 38.057577 ], [ -78.494845, 38.057747 ], [ -78.494782, 38.057825 ], [ -78.494593, 38.05807 ], [ -78.494413, 38.058298 ], [ -78.494268, 38.05847 ], [ -78.494235, 38.058509 ], [ -78.494159, 38.058601 ], [ -78.493967, 38.058833 ], [ -78.493505, 38.059401 ], [ -78.493364, 38.059586 ], [ -78.492889, 38.060182 ], [ -78.492564, 38.060616 ], [ -78.492196, 38.061101 ], [ -78.491916, 38.061468 ], [ -78.491724, 38.061722 ], [ -78.491723, 38.061722 ], [ -78.491578, 38.061897 ], [ -78.491244, 38.062293 ], [ -78.490863, 38.062734 ], [ -78.490477, 38.063153 ], [ -78.490269, 38.06338 ], [ -78.489937, 38.063742 ], [ -78.48969, 38.064008 ], [ -78.489478, 38.064259 ], [ -78.489344, 38.064409 ], [ -78.489289, 38.06447 ], [ -78.489212, 38.064554 ], [ -78.488761, 38.065053 ], [ -78.48815, 38.065739 ], [ -78.488116, 38.065779 ], [ -78.487867, 38.06605 ], [ -78.48713, 38.06686 ], [ -78.486995, 38.067008 ], [ -78.486825, 38.067194 ], [ -78.486343, 38.067727 ], [ -78.486218, 38.067866 ], [ -78.486208, 38.067877 ], [ -78.486134, 38.067959 ], [ -78.48576, 38.068363 ], [ -78.485475, 38.06867 ], [ -78.485154, 38.069027 ], [ -78.484295, 38.070023 ], [ -78.484063, 38.070271 ], [ -78.483776, 38.070614 ], [ -78.483281, 38.071164 ], [ -78.482433, 38.07211 ], [ -78.480968, 38.073741 ], [ -78.480778, 38.073943 ], [ -78.480706, 38.07403 ], [ -78.480376, 38.074401 ], [ -78.479882, 38.074956 ], [ -78.479801, 38.075034 ], [ -78.479272, 38.075634 ], [ -78.478606, 38.076375 ], [ -78.478527, 38.076469 ], [ -78.478367, 38.076647 ], [ -78.477091, 38.078062 ], [ -78.476397, 38.078846 ], [ -78.475743, 38.079571 ], [ -78.474543, 38.08091 ], [ -78.474163, 38.081335 ], [ -78.473969, 38.081577 ], [ -78.473788, 38.081788 ], [ -78.473613, 38.082014 ], [ -78.47347, 38.082218 ], [ -78.472971, 38.083082 ], [ -78.472639, 38.083666 ], [ -78.472264, 38.084319 ], [ -78.471709, 38.085285 ], [ -78.471146, 38.086271 ], [ -78.47079, 38.086895 ], [ -78.470583, 38.087258 ], [ -78.47026, 38.087825 ], [ -78.469568, 38.089039 ], [ -78.468607, 38.090712 ], [ -78.468501, 38.090897 ], [ -78.468139, 38.091557 ], [ -78.468043, 38.091733 ], [ -78.467922, 38.09192 ], [ -78.467732, 38.092218 ], [ -78.46735, 38.0929 ], [ -78.466766, 38.093924 ], [ -78.466497, 38.09437 ], [ -78.466369, 38.094558 ], [ -78.46599, 38.095057 ], [ -78.465526, 38.09564 ], [ -78.465381, 38.095816 ], [ -78.464933, 38.096381 ], [ -78.464463, 38.096962 ], [ -78.464049, 38.097474 ], [ -78.463974, 38.097573 ], [ -78.463441, 38.098232 ], [ -78.46294, 38.098874 ], [ -78.462231, 38.099765 ], [ -78.461478, 38.100721 ], [ -78.460943, 38.101395 ], [ -78.460544, 38.101882 ], [ -78.460009, 38.102564 ], [ -78.459568, 38.103126 ], [ -78.459337, 38.103403 ], [ -78.458603, 38.10429 ], [ -78.457804, 38.105297 ], [ -78.45751, 38.105695 ], [ -78.4569, 38.106619 ], [ -78.456598, 38.107068 ], [ -78.45544, 38.108845 ], [ -78.454988, 38.109578 ], [ -78.454476, 38.110311 ], [ -78.454296, 38.110569 ], [ -78.454206, 38.110708 ], [ -78.454093, 38.110899 ], [ -78.453942, 38.111128 ], [ -78.453769, 38.111409 ], [ -78.453294, 38.112125 ], [ -78.453172, 38.112318 ], [ -78.452856, 38.112817 ], [ -78.452688, 38.11307 ], [ -78.452602, 38.113223 ], [ -78.451975, 38.114186 ], [ -78.451686, 38.11461 ], [ -78.45106, 38.115568 ], [ -78.450908, 38.115798 ], [ -78.450496, 38.11642 ], [ -78.450419, 38.116537 ], [ -78.45032, 38.116697 ], [ -78.450137, 38.116993 ], [ -78.449702, 38.117634 ], [ -78.449172, 38.118448 ], [ -78.448773, 38.119065 ], [ -78.448006, 38.120242 ], [ -78.447677, 38.120726 ], [ -78.447299, 38.121219 ], [ -78.44692, 38.121631 ], [ -78.446411, 38.122124 ], [ -78.4458, 38.12267 ], [ -78.444661, 38.123687 ], [ -78.442392, 38.125724 ], [ -78.441529, 38.126494 ], [ -78.440922, 38.127044 ], [ -78.440006, 38.127866 ], [ -78.439371, 38.128436 ], [ -78.437997, 38.129669 ], [ -78.437902, 38.129754 ], [ -78.437019, 38.130549 ], [ -78.436453, 38.131059 ], [ -78.436187, 38.131299 ], [ -78.435995, 38.13147 ], [ -78.435251, 38.132172 ], [ -78.435106, 38.132303 ], [ -78.434673, 38.132753 ], [ -78.434293, 38.13317 ], [ -78.433695, 38.133887 ], [ -78.433416, 38.134269 ], [ -78.433195, 38.134572 ], [ -78.432173, 38.13616 ], [ -78.430917, 38.138131 ], [ -78.430468, 38.138847 ], [ -78.429836, 38.139833 ], [ -78.429464, 38.140424 ], [ -78.428859, 38.141359 ], [ -78.428348, 38.142178 ], [ -78.428275, 38.142291 ], [ -78.427887, 38.14289 ], [ -78.427641, 38.143278 ], [ -78.427277, 38.143851 ], [ -78.427263, 38.143873 ], [ -78.425718, 38.146293 ], [ -78.4249, 38.147586 ], [ -78.423982, 38.149017 ], [ -78.423879, 38.149181 ], [ -78.4234, 38.149936 ], [ -78.422346, 38.1516 ], [ -78.42208, 38.151996 ], [ -78.421684, 38.152621 ], [ -78.421337, 38.15319 ], [ -78.420383, 38.154692 ], [ -78.419605, 38.155908 ], [ -78.417659, 38.158962 ], [ -78.415009, 38.163121 ], [ -78.414626, 38.163716 ], [ -78.414541, 38.163851 ], [ -78.414293, 38.164245 ], [ -78.412771, 38.16663 ], [ -78.41231, 38.167345 ], [ -78.411781, 38.168185 ], [ -78.410521, 38.170164 ], [ -78.410064, 38.170881 ], [ -78.408661, 38.173081 ], [ -78.408289, 38.173661 ], [ -78.406754, 38.176057 ], [ -78.405791, 38.177582 ], [ -78.405633, 38.177824 ], [ -78.404819, 38.179105 ], [ -78.40451, 38.179581 ], [ -78.403702, 38.180857 ], [ -78.403534, 38.181116 ], [ -78.40229, 38.183084 ], [ -78.402, 38.183534 ], [ -78.401567, 38.184219 ], [ -78.401491, 38.184329 ], [ -78.400918, 38.18523 ], [ -78.400512, 38.185861 ], [ -78.399321, 38.187671 ], [ -78.399195, 38.187856 ], [ -78.399077, 38.188041 ], [ -78.398689, 38.188617 ], [ -78.398558, 38.18882 ], [ -78.397589, 38.190295 ], [ -78.3974, 38.190566 ], [ -78.397207, 38.19086 ], [ -78.396877, 38.191349 ], [ -78.396731, 38.191574 ], [ -78.396016, 38.192652 ], [ -78.395969, 38.192724 ], [ -78.395198, 38.193895 ], [ -78.395145, 38.193978 ], [ -78.395092, 38.194057 ], [ -78.395078, 38.194078 ], [ -78.394787, 38.194511 ], [ -78.394461, 38.19501 ], [ -78.394425, 38.195065 ], [ -78.393867, 38.195904 ], [ -78.393697, 38.196162 ], [ -78.392569, 38.197862 ], [ -78.392356, 38.198186 ], [ -78.391791, 38.199049 ], [ -78.3916, 38.199341 ], [ -78.391424, 38.19959 ], [ -78.391056, 38.200141 ], [ -78.390364, 38.201178 ], [ -78.388697, 38.203713 ], [ -78.387884, 38.204937 ], [ -78.387682, 38.20524 ], [ -78.387424, 38.205639 ], [ -78.386997, 38.206278 ], [ -78.386781, 38.206604 ], [ -78.386138, 38.207581 ], [ -78.385992, 38.207804 ], [ -78.385531, 38.2085 ], [ -78.38498, 38.209334 ], [ -78.384853, 38.209537 ], [ -78.383889, 38.210987 ], [ -78.383519, 38.211533 ], [ -78.383408, 38.211705 ], [ -78.383194, 38.212041 ], [ -78.382209, 38.213531 ], [ -78.381949, 38.213932 ], [ -78.381401, 38.214759 ], [ -78.380953, 38.215433 ], [ -78.380697, 38.215818 ], [ -78.380472, 38.216158 ], [ -78.379118, 38.218196 ], [ -78.378999, 38.218384 ], [ -78.37862, 38.21895 ], [ -78.377882, 38.220071 ], [ -78.377739, 38.220289 ], [ -78.377587, 38.220523 ], [ -78.376908, 38.221535 ], [ -78.376698, 38.221851 ], [ -78.376516, 38.222128 ], [ -78.375966, 38.222959 ], [ -78.375503, 38.223658 ], [ -78.374143, 38.225716 ], [ -78.373741, 38.226317 ], [ -78.372465, 38.228246 ], [ -78.371604, 38.229546 ], [ -78.371224, 38.230126 ], [ -78.37075, 38.230832 ], [ -78.370117, 38.231792 ], [ -78.369796, 38.23229 ], [ -78.369344, 38.233031 ], [ -78.369247, 38.233202 ], [ -78.369201, 38.233285 ], [ -78.369089, 38.233499 ], [ -78.368757, 38.234191 ], [ -78.368537, 38.23469 ], [ -78.368285, 38.235273 ], [ -78.367348, 38.237406 ], [ -78.367125, 38.237924 ], [ -78.366876, 38.23848 ], [ -78.366632, 38.239054 ], [ -78.366538, 38.239263 ], [ -78.366315, 38.239761 ], [ -78.365981, 38.240523 ], [ -78.365112, 38.242495 ], [ -78.364536, 38.243815 ], [ -78.364277, 38.244425 ], [ -78.363872, 38.245322 ], [ -78.363644, 38.245831 ], [ -78.363475, 38.246227 ], [ -78.363324, 38.246579 ], [ -78.363065, 38.24716 ], [ -78.362399, 38.248697 ], [ -78.362213, 38.249115 ], [ -78.36185, 38.249928 ], [ -78.360994, 38.251906 ], [ -78.360894, 38.252122 ], [ -78.360732, 38.252472 ], [ -78.359818, 38.254556 ], [ -78.359604, 38.255032 ], [ -78.358451, 38.257672 ], [ -78.35837, 38.257854 ], [ -78.357235, 38.260418 ], [ -78.35697, 38.261034 ], [ -78.356749, 38.261526 ], [ -78.356328, 38.262487 ], [ -78.3557, 38.26392 ], [ -78.355441, 38.264489 ], [ -78.354985, 38.265534 ], [ -78.354199, 38.267311 ], [ -78.354014, 38.267697 ], [ -78.353899, 38.267927 ], [ -78.353632, 38.268419 ], [ -78.353386, 38.268835 ], [ -78.353012, 38.269405 ], [ -78.352727, 38.269807 ], [ -78.352433, 38.270193 ], [ -78.351176, 38.271816 ], [ -78.35069, 38.272444 ], [ -78.350332, 38.272914 ], [ -78.349867, 38.273496 ], [ -78.349659, 38.273731 ], [ -78.349448, 38.273949 ], [ -78.349246, 38.274133 ], [ -78.348925, 38.274393 ], [ -78.348653, 38.274592 ], [ -78.348309, 38.274816 ], [ -78.346752, 38.275754 ], [ -78.345609, 38.276449 ], [ -78.34394, 38.277447 ], [ -78.343411, 38.277789 ], [ -78.343205, 38.277938 ], [ -78.342906, 38.278167 ], [ -78.342692, 38.278348 ], [ -78.342621, 38.27841 ], [ -78.342399, 38.278622 ], [ -78.342335, 38.278686 ], [ -78.342171, 38.278857 ], [ -78.341631, 38.279482 ], [ -78.341204, 38.280003 ], [ -78.341139, 38.280089 ], [ -78.341053, 38.280202 ], [ -78.340551, 38.280804 ], [ -78.34033, 38.281097 ], [ -78.339739, 38.281771 ], [ -78.337121, 38.284947 ], [ -78.335554, 38.286807 ], [ -78.334912, 38.287652 ], [ -78.334363, 38.288479 ], [ -78.333901, 38.289321 ], [ -78.332891, 38.291302 ], [ -78.33264, 38.291856 ], [ -78.332046, 38.29316 ], [ -78.331547, 38.294091 ], [ -78.33002, 38.297253 ], [ -78.328705, 38.299896 ], [ -78.328454, 38.300437 ], [ -78.327604, 38.302025 ], [ -78.326529, 38.303681 ], [ -78.325643, 38.304891 ], [ -78.325058, 38.305662 ], [ -78.32399, 38.30691 ], [ -78.3236, 38.307359 ], [ -78.323233, 38.30771 ], [ -78.322626, 38.308335 ], [ -78.320591, 38.310229 ], [ -78.317859, 38.312439 ], [ -78.317136, 38.313055 ], [ -78.314274, 38.315396 ], [ -78.313204, 38.316275 ], [ -78.313084, 38.316374 ], [ -78.312238, 38.317069 ], [ -78.31127, 38.317874 ], [ -78.310555, 38.318624 ], [ -78.308339, 38.321068 ], [ -78.307189, 38.322326 ], [ -78.306432, 38.323147 ], [ -78.305157, 38.324565 ], [ -78.299683, 38.33067 ], [ -78.296227, 38.334366 ], [ -78.294775, 38.336025 ], [ -78.294422, 38.336434 ], [ -78.293518, 38.337393 ], [ -78.292283, 38.338774 ], [ -78.290905, 38.340301 ], [ -78.289054, 38.34231 ], [ -78.287698, 38.343781 ], [ -78.286127, 38.345511 ], [ -78.284805, 38.346961 ], [ -78.284197, 38.347653 ], [ -78.281261, 38.350904 ], [ -78.27928, 38.353063 ], [ -78.277989, 38.354462 ], [ -78.276967, 38.355626 ], [ -78.275482, 38.357205 ], [ -78.275108, 38.357686 ], [ -78.273995, 38.359116 ], [ -78.272612, 38.361053 ], [ -78.269402, 38.365549 ], [ -78.268281, 38.367067 ], [ -78.26707, 38.368543 ], [ -78.266209, 38.369424 ], [ -78.26463, 38.370803 ], [ -78.263855, 38.371431 ], [ -78.262777, 38.372178 ], [ -78.262167, 38.372601 ], [ -78.258589, 38.375046 ], [ -78.253931, 38.378242 ], [ -78.253419, 38.378585 ], [ -78.252722, 38.379065 ], [ -78.251038, 38.380279 ], [ -78.249725, 38.3814 ], [ -78.248824, 38.38242 ], [ -78.247019, 38.384778 ], [ -78.243045, 38.39007 ], [ -78.242379, 38.390835 ], [ -78.241798, 38.391304 ], [ -78.241358, 38.391649 ], [ -78.240659, 38.392107 ], [ -78.239791, 38.392562 ], [ -78.236781, 38.394134 ], [ -78.234618, 38.395478 ], [ -78.233524, 38.396238 ], [ -78.231366, 38.397688 ], [ -78.230593, 38.398159 ], [ -78.229713, 38.398631 ], [ -78.22927, 38.398846 ], [ -78.227176, 38.399941 ], [ -78.224001, 38.401573 ], [ -78.221687, 38.402762 ], [ -78.220927, 38.403115 ], [ -78.219583, 38.403494 ], [ -78.217956, 38.403869 ], [ -78.216834, 38.404329 ], [ -78.216198, 38.404653 ], [ -78.215673, 38.404943 ], [ -78.2147, 38.405692 ], [ -78.214341, 38.406017 ], [ -78.211846, 38.409013 ], [ -78.211205, 38.409859 ], [ -78.208931, 38.412831 ], [ -78.207891, 38.413946 ], [ -78.207388, 38.414459 ], [ -78.206848, 38.414885 ], [ -78.20502, 38.416246 ], [ -78.204339, 38.416746 ], [ -78.203587, 38.417231 ], [ -78.201789, 38.418025 ], [ -78.199931, 38.418788 ], [ -78.198775, 38.419213 ], [ -78.197516, 38.419599 ], [ -78.196891, 38.419728 ], [ -78.193593, 38.420311 ], [ -78.192656, 38.420508 ], [ -78.191772, 38.420736 ], [ -78.190615, 38.421137 ], [ -78.189756, 38.421485 ], [ -78.189131, 38.421795 ], [ -78.188009, 38.422501 ], [ -78.186635, 38.423265 ], [ -78.185396, 38.423841 ], [ -78.184545, 38.424162 ], [ -78.179643, 38.425692 ], [ -78.176595, 38.426575 ], [ -78.175037, 38.427149 ], [ -78.174014, 38.427529 ], [ -78.171007, 38.428688 ], [ -78.169272, 38.429381 ], [ -78.165511, 38.430827 ], [ -78.164119, 38.431371 ], [ -78.162591, 38.431967 ], [ -78.161653, 38.432308 ], [ -78.160661, 38.43271 ], [ -78.160269, 38.432865 ], [ -78.159874, 38.433009 ], [ -78.157491, 38.433942 ], [ -78.157022, 38.434133 ], [ -78.156281, 38.434403 ], [ -78.154122, 38.435214 ], [ -78.152887, 38.435503 ], [ -78.151935, 38.435645 ], [ -78.151237, 38.435723 ], [ -78.149391, 38.435895 ], [ -78.145341, 38.436294 ], [ -78.143178, 38.436516 ], [ -78.141588, 38.436723 ], [ -78.140742, 38.436927 ], [ -78.139967, 38.43716 ], [ -78.139029, 38.437478 ], [ -78.138213, 38.437833 ], [ -78.13673, 38.438732 ], [ -78.135769, 38.439493 ], [ -78.133667, 38.441543 ], [ -78.13309, 38.442092 ], [ -78.132637, 38.442565 ], [ -78.131362, 38.443807 ], [ -78.131197, 38.443972 ], [ -78.13069, 38.444456 ], [ -78.13004, 38.445093 ], [ -78.129654, 38.445515 ], [ -78.129431, 38.445788 ], [ -78.129306, 38.445939 ], [ -78.129135, 38.446147 ], [ -78.126535, 38.449414 ], [ -78.12559, 38.450596 ], [ -78.124937, 38.451403 ], [ -78.12463, 38.451786 ], [ -78.122999, 38.453819 ], [ -78.12268, 38.454222 ], [ -78.122212, 38.454799 ], [ -78.122012, 38.455018 ], [ -78.121815, 38.455209 ], [ -78.121657, 38.455346 ], [ -78.121484, 38.455481 ], [ -78.121283, 38.455622 ], [ -78.121072, 38.455755 ], [ -78.120838, 38.455889 ], [ -78.120605, 38.456007 ], [ -78.120411, 38.456093 ], [ -78.120081, 38.45622 ], [ -78.11988, 38.456286 ], [ -78.119617, 38.456362 ], [ -78.119481, 38.456395 ], [ -78.119029, 38.456484 ], [ -78.118859, 38.456513 ], [ -78.118556, 38.456543 ], [ -78.118252, 38.456558 ], [ -78.117886, 38.45656 ], [ -78.117582, 38.456545 ], [ -78.117215, 38.456509 ], [ -78.11691, 38.456463 ], [ -78.116669, 38.456417 ], [ -78.116299, 38.456332 ], [ -78.114395, 38.455867 ], [ -78.113075, 38.455549 ], [ -78.112183, 38.455337 ], [ -78.111983, 38.455288 ], [ -78.110622, 38.454956 ], [ -78.109647, 38.454713 ], [ -78.109318, 38.454619 ], [ -78.108646, 38.454427 ], [ -78.108148, 38.454266 ], [ -78.107826, 38.454152 ], [ -78.107433, 38.454006 ], [ -78.106215, 38.453523 ], [ -78.103244, 38.452284 ], [ -78.103113, 38.45223 ], [ -78.101465, 38.451517 ], [ -78.100793, 38.451267 ], [ -78.099999, 38.450965 ], [ -78.099633, 38.450843 ], [ -78.099366, 38.450762 ], [ -78.098981, 38.450649 ], [ -78.098604, 38.450547 ], [ -78.098262, 38.45046 ], [ -78.09792, 38.450384 ], [ -78.096808, 38.450181 ], [ -78.096151, 38.450083 ], [ -78.095446, 38.449969 ], [ -78.093727, 38.449707 ], [ -78.092677, 38.449547 ], [ -78.092158, 38.449481 ], [ -78.091766, 38.449445 ], [ -78.091635, 38.449437 ], [ -78.091391, 38.44943 ], [ -78.09088, 38.449437 ], [ -78.090541, 38.449459 ], [ -78.090154, 38.449505 ], [ -78.090027, 38.449526 ], [ -78.089761, 38.44957 ], [ -78.089091, 38.449707 ], [ -78.08849, 38.449845 ], [ -78.087312, 38.450134 ], [ -78.086546, 38.450314 ], [ -78.086092, 38.450427 ], [ -78.085716, 38.450516 ], [ -78.085217, 38.45064 ], [ -78.083614, 38.45102 ], [ -78.082588, 38.451268 ], [ -78.081682, 38.451496 ], [ -78.080934, 38.451707 ], [ -78.080808, 38.451743 ], [ -78.080252, 38.451928 ], [ -78.080061, 38.451995 ], [ -78.079356, 38.452244 ], [ -78.079056, 38.452366 ], [ -78.077758, 38.452899 ], [ -78.07693, 38.453218 ], [ -78.07648, 38.453363 ], [ -78.075972, 38.453504 ], [ -78.075519, 38.453613 ], [ -78.075245, 38.453672 ], [ -78.074633, 38.453773 ], [ -78.073634, 38.453917 ], [ -78.073086, 38.453985 ], [ -78.071708, 38.454165 ], [ -78.070367, 38.45434 ], [ -78.069606, 38.454439 ], [ -78.065196, 38.455001 ], [ -78.0636, 38.455212 ], [ -78.062967, 38.455296 ], [ -78.062279, 38.455383 ], [ -78.061807, 38.45545 ], [ -78.061375, 38.455516 ], [ -78.060496, 38.455651 ], [ -78.059099, 38.455874 ], [ -78.058415, 38.455997 ], [ -78.057861, 38.456107 ], [ -78.057398, 38.456211 ], [ -78.057094, 38.456284 ], [ -78.055369, 38.456762 ], [ -78.054558, 38.456978 ], [ -78.05416, 38.457057 ], [ -78.053923, 38.4571 ], [ -78.053692, 38.457137 ], [ -78.053464, 38.457172 ], [ -78.052965, 38.457229 ], [ -78.052547, 38.457266 ], [ -78.05168, 38.457327 ], [ -78.051381, 38.457343 ], [ -78.051209, 38.457356 ], [ -78.050231, 38.457415 ], [ -78.049522, 38.45745 ], [ -78.049115, 38.457457 ], [ -78.048707, 38.45745 ], [ -78.048107, 38.457414 ], [ -78.046583, 38.457296 ], [ -78.045473, 38.457209 ], [ -78.043615, 38.457066 ], [ -78.04299, 38.457014 ], [ -78.041948, 38.456934 ], [ -78.041564, 38.4569 ], [ -78.040447, 38.456809 ], [ -78.039807, 38.456752 ], [ -78.039565, 38.456722 ], [ -78.038614, 38.456586 ], [ -78.037992, 38.45648 ], [ -78.036619, 38.456229 ], [ -78.036312, 38.456174 ], [ -78.035316, 38.455996 ], [ -78.033993, 38.455756 ], [ -78.033455, 38.455659 ], [ -78.032995, 38.455576 ], [ -78.032344, 38.455462 ], [ -78.032225, 38.455441 ], [ -78.032071, 38.455411 ], [ -78.031918, 38.455381 ], [ -78.030629, 38.455156 ], [ -78.030487, 38.455136 ], [ -78.02993, 38.455035 ], [ -78.029397, 38.454939 ], [ -78.027154, 38.454551 ], [ -78.026507, 38.454439 ], [ -78.026143, 38.454368 ], [ -78.025005, 38.454171 ], [ -78.024336, 38.45404 ], [ -78.023622, 38.453878 ], [ -78.02312, 38.453727 ], [ -78.02273, 38.453603 ], [ -78.022384, 38.453473 ], [ -78.021945, 38.453293 ], [ -78.021688, 38.453179 ], [ -78.02141, 38.45304 ], [ -78.020949, 38.452794 ], [ -78.020606, 38.452593 ], [ -78.018376, 38.451156 ], [ -78.015052, 38.449001 ], [ -78.013038, 38.447702 ], [ -78.012718, 38.447476 ], [ -78.012365, 38.447314 ], [ -78.011913, 38.44707 ], [ -78.011467, 38.446849 ], [ -78.011017, 38.446646 ], [ -78.010785, 38.446548 ], [ -78.01041, 38.446389 ], [ -78.009947, 38.446212 ], [ -78.009475, 38.446047 ], [ -78.009032, 38.44592 ], [ -78.008198, 38.445668 ], [ -78.007806, 38.445574 ], [ -78.007536, 38.445509 ], [ -78.00704, 38.445404 ], [ -78.006541, 38.445314 ], [ -78.006039, 38.445234 ], [ -78.005535, 38.445168 ], [ -78.004882, 38.445103 ], [ -78.00427, 38.44506 ], [ -78.003857, 38.445042 ], [ -78.003259, 38.445032 ], [ -77.996098, 38.445039 ], [ -77.995524, 38.445052 ], [ -77.995083, 38.445072 ], [ -77.9946, 38.445108 ], [ -77.994291, 38.44514 ], [ -77.994119, 38.445159 ], [ -77.993562, 38.445235 ], [ -77.993077, 38.445314 ], [ -77.992738, 38.44538 ], [ -77.992304, 38.445476 ], [ -77.991774, 38.445609 ], [ -77.991277, 38.445754 ], [ -77.990885, 38.44588 ], [ -77.990401, 38.446049 ], [ -77.989902, 38.446248 ], [ -77.98951, 38.446417 ], [ -77.989127, 38.446595 ], [ -77.988671, 38.446826 ], [ -77.988226, 38.44707 ], [ -77.988015, 38.447193 ], [ -77.987964, 38.447222 ], [ -77.986229, 38.448266 ], [ -77.982377, 38.450578 ], [ -77.980067, 38.451965 ], [ -77.978396, 38.452971 ], [ -77.976723, 38.453978 ], [ -77.971729, 38.456974 ], [ -77.970854, 38.457513 ], [ -77.970447, 38.457776 ], [ -77.969812, 38.458205 ], [ -77.969672, 38.458304 ], [ -77.969294, 38.458571 ], [ -77.968878, 38.458872 ], [ -77.968162, 38.459423 ], [ -77.967696, 38.459799 ], [ -77.967125, 38.46028 ], [ -77.966325, 38.460982 ], [ -77.965258, 38.461918 ], [ -77.964866, 38.462267 ], [ -77.960196, 38.466376 ], [ -77.955939, 38.470123 ], [ -77.954947, 38.470996 ], [ -77.954533, 38.471358 ], [ -77.953922, 38.471893 ], [ -77.953458, 38.472304 ], [ -77.953176, 38.472548 ], [ -77.952583, 38.473072 ], [ -77.951119, 38.474355 ], [ -77.950943, 38.474509 ], [ -77.949669, 38.47563 ], [ -77.948949, 38.476265 ], [ -77.948002, 38.477098 ], [ -77.940672, 38.483548 ], [ -77.940481, 38.483731 ], [ -77.940188, 38.484012 ], [ -77.939893, 38.484318 ], [ -77.939484, 38.484776 ], [ -77.93926, 38.485054 ], [ -77.939039, 38.48534 ], [ -77.938835, 38.485618 ], [ -77.938574, 38.486003 ], [ -77.938385, 38.4863 ], [ -77.938154, 38.486695 ], [ -77.936929, 38.489071 ], [ -77.936476, 38.48995 ], [ -77.936307, 38.490277 ], [ -77.936213, 38.490449 ], [ -77.936032, 38.490779 ], [ -77.935797, 38.491168 ], [ -77.935515, 38.491593 ], [ -77.935238, 38.491981 ], [ -77.934904, 38.492412 ], [ -77.934836, 38.492493 ], [ -77.93462, 38.492753 ], [ -77.934238, 38.493183 ], [ -77.933985, 38.493449 ], [ -77.933681, 38.493753 ], [ -77.933395, 38.494018 ], [ -77.933018, 38.494354 ], [ -77.932749, 38.494585 ], [ -77.932252, 38.494973 ], [ -77.93171, 38.495374 ], [ -77.931341, 38.495628 ], [ -77.930966, 38.495866 ], [ -77.930194, 38.496327 ], [ -77.929795, 38.496546 ], [ -77.929468, 38.496713 ], [ -77.928898, 38.496989 ], [ -77.928401, 38.497211 ], [ -77.927814, 38.497454 ], [ -77.927352, 38.49763 ], [ -77.926883, 38.497792 ], [ -77.92627, 38.497988 ], [ -77.925745, 38.498139 ], [ -77.925688, 38.498154 ], [ -77.925207, 38.498279 ], [ -77.924635, 38.498412 ], [ -77.924059, 38.498531 ], [ -77.923478, 38.498637 ], [ -77.923244, 38.498675 ], [ -77.9209, 38.499106 ], [ -77.920407, 38.499196 ], [ -77.916265, 38.499951 ], [ -77.914897, 38.500194 ], [ -77.913262, 38.500498 ], [ -77.912906, 38.500563 ], [ -77.911059, 38.5009 ], [ -77.910401, 38.501012 ], [ -77.909308, 38.501222 ], [ -77.90816, 38.501425 ], [ -77.906956, 38.501647 ], [ -77.902649, 38.502433 ], [ -77.901836, 38.502578 ], [ -77.901383, 38.502661 ], [ -77.899056, 38.503088 ], [ -77.897887, 38.503302 ], [ -77.896932, 38.503454 ], [ -77.896481, 38.503514 ], [ -77.896026, 38.50356 ], [ -77.89557, 38.503592 ], [ -77.895091, 38.503613 ], [ -77.894605, 38.503621 ], [ -77.894338, 38.503619 ], [ -77.894023, 38.503612 ], [ -77.893539, 38.503589 ], [ -77.893152, 38.50356 ], [ -77.891645, 38.503392 ], [ -77.891145, 38.503351 ], [ -77.890705, 38.503331 ], [ -77.890264, 38.503325 ], [ -77.89, 38.503328 ], [ -77.889421, 38.503346 ], [ -77.888918, 38.503375 ], [ -77.888578, 38.503406 ], [ -77.888318, 38.503429 ], [ -77.887823, 38.50349 ], [ -77.887334, 38.503566 ], [ -77.886849, 38.503655 ], [ -77.886369, 38.503759 ], [ -77.885701, 38.503929 ], [ -77.88504, 38.504114 ], [ -77.883872, 38.504451 ], [ -77.882026, 38.504972 ], [ -77.880726, 38.50535 ], [ -77.879756, 38.505628 ], [ -77.879416, 38.505726 ], [ -77.878734, 38.505916 ], [ -77.87665, 38.506514 ], [ -77.873295, 38.507467 ], [ -77.870872, 38.508164 ], [ -77.867574, 38.509112 ], [ -77.86643, 38.509426 ], [ -77.865139, 38.509804 ], [ -77.864878, 38.509875 ], [ -77.864614, 38.509946 ], [ -77.864004, 38.510124 ], [ -77.863963, 38.510136 ], [ -77.863243, 38.510359 ], [ -77.862776, 38.510515 ], [ -77.862313, 38.51068 ], [ -77.86153, 38.510992 ], [ -77.86091, 38.511252 ], [ -77.860341, 38.511504 ], [ -77.860101, 38.511597 ], [ -77.859873, 38.511706 ], [ -77.859049, 38.512033 ], [ -77.858596, 38.512199 ], [ -77.85801, 38.512393 ], [ -77.85641, 38.512859 ], [ -77.85546, 38.513131 ], [ -77.853636, 38.513652 ], [ -77.852939, 38.513842 ], [ -77.85189, 38.514117 ], [ -77.851773, 38.514147 ], [ -77.851155, 38.514282 ], [ -77.850783, 38.514355 ], [ -77.850158, 38.514468 ], [ -77.849529, 38.514566 ], [ -77.848611, 38.514673 ], [ -77.847601, 38.514814 ], [ -77.847219, 38.514874 ], [ -77.846744, 38.514961 ], [ -77.846275, 38.515063 ], [ -77.845622, 38.515227 ], [ -77.843493, 38.515828 ], [ -77.840926, 38.516554 ], [ -77.838953, 38.517123 ], [ -77.838611, 38.51724 ], [ -77.838276, 38.51737 ], [ -77.838087, 38.517452 ], [ -77.837878, 38.517559 ], [ -77.837641, 38.517698 ], [ -77.837371, 38.517879 ], [ -77.837159, 38.518042 ], [ -77.836631, 38.518508 ], [ -77.833939, 38.52107 ], [ -77.833536, 38.521444 ], [ -77.832859, 38.52207 ], [ -77.832618, 38.52227 ], [ -77.832363, 38.52246 ], [ -77.832151, 38.522605 ], [ -77.831761, 38.52284 ], [ -77.831645, 38.522905 ], [ -77.831341, 38.523059 ], [ -77.831027, 38.523201 ], [ -77.830705, 38.52333 ], [ -77.830375, 38.523446 ], [ -77.82725, 38.524408 ], [ -77.825282, 38.525005 ], [ -77.824825, 38.525153 ], [ -77.824766, 38.525172 ], [ -77.82414, 38.525403 ], [ -77.823904, 38.525501 ], [ -77.823444, 38.525707 ], [ -77.823161, 38.525842 ], [ -77.822816, 38.526023 ], [ -77.822483, 38.526216 ], [ -77.82216, 38.526429 ], [ -77.821905, 38.526618 ], [ -77.821824, 38.526681 ], [ -77.821661, 38.526816 ], [ -77.82143, 38.527024 ], [ -77.821026, 38.527454 ], [ -77.820758, 38.527783 ], [ -77.820516, 38.528112 ], [ -77.820197, 38.52856 ], [ -77.819895, 38.529029 ], [ -77.81945, 38.529798 ], [ -77.818541, 38.531386 ], [ -77.817476, 38.533249 ], [ -77.817174, 38.533749 ], [ -77.815779, 38.536111 ], [ -77.812836, 38.541042 ], [ -77.812145, 38.542152 ], [ -77.811443, 38.543345 ], [ -77.81107, 38.543916 ], [ -77.809169, 38.54677 ], [ -77.807061, 38.549912 ], [ -77.805801, 38.55177 ], [ -77.803189, 38.555743 ], [ -77.802664, 38.55653 ], [ -77.802442, 38.556869 ], [ -77.802253, 38.557175 ], [ -77.802079, 38.557492 ], [ -77.801838, 38.557971 ], [ -77.801782, 38.55809 ], [ -77.801657, 38.55838 ], [ -77.801522, 38.558722 ], [ -77.801429, 38.558994 ], [ -77.801302, 38.559432 ], [ -77.801209, 38.559822 ], [ -77.801144, 38.560169 ], [ -77.801065, 38.560727 ], [ -77.801025, 38.56131 ], [ -77.801027, 38.561813 ], [ -77.801049, 38.562487 ], [ -77.801069, 38.562893 ], [ -77.801213, 38.565749 ], [ -77.801305, 38.567636 ], [ -77.80137, 38.568961 ], [ -77.801541, 38.572402 ], [ -77.801599, 38.573623 ], [ -77.801669, 38.575224 ], [ -77.801707, 38.575829 ], [ -77.801772, 38.577117 ], [ -77.801874, 38.579138 ], [ -77.801902, 38.579759 ], [ -77.801914, 38.579914 ], [ -77.801945, 38.580642 ], [ -77.801977, 38.581198 ], [ -77.802036, 38.582417 ], [ -77.802118, 38.584113 ], [ -77.802126, 38.584391 ], [ -77.802131, 38.584986 ], [ -77.802118, 38.585525 ], [ -77.802088, 38.586052 ], [ -77.802017, 38.586791 ], [ -77.801743, 38.589112 ], [ -77.801725, 38.589268 ], [ -77.801437, 38.591698 ], [ -77.801342, 38.5925 ], [ -77.801281, 38.593006 ], [ -77.800994, 38.595455 ], [ -77.800644, 38.598437 ], [ -77.800492, 38.599704 ], [ -77.800457, 38.599972 ], [ -77.800268, 38.601612 ], [ -77.800209, 38.602305 ], [ -77.80017, 38.602992 ], [ -77.800152, 38.603904 ], [ -77.800152, 38.604035 ], [ -77.800152, 38.604483 ], [ -77.800172, 38.60559 ], [ -77.800187, 38.606551 ], [ -77.800205, 38.607644 ], [ -77.80022, 38.608813 ], [ -77.800237, 38.609384 ], [ -77.800232, 38.610093 ], [ -77.800248, 38.611162 ], [ -77.80027, 38.611781 ], [ -77.800276, 38.611972 ], [ -77.800298, 38.612639 ], [ -77.800312, 38.613039 ], [ -77.800332, 38.613399 ], [ -77.800397, 38.614527 ], [ -77.800421, 38.615203 ], [ -77.800432, 38.61575 ], [ -77.800444, 38.616559 ], [ -77.800478, 38.618723 ], [ -77.8005, 38.619601 ], [ -77.800525, 38.620811 ], [ -77.800527, 38.620908 ], [ -77.800548, 38.62192 ], [ -77.80058, 38.623403 ], [ -77.800594, 38.624213 ], [ -77.800603, 38.625413 ], [ -77.80062, 38.627386 ], [ -77.800629, 38.627856 ], [ -77.800651, 38.62934 ], [ -77.800658, 38.629863 ], [ -77.800688, 38.631295 ], [ -77.800701, 38.63219 ], [ -77.800708, 38.632656 ], [ -77.800729, 38.632937 ], [ -77.800749, 38.6331 ], [ -77.800764, 38.633194 ], [ -77.800824, 38.633493 ], [ -77.8009, 38.63375 ], [ -77.801033, 38.634132 ], [ -77.801091, 38.634277 ], [ -77.801339, 38.634852 ], [ -77.801526, 38.635289 ], [ -77.801703, 38.635692 ], [ -77.801752, 38.635808 ], [ -77.801965, 38.636295 ], [ -77.802897, 38.638462 ], [ -77.802996, 38.638693 ], [ -77.803206, 38.639174 ], [ -77.803351, 38.639505 ], [ -77.803635, 38.640158 ], [ -77.803774, 38.640485 ], [ -77.80405, 38.641121 ], [ -77.804137, 38.641325 ], [ -77.804199, 38.641471 ], [ -77.804367, 38.641868 ], [ -77.804398, 38.641941 ], [ -77.804535, 38.642359 ], [ -77.804602, 38.642621 ], [ -77.804642, 38.642832 ], [ -77.804669, 38.643038 ], [ -77.804677, 38.643118 ], [ -77.804687, 38.643291 ], [ -77.804696, 38.643722 ], [ -77.804696, 38.644409 ], [ -77.804677, 38.644766 ], [ -77.804636, 38.645023 ], [ -77.804576, 38.645279 ], [ -77.804498, 38.645531 ], [ -77.804445, 38.645671 ], [ -77.804179, 38.646296 ], [ -77.803976, 38.646795 ], [ -77.803645, 38.647584 ], [ -77.803607, 38.647672 ], [ -77.803037, 38.649027 ], [ -77.802582, 38.650099 ], [ -77.802488, 38.65032 ], [ -77.80226, 38.650816 ], [ -77.802226, 38.650891 ], [ -77.801705, 38.651973 ], [ -77.801524, 38.652348 ], [ -77.800517, 38.654435 ], [ -77.800311, 38.654856 ], [ -77.800109, 38.655223 ], [ -77.799504, 38.656216 ], [ -77.799258, 38.656629 ], [ -77.799064, 38.656995 ], [ -77.798952, 38.657238 ], [ -77.798593, 38.658126 ], [ -77.798524, 38.658287 ], [ -77.798395, 38.658591 ], [ -77.798266, 38.658901 ], [ -77.798049, 38.659428 ], [ -77.797829, 38.659963 ], [ -77.79736, 38.661105 ], [ -77.797075, 38.661795 ], [ -77.796724, 38.662641 ], [ -77.79625, 38.663783 ], [ -77.796094, 38.664161 ], [ -77.795637, 38.665271 ], [ -77.79528, 38.666132 ], [ -77.795248, 38.66621 ], [ -77.794069, 38.669063 ], [ -77.793674, 38.670024 ], [ -77.793379, 38.670723 ], [ -77.793244, 38.671036 ], [ -77.793103, 38.671307 ], [ -77.792943, 38.671571 ], [ -77.792813, 38.671755 ], [ -77.792641, 38.671968 ], [ -77.792454, 38.672174 ], [ -77.792251, 38.672371 ], [ -77.791496, 38.673047 ], [ -77.791134, 38.673372 ], [ -77.790643, 38.673809 ], [ -77.789269, 38.675032 ], [ -77.788765, 38.675507 ], [ -77.788692, 38.675576 ], [ -77.788181, 38.676104 ], [ -77.787807, 38.676549 ], [ -77.787668, 38.676743 ], [ -77.787501, 38.677031 ], [ -77.78738, 38.677265 ], [ -77.78733, 38.677383 ], [ -77.787232, 38.677659 ], [ -77.787165, 38.677911 ], [ -77.787115, 38.678177 ], [ -77.787085, 38.678445 ], [ -77.787079, 38.678552 ], [ -77.787095, 38.67913 ], [ -77.787153, 38.679798 ], [ -77.787259, 38.680924 ], [ -77.787331, 38.681886 ], [ -77.787363, 38.682419 ], [ -77.787413, 38.683635 ], [ -77.787401, 38.684203 ], [ -77.787392, 38.684611 ], [ -77.78735, 38.685019 ], [ -77.787315, 38.685264 ], [ -77.787231, 38.685728 ], [ -77.787136, 38.686251 ], [ -77.787114, 38.686332 ], [ -77.78692, 38.686986 ], [ -77.786696, 38.687619 ], [ -77.786501, 38.688074 ], [ -77.786277, 38.68855 ], [ -77.786098, 38.688888 ], [ -77.785944, 38.689154 ], [ -77.785576, 38.689748 ], [ -77.784818, 38.690938 ], [ -77.784516, 38.691425 ], [ -77.784271, 38.691807 ], [ -77.783827, 38.692506 ], [ -77.783401, 38.6932 ], [ -77.783246, 38.693444 ], [ -77.782384, 38.694802 ], [ -77.782205, 38.695084 ], [ -77.781593, 38.696059 ], [ -77.781243, 38.69667 ], [ -77.78108, 38.696994 ], [ -77.780923, 38.697347 ], [ -77.780812, 38.697637 ], [ -77.780687, 38.698004 ], [ -77.780614, 38.698231 ], [ -77.780587, 38.698314 ], [ -77.780392, 38.699181 ], [ -77.780333, 38.699659 ], [ -77.780298, 38.700094 ], [ -77.780287, 38.700389 ], [ -77.780289, 38.700757 ], [ -77.780315, 38.701452 ], [ -77.780365, 38.702797 ], [ -77.780397, 38.703509 ], [ -77.780462, 38.705131 ], [ -77.780535, 38.706895 ], [ -77.780587, 38.708144 ], [ -77.780612, 38.708911 ], [ -77.780675, 38.710324 ], [ -77.780782, 38.713019 ], [ -77.780806, 38.713639 ], [ -77.780906, 38.716128 ], [ -77.780923, 38.716557 ], [ -77.780985, 38.71812 ], [ -77.781094, 38.720811 ], [ -77.781111, 38.721348 ], [ -77.78117, 38.722771 ], [ -77.781205, 38.723428 ], [ -77.781207, 38.723933 ], [ -77.781141, 38.724638 ], [ -77.781062, 38.725028 ], [ -77.780986, 38.725313 ], [ -77.780873, 38.725651 ], [ -77.780799, 38.725838 ], [ -77.780763, 38.72593 ], [ -77.780608, 38.726258 ], [ -77.780457, 38.726537 ], [ -77.78029, 38.726814 ], [ -77.780067, 38.727137 ], [ -77.779841, 38.727426 ], [ -77.779593, 38.727712 ], [ -77.779535, 38.727773 ], [ -77.779432, 38.727882 ], [ -77.779137, 38.728163 ], [ -77.778889, 38.728379 ], [ -77.778564, 38.728638 ], [ -77.777988, 38.729064 ], [ -77.777903, 38.729128 ], [ -77.777813, 38.729195 ], [ -77.777751, 38.72924 ], [ -77.777544, 38.729395 ], [ -77.776507, 38.73018 ], [ -77.77534, 38.731069 ], [ -77.775049, 38.73127 ], [ -77.774364, 38.73177 ], [ -77.774051, 38.732009 ], [ -77.773303, 38.732554 ], [ -77.772496, 38.733155 ], [ -77.772444, 38.733192 ], [ -77.771424, 38.733941 ], [ -77.770375, 38.73472 ], [ -77.769774, 38.735166 ], [ -77.766501, 38.737595 ], [ -77.766092, 38.7379 ], [ -77.766013, 38.737957 ], [ -77.764613, 38.738973 ], [ -77.763699, 38.739647 ], [ -77.760294, 38.742188 ], [ -77.759475, 38.742805 ], [ -77.758292, 38.743704 ], [ -77.757242, 38.744507 ], [ -77.756734, 38.744888 ], [ -77.75607, 38.745394 ], [ -77.755332, 38.74595 ], [ -77.753869, 38.747051 ], [ -77.753512, 38.747317 ], [ -77.752239, 38.748266 ], [ -77.751486, 38.748835 ], [ -77.749304, 38.750477 ], [ -77.747696, 38.751677 ], [ -77.747175, 38.752069 ], [ -77.746636, 38.752468 ], [ -77.746089, 38.752858 ], [ -77.745719, 38.753113 ], [ -77.745109, 38.753534 ], [ -77.744529, 38.753946 ], [ -77.744441, 38.754016 ], [ -77.743143, 38.755039 ], [ -77.742369, 38.755648 ], [ -77.741019, 38.756723 ], [ -77.740302, 38.757289 ], [ -77.74012, 38.757439 ], [ -77.739869, 38.757633 ], [ -77.739452, 38.757933 ], [ -77.738896, 38.758325 ], [ -77.738458, 38.758616 ], [ -77.737994, 38.758912 ], [ -77.737675, 38.759109 ], [ -77.736928, 38.759546 ], [ -77.736529, 38.759764 ], [ -77.73598, 38.760062 ], [ -77.735512, 38.760302 ], [ -77.734641, 38.760749 ], [ -77.731871, 38.762168 ], [ -77.730354, 38.762946 ], [ -77.726563, 38.764904 ], [ -77.726297, 38.765042 ], [ -77.725494, 38.765462 ], [ -77.724993, 38.765717 ], [ -77.724283, 38.76606 ], [ -77.724155, 38.766114 ], [ -77.723683, 38.766274 ], [ -77.723631, 38.766287 ], [ -77.723461, 38.76633 ], [ -77.723208, 38.766384 ], [ -77.722948, 38.766425 ], [ -77.722732, 38.766449 ], [ -77.722439, 38.766466 ], [ -77.722204, 38.76647 ], [ -77.721761, 38.76645 ], [ -77.721338, 38.766416 ], [ -77.720827, 38.766373 ], [ -77.71958, 38.766268 ], [ -77.718945, 38.766226 ], [ -77.71829, 38.766214 ], [ -77.717886, 38.766231 ], [ -77.717644, 38.766248 ], [ -77.717238, 38.766296 ], [ -77.716986, 38.766333 ], [ -77.716478, 38.766426 ], [ -77.715933, 38.766539 ], [ -77.71313, 38.767126 ], [ -77.71253, 38.76725 ], [ -77.711446, 38.767475 ], [ -77.711213, 38.767521 ], [ -77.709832, 38.76781 ], [ -77.709246, 38.767933 ], [ -77.708584, 38.768078 ], [ -77.708134, 38.768177 ], [ -77.707984, 38.768211 ], [ -77.707651, 38.768287 ], [ -77.707208, 38.768389 ], [ -77.707037, 38.768429 ], [ -77.706966, 38.768445 ], [ -77.706604, 38.768529 ], [ -77.705724, 38.768733 ], [ -77.704884, 38.768928 ], [ -77.704008, 38.769125 ], [ -77.703413, 38.769266 ], [ -77.703044, 38.769359 ], [ -77.702667, 38.769454 ], [ -77.702289, 38.769565 ], [ -77.701922, 38.769687 ], [ -77.701705, 38.769766 ], [ -77.701294, 38.769925 ], [ -77.700381, 38.770277 ], [ -77.698624, 38.770957 ], [ -77.69792, 38.771222 ], [ -77.696779, 38.771656 ], [ -77.696286, 38.771839 ], [ -77.694688, 38.772451 ], [ -77.693388, 38.772942 ], [ -77.69338, 38.772945 ], [ -77.69299, 38.773092 ], [ -77.691828, 38.773541 ], [ -77.689985, 38.774273 ], [ -77.689184, 38.774593 ], [ -77.687947, 38.775099 ], [ -77.68652, 38.775696 ], [ -77.686093, 38.775875 ], [ -77.685013, 38.776323 ], [ -77.684548, 38.776508 ], [ -77.683617, 38.77688 ], [ -77.682281, 38.77742 ], [ -77.681906, 38.77757 ], [ -77.680152, 38.778273 ], [ -77.680071, 38.778309 ], [ -77.679964, 38.778348 ], [ -77.67944, 38.778559 ], [ -77.679135, 38.778682 ], [ -77.679008, 38.778733 ], [ -77.678765, 38.778831 ], [ -77.678322, 38.779011 ], [ -77.677302, 38.779417 ], [ -77.677036, 38.779514 ], [ -77.676871, 38.779569 ], [ -77.676375, 38.779711 ], [ -77.675903, 38.779834 ], [ -77.675739, 38.779874 ], [ -77.675282, 38.779966 ], [ -77.675165, 38.77999 ], [ -77.673681, 38.780291 ], [ -77.67245, 38.780538 ], [ -77.671784, 38.780666 ], [ -77.671623, 38.780699 ], [ -77.671392, 38.780752 ], [ -77.670977, 38.780857 ], [ -77.67067, 38.780949 ], [ -77.669909, 38.781181 ], [ -77.669755, 38.781229 ], [ -77.668691, 38.781557 ], [ -77.668105, 38.781729 ], [ -77.66717, 38.781984 ], [ -77.665556, 38.7824 ], [ -77.665397, 38.782443 ], [ -77.66509, 38.782528 ], [ -77.663117, 38.783041 ], [ -77.662729, 38.783142 ], [ -77.658982, 38.784122 ], [ -77.658234, 38.784318 ], [ -77.657487, 38.784515 ], [ -77.656903, 38.784668 ], [ -77.656444, 38.784785 ], [ -77.655772, 38.784954 ], [ -77.655488, 38.785028 ], [ -77.654149, 38.78538 ], [ -77.653073, 38.785665 ], [ -77.652817, 38.785732 ], [ -77.652723, 38.785757 ], [ -77.652335, 38.78586 ], [ -77.650432, 38.786358 ], [ -77.650292, 38.786394 ], [ -77.648546, 38.786845 ], [ -77.648132, 38.786953 ], [ -77.6471, 38.787217 ], [ -77.646912, 38.787266 ], [ -77.646792, 38.787296 ], [ -77.646475, 38.787378 ], [ -77.643862, 38.788066 ], [ -77.643514, 38.788151 ], [ -77.642956, 38.788288 ], [ -77.641845, 38.788545 ], [ -77.641256, 38.788678 ], [ -77.640668, 38.788812 ], [ -77.637878, 38.789456 ], [ -77.637724, 38.789491 ], [ -77.635026, 38.790112 ], [ -77.633026, 38.790572 ], [ -77.631672, 38.790883 ], [ -77.630391, 38.791179 ], [ -77.630168, 38.791231 ], [ -77.629412, 38.791414 ], [ -77.629006, 38.791523 ], [ -77.628982, 38.791529 ], [ -77.628275, 38.791722 ], [ -77.626219, 38.792284 ], [ -77.625465, 38.792483 ], [ -77.624741, 38.792675 ], [ -77.624567, 38.792721 ], [ -77.624468, 38.792748 ], [ -77.624067, 38.792856 ], [ -77.622821, 38.793191 ], [ -77.622323, 38.793326 ], [ -77.622182, 38.793359 ], [ -77.62157, 38.793529 ], [ -77.621412, 38.793572 ], [ -77.620477, 38.793825 ], [ -77.620443, 38.793835 ], [ -77.619193, 38.794171 ], [ -77.619018, 38.794213 ], [ -77.617763, 38.794556 ], [ -77.617092, 38.79473 ], [ -77.616747, 38.794832 ], [ -77.614017, 38.7956 ], [ -77.613309, 38.7958 ], [ -77.613097, 38.795859 ], [ -77.611965, 38.796178 ], [ -77.611011, 38.796432 ], [ -77.609519, 38.79683 ], [ -77.609066, 38.796955 ], [ -77.60887, 38.79701 ], [ -77.608124, 38.797223 ], [ -77.607861, 38.79729 ], [ -77.60659, 38.797608 ], [ -77.604759, 38.798106 ], [ -77.603341, 38.798433 ], [ -77.602615, 38.798623 ], [ -77.60217, 38.798681 ], [ -77.60178, 38.798726 ], [ -77.60159, 38.798739 ], [ -77.601338, 38.79876 ], [ -77.601043, 38.798748 ], [ -77.600761, 38.798726 ], [ -77.600475, 38.798685 ], [ -77.600088, 38.798626 ], [ -77.598701, 38.798329 ], [ -77.598447, 38.798288 ], [ -77.598168, 38.798263 ], [ -77.597945, 38.798266 ], [ -77.597733, 38.798267 ], [ -77.597515, 38.798295 ], [ -77.597295, 38.798329 ], [ -77.59709, 38.79838 ], [ -77.596838, 38.798472 ], [ -77.596056, 38.79873 ], [ -77.595792, 38.798802 ], [ -77.595557, 38.798839 ], [ -77.595321, 38.798872 ], [ -77.595123, 38.798893 ], [ -77.594903, 38.798906 ], [ -77.594606, 38.798902 ], [ -77.592349, 38.798571 ], [ -77.589853, 38.798246 ], [ -77.587564, 38.797961 ], [ -77.584659, 38.797708 ], [ -77.583518, 38.797592 ], [ -77.582596, 38.797507 ], [ -77.581727, 38.797465 ], [ -77.580645, 38.797422 ], [ -77.579853, 38.797408 ], [ -77.579381, 38.797391 ], [ -77.579328, 38.797391 ], [ -77.578346, 38.797391 ], [ -77.576989, 38.797404 ], [ -77.576007, 38.797446 ], [ -77.575373, 38.797504 ], [ -77.571144, 38.797797 ], [ -77.569287, 38.79792 ], [ -77.56555, 38.798187 ], [ -77.561659, 38.798447 ], [ -77.555891, 38.7988 ], [ -77.553755, 38.798951 ], [ -77.550887, 38.799152 ], [ -77.550295, 38.799193 ], [ -77.548407, 38.799331 ], [ -77.54595, 38.799494 ], [ -77.541063, 38.799812 ], [ -77.539341, 38.799946 ], [ -77.536546, 38.800151 ], [ -77.532281, 38.800448 ], [ -77.529135, 38.800667 ], [ -77.525861, 38.800895 ], [ -77.523173, 38.801079 ], [ -77.520134, 38.801324 ], [ -77.519426, 38.801374 ], [ -77.518588, 38.801436 ], [ -77.514662, 38.801698 ], [ -77.51275, 38.801833 ], [ -77.512257, 38.801883 ], [ -77.51176, 38.801949 ], [ -77.511242, 38.802033 ], [ -77.510728, 38.802133 ], [ -77.510237, 38.802245 ], [ -77.509757, 38.802371 ], [ -77.509283, 38.802511 ], [ -77.508762, 38.802686 ], [ -77.508249, 38.802874 ], [ -77.503238, 38.804849 ], [ -77.501867, 38.805383 ], [ -77.49854, 38.806696 ], [ -77.492854, 38.808929 ], [ -77.492586, 38.809039 ], [ -77.491408, 38.809499 ], [ -77.490728, 38.809768 ], [ -77.490387, 38.809903 ], [ -77.489846, 38.810125 ], [ -77.48976, 38.810159 ], [ -77.489588, 38.810228 ], [ -77.488128, 38.810814 ], [ -77.487975, 38.810876 ], [ -77.487938, 38.810891 ], [ -77.487614, 38.811027 ], [ -77.486889, 38.811312 ], [ -77.485515, 38.811841 ], [ -77.481021, 38.813606 ], [ -77.480031, 38.813987 ], [ -77.479528, 38.81418 ], [ -77.478278, 38.814671 ], [ -77.477784, 38.814859 ], [ -77.476696, 38.815283 ], [ -77.476308, 38.815444 ], [ -77.470849, 38.817587 ], [ -77.469997, 38.817934 ], [ -77.469107, 38.818314 ], [ -77.468263, 38.818692 ], [ -77.467788, 38.818912 ], [ -77.466824, 38.819384 ], [ -77.466481, 38.819559 ], [ -77.465978, 38.819814 ], [ -77.465888, 38.819862 ], [ -77.465082, 38.820299 ], [ -77.464689, 38.820516 ], [ -77.463916, 38.820976 ], [ -77.463568, 38.821184 ], [ -77.462817, 38.82165 ], [ -77.462169, 38.822067 ], [ -77.461524, 38.822499 ], [ -77.460742, 38.823046 ], [ -77.459971, 38.823615 ], [ -77.459453, 38.824009 ], [ -77.458829, 38.824505 ], [ -77.458041, 38.825157 ], [ -77.457989, 38.825199 ], [ -77.457719, 38.825436 ], [ -77.457456, 38.825667 ], [ -77.457174, 38.825914 ], [ -77.456485, 38.82655 ], [ -77.455925, 38.827089 ], [ -77.455609, 38.827408 ], [ -77.455354, 38.827664 ], [ -77.455286, 38.827736 ], [ -77.454763, 38.828288 ], [ -77.453687, 38.829492 ], [ -77.45117, 38.83231 ], [ -77.450091, 38.833546 ], [ -77.449603, 38.834072 ], [ -77.4484, 38.835411 ], [ -77.448317, 38.835496 ], [ -77.447073, 38.836883 ], [ -77.446568, 38.837456 ], [ -77.444983, 38.839239 ], [ -77.444962, 38.839261 ], [ -77.44448, 38.839771 ], [ -77.443925, 38.840374 ], [ -77.443121, 38.841151 ], [ -77.442523, 38.841683 ], [ -77.442048, 38.842083 ], [ -77.441563, 38.842472 ], [ -77.44121, 38.842729 ], [ -77.440835, 38.842989 ], [ -77.440353, 38.843301 ], [ -77.439357, 38.843895 ], [ -77.438808, 38.844189 ], [ -77.438412, 38.844388 ], [ -77.438154, 38.844513 ], [ -77.437585, 38.844773 ], [ -77.43695, 38.845042 ], [ -77.436125, 38.845358 ], [ -77.435386, 38.845611 ], [ -77.434841, 38.845778 ], [ -77.434461, 38.845886 ], [ -77.434065, 38.845989 ], [ -77.433588, 38.846102 ], [ -77.432595, 38.846311 ], [ -77.431976, 38.846424 ], [ -77.431894, 38.846439 ], [ -77.43166, 38.846482 ], [ -77.43013, 38.84677 ], [ -77.428638, 38.847052 ], [ -77.427672, 38.847201 ], [ -77.426895, 38.847336 ], [ -77.426613, 38.847387 ], [ -77.423954, 38.847868 ], [ -77.42318, 38.84802 ], [ -77.422578, 38.848129 ], [ -77.421734, 38.848284 ], [ -77.419777, 38.84865 ], [ -77.418032, 38.848977 ], [ -77.416532, 38.849246 ], [ -77.415198, 38.849482 ], [ -77.414151, 38.849672 ], [ -77.413692, 38.849756 ], [ -77.413004, 38.849886 ], [ -77.41025, 38.850388 ], [ -77.408348, 38.850725 ], [ -77.406003, 38.851167 ], [ -77.404553, 38.851419 ], [ -77.403103, 38.851676 ], [ -77.402433, 38.851803 ], [ -77.401513, 38.851954 ], [ -77.399882, 38.852249 ], [ -77.399048, 38.852319 ], [ -77.398718, 38.852375 ], [ -77.397996, 38.852492 ], [ -77.397318, 38.852624 ], [ -77.396752, 38.852714 ], [ -77.396348, 38.852749 ], [ -77.395658, 38.852767 ], [ -77.395009, 38.8528 ], [ -77.394695, 38.852837 ], [ -77.39433, 38.852891 ], [ -77.393802, 38.852984 ], [ -77.393126, 38.853114 ], [ -77.392725, 38.85318 ], [ -77.392095, 38.853297 ], [ -77.391904, 38.853339 ], [ -77.391134, 38.853478 ], [ -77.389836, 38.853723 ], [ -77.389215, 38.853845 ], [ -77.38892, 38.853895 ], [ -77.388716, 38.853941 ], [ -77.388024, 38.854062 ], [ -77.387165, 38.854196 ], [ -77.386771, 38.854162 ], [ -77.386529, 38.854111 ], [ -77.386343, 38.854055 ], [ -77.386187, 38.853987 ], [ -77.386127, 38.853954 ], [ -77.386079, 38.85392 ], [ -77.385986, 38.853839 ], [ -77.385938, 38.853785 ], [ -77.385904, 38.853738 ], [ -77.385849, 38.853638 ], [ -77.385829, 38.853585 ], [ -77.385812, 38.853521 ], [ -77.3858, 38.853402 ], [ -77.385805, 38.853336 ], [ -77.385817, 38.853271 ], [ -77.38586, 38.853155 ], [ -77.385888, 38.853105 ], [ -77.385929, 38.853047 ], [ -77.38601, 38.852959 ], [ -77.386068, 38.85291 ], [ -77.386119, 38.852873 ], [ -77.386233, 38.85281 ], [ -77.386292, 38.852784 ], [ -77.386367, 38.852757 ], [ -77.386444, 38.852736 ], [ -77.386551, 38.852715 ], [ -77.386695, 38.852705 ], [ -77.38684, 38.852711 ], [ -77.386899, 38.85272 ], [ -77.386985, 38.852739 ], [ -77.387131, 38.852784 ], [ -77.387234, 38.852827 ], [ -77.387327, 38.852872 ], [ -77.387501, 38.852977 ], [ -77.387596, 38.853046 ], [ -77.387689, 38.853125 ], [ -77.387869, 38.853301 ], [ -77.388005, 38.8535 ], [ -77.388211, 38.853861 ], [ -77.388248, 38.853958 ], [ -77.38834, 38.854202 ], [ -77.388434, 38.854509 ], [ -77.388512, 38.85483 ], [ -77.388556, 38.855045 ], [ -77.388563, 38.855077 ], [ -77.388615, 38.855398 ], [ -77.38864, 38.855726 ], [ -77.388657, 38.85606 ], [ -77.388632, 38.856494 ], [ -77.388606, 38.856728 ], [ -77.388546, 38.857062 ], [ -77.388494, 38.857283 ], [ -77.388383, 38.85759 ], [ -77.388245, 38.857898 ], [ -77.387962, 38.858392 ], [ -77.387722, 38.858713 ], [ -77.387587, 38.858842 ], [ -77.387448, 38.858992 ], [ -77.38738, 38.859049 ], [ -77.387049, 38.859315 ], [ -77.387001, 38.859355 ], [ -77.386572, 38.859616 ], [ -77.386057, 38.859876 ], [ -77.385696, 38.860037 ], [ -77.385104, 38.860297 ], [ -77.384246, 38.860678 ], [ -77.383311, 38.861091 ], [ -77.382484, 38.861549 ], [ -77.381927, 38.861964 ], [ -77.381649, 38.862271 ], [ -77.381472, 38.862656 ], [ -77.38114, 38.86254 ], [ -77.380676, 38.862336 ], [ -77.380373, 38.862167 ], [ -77.380144, 38.862016 ], [ -77.379932, 38.861857 ], [ -77.379724, 38.861669 ], [ -77.379541, 38.861495 ], [ -77.379299, 38.861256 ], [ -77.379174, 38.86114 ], [ -77.378963, 38.86097 ], [ -77.378779, 38.860822 ], [ -77.378622, 38.860715 ], [ -77.378375, 38.860584 ], [ -77.37825, 38.860526 ], [ -77.377901, 38.860354 ], [ -77.377674, 38.860258 ], [ -77.377503, 38.860194 ], [ -77.376982, 38.860031 ], [ -77.376724, 38.859968 ], [ -77.376465, 38.859908 ], [ -77.376139, 38.859843 ], [ -77.375957, 38.859809 ], [ -77.375449, 38.859704 ], [ -77.37477, 38.859591 ], [ -77.373992, 38.859482 ], [ -77.373385, 38.859411 ], [ -77.373319, 38.859405 ], [ -77.371684, 38.859251 ], [ -77.371331, 38.859226 ], [ -77.37112, 38.859211 ], [ -77.371099, 38.85942 ], [ -77.371098, 38.859619 ], [ -77.371033, 38.860102 ], [ -77.370993, 38.860407 ], [ -77.370953, 38.86073 ], [ -77.370894, 38.86095 ], [ -77.370816, 38.861165 ], [ -77.370757, 38.861296 ], [ -77.370665, 38.861443 ], [ -77.370575, 38.861587 ], [ -77.370384, 38.861875 ], [ -77.370116, 38.862301 ], [ -77.369869, 38.862675 ], [ -77.369695, 38.862937 ], [ -77.369553, 38.863149 ], [ -77.369282, 38.863562 ], [ -77.369075, 38.863878 ], [ -77.369003, 38.863978 ], [ -77.368943, 38.864053 ], [ -77.368872, 38.864143 ], [ -77.368754, 38.864281 ], [ -77.368648, 38.864383 ], [ -77.368548, 38.86448 ], [ -77.368413, 38.864611 ], [ -77.368244, 38.864751 ], [ -77.368139, 38.86483 ], [ -77.368096, 38.864859 ], [ -77.367962, 38.864949 ], [ -77.367753, 38.865087 ], [ -77.36752, 38.865221 ], [ -77.36716, 38.865425 ], [ -77.366916, 38.865565 ], [ -77.366749, 38.865664 ], [ -77.366693, 38.865696 ], [ -77.366603, 38.865757 ], [ -77.36621, 38.865941 ], [ -77.365964, 38.866096 ], [ -77.365677, 38.866275 ], [ -77.365412, 38.86648 ], [ -77.365205, 38.866666 ], [ -77.365092, 38.866802 ], [ -77.364926, 38.867027 ], [ -77.364819, 38.867215 ], [ -77.364795, 38.867271 ], [ -77.364687, 38.867526 ], [ -77.364631, 38.867731 ], [ -77.364602, 38.867885 ], [ -77.364585, 38.868103 ], [ -77.364599, 38.86833 ], [ -77.364602, 38.868416 ], [ -77.364653, 38.868646 ], [ -77.364749, 38.868903 ], [ -77.364915, 38.869232 ], [ -77.365031, 38.869489 ], [ -77.36519, 38.869811 ], [ -77.365353, 38.870145 ], [ -77.365541, 38.870577 ], [ -77.365608, 38.870714 ], [ -77.36564, 38.87078 ], [ -77.365767, 38.871048 ], [ -77.365858, 38.871232 ], [ -77.365914, 38.871335 ], [ -77.366032, 38.871546 ], [ -77.366196, 38.871805 ], [ -77.366355, 38.872046 ], [ -77.366507, 38.872259 ], [ -77.366678, 38.872501 ], [ -77.366856, 38.872754 ], [ -77.366963, 38.872925 ], [ -77.367022, 38.873039 ], [ -77.367081, 38.873163 ], [ -77.367145, 38.873344 ], [ -77.367182, 38.87346 ], [ -77.367204, 38.873534 ], [ -77.367233, 38.873695 ], [ -77.36726, 38.873889 ], [ -77.367273, 38.874003 ], [ -77.367165, 38.874012 ], [ -77.366994, 38.874012 ], [ -77.366779, 38.873999 ], [ -77.366666, 38.873986 ], [ -77.366501, 38.873968 ], [ -77.366313, 38.873934 ], [ -77.366155, 38.873897 ], [ -77.365932, 38.873832 ], [ -77.36562, 38.873728 ], [ -77.365375, 38.873647 ], [ -77.36552, 38.873752 ], [ -77.365645, 38.873824 ], [ -77.365759, 38.873875 ] ] } } diff --git a/packages/turf-along/tsconfig.json b/packages/turf-along/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-along/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-along/tslint.json b/packages/turf-along/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-along/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-angle/.gitignore b/packages/turf-angle/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-angle/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-angle/LICENSE b/packages/turf-angle/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-angle/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-angle/README.md b/packages/turf-angle/README.md deleted file mode 100644 index 5ba80d8c56..0000000000 --- a/packages/turf-angle/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# @turf/angle - - - -## angle - -Finds the angle formed by two adjacent segments defined by 3 points. The result will be the (positive clockwise) -angle with origin on the `startPoint-midPoint` segment, or its explementary angle if required. - -**Parameters** - -- `startPoint` **[Coord][1]** Start Point Coordinates -- `midPoint` **[Coord][1]** Mid Point Coordinates -- `endPoint` **[Coord][1]** End Point Coordinates -- `options` **[Object][2]** Optional parameters (optional, default `{}`) - - `options.explementary` **[boolean][3]** Returns the explementary angle instead (360 - angle) (optional, default `false`) - - `options.mercator` **[boolean][3]** if calculations should be performed over Mercator or WGS84 projection (optional, default `false`) - -**Examples** - -```javascript -turf.angle([5, 5], [5, 6], [3, 4]); -//=45 -``` - -Returns **[number][4]** Angle between the provided points, or its explementary. - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/angle -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` - - -### Diagrams - -![turf-angle](diagrams/turf-angle.png) \ No newline at end of file diff --git a/packages/turf-angle/index.ts b/packages/turf-angle/index.ts deleted file mode 100644 index 7cf559ceed..0000000000 --- a/packages/turf-angle/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -import bearing from "@turf/bearing"; -import { bearingToAzimuth, Coord, isObject } from "@turf/helpers"; -import rhumbBearing from "@turf/rhumb-bearing"; - -/** - * Finds the angle formed by two adjacent segments defined by 3 points. The result will be the (positive clockwise) - * angle with origin on the `startPoint-midPoint` segment, or its explementary angle if required. - * - * @name angle - * @param {Coord} startPoint Start Point Coordinates - * @param {Coord} midPoint Mid Point Coordinates - * @param {Coord} endPoint End Point Coordinates - * @param {Object} [options={}] Optional parameters - * @param {boolean} [options.explementary=false] Returns the explementary angle instead (360 - angle) - * @param {boolean} [options.mercator=false] if calculations should be performed over Mercator or WGS84 projection - * @returns {number} Angle between the provided points, or its explementary. - * @example - * turf.angle([5, 5], [5, 6], [3, 4]); - * //=45 - */ -function angle(startPoint: Coord, midPoint: Coord, endPoint: Coord, options: { - explementary?: boolean - mercator?: boolean, -} = {}): number { - // Optional Parameters - if (!isObject(options)) { throw new Error("options is invalid"); } - - // Validation - if (!startPoint) { throw new Error("startPoint is required"); } - if (!midPoint) { throw new Error("midPoint is required"); } - if (!endPoint) { throw new Error("endPoint is required"); } - - // Rename to shorter variables - const A = startPoint; - const O = midPoint; - const B = endPoint; - - // Main - const azimuthAO = bearingToAzimuth((options.mercator !== true) ? bearing(A, O) : rhumbBearing(A, O)); - const azimuthBO = bearingToAzimuth((options.mercator !== true) ? bearing(B, O) : rhumbBearing(B, O)); - const angleAO = Math.abs(azimuthAO - azimuthBO); - - // Explementary angle - if (options.explementary === true) { return 360 - angleAO; } - return angleAO; -} - -export default angle; diff --git a/packages/turf-angle/package.json b/packages/turf-angle/package.json deleted file mode 100644 index b9250c7f3d..0000000000 --- a/packages/turf-angle/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@turf/angle", - "version": "6.0.1", - "description": "turf angle module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "angle" - ], - "author": "Turf Authors", - "contributors": [ - "Denis <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/distance": "*", - "@turf/sector": "*", - "@turf/truncate": "*", - "benchmark": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/bearing": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/rhumb-bearing": "6.x" - } -} diff --git a/packages/turf-angle/test.js b/packages/turf-angle/test.js deleted file mode 100644 index fd70529702..0000000000 --- a/packages/turf-angle/test.js +++ /dev/null @@ -1,81 +0,0 @@ -const test = require('tape'); -const path = require('path'); -const glob = require('glob'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const sector = require('@turf/sector').default; -const bearing = require('@turf/bearing').default; -const truncate = require('@turf/truncate').default; -const distance = require('@turf/distance').default; -const { point, round, lineString, featureCollection } = require('@turf/helpers'); -const angle = require('./').default; - -test('turf-angle', t => { - glob.sync(path.join(__dirname, 'test', 'in', '*.json')).forEach(filepath => { - // Input - const {name} = path.parse(filepath); - const geojson = load.sync(filepath); - const [start, mid, end] = geojson.features; - - // Results - const angleProperties = { - interiorAngle: round(angle(start, mid, end), 6), - interiorMercatorAngle: round(angle(start, mid, end, {mercator: true}), 6), - explementary: false, - fill: '#F00', - stroke: '#F00', - 'fill-opacity': 0.3 - }; - const angleExplementaryProperties = { - explementaryAngle: round(angle(start, mid, end, {explementary: true}), 6), - explementaryMercatorAngle: round(angle(start, mid, end, {explementary: true, mercator: true}), 6), - explementary: true, - fill: '#00F', - stroke: '#00F', - 'fill-opacity': 0.3 - }; - const results = featureCollection([ - truncate(sector(mid, distance(mid, start) / 3, bearing(mid, start), bearing(mid, end), {properties: angleProperties})), - truncate(sector(mid, distance(mid, start) / 2, bearing(mid, end), bearing(mid, start), {properties: angleExplementaryProperties})), - lineString([start.geometry.coordinates, mid.geometry.coordinates, end.geometry.coordinates], {'stroke-width': 4, stroke: '#222'}), - start, - mid, - end, - ]); - - // Save results - const expected = filepath.replace(path.join('test', 'in'), path.join('test', 'out')); - if (process.env.REGEN) write.sync(expected, results); - t.deepEqual(results, load.sync(expected), name); - }); - t.end(); -}); - -test('turf-angle -- simple', t => { - t.equal(round(angle([5, 5], [5, 6], [3, 4])), 45, '45 degrees'); - t.equal(round(angle([3, 4], [5, 6], [5, 5])), 45, '45 degrees -- inverse'); - t.equal(round(angle([3, 4], [5, 6], [5, 5], {explementary: true})), 360 - 45, 'explementary angle'); - t.end(); -}); - -test('turf-angle -- issues', t => { - const start = [167.72709868848324, -45.56543836343071]; - const mid = [167.7269698586315, -45.56691059720167]; - const end = [167.72687866352499, -45.566989345276355]; - const a = angle(start, mid, end); - - t.false(isNaN(a), 'result is not NaN'); - t.end(); -}); - -test('turf-angle -- throws', t => { - const pt1 = point([-10, -30]); - const pt2 = point([-11, -33]); - const pt3 = point([-12, -36]); - t.throws(() => angle(null, pt2, pt3), /startPoint is required/, 'startPoint is required'); - t.throws(() => angle(pt1, undefined, pt3), /midPoint is required/, 'midPoint is required'); - t.throws(() => angle(pt1, pt2), /endPoint is required/, 'endPoint is required'); - t.throws(() => angle(pt1, pt2, pt3, 'string'), /options is invalid/, 'invalid options'); - - t.end(); -}); diff --git a/packages/turf-angle/tsconfig.json b/packages/turf-angle/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-angle/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-angle/tslint.json b/packages/turf-angle/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-angle/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-area/.gitignore b/packages/turf-area/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-area/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-area/LICENSE b/packages/turf-area/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-area/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-area/README.md b/packages/turf-area/README.md deleted file mode 100644 index 48d091ff50..0000000000 --- a/packages/turf-area/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# @turf/area - - - -## area - -Takes one or more features and returns their area in square meters. - -**Parameters** - -- `geojson` **[GeoJSON][1]** input GeoJSON feature(s) - -**Examples** - -```javascript -var polygon = turf.polygon([[[125, -15], [113, -22], [154, -27], [144, -15], [125, -15]]]); - -var area = turf.area(polygon); - -//addToMap -var addToMap = [polygon] -polygon.properties.area = area -``` - -Returns **[number][2]** area in square meters - -[1]: https://tools.ietf.org/html/rfc7946#section-3 - -[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/area -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-area/index.d.ts b/packages/turf-area/index.d.ts deleted file mode 100644 index 6503534b92..0000000000 --- a/packages/turf-area/index.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Feature, FeatureCollection, Geometry } from "@turf/helpers"; -/** - * Takes one or more features and returns their area in square meters. - * - * @name area - * @param {GeoJSON} geojson input GeoJSON feature(s) - * @returns {number} area in square meters - * @example - * var polygon = turf.polygon([[[125, -15], [113, -22], [154, -27], [144, -15], [125, -15]]]); - * - * var area = turf.area(polygon); - * - * //addToMap - * var addToMap = [polygon] - * polygon.properties.area = area - */ -export default function area(geojson: Feature | FeatureCollection | Geometry): number; diff --git a/packages/turf-area/index.ts b/packages/turf-area/index.ts deleted file mode 100644 index 4c375b0510..0000000000 --- a/packages/turf-area/index.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { Feature, FeatureCollection, Geometry } from "@turf/helpers"; -import { geomReduce } from "@turf/meta"; - -// Note: change RADIUS => earthRadius -const RADIUS = 6378137; - -/** - * Takes one or more features and returns their area in square meters. - * - * @name area - * @param {GeoJSON} geojson input GeoJSON feature(s) - * @returns {number} area in square meters - * @example - * var polygon = turf.polygon([[[125, -15], [113, -22], [154, -27], [144, -15], [125, -15]]]); - * - * var area = turf.area(polygon); - * - * //addToMap - * var addToMap = [polygon] - * polygon.properties.area = area - */ -export default function area(geojson: Feature | FeatureCollection | Geometry) { - return geomReduce(geojson, (value, geom) => { - return value + calculateArea(geom); - }, 0); -} - -/** - * Calculate Area - * - * @private - * @param {Geometry} geom GeoJSON Geometries - * @returns {number} area - */ -function calculateArea(geom: Geometry): number { - let total = 0; - let i; - switch (geom.type) { - case "Polygon": - return polygonArea(geom.coordinates); - case "MultiPolygon": - for (i = 0; i < geom.coordinates.length; i++) { - total += polygonArea(geom.coordinates[i]); - } - return total; - case "Point": - case "MultiPoint": - case "LineString": - case "MultiLineString": - return 0; - } - return 0; -} - -function polygonArea(coords: any) { - let total = 0; - if (coords && coords.length > 0) { - total += Math.abs(ringArea(coords[0])); - for (let i = 1; i < coords.length; i++) { - total -= Math.abs(ringArea(coords[i])); - } - } - return total; -} - -/** - * @private - * Calculate the approximate area of the polygon were it projected onto the earth. - * Note that this area will be positive if ring is oriented clockwise, otherwise it will be negative. - * - * Reference: - * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for Polygons on a Sphere", - * JPL Publication 07-03, Jet Propulsion - * Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409 - * - * @param {Array>} coords Ring Coordinates - * @returns {number} The approximate signed geodesic area of the polygon in square meters. - */ -function ringArea(coords: number[][]) { - let p1; - let p2; - let p3; - let lowerIndex; - let middleIndex; - let upperIndex; - let i; - let total = 0; - const coordsLength = coords.length; - - if (coordsLength > 2) { - for (i = 0; i < coordsLength; i++) { - if (i === coordsLength - 2) { // i = N-2 - lowerIndex = coordsLength - 2; - middleIndex = coordsLength - 1; - upperIndex = 0; - } else if (i === coordsLength - 1) { // i = N-1 - lowerIndex = coordsLength - 1; - middleIndex = 0; - upperIndex = 1; - } else { // i = 0 to N-3 - lowerIndex = i; - middleIndex = i + 1; - upperIndex = i + 2; - } - p1 = coords[lowerIndex]; - p2 = coords[middleIndex]; - p3 = coords[upperIndex]; - total += (rad(p3[0]) - rad(p1[0])) * Math.sin(rad(p2[1])); - } - - total = total * RADIUS * RADIUS / 2; - } - return total; -} - -function rad(num: number) { - return num * Math.PI / 180; -} diff --git a/packages/turf-area/package.json b/packages/turf-area/package.json deleted file mode 100644 index 456087df98..0000000000 --- a/packages/turf-area/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "@turf/area", - "version": "6.0.1", - "description": "turf area module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "area", - "polygon", - "multipolygon" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-area/test/out/polygon.json b/packages/turf-area/test/out/polygon.json deleted file mode 100644 index 9a8d74ff68..0000000000 --- a/packages/turf-area/test/out/polygon.json +++ /dev/null @@ -1 +0,0 @@ -7766240997209 diff --git a/packages/turf-area/tsconfig.json b/packages/turf-area/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-area/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-area/tslint.json b/packages/turf-area/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-area/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-bbox-clip/.gitignore b/packages/turf-bbox-clip/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-bbox-clip/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-bbox-clip/LICENSE b/packages/turf-bbox-clip/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-bbox-clip/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-bbox-clip/README.md b/packages/turf-bbox-clip/README.md deleted file mode 100644 index 6a5077557c..0000000000 --- a/packages/turf-bbox-clip/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# @turf/bbox-clip - - - -## bboxClip - -Takes a [Feature][1] and a bbox and clips the feature to the bbox using [lineclip][2]. -May result in degenerate edges when clipping Polygons. - -**Parameters** - -- `feature` **[Feature][3]<([LineString][4] \| [MultiLineString][5] \| [Polygon][6] \| [MultiPolygon][7])>** feature to clip to the bbox -- `bbox` **[BBox][8]** extent in [minX, minY, maxX, maxY] order - -**Examples** - -```javascript -var bbox = [0, 0, 10, 10]; -var poly = turf.polygon([[[2, 2], [8, 4], [12, 8], [3, 7], [2, 2]]]); - -var clipped = turf.bboxClip(poly, bbox); - -//addToMap -var addToMap = [bbox, poly, clipped] -``` - -Returns **[Feature][3]<([LineString][4] \| [MultiLineString][5] \| [Polygon][6] \| [MultiPolygon][7])>** clipped Feature - -[1]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[2]: https://github.com/mapbox/lineclip - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[8]: https://tools.ietf.org/html/rfc7946#section-5 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/bbox-clip -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-bbox-clip/index.ts b/packages/turf-bbox-clip/index.ts deleted file mode 100644 index 29bc4f492d..0000000000 --- a/packages/turf-bbox-clip/index.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { - BBox, Feature, LineString, lineString, - multiLineString, MultiLineString, multiPolygon, MultiPolygon, polygon, Polygon, Properties, -} from "@turf/helpers"; -import { getCoords, getGeom } from "@turf/invariant"; -import * as lineclip from "./lib/lineclip"; - -/** - * Takes a {@link Feature} and a bbox and clips the feature to the bbox using - * [lineclip](https://github.com/mapbox/lineclip). - * May result in degenerate edges when clipping Polygons. - * - * @name bboxClip - * @param {Feature} feature feature to clip to the bbox - * @param {BBox} bbox extent in [minX, minY, maxX, maxY] order - * @returns {Feature} clipped Feature - * @example - * var bbox = [0, 0, 10, 10]; - * var poly = turf.polygon([[[2, 2], [8, 4], [12, 8], [3, 7], [2, 2]]]); - * - * var clipped = turf.bboxClip(poly, bbox); - * - * //addToMap - * var addToMap = [bbox, poly, clipped] - */ -export default function bboxClip( - feature: Feature | G, - bbox: BBox, -) { - const geom = getGeom(feature); - const type = geom.type; - const properties = feature.type === "Feature" ? feature.properties : {}; - let coords: any[] = geom.coordinates; - - switch (type) { - case "LineString": - case "MultiLineString": - const lines: any[] = []; - if (type === "LineString") { coords = [coords]; } - coords.forEach((line) => { - lineclip.polyline(line, bbox, lines); - }); - if (lines.length === 1) { return lineString(lines[0], properties); } - return multiLineString(lines, properties); - case "Polygon": - return polygon(clipPolygon(coords, bbox), properties); - case "MultiPolygon": - return multiPolygon(coords.map((poly) => { - return clipPolygon(poly, bbox); - }), properties); - default: - throw new Error("geometry " + type + " not supported"); - } -} - -function clipPolygon(rings: any[], bbox: BBox) { - const outRings = []; - for (const ring of rings) { - const clipped: any = lineclip.polygon(ring, bbox); - if (clipped.length > 0) { - if (clipped[0][0] !== clipped[clipped.length - 1][0] || clipped[0][1] !== clipped[clipped.length - 1][1]) { - clipped.push(clipped[0]); - } - if (clipped.length >= 4) { - outRings.push(clipped); - } - } - } - return outRings; -} diff --git a/packages/turf-bbox-clip/package.json b/packages/turf-bbox-clip/package.json deleted file mode 100644 index 931152291c..0000000000 --- a/packages/turf-bbox-clip/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "@turf/bbox-clip", - "version": "6.0.3", - "description": "turf bbox-clip module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "lib/lineclip.js", - "lib/lineclip.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "gis", - "bbox", - "clip" - ], - "author": "Turf Authors", - "contributors": [ - "Tim Channell <@tcql>", - "Vladimir Agafonkin <@mourner>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/bbox": "*", - "benchmark": "*", - "load-json-file": "*", - "tape": "*", - "typescript": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-bbox-clip/test.js b/packages/turf-bbox-clip/test.js deleted file mode 100644 index 0013ed43e6..0000000000 --- a/packages/turf-bbox-clip/test.js +++ /dev/null @@ -1,59 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { point, feature, featureCollection } = require('@turf/helpers'); -const turfBBox = require('@turf/bbox').default; -const bboxClip = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-bbox-clip', t => { - for (const fixture of fixtures) { - const filename = fixture.filename; - const name = fixture.name; - const geojson = fixture.geojson; - const feature = geojson.features[0]; - const bbox = turfBBox(geojson.features[1]); - const clipped = bboxClip(feature, bbox); - const results = featureCollection([colorize(feature, '#080'), colorize(clipped, '#F00'), colorize(geojson.features[1], '#00F', 3)]); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEquals(results, load.sync(directories.out + filename), name); - } - t.end(); -}); - -test('turf-bbox-clip -- throws', t => { - t.throws(() => bboxClip(point([5, 10]), [-180, -90, 180, 90]), /geometry Point not supported/); - t.end(); -}); - -function colorize(feature, color, width) { - color = color || '#F00'; - width = width || 6; - feature.properties = { - stroke: color, - fill: color, - 'stroke-width': width, - 'fill-opacity': 0.1 - }; - return feature; -} - -test('turf-bbox-clip -- null geometries', t => { - t.throws(() => bboxClip(feature(null), [-180, -90, 180, 90]), 'coords must be GeoJSON Feature, Geometry Object or an Array'); - t.end(); -}); diff --git a/packages/turf-bbox-clip/tsconfig.json b/packages/turf-bbox-clip/tsconfig.json deleted file mode 100644 index 91cffcbf55..0000000000 --- a/packages/turf-bbox-clip/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - }, - "files": [ - "index.ts" - ] -} \ No newline at end of file diff --git a/packages/turf-bbox-clip/tslint.json b/packages/turf-bbox-clip/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-bbox-clip/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-bbox-polygon/.gitignore b/packages/turf-bbox-polygon/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-bbox-polygon/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-bbox-polygon/LICENSE b/packages/turf-bbox-polygon/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-bbox-polygon/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-bbox-polygon/README.md b/packages/turf-bbox-polygon/README.md deleted file mode 100644 index ca79e7fd26..0000000000 --- a/packages/turf-bbox-polygon/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# @turf/bbox-polygon - - - -## bboxPolygon - -Takes a bbox and returns an equivalent [polygon][1]. - -**Parameters** - -- `bbox` **[BBox][2]** extent in [minX, minY, maxX, maxY] order -- `options` **[Object][3]** Optional parameters (optional, default `{}`) - - `options.properties` **Properties** Translate properties to Polygon (optional, default `{}`) - - `options.id` **([string][4] \| [number][5])** Translate Id to Polygon (optional, default `{}`) - -**Examples** - -```javascript -var bbox = [0, 0, 10, 10]; - -var poly = turf.bboxPolygon(bbox); - -//addToMap -var addToMap = [poly] -``` - -Returns **[Feature][6]<[Polygon][7]>** a Polygon representation of the bounding box - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[2]: https://tools.ietf.org/html/rfc7946#section-5 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[6]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/bbox-polygon -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-bbox-polygon/index.ts b/packages/turf-bbox-polygon/index.ts deleted file mode 100644 index 44b9759bba..0000000000 --- a/packages/turf-bbox-polygon/index.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { - BBox, Feature, Id, - isObject, polygon, Polygon, Properties, validateBBox, -} from "@turf/helpers"; - -/** - * Takes a bbox and returns an equivalent {@link Polygon|polygon}. - * - * @name bboxPolygon - * @param {BBox} bbox extent in [minX, minY, maxX, maxY] order - * @param {Object} [options={}] Optional parameters - * @param {Properties} [options.properties={}] Translate properties to Polygon - * @param {string|number} [options.id={}] Translate Id to Polygon - * @returns {Feature} a Polygon representation of the bounding box - * @example - * var bbox = [0, 0, 10, 10]; - * - * var poly = turf.bboxPolygon(bbox); - * - * //addToMap - * var addToMap = [poly] - */ -export default function bboxPolygon

(bbox: BBox, options: { - properties?: P, - id?: Id, -} = {}): Feature { - // Convert BBox positions to Numbers - // No performance loss for including Number() - // https://github.com/Turfjs/turf/issues/1119 - const west = Number(bbox[0]); - const south = Number(bbox[1]); - const east = Number(bbox[2]); - const north = Number(bbox[3]); - - if (bbox.length === 6) { throw new Error("@turf/bbox-polygon does not support BBox with 6 positions"); } - - const lowLeft = [west, south]; - const topLeft = [west, north]; - const topRight = [east, north]; - const lowRight = [east, south]; - - return polygon([[ - lowLeft, - lowRight, - topRight, - topLeft, - lowLeft, - ]], options.properties, {bbox, id: options.id}); -} diff --git a/packages/turf-bbox-polygon/package.json b/packages/turf-bbox-polygon/package.json deleted file mode 100644 index 17e81c03d1..0000000000 --- a/packages/turf-bbox-polygon/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "@turf/bbox-polygon", - "version": "6.0.1", - "description": "turf bbox-polygon module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis", - "geojson", - "extent", - "bbox" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "tape": "*", - "typescript": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x" - } -} diff --git a/packages/turf-bbox-polygon/tsconfig.json b/packages/turf-bbox-polygon/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-bbox-polygon/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-bbox-polygon/tslint.json b/packages/turf-bbox-polygon/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-bbox-polygon/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-bbox/.gitignore b/packages/turf-bbox/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-bbox/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-bbox/LICENSE b/packages/turf-bbox/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-bbox/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-bbox/README.md b/packages/turf-bbox/README.md deleted file mode 100644 index 043cc93852..0000000000 --- a/packages/turf-bbox/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# @turf/bbox - - - -## bbox - -Takes a set of features, calculates the bbox of all input features, and returns a bounding box. - -**Parameters** - -- `geojson` **[GeoJSON][1]** any GeoJSON object - -**Examples** - -```javascript -var line = turf.lineString([[-74, 40], [-78, 42], [-82, 35]]); -var bbox = turf.bbox(line); -var bboxPolygon = turf.bboxPolygon(bbox); - -//addToMap -var addToMap = [line, bboxPolygon] -``` - -Returns **[BBox][2]** bbox extent in [minX, minY, maxX, maxY] order - -[1]: https://tools.ietf.org/html/rfc7946#section-3 - -[2]: https://tools.ietf.org/html/rfc7946#section-5 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/bbox -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-bbox/index.ts b/packages/turf-bbox/index.ts deleted file mode 100644 index 3dc7e65efb..0000000000 --- a/packages/turf-bbox/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { BBox } from "@turf/helpers"; -import { coordEach } from "@turf/meta"; - -/** - * Takes a set of features, calculates the bbox of all input features, and returns a bounding box. - * - * @name bbox - * @param {GeoJSON} geojson any GeoJSON object - * @returns {BBox} bbox extent in [minX, minY, maxX, maxY] order - * @example - * var line = turf.lineString([[-74, 40], [-78, 42], [-82, 35]]); - * var bbox = turf.bbox(line); - * var bboxPolygon = turf.bboxPolygon(bbox); - * - * //addToMap - * var addToMap = [line, bboxPolygon] - */ -export default function bbox(geojson: any): BBox { - const result: BBox = [Infinity, Infinity, -Infinity, -Infinity]; - coordEach(geojson, (coord) => { - if (result[0] > coord[0]) { result[0] = coord[0]; } - if (result[1] > coord[1]) { result[1] = coord[1]; } - if (result[2] < coord[0]) { result[2] = coord[0]; } - if (result[3] < coord[1]) { result[3] = coord[1]; } - }); - return result; -} diff --git a/packages/turf-bbox/package.json b/packages/turf-bbox/package.json deleted file mode 100644 index c56fcee75d..0000000000 --- a/packages/turf-bbox/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "@turf/bbox", - "version": "6.0.1", - "description": "turf bbox module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "extent", - "bbox", - "polygon", - "featurecollection", - "geojson" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-bbox/test.js b/packages/turf-bbox/test.js deleted file mode 100644 index 0cb46b5ee7..0000000000 --- a/packages/turf-bbox/test.js +++ /dev/null @@ -1,63 +0,0 @@ -const test = require('tape'); -const { - point, - polygon, - feature, - lineString, - multiPolygon, - multiLineString, - featureCollection } = require('@turf/helpers') -const bbox = require('./').default; - -// Fixtures -const pt = point([102.0, 0.5]); -const line = lineString([[102.0, -10.0], [103.0, 1.0], [104.0, 0.0], [130.0, 4.0]]); -const poly = polygon([[[101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0], [101.0, 0.0]]]); -const multiLine = multiLineString([ - [[100.0, 0.0], [101.0, 1.0]], - [[102.0, 2.0], [103.0, 3.0]] -]); -const multiPoly = multiPolygon([ - [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]], - [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]] -]); -const fc = featureCollection([pt, line, poly, multiLine, multiPoly]); - -test('bbox', t => { - // FeatureCollection - const fcBBox = bbox(fc); - t.deepEqual(fcBBox, [100, -10, 130, 4], 'featureCollection'); - - // Point - const ptBBox = bbox(pt); - t.deepEqual(ptBBox, [102, 0.5, 102, 0.5], 'point'); - - // Line - const lineBBox = bbox(line); - t.deepEqual(lineBBox, [102, -10, 130, 4], 'lineString'); - - // Polygon - const polyExtent = bbox(poly); - t.deepEqual(polyExtent, [100, 0, 101, 1], 'polygon'); - - // MultiLineString - const multiLineBBox = bbox(multiLine); - t.deepEqual(multiLineBBox, [100, 0, 103, 3], 'multiLineString'); - - // MultiPolygon - const multiPolyBBox = bbox(multiPoly); - t.deepEqual(multiPolyBBox, [100, 0, 103, 3], 'multiPolygon'); - - - t.end(); -}); - -test('bbox -- throws', t => { - t.throws(() => bbox({}), /Unknown Geometry Type/, 'unknown geometry type error'); - t.end(); -}); - -test('bbox -- null geometries', t => { - t.deepEqual(bbox(feature(null)), [Infinity, Infinity, -Infinity, -Infinity]); - t.end(); -}); diff --git a/packages/turf-bbox/tsconfig.json b/packages/turf-bbox/tsconfig.json deleted file mode 100644 index 91cffcbf55..0000000000 --- a/packages/turf-bbox/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - }, - "files": [ - "index.ts" - ] -} \ No newline at end of file diff --git a/packages/turf-bbox/tslint.json b/packages/turf-bbox/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-bbox/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-bearing/.gitignore b/packages/turf-bearing/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-bearing/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-bearing/LICENSE b/packages/turf-bearing/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-bearing/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-bearing/README.md b/packages/turf-bearing/README.md deleted file mode 100644 index a6414e8a46..0000000000 --- a/packages/turf-bearing/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# @turf/bearing - - - -## bearing - -Takes two [points][1] and finds the geographic bearing between them, -i.e. the angle measured in degrees from the north line (0 degrees) - -**Parameters** - -- `start` **[Coord][2]** starting Point -- `end` **[Coord][2]** ending Point -- `options` **[Object][3]** Optional parameters (optional, default `{}`) - - `options.final` **[boolean][4]** calculates the final bearing if true (optional, default `false`) - -**Examples** - -```javascript -var point1 = turf.point([-75.343, 39.984]); -var point2 = turf.point([-75.534, 39.123]); - -var bearing = turf.bearing(point1, point2); - -//addToMap -var addToMap = [point1, point2] -point1.properties['marker-color'] = '#f00' -point2.properties['marker-color'] = '#0f0' -point1.properties.bearing = bearing -``` - -Returns **[number][5]** bearing in decimal degrees, between -180 and 180 degrees (positive clockwise) - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/bearing -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-bearing/index.ts b/packages/turf-bearing/index.ts deleted file mode 100644 index 720d06d293..0000000000 --- a/packages/turf-bearing/index.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Coord, degreesToRadians, radiansToDegrees } from "@turf/helpers"; -import { getCoord } from "@turf/invariant"; - -// http://en.wikipedia.org/wiki/Haversine_formula -// http://www.movable-type.co.uk/scripts/latlong.html - -/** - * Takes two {@link Point|points} and finds the geographic bearing between them, - * i.e. the angle measured in degrees from the north line (0 degrees) - * - * @name bearing - * @param {Coord} start starting Point - * @param {Coord} end ending Point - * @param {Object} [options={}] Optional parameters - * @param {boolean} [options.final=false] calculates the final bearing if true - * @returns {number} bearing in decimal degrees, between -180 and 180 degrees (positive clockwise) - * @example - * var point1 = turf.point([-75.343, 39.984]); - * var point2 = turf.point([-75.534, 39.123]); - * - * var bearing = turf.bearing(point1, point2); - * - * //addToMap - * var addToMap = [point1, point2] - * point1.properties['marker-color'] = '#f00' - * point2.properties['marker-color'] = '#0f0' - * point1.properties.bearing = bearing - */ -export default function bearing(start: Coord, end: Coord, options: { - final?: boolean, -} = {}): number { - // Reverse calculation - if (options.final === true) { return calculateFinalBearing(start, end); } - - const coordinates1 = getCoord(start); - const coordinates2 = getCoord(end); - - const lon1 = degreesToRadians(coordinates1[0]); - const lon2 = degreesToRadians(coordinates2[0]); - const lat1 = degreesToRadians(coordinates1[1]); - const lat2 = degreesToRadians(coordinates2[1]); - const a = Math.sin(lon2 - lon1) * Math.cos(lat2); - const b = Math.cos(lat1) * Math.sin(lat2) - - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1); - - return radiansToDegrees(Math.atan2(a, b)); -} - -/** - * Calculates Final Bearing - * - * @private - * @param {Coord} start starting Point - * @param {Coord} end ending Point - * @returns {number} bearing - */ -function calculateFinalBearing(start: Coord, end: Coord) { - // Swap start & end - let bear = bearing(end, start); - bear = (bear + 180) % 360; - return bear; -} diff --git a/packages/turf-bearing/package.json b/packages/turf-bearing/package.json deleted file mode 100644 index 4e5d8df8d1..0000000000 --- a/packages/turf-bearing/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "@turf/bearing", - "version": "6.0.1", - "description": "turf bearing module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "bearing" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/destination": "*", - "benchmark": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-bearing/test.js b/packages/turf-bearing/test.js deleted file mode 100644 index c1a148bb4f..0000000000 --- a/packages/turf-bearing/test.js +++ /dev/null @@ -1,37 +0,0 @@ -const path = require('path'); -const test = require('tape'); -const write = require('write-json-file'); -const destination = require('@turf/destination').default; -const { point, lineString, featureCollection } = require('@turf/helpers'); -const bearing = require('./').default; - -const out = path.join(__dirname, 'test', 'out') + path.sep; - -test('bearing', t => { - const start = point([-75, 45], {'marker-color': '#F00'}); - const end = point([20, 60], {'marker-color': '#00F'}); - - const initialBearing = bearing(start, end); - t.equal(initialBearing.toFixed(2), '37.75', 'initial bearing'); - - const finalBearing = bearing(start, end, {final: true}); - t.equal(finalBearing.toFixed(2), '120.01', 'final bearing'); - t.end(); - - if (process.env.REGEN) { - const initialDestination = destination(start, 1000, initialBearing); - const initialLine = lineString([start.geometry.coordinates, initialDestination.geometry.coordinates], { - 'stroke': '#F00', - 'stroke-width': 6 - }); - - const finalDestination = destination(end, 1000, finalBearing - 180); - const finalLine = lineString([end.geometry.coordinates, finalDestination.geometry.coordinates], { - 'stroke': '#00F', - 'stroke-width': 6 - }); - - const results = featureCollection([start, end, initialLine, finalLine]); - write.sync(out + 'results.geojson', results); - } -}); diff --git a/packages/turf-bearing/tsconfig.json b/packages/turf-bearing/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-bearing/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-bearing/tslint.json b/packages/turf-bearing/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-bearing/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-bezier-spline/.gitignore b/packages/turf-bezier-spline/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-bezier-spline/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-bezier-spline/LICENSE b/packages/turf-bezier-spline/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-bezier-spline/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-bezier-spline/README.md b/packages/turf-bezier-spline/README.md deleted file mode 100644 index 953959cd2f..0000000000 --- a/packages/turf-bezier-spline/README.md +++ /dev/null @@ -1,79 +0,0 @@ -# @turf/bezier-spline - - - -## bezierSpline - -Takes a [line][1] and returns a curved version -by applying a [Bezier spline][2] -algorithm. - -The bezier spline implementation is by [Leszek Rybicki][3]. - -**Parameters** - -- `line` **[Feature][4]<[LineString][5]>** input LineString -- `options` **[Object][6]** Optional parameters (optional, default `{}`) - - `options.properties` **[Object][6]** Translate properties to output (optional, default `{}`) - - `options.resolution` **[number][7]** time in milliseconds between points (optional, default `10000`) - - `options.sharpness` **[number][7]** a measure of how curvy the path should be between splines (optional, default `0.85`) - -**Examples** - -```javascript -var line = turf.lineString([ - [-76.091308, 18.427501], - [-76.695556, 18.729501], - [-76.552734, 19.40443], - [-74.61914, 19.134789], - [-73.652343, 20.07657], - [-73.157958, 20.210656] -]); - -var curved = turf.bezierSpline(line); - -//addToMap -var addToMap = [line, curved] -curved.properties = { stroke: '#0F0' }; -``` - -Returns **[Feature][4]<[LineString][5]>** curved line - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[2]: http://en.wikipedia.org/wiki/B%C3%A9zier_spline - -[3]: http://leszek.rybicki.cc/ - -[4]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/bezier-spline -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-bezier-spline/index.ts b/packages/turf-bezier-spline/index.ts deleted file mode 100644 index 853f86c344..0000000000 --- a/packages/turf-bezier-spline/index.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { - Feature, isNumber, isObject, - lineString, LineString, Properties, -} from "@turf/helpers"; -import { getGeom } from "@turf/invariant"; -import Spline from "./lib/spline"; - -/** - * Takes a {@link LineString|line} and returns a curved version - * by applying a [Bezier spline](http://en.wikipedia.org/wiki/B%C3%A9zier_spline) - * algorithm. - * - * The bezier spline implementation is by [Leszek Rybicki](http://leszek.rybicki.cc/). - * - * @name bezierSpline - * @param {Feature} line input LineString - * @param {Object} [options={}] Optional parameters - * @param {Object} [options.properties={}] Translate properties to output - * @param {number} [options.resolution=10000] time in milliseconds between points - * @param {number} [options.sharpness=0.85] a measure of how curvy the path should be between splines - * @returns {Feature} curved line - * @example - * var line = turf.lineString([ - * [-76.091308, 18.427501], - * [-76.695556, 18.729501], - * [-76.552734, 19.40443], - * [-74.61914, 19.134789], - * [-73.652343, 20.07657], - * [-73.157958, 20.210656] - * ]); - * - * var curved = turf.bezierSpline(line); - * - * //addToMap - * var addToMap = [line, curved] - * curved.properties = { stroke: '#0F0' }; - */ -function bezier

(line: Feature | LineString, options: { - properties?: P, - resolution?: number, - sharpness?: number, -} = {}): Feature { - // Optional params - const resolution = options.resolution || 10000; - const sharpness = options.sharpness || 0.85; - - const coords = []; - const points = getGeom(line).coordinates.map((pt) => { - return {x: pt[0], y: pt[1]}; - }); - const spline = new Spline({ - duration: resolution, - points, - sharpness, - }); - - for (let i = 0; i < spline.duration; i += 10) { - const pos = spline.pos(i); - if (Math.floor(i / 100) % 2 === 0) { - coords.push([pos.x, pos.y]); - } - } - return lineString(coords, options.properties); -} - -export default bezier; diff --git a/packages/turf-bezier-spline/lib/spline.ts b/packages/turf-bezier-spline/lib/spline.ts deleted file mode 100644 index 9a016c7b30..0000000000 --- a/packages/turf-bezier-spline/lib/spline.ts +++ /dev/null @@ -1,155 +0,0 @@ -export interface Point { - x: number; - y: number; - z: number; -} - -/** - * BezierSpline - * https://github.com/leszekr/bezier-spline-js - * - * @private - * @copyright - * Copyright (c) 2013 Leszek Rybicki - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -export default class Spline { - public duration: number; - public points: Point[]; - public sharpness: number; - public centers: Point[]; - public controls: Array<[Point, Point]>; - public stepLength: number; - public length: number; - public delay: number; - public steps: number[]; - - constructor(options?: any) { - this.points = options.points || []; - this.duration = options.duration || 10000; - this.sharpness = options.sharpness || 0.85; - this.centers = []; - this.controls = []; - this.stepLength = options.stepLength || 60; - this.length = this.points.length; - this.delay = 0; - - // this is to ensure compatibility with the 2d version - for (let i = 0; i < this.length; i++) { this.points[i].z = this.points[i].z || 0; } - for (let i = 0; i < this.length - 1; i++) { - const p1 = this.points[i]; - const p2 = this.points[i + 1]; - this.centers.push({ - x: (p1.x + p2.x) / 2, - y: (p1.y + p2.y) / 2, - z: (p1.z + p2.z) / 2, - }); - } - this.controls.push([this.points[0], this.points[0]]); - for (let i = 0; i < this.centers.length - 1; i++) { - const p1 = this.centers[i]; - const p2 = this.centers[i + 1]; - const dx = this.points[i + 1].x - (this.centers[i].x + this.centers[i + 1].x) / 2; - const dy = this.points[i + 1].y - (this.centers[i].y + this.centers[i + 1].y) / 2; - const dz = this.points[i + 1].z - (this.centers[i].y + this.centers[i + 1].z) / 2; - this.controls.push([{ - x: (1.0 - this.sharpness) * this.points[i + 1].x + this.sharpness * (this.centers[i].x + dx), - y: (1.0 - this.sharpness) * this.points[i + 1].y + this.sharpness * (this.centers[i].y + dy), - z: (1.0 - this.sharpness) * this.points[i + 1].z + this.sharpness * (this.centers[i].z + dz)}, - { - x: (1.0 - this.sharpness) * this.points[i + 1].x + this.sharpness * (this.centers[i + 1].x + dx), - y: (1.0 - this.sharpness) * this.points[i + 1].y + this.sharpness * (this.centers[i + 1].y + dy), - z: (1.0 - this.sharpness) * this.points[i + 1].z + this.sharpness * (this.centers[i + 1].z + dz)}]); - } - this.controls.push([this.points[this.length - 1], this.points[this.length - 1]]); - this.steps = this.cacheSteps(this.stepLength); - return this; - } - /** - * Caches an array of equidistant (more or less) points on the curve. - */ - public cacheSteps(mindist: number) { - const steps = []; - let laststep = this.pos(0); - steps.push(0); - for (let t = 0; t < this.duration; t += 10) { - const step = this.pos(t); - const dist = Math.sqrt( - (step.x - laststep.x) * (step.x - laststep.x) + - (step.y - laststep.y) * (step.y - laststep.y) + - (step.z - laststep.z) * (step.z - laststep.z)); - if (dist > mindist) { - steps.push(t); - laststep = step; - } - } - return steps; - } - - /** - * returns angle and speed in the given point in the curve - */ - public vector(t: number) { - const p1 = this.pos(t + 10); - const p2 = this.pos(t - 10); - return { - angle: 180 * Math.atan2(p1.y - p2.y, p1.x - p2.x) / 3.14, - speed: Math.sqrt( - (p2.x - p1.x) * (p2.x - p1.x) + - (p2.y - p1.y) * (p2.y - p1.y) + - (p2.z - p1.z) * (p2.z - p1.z)), - }; - } - - /** - * Gets the position of the point, given time. - * - * WARNING: The speed is not constant. The time it takes between control points is constant. - * - * For constant speed, use Spline.steps[i]; - */ - public pos(time: number) { - let t = time - this.delay; - if (t < 0) { t = 0; } - if (t > this.duration) { t = this.duration - 1; } - // t = t-this.delay; - const t2 = (t) / this.duration; - if (t2 >= 1) { return this.points[this.length - 1]; } - - const n = Math.floor((this.points.length - 1) * t2); - const t1 = (this.length - 1) * t2 - n; - return bezier(t1, this.points[n], this.controls[n][1], this.controls[n + 1][0], this.points[n + 1]); - } -} - -function bezier(t: number, p1: Point, c1: Point, c2: Point, p2: Point) { - const b = B(t); - const pos = { - x : p2.x * b[0] + c2.x * b[1] + c1.x * b[2] + p1.x * b[3], - y : p2.y * b[0] + c2.y * b[1] + c1.y * b[2] + p1.y * b[3], - z : p2.z * b[0] + c2.z * b[1] + c1.z * b[2] + p1.z * b[3], - }; - return pos; -} -function B(t: number) { - const t2 = t * t; - const t3 = t2 * t; - return [(t3), (3 * t2 * (1 - t)), (3 * t * (1 - t) * (1 - t)), ((1 - t) * (1 - t) * (1 - t))]; -} diff --git a/packages/turf-bezier-spline/package.json b/packages/turf-bezier-spline/package.json deleted file mode 100644 index 6fbd175ce4..0000000000 --- a/packages/turf-bezier-spline/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@turf/bezier-spline", - "version": "6.0.3", - "description": "turf bezier-spline module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "lib/spline.js", - "lib/spline.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geometry", - "bezier", - "curve", - "linestring" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@types/tape": "*", - "benchmark": "*", - "load-json-file": "*", - "tape": "*", - "tslint": "*", - "typescript": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-bezier-spline/test.js b/packages/turf-bezier-spline/test.js deleted file mode 100644 index de366b33a0..0000000000 --- a/packages/turf-bezier-spline/test.js +++ /dev/null @@ -1,46 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { featureCollection } = require('@turf/helpers'); -const bezierSpline = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-bezier-spline', t => { - fixtures.forEach(fixture => { - const filename = fixture.filename; - const name = fixture.name; - const geojson = fixture.geojson; - const spline = colorize(bezierSpline(geojson)); - const results = featureCollection([spline, geojson]); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEquals(results, load.sync(directories.out + filename), name); - }); - t.end(); -}); - -function colorize(feature, color, width) { - color = color || '#F00'; - width = width || 6; - feature.properties = { - stroke: color, - fill: color, - 'stroke-width': width, - 'fill-opacity': 0.1 - }; - return feature; -} diff --git a/packages/turf-bezier-spline/tsconfig.json b/packages/turf-bezier-spline/tsconfig.json deleted file mode 100644 index a896721cb4..0000000000 --- a/packages/turf-bezier-spline/tsconfig.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - }, - "files": [ - "index.ts", - "lib/spline.ts" - ] -} \ No newline at end of file diff --git a/packages/turf-bezier-spline/tslint.json b/packages/turf-bezier-spline/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-bezier-spline/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-boolean-clockwise/.gitignore b/packages/turf-boolean-clockwise/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-boolean-clockwise/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-boolean-clockwise/LICENSE b/packages/turf-boolean-clockwise/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-boolean-clockwise/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-boolean-clockwise/README.md b/packages/turf-boolean-clockwise/README.md deleted file mode 100755 index f4b5cbfe2f..0000000000 --- a/packages/turf-boolean-clockwise/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# @turf/boolean-clockwise - - - -## booleanClockwise - -Takes a ring and return true or false whether or not the ring is clockwise or counter-clockwise. - -**Parameters** - -- `line` **([Feature][1]<[LineString][2]> | [LineString][2] \| [Array][3]<[Array][3]<[number][4]>>)** to be evaluated - -**Examples** - -```javascript -var clockwiseRing = turf.lineString([[0,0],[1,1],[1,0],[0,0]]); -var counterClockwiseRing = turf.lineString([[0,0],[1,0],[1,1],[0,0]]); - -turf.booleanClockwise(clockwiseRing) -//=true -turf.booleanClockwise(counterClockwiseRing) -//=false -``` - -Returns **[boolean][5]** true/false - -[1]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/boolean-clockwise -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-boolean-clockwise/index.ts b/packages/turf-boolean-clockwise/index.ts deleted file mode 100644 index fe17f30486..0000000000 --- a/packages/turf-boolean-clockwise/index.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Feature, LineString, Position } from "@turf/helpers"; -import { getCoords } from "@turf/invariant"; - -/** - * Takes a ring and return true or false whether or not the ring is clockwise or counter-clockwise. - * - * @name booleanClockwise - * @param {Feature|LineString|Array>} line to be evaluated - * @returns {boolean} true/false - * @example - * var clockwiseRing = turf.lineString([[0,0],[1,1],[1,0],[0,0]]); - * var counterClockwiseRing = turf.lineString([[0,0],[1,0],[1,1],[0,0]]); - * - * turf.booleanClockwise(clockwiseRing) - * //=true - * turf.booleanClockwise(counterClockwiseRing) - * //=false - */ -export default function booleanClockwise(line: Feature | LineString | Position[]): boolean { - const ring = getCoords(line); - let sum = 0; - let i = 1; - let prev; - let cur; - - while (i < ring.length) { - prev = cur || ring[0]; - cur = ring[i]; - sum += ((cur[0] - prev[0]) * (cur[1] + prev[1])); - i++; - } - return sum > 0; -} diff --git a/packages/turf-boolean-clockwise/package.json b/packages/turf-boolean-clockwise/package.json deleted file mode 100755 index 5eee2bad68..0000000000 --- a/packages/turf-boolean-clockwise/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "@turf/boolean-clockwise", - "version": "6.0.1", - "description": "turf boolean-clockwise module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "clockwise", - "boolean" - ], - "author": "Turf Authors", - "contributors": [ - "Morgan Herlocker <@morganherlocker>", - "Rowan Winsemius <@rowanwins>", - "Denis Carriere <@DenisCarriere>", - "Stefano Borghi <@stebogit>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-boolean-clockwise/test.js b/packages/turf-boolean-clockwise/test.js deleted file mode 100644 index 71af2c311a..0000000000 --- a/packages/turf-boolean-clockwise/test.js +++ /dev/null @@ -1,50 +0,0 @@ -const glob = require('glob'); -const path = require('path'); -const test = require('tape'); -const load = require('load-json-file'); -const { point, lineString } = require('@turf/helpers'); -const isClockwise = require('./').default; - -test('isClockwise#fixtures', t => { - // True Fixtures - glob.sync(path.join(__dirname, 'test', 'true', '*.geojson')).forEach(filepath => { - const name = path.parse(filepath).name; - const geojson = load.sync(filepath); - const feature = geojson.features[0]; - t.true(isClockwise(feature), '[true] ' + name); - }); - // False Fixtures - glob.sync(path.join(__dirname, 'test', 'false', '*.geojson')).forEach(filepath => { - const name = path.parse(filepath).name; - const geojson = load.sync(filepath); - const feature = geojson.features[0]; - t.false(isClockwise(feature), '[false] ' + name); - }); - t.end(); -}); - -test('isClockwise', t => { - const cwArray = [[0, 0], [1, 1], [1, 0], [0, 0]]; - const ccwArray = [[0, 0], [1, 0], [1, 1], [0, 0]]; - - t.equal(isClockwise(cwArray), true, '[true] clockwise array input'); - t.equal(isClockwise(ccwArray), false, '[false] counter-clockwise array input'); - - t.end(); -}); - -test('isClockwise -- Geometry types', t => { - const line = lineString([[0, 0], [1, 1], [1, 0], [0, 0]]); - - t.equal(isClockwise(line), true, 'Feature'); - t.equal(isClockwise(line.geometry), true, 'Geometry Object'); - - t.end(); -}); - -// test('isClockwise -- throws', t => { -// const pt = point([-10, -33]); -// t.throws(() => isClockwise(pt), 'feature geometry not supported'); - -// t.end(); -// }); diff --git a/packages/turf-boolean-clockwise/tsconfig.json b/packages/turf-boolean-clockwise/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-boolean-clockwise/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-boolean-clockwise/tslint.json b/packages/turf-boolean-clockwise/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-boolean-clockwise/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-boolean-concave/.gitignore b/packages/turf-boolean-concave/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-boolean-concave/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-boolean-concave/LICENSE b/packages/turf-boolean-concave/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-boolean-concave/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-boolean-concave/README.md b/packages/turf-boolean-concave/README.md deleted file mode 100644 index 2e3633c632..0000000000 --- a/packages/turf-boolean-concave/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# @turf/boolean-concave - - - -## booleanConcave - -Takes a polygon and return true or false as to whether it is concave or not. - -**Parameters** - -- `polygon` **[Feature][1]<[Polygon][2]>** to be evaluated - -**Examples** - -```javascript -var convexPolygon = turf.polygon([[[0,0],[0,1],[1,1],[1,0],[0,0]]]); - -turf.booleanConcave(convexPolygon) -//=false -``` - -Returns **[boolean][3]** true/false - -[1]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/boolean-concave -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-boolean-concave/index.ts b/packages/turf-boolean-concave/index.ts deleted file mode 100644 index 0dc2d25692..0000000000 --- a/packages/turf-boolean-concave/index.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Feature, Polygon } from "@turf/helpers"; -import { getCoords, getGeom } from "@turf/invariant"; - -/** - * Takes a polygon and return true or false as to whether it is concave or not. - * - * @name booleanConcave - * @param {Feature} polygon to be evaluated - * @returns {boolean} true/false - * @example - * var convexPolygon = turf.polygon([[[0,0],[0,1],[1,1],[1,0],[0,0]]]); - * - * turf.booleanConcave(convexPolygon) - * //=false - */ -export default function booleanConcave(polygon: Feature | Polygon) { - // Taken from https://stackoverflow.com/a/1881201 & https://stackoverflow.com/a/25304159 - const coords = getGeom(polygon).coordinates; - if (coords[0].length <= 4) { return false; } - - let sign = false; - const n = coords[0].length - 1; - for (let i = 0; i < n; i++) { - const dx1 = coords[0][(i + 2) % n][0] - coords[0][(i + 1) % n][0]; - const dy1 = coords[0][(i + 2) % n][1] - coords[0][(i + 1) % n][1]; - const dx2 = coords[0][i][0] - coords[0][(i + 1) % n][0]; - const dy2 = coords[0][i][1] - coords[0][(i + 1) % n][1]; - const zcrossproduct = (dx1 * dy2) - (dy1 * dx2); - if (i === 0) { sign = zcrossproduct > 0; - } else if (sign !== (zcrossproduct > 0)) { return true; } - } - return false; -} diff --git a/packages/turf-boolean-concave/package.json b/packages/turf-boolean-concave/package.json deleted file mode 100644 index 9083ae2dab..0000000000 --- a/packages/turf-boolean-concave/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "@turf/boolean-concave", - "version": "6.0.1", - "description": "turf boolean-concave module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "polygon", - "concave", - "convex", - "boolean" - ], - "author": "Turf Authors", - "contributors": [ - "Rowan Winsemius <@rowanwins>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-boolean-concave/test.js b/packages/turf-boolean-concave/test.js deleted file mode 100644 index 69ce94d930..0000000000 --- a/packages/turf-boolean-concave/test.js +++ /dev/null @@ -1,39 +0,0 @@ -const glob = require('glob'); -const path = require('path'); -const test = require('tape'); -const load = require('load-json-file'); -const { polygon, point } = require('@turf/helpers'); -const isConcave = require('./').default; - -test('isConcave#fixtures', t => { - // True Fixtures - glob.sync(path.join(__dirname, 'test', 'true', '*.geojson')).forEach(filepath => { - const name = path.parse(filepath).name; - const geojson = load.sync(filepath); - const feature = geojson.features[0]; - t.true(isConcave(feature), '[true] ' + name); - }); - // False Fixtures - glob.sync(path.join(__dirname, 'test', 'false', '*.geojson')).forEach(filepath => { - const name = path.parse(filepath).name; - const geojson = load.sync(filepath); - const feature = geojson.features[0]; - t.false(isConcave(feature), '[false] ' + name); - }); - t.end(); -}); - -test('isConcave -- Geometry types', t => { - const poly = polygon([[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]]); - - t.equal(isConcave(poly), false, 'Feature'); - t.equal(isConcave(poly.geometry), false, 'Geometry Object'); - - t.end(); -}); - -test('isConcave -- throws', t => { - const pt = point([-10, -33]); - // t.throws(() => isConcave(pt), 'feature geometry not supported'); - t.end(); -}); diff --git a/packages/turf-boolean-concave/tsconfig.json b/packages/turf-boolean-concave/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-boolean-concave/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-boolean-concave/tslint.json b/packages/turf-boolean-concave/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-boolean-concave/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-boolean-contains/.gitignore b/packages/turf-boolean-contains/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-boolean-contains/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-boolean-contains/LICENSE b/packages/turf-boolean-contains/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-boolean-contains/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-boolean-contains/README.md b/packages/turf-boolean-contains/README.md deleted file mode 100644 index 48d1fe8313..0000000000 --- a/packages/turf-boolean-contains/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# @turf/boolean-contains - - - -## booleanContains - -Boolean-contains returns True if the second geometry is completely contained by the first geometry. -The interiors of both geometries must intersect and, the interior and boundary of the secondary (geometry b) -must not intersect the exterior of the primary (geometry a). -Boolean-contains returns the exact opposite result of the `@turf/boolean-within`. - -**Parameters** - -- `feature1` **([Geometry][1] \| [Feature][2]<any>)** GeoJSON Feature or Geometry -- `feature2` **([Geometry][1] \| [Feature][2]<any>)** GeoJSON Feature or Geometry - -**Examples** - -```javascript -var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); -var point = turf.point([1, 2]); - -turf.booleanContains(line, point); -//=true -``` - -Returns **[boolean][3]** true/false - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/boolean-contains -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` - - -### Diagrams - -![esri-contains](diagrams/esri-contains.gif) \ No newline at end of file diff --git a/packages/turf-boolean-contains/index.ts b/packages/turf-boolean-contains/index.ts deleted file mode 100644 index d8a85e0086..0000000000 --- a/packages/turf-boolean-contains/index.ts +++ /dev/null @@ -1,217 +0,0 @@ -import calcBbox from "@turf/bbox"; -import booleanPointInPolygon from "@turf/boolean-point-in-polygon"; -import isPointOnLine from "@turf/boolean-point-on-line"; -import { point } from "@turf/helpers"; -import { BBox, Feature, Geometry, LineString, MultiPoint, Point, Polygon } from "@turf/helpers"; -import { getCoords, getGeom, getType } from "@turf/invariant"; - -/** - * Boolean-contains returns True if the second geometry is completely contained by the first geometry. - * The interiors of both geometries must intersect and, the interior and boundary of the secondary (geometry b) - * must not intersect the exterior of the primary (geometry a). - * Boolean-contains returns the exact opposite result of the `@turf/boolean-within`. - * - * @name booleanContains - * @param {Geometry|Feature} feature1 GeoJSON Feature or Geometry - * @param {Geometry|Feature} feature2 GeoJSON Feature or Geometry - * @returns {boolean} true/false - * @example - * var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); - * var point = turf.point([1, 2]); - * - * turf.booleanContains(line, point); - * //=true - */ -export default function booleanContains(feature1: Feature | Geometry, feature2: Feature | Geometry) { - const geom1 = getGeom(feature1); - const geom2 = getGeom(feature2); - const type1 = geom1.type; - const type2 = geom2.type; - const coords1 = geom1.coordinates; - const coords2 = geom2.coordinates; - - switch (type1) { - case "Point": - switch (type2) { - case "Point": - return compareCoords(coords1, coords2); - default: - throw new Error("feature2 " + type2 + " geometry not supported"); - } - case "MultiPoint": - switch (type2) { - case "Point": - return isPointInMultiPoint(geom1, geom2); - case "MultiPoint": - return isMultiPointInMultiPoint(geom1, geom2); - default: - throw new Error("feature2 " + type2 + " geometry not supported"); - } - case "LineString": - switch (type2) { - case "Point": - return isPointOnLine(geom2, geom1, {ignoreEndVertices: true}); - case "LineString": - return isLineOnLine(geom1, geom2); - case "MultiPoint": - return isMultiPointOnLine(geom1, geom2); - default: - throw new Error("feature2 " + type2 + " geometry not supported"); - } - case "Polygon": - switch (type2) { - case "Point": - return booleanPointInPolygon(geom2, geom1, {ignoreBoundary: true}); - case "LineString": - return isLineInPoly(geom1, geom2); - case "Polygon": - return isPolyInPoly(geom1, geom2); - case "MultiPoint": - return isMultiPointInPoly(geom1, geom2); - default: - throw new Error("feature2 " + type2 + " geometry not supported"); - } - default: - throw new Error("feature1 " + type1 + " geometry not supported"); - } -} - -export function isPointInMultiPoint(multiPoint: MultiPoint, pt: Point) { - let i; - let output = false; - for (i = 0; i < multiPoint.coordinates.length; i++) { - if (compareCoords(multiPoint.coordinates[i], pt.coordinates)) { - output = true; - break; - } - } - return output; -} - -export function isMultiPointInMultiPoint(multiPoint1: MultiPoint, multiPoint2: MultiPoint) { - for (const coord2 of multiPoint2.coordinates) { - let matchFound = false; - for (const coord1 of multiPoint1.coordinates) { - if (compareCoords(coord2, coord1)) { - matchFound = true; - break; - } - } - if (!matchFound) { - return false; - } - } - return true; -} - -export function isMultiPointOnLine(lineString: LineString, multiPoint: MultiPoint) { - let haveFoundInteriorPoint = false; - for (const coord of multiPoint.coordinates) { - if (isPointOnLine(coord, lineString, {ignoreEndVertices: true})) { - haveFoundInteriorPoint = true; - } - if (!isPointOnLine(coord, lineString)) { - return false; - } - } - if (haveFoundInteriorPoint) { - return true; - } - return false; -} - -export function isMultiPointInPoly(polygon: Polygon, multiPoint: MultiPoint) { - for (const coord of multiPoint.coordinates) { - if (!booleanPointInPolygon(coord, polygon, {ignoreBoundary: true})) { - return false; - } - } - return true; -} - -export function isLineOnLine(lineString1: LineString, lineString2: LineString) { - let haveFoundInteriorPoint = false; - for (const coords of lineString2.coordinates) { - if (isPointOnLine({type: "Point", coordinates: coords}, lineString1, { ignoreEndVertices: true })) { - haveFoundInteriorPoint = true; - } - if (!isPointOnLine({type: "Point", coordinates: coords}, lineString1, {ignoreEndVertices: false })) { - return false; - } - } - return haveFoundInteriorPoint; -} - -export function isLineInPoly(polygon: Polygon, linestring: LineString) { - let output = false; - let i = 0; - - const polyBbox = calcBbox(polygon); - const lineBbox = calcBbox(linestring); - if (!doBBoxOverlap(polyBbox, lineBbox)) { - return false; - } - for (i; i < linestring.coordinates.length - 1; i++) { - const midPoint = getMidpoint(linestring.coordinates[i], linestring.coordinates[i + 1]); - if (booleanPointInPolygon({type: "Point", coordinates: midPoint}, polygon, { ignoreBoundary: true })) { - output = true; - break; - } - } - return output; -} - -/** - * Is Polygon2 in Polygon1 - * Only takes into account outer rings - * - * @private - * @param {Geometry|Feature} feature1 Polygon1 - * @param {Geometry|Feature} feature2 Polygon2 - * @returns {boolean} true/false - */ -export function isPolyInPoly(feature1: Feature|Polygon, feature2: Feature|Polygon) { - // Handle Nulls - if (feature1.type === "Feature" && feature1.geometry === null) { return false; } - if (feature2.type === "Feature" && feature2.geometry === null) { return false; } - - const poly1Bbox = calcBbox(feature1); - const poly2Bbox = calcBbox(feature2); - if (!doBBoxOverlap(poly1Bbox, poly2Bbox)) { - return false; - } - - const coords = getGeom(feature2).coordinates; - for (const ring of coords) { - for (const coord of ring) { - if (!booleanPointInPolygon(coord, feature1)) { - return false; - } - } - } - return true; -} - -export function doBBoxOverlap(bbox1: BBox, bbox2: BBox) { - if (bbox1[0] > bbox2[0]) { return false; } - if (bbox1[2] < bbox2[2]) { return false; } - if (bbox1[1] > bbox2[1]) { return false; } - if (bbox1[3] < bbox2[3]) { return false; } - return true; -} - -/** - * compareCoords - * - * @private - * @param {Position} pair1 point [x,y] - * @param {Position} pair2 point [x,y] - * @returns {boolean} true/false if coord pairs match - */ -export function compareCoords(pair1: number[], pair2: number[]) { - return pair1[0] === pair2[0] && pair1[1] === pair2[1]; -} - -export function getMidpoint(pair1: number[], pair2: number[]) { - return [(pair1[0] + pair2[0]) / 2, (pair1[1] + pair2[1]) / 2]; -} diff --git a/packages/turf-boolean-contains/package.json b/packages/turf-boolean-contains/package.json deleted file mode 100644 index 75cb8127c3..0000000000 --- a/packages/turf-boolean-contains/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "@turf/boolean-contains", - "version": "6.0.1", - "description": "turf boolean-contains module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "contains", - "boolean", - "de-9im" - ], - "author": "Turf Authors", - "contributors": [ - "Rowan Winsemius <@rowanwins>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "boolean-jsts": "*", - "boolean-shapely": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/boolean-point-in-polygon": "6.x", - "@turf/boolean-point-on-line": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-boolean-contains/test.js b/packages/turf-boolean-contains/test.js deleted file mode 100644 index 68dec44391..0000000000 --- a/packages/turf-boolean-contains/test.js +++ /dev/null @@ -1,44 +0,0 @@ -const glob = require('glob'); -const path = require('path'); -const test = require('tape'); -const load = require('load-json-file'); -const { point } = require('@turf/helpers'); -const booleanJSTS = require('boolean-jsts'); -const shapely = require('boolean-shapely'); -const contains = require('./').default; - -test('turf-boolean-contains', t => { - // True Fixtures - glob.sync(path.join(__dirname, 'test', 'true', '**', '*.geojson')).forEach(filepath => { - const name = path.parse(filepath).name; - const geojson = load.sync(filepath); - const feature1 = geojson.features[0]; - const feature2 = geojson.features[1]; - const result = contains(feature1, feature2); - - if (process.env.JSTS) t.true(booleanJSTS('contains', feature1, feature2), '[true] JSTS - ' + name); - if (process.env.SHAPELY) shapely.contains(feature1, feature2).then(result => t.true(result, '[true] shapely - ' + name)); - t.true(result, '[true] ' + name); - }); - // False Fixtures - glob.sync(path.join(__dirname, 'test', 'false', '**', '*.geojson')).forEach(filepath => { - const name = path.parse(filepath).name; - const geojson = load.sync(filepath); - const feature1 = geojson.features[0]; - const feature2 = geojson.features[1]; - const result = contains(feature1, feature2); - - if (process.env.JSTS) t.false(booleanJSTS('contains', feature1, feature2), '[false] JSTS - ' + name); - if (process.env.SHAPELY) shapely.contains(feature1, feature2).then(result => t.false(result, '[false] shapely - ' + name)); - t.false(result, '[false] ' + name); - }); - t.end(); -}); - -test('turf-boolean-contains -- Geometry Objects', t => { - const pt1 = point([0, 0]); - const pt2 = point([0, 0]); - - t.assert(contains(pt1.geometry, pt2.geometry)); - t.end(); -}); diff --git a/packages/turf-boolean-contains/tsconfig.json b/packages/turf-boolean-contains/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-boolean-contains/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-boolean-contains/tslint.json b/packages/turf-boolean-contains/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-boolean-contains/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-boolean-crosses/.gitignore b/packages/turf-boolean-crosses/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-boolean-crosses/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-boolean-crosses/LICENSE b/packages/turf-boolean-crosses/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-boolean-crosses/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-boolean-crosses/README.md b/packages/turf-boolean-crosses/README.md deleted file mode 100644 index caedd9bd27..0000000000 --- a/packages/turf-boolean-crosses/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# @turf/boolean-crosses - - - -## booleanCrosses - -Boolean-Crosses returns True if the intersection results in a geometry whose dimension is one less than -the maximum dimension of the two source geometries and the intersection set is interior to -both source geometries. - -Boolean-Crosses returns t (TRUE) for only multipoint/polygon, multipoint/linestring, linestring/linestring, linestring/polygon, and linestring/multipolygon comparisons. - -**Parameters** - -- `feature1` **([Geometry][1] \| [Feature][2]<any>)** GeoJSON Feature or Geometry -- `feature2` **([Geometry][1] \| [Feature][2]<any>)** GeoJSON Feature or Geometry - -**Examples** - -```javascript -var line1 = turf.lineString([[-2, 2], [4, 2]]); -var line2 = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); - -var cross = turf.booleanCrosses(line1, line2); -//=true -``` - -Returns **[boolean][3]** true/false - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/boolean-crosses -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` - - -### Diagrams - -![esri-crosses](diagrams/esri-crosses.gif) \ No newline at end of file diff --git a/packages/turf-boolean-crosses/index.ts b/packages/turf-boolean-crosses/index.ts deleted file mode 100644 index c6d51b988e..0000000000 --- a/packages/turf-boolean-crosses/index.ts +++ /dev/null @@ -1,166 +0,0 @@ -import lineIntersect from '@turf/line-intersect'; -import { polygonToLine } from '@turf/polygon-to-line'; -import booleanPointInPolygon from '@turf/boolean-point-in-polygon'; -import { getGeom, getType } from '@turf/invariant'; -import { point, Feature, Geometry, MultiPolygon, Polygon } from '@turf/helpers'; - -/** - * Boolean-Crosses returns True if the intersection results in a geometry whose dimension is one less than - * the maximum dimension of the two source geometries and the intersection set is interior to - * both source geometries. - * - * Boolean-Crosses returns t (TRUE) for only multipoint/polygon, multipoint/linestring, linestring/linestring, linestring/polygon, and linestring/multipolygon comparisons. - * - * @name booleanCrosses - * @param {Geometry|Feature} feature1 GeoJSON Feature or Geometry - * @param {Geometry|Feature} feature2 GeoJSON Feature or Geometry - * @returns {boolean} true/false - * @example - * var line1 = turf.lineString([[-2, 2], [4, 2]]); - * var line2 = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); - * - * var cross = turf.booleanCrosses(line1, line2); - * //=true - */ -function booleanCrosses(feature1: Feature | Geometry, feature2: Feature | Geometry): boolean { - var geom1 = getGeom(feature1); - var geom2 = getGeom(feature2); - var type1 = geom1.type; - var type2 = geom2.type; - - switch (type1) { - case 'MultiPoint': - switch (type2) { - case 'LineString': - return doMultiPointAndLineStringCross(geom1, geom2); - case 'Polygon': - return doesMultiPointCrossPoly(geom1, geom2); - default: - throw new Error('feature2 ' + type2 + ' geometry not supported'); - } - case 'LineString': - switch (type2) { - case 'MultiPoint': // An inverse operation - return doMultiPointAndLineStringCross(geom2, geom1); - case 'LineString': - return doLineStringsCross(geom1, geom2); - case 'Polygon': - return doLineStringAndPolygonCross(geom1, geom2); - default: - throw new Error('feature2 ' + type2 + ' geometry not supported'); - } - case 'Polygon': - switch (type2) { - case 'MultiPoint': // An inverse operation - return doesMultiPointCrossPoly(geom2, geom1); - case 'LineString': // An inverse operation - return doLineStringAndPolygonCross(geom2, geom1); - default: - throw new Error('feature2 ' + type2 + ' geometry not supported'); - } - default: - throw new Error('feature1 ' + type1 + ' geometry not supported'); - } -} - -function doMultiPointAndLineStringCross(multiPoint, lineString) { - var foundIntPoint = false; - var foundExtPoint = false; - var pointLength = multiPoint.coordinates.length; - var i = 0; - while (i < pointLength && !foundIntPoint && !foundExtPoint) { - for (var i2 = 0; i2 < lineString.coordinates.length - 1; i2++) { - var incEndVertices = true; - if (i2 === 0 || i2 === lineString.coordinates.length - 2) { - incEndVertices = false; - } - if (isPointOnLineSegment(lineString.coordinates[i2], lineString.coordinates[i2 + 1], multiPoint.coordinates[i], incEndVertices)) { - foundIntPoint = true; - } else { - foundExtPoint = true; - } - } - i++; - } - return foundIntPoint && foundExtPoint; -} - -function doLineStringsCross(lineString1, lineString2) { - var doLinesIntersect = lineIntersect(lineString1, lineString2); - if (doLinesIntersect.features.length > 0) { - for (var i = 0; i < lineString1.coordinates.length - 1; i++) { - for (var i2 = 0; i2 < lineString2.coordinates.length - 1; i2++) { - var incEndVertices = true; - if (i2 === 0 || i2 === lineString2.coordinates.length - 2) { - incEndVertices = false; - } - if (isPointOnLineSegment(lineString1.coordinates[i], lineString1.coordinates[i + 1], lineString2.coordinates[i2], incEndVertices)) { - return true; - } - } - } - } - return false; -} - -function doLineStringAndPolygonCross(lineString, polygon: Polygon) { - const line: any = polygonToLine(polygon); - const doLinesIntersect = lineIntersect(lineString, line); - if (doLinesIntersect.features.length > 0) { - return true; - } - return false; -} - -function doesMultiPointCrossPoly(multiPoint, polygon) { - var foundIntPoint = false; - var foundExtPoint = false; - var pointLength = multiPoint.coordinates[0].length; - var i = 0; - while (i < pointLength && foundIntPoint && foundExtPoint) { - if (booleanPointInPolygon(point(multiPoint.coordinates[0][i]), polygon)) { - foundIntPoint = true; - } else { - foundExtPoint = true; - } - i++; - } - - return foundExtPoint && foundExtPoint; -} - -/** - * Is a point on a line segment - * Only takes into account outer rings - * See http://stackoverflow.com/a/4833823/1979085 - * - * @private - * @param {number[]} lineSegmentStart coord pair of start of line - * @param {number[]} lineSegmentEnd coord pair of end of line - * @param {number[]} pt coord pair of point to check - * @param {boolean} incEnd whether the point is allowed to fall on the line ends - * @returns {boolean} true/false - */ -function isPointOnLineSegment(lineSegmentStart, lineSegmentEnd, pt, incEnd) { - var dxc = pt[0] - lineSegmentStart[0]; - var dyc = pt[1] - lineSegmentStart[1]; - var dxl = lineSegmentEnd[0] - lineSegmentStart[0]; - var dyl = lineSegmentEnd[1] - lineSegmentStart[1]; - var cross = dxc * dyl - dyc * dxl; - if (cross !== 0) { - return false; - } - if (incEnd) { - if (Math.abs(dxl) >= Math.abs(dyl)) { - return dxl > 0 ? lineSegmentStart[0] <= pt[0] && pt[0] <= lineSegmentEnd[0] : lineSegmentEnd[0] <= pt[0] && pt[0] <= lineSegmentStart[0]; - } - return dyl > 0 ? lineSegmentStart[1] <= pt[1] && pt[1] <= lineSegmentEnd[1] : lineSegmentEnd[1] <= pt[1] && pt[1] <= lineSegmentStart[1]; - } else { - if (Math.abs(dxl) >= Math.abs(dyl)) { - return dxl > 0 ? lineSegmentStart[0] < pt[0] && pt[0] < lineSegmentEnd[0] : lineSegmentEnd[0] < pt[0] && pt[0] < lineSegmentStart[0]; - } - return dyl > 0 ? lineSegmentStart[1] < pt[1] && pt[1] < lineSegmentEnd[1] : lineSegmentEnd[1] < pt[1] && pt[1] < lineSegmentStart[1]; - } -} - -export default booleanCrosses; diff --git a/packages/turf-boolean-crosses/package.json b/packages/turf-boolean-crosses/package.json deleted file mode 100644 index 4f861ab02a..0000000000 --- a/packages/turf-boolean-crosses/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "@turf/boolean-crosses", - "version": "6.0.1", - "description": "turf boolean-crosses module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "equal", - "boolean", - "de-9im" - ], - "author": "Turf Authors", - "contributors": [ - "Rowan Winsemius <@rowanwins>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "boolean-shapely": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/boolean-point-in-polygon": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/line-intersect": "6.x", - "@turf/polygon-to-line": "6.x" - } -} diff --git a/packages/turf-boolean-disjoint/.gitignore b/packages/turf-boolean-disjoint/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-boolean-disjoint/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-boolean-disjoint/LICENSE b/packages/turf-boolean-disjoint/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-boolean-disjoint/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-boolean-disjoint/README.md b/packages/turf-boolean-disjoint/README.md deleted file mode 100644 index fef6a7fb80..0000000000 --- a/packages/turf-boolean-disjoint/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# @turf/boolean-disjoint - - - -## booleanDisjoint - -Boolean-disjoint returns (TRUE) if the intersection of the two geometries is an empty set. - -**Parameters** - -- `feature1` **([Geometry][1] \| [Feature][2]<any>)** GeoJSON Feature or Geometry -- `feature2` **([Geometry][1] \| [Feature][2]<any>)** GeoJSON Feature or Geometry - -**Examples** - -```javascript -var point = turf.point([2, 2]); -var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); - -turf.booleanDisjoint(line, point); -//=true -``` - -Returns **[boolean][3]** true/false - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/boolean-disjoint -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` - - -### Diagrams - -![esri-disjoint](diagrams/esri-disjoint.gif) \ No newline at end of file diff --git a/packages/turf-boolean-disjoint/index.ts b/packages/turf-boolean-disjoint/index.ts deleted file mode 100644 index 2498ec6abb..0000000000 --- a/packages/turf-boolean-disjoint/index.ts +++ /dev/null @@ -1,170 +0,0 @@ -import booleanPointInPolygon from "@turf/boolean-point-in-polygon"; -import { BBox, Feature, Geometry, LineString, Point, Polygon } from "@turf/helpers"; -import lineIntersect from "@turf/line-intersect"; -import { flattenEach } from "@turf/meta"; -import polygonToLine from "@turf/polygon-to-line"; - -/** - * Boolean-disjoint returns (TRUE) if the intersection of the two geometries is an empty set. - * - * @name booleanDisjoint - * @param {Geometry|Feature} feature1 GeoJSON Feature or Geometry - * @param {Geometry|Feature} feature2 GeoJSON Feature or Geometry - * @returns {boolean} true/false - * @example - * var point = turf.point([2, 2]); - * var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); - * - * turf.booleanDisjoint(line, point); - * //=true - */ -function booleanDisjoint(feature1: Feature | Geometry, feature2: Feature | Geometry): boolean { - let bool = true; - flattenEach(feature1, (flatten1) => { - flattenEach(feature2, (flatten2) => { - if (bool === false) { return false; } - bool = disjoint(flatten1.geometry, flatten2.geometry); - }); - }); - return bool; -} - -/** - * Disjoint operation for simple Geometries (Point/LineString/Polygon) - * - * @private - * @param {Geometry} geom1 GeoJSON Geometry - * @param {Geometry} geom2 GeoJSON Geometry - * @returns {boolean} true/false - */ -function disjoint(geom1: any, geom2: any) { - switch (geom1.type) { - case "Point": - switch (geom2.type) { - case "Point": - return !compareCoords(geom1.coordinates, geom2.coordinates); - case "LineString": - return !isPointOnLine(geom2, geom1); - case "Polygon": - return !booleanPointInPolygon(geom1, geom2); - } - /* istanbul ignore next */ - break; - case "LineString": - switch (geom2.type) { - case "Point": - return !isPointOnLine(geom1, geom2); - case "LineString": - return !isLineOnLine(geom1, geom2); - case "Polygon": - return !isLineInPoly(geom2, geom1); - } - /* istanbul ignore next */ - break; - case "Polygon": - switch (geom2.type) { - case "Point": - return !booleanPointInPolygon(geom2, geom1); - case "LineString": - return !isLineInPoly(geom1, geom2); - case "Polygon": - return !isPolyInPoly(geom2, geom1); - } - } - return false; -} - -// http://stackoverflow.com/a/11908158/1979085 -function isPointOnLine(lineString: LineString, pt: Point) { - for (let i = 0; i < lineString.coordinates.length - 1; i++) { - if (isPointOnLineSegment(lineString.coordinates[i], lineString.coordinates[i + 1], pt.coordinates)) { - return true; - } - } - return false; -} - -function isLineOnLine(lineString1: LineString, lineString2: LineString) { - const doLinesIntersect = lineIntersect(lineString1, lineString2); - if (doLinesIntersect.features.length > 0) { - return true; - } - return false; -} - -function isLineInPoly(polygon: Polygon, lineString: LineString) { - for (const coord of lineString.coordinates) { - if (booleanPointInPolygon(coord, polygon)) { - return true; - } - } - const doLinesIntersect = lineIntersect(lineString, polygonToLine(polygon)); - if (doLinesIntersect.features.length > 0) { - return true; - } - return false; -} - -/** - * Is Polygon (geom1) in Polygon (geom2) - * Only takes into account outer rings - * See http://stackoverflow.com/a/4833823/1979085 - * - * @private - * @param {Geometry|Feature} feature1 Polygon1 - * @param {Geometry|Feature} feature2 Polygon2 - * @returns {boolean} true/false - */ -function isPolyInPoly(feature1: Polygon, feature2: Polygon) { - for (const coord1 of feature1.coordinates[0]) { - if (booleanPointInPolygon(coord1, feature2)) { - return true; - } - } - for (const coord2 of feature2.coordinates[0]) { - if (booleanPointInPolygon(coord2, feature1)) { - return true; - } - } - const doLinesIntersect = lineIntersect(polygonToLine(feature1), polygonToLine(feature2)); - if (doLinesIntersect.features.length > 0) { - return true; - } - return false; -} - -function isPointOnLineSegment(lineSegmentStart: number[], lineSegmentEnd: number[], pt: number[]) { - const dxc = pt[0] - lineSegmentStart[0]; - const dyc = pt[1] - lineSegmentStart[1]; - const dxl = lineSegmentEnd[0] - lineSegmentStart[0]; - const dyl = lineSegmentEnd[1] - lineSegmentStart[1]; - const cross = dxc * dyl - dyc * dxl; - if (cross !== 0) { - return false; - } - if (Math.abs(dxl) >= Math.abs(dyl)) { - if (dxl > 0) { - return lineSegmentStart[0] <= pt[0] && pt[0] <= lineSegmentEnd[0]; - } else { - return lineSegmentEnd[0] <= pt[0] && pt[0] <= lineSegmentStart[0]; - } - } else if (dyl > 0) { - return lineSegmentStart[1] <= pt[1] && pt[1] <= lineSegmentEnd[1]; - } else { - return lineSegmentEnd[1] <= pt[1] && pt[1] <= lineSegmentStart[1]; - } -} - -/** - * compareCoords - * - * @private - * @param {Position} pair1 point [x,y] - * @param {Position} pair2 point [x,y] - * @returns {boolean} true/false if coord pairs match - */ -function compareCoords(pair1: number[], pair2: number[]) { - return pair1[0] === pair2[0] && pair1[1] === pair2[1]; -} - -export default booleanDisjoint; diff --git a/packages/turf-boolean-disjoint/package.json b/packages/turf-boolean-disjoint/package.json deleted file mode 100644 index e14d8fdbf0..0000000000 --- a/packages/turf-boolean-disjoint/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@turf/boolean-disjoint", - "version": "6.0.2", - "description": "turf boolean-disjoint module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "disjoint", - "boolean", - "de-9im" - ], - "author": "Turf Authors", - "contributors": [ - "Rowan Winsemius <@rowanwins>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "boolean-shapely": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/boolean-point-in-polygon": "6.x", - "@turf/helpers": "6.x", - "@turf/line-intersect": "6.x", - "@turf/meta": "6.x", - "@turf/polygon-to-line": "6.x" - } -} diff --git a/packages/turf-boolean-disjoint/tsconfig.json b/packages/turf-boolean-disjoint/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-boolean-disjoint/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-boolean-disjoint/tslint.json b/packages/turf-boolean-disjoint/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-boolean-disjoint/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-boolean-equal/.gitignore b/packages/turf-boolean-equal/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-boolean-equal/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-boolean-equal/LICENSE b/packages/turf-boolean-equal/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-boolean-equal/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-boolean-equal/README.md b/packages/turf-boolean-equal/README.md deleted file mode 100644 index 3f94d80e43..0000000000 --- a/packages/turf-boolean-equal/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# @turf/boolean-equal - - - -## booleanEqual - -Determine whether two geometries of the same type have identical X,Y coordinate values. -See [http://edndoc.esri.com/arcsde/9.0/general_topics/understand_spatial_relations.htm][1] - -**Parameters** - -- `feature1` **([Geometry][2] \| [Feature][3])** GeoJSON input -- `feature2` **([Geometry][2] \| [Feature][3])** GeoJSON input - -**Examples** - -```javascript -var pt1 = turf.point([0, 0]); -var pt2 = turf.point([0, 0]); -var pt3 = turf.point([1, 1]); - -turf.booleanEqual(pt1, pt2); -//= true -turf.booleanEqual(pt2, pt3); -//= false -``` - -Returns **[boolean][4]** true if the objects are equal, false otherwise - -[1]: http://edndoc.esri.com/arcsde/9.0/general_topics/understand_spatial_relations.htm - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/boolean-equal -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` - - -### Diagrams - -![esri-equals](diagrams/esri-equals.gif) \ No newline at end of file diff --git a/packages/turf-boolean-equal/index.ts b/packages/turf-boolean-equal/index.ts deleted file mode 100644 index cdd3d42f1b..0000000000 --- a/packages/turf-boolean-equal/index.ts +++ /dev/null @@ -1,33 +0,0 @@ -import * as GeojsonEquality from 'geojson-equality'; -import cleanCoords from '@turf/clean-coords'; -import { getGeom } from '@turf/invariant'; -import { Feature, Geometry } from '@turf/helpers'; - -/** - * Determine whether two geometries of the same type have identical X,Y coordinate values. - * See http://edndoc.esri.com/arcsde/9.0/general_topics/understand_spatial_relations.htm - * - * @name booleanEqual - * @param {Geometry|Feature} feature1 GeoJSON input - * @param {Geometry|Feature} feature2 GeoJSON input - * @returns {boolean} true if the objects are equal, false otherwise - * @example - * var pt1 = turf.point([0, 0]); - * var pt2 = turf.point([0, 0]); - * var pt3 = turf.point([1, 1]); - * - * turf.booleanEqual(pt1, pt2); - * //= true - * turf.booleanEqual(pt2, pt3); - * //= false - */ -function booleanEqual(feature1: Feature | Geometry, feature2: Feature | Geometry): boolean { - const type1 = getGeom(feature1).type; - const type2 = getGeom(feature2).type; - if (type1 !== type2) return false; - - const equality = new GeojsonEquality({precision: 6}); - return equality.compare(cleanCoords(feature1), cleanCoords(feature2)); -} - -export default booleanEqual; diff --git a/packages/turf-boolean-equal/package.json b/packages/turf-boolean-equal/package.json deleted file mode 100644 index dc4da6e424..0000000000 --- a/packages/turf-boolean-equal/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "@turf/boolean-equal", - "version": "6.0.1", - "description": "turf boolean-equal module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis", - "boolean", - "de-9im", - "equal", - "boolean-equal" - ], - "author": "Turf Authors", - "contributors": [ - "Tom MacWright <@tmcw>", - "Tim Channell <@tcql>", - "Stefano Borghi <@stebogit>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "boolean-shapely": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/clean-coords": "6.0.0", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "geojson-equality": "0.1.6" - } -} diff --git a/packages/turf-boolean-equal/test.js b/packages/turf-boolean-equal/test.js deleted file mode 100644 index 441e478fa7..0000000000 --- a/packages/turf-boolean-equal/test.js +++ /dev/null @@ -1,55 +0,0 @@ -const glob = require('glob'); -const path = require('path'); -const test = require('tape'); -const load = require('load-json-file'); -const shapely = require('boolean-shapely'); -const { point, lineString, polygon } = require('@turf/helpers'); -const equal = require('./').default; - -test('turf-boolean-equal', t => { - // True Fixtures - glob.sync(path.join(__dirname, 'test', 'true', '**', '*.geojson')).forEach(filepath => { - const name = path.parse(filepath).name; - const geojson = load.sync(filepath); - const feature1 = geojson.features[0]; - const feature2 = geojson.features[1]; - const result = equal(feature1, feature2); - - if (process.env.SHAPELY) shapely.contains(feature1, feature2).then(result => t.true(result, '[true] shapely - ' + name)); - t.true(result, '[true] ' + name); - }); - // False Fixtures - glob.sync(path.join(__dirname, 'test', 'false', '**', '*.geojson')).forEach(filepath => { - const name = path.parse(filepath).name; - const geojson = load.sync(filepath); - const feature1 = geojson.features[0]; - const feature2 = geojson.features[1]; - const result = equal(feature1, feature2); - - if (process.env.SHAPELY) shapely.contains(feature1, feature2).then(result => t.false(result, '[false] shapely - ' + name)); - t.false(result, '[false] ' + name); - }); - t.end(); -}); - -const pt = point([9, 50]); -const line1 = lineString([[7, 50], [8, 50], [9, 50]]); -const line2 = lineString([[7, 50], [8, 50], [9, 50]]); -const poly1 = polygon([[[8.5, 50], [9.5, 50], [9.5, 49], [8.5, 49], [8.5, 50]]]); -const poly2 = polygon([[[8.5, 50], [9.5, 50], [9.5, 49], [8.5, 49], [8.5, 50]]]); -const poly3 = polygon([[[10, 50], [10.5, 50], [10.5, 49], [10, 49], [10, 50]]]); - -test('turf-boolean-equal -- geometries', t => { - t.true(equal(line1.geometry, line2.geometry), '[true] LineString geometry'); - t.true(equal(poly1.geometry, poly2.geometry), '[true] Polygon geometry'); - t.false(equal(poly1.geometry, poly3.geometry), '[false] Polygon geometry'); - t.false(equal(pt, line1), '[false] different types'); - t.end(); -}); - - -test('turf-boolean-equal -- throws', t => { - // t.throws(() => equal(null, line1), /feature1 is required/, 'missing feature1'); - // t.throws(() => equal(line1, null), /feature2 is required/, 'missing feature2'); - t.end(); -}); diff --git a/packages/turf-boolean-intersects/.gitignore b/packages/turf-boolean-intersects/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-boolean-intersects/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-boolean-intersects/LICENSE b/packages/turf-boolean-intersects/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-boolean-intersects/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-boolean-intersects/README.md b/packages/turf-boolean-intersects/README.md deleted file mode 100644 index 04e07bb018..0000000000 --- a/packages/turf-boolean-intersects/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# @turf/boolean-intersects - - - -## booleanIntersects - -Boolean-intersects returns (TRUE) two geometries intersect. - -**Parameters** - -- `feature1` **([Geometry][1] \| [Feature][2]<any>)** GeoJSON Feature or Geometry -- `feature2` **([Geometry][1] \| [Feature][2]<any>)** GeoJSON Feature or Geometry - -**Examples** - -```javascript -var point = turf.point([2, 2]); -var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); - -turf.booleanIntersects(line, point); -//=true -``` - -Returns **[boolean][3]** true/false - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/boolean-intersects -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-boolean-intersects/index.ts b/packages/turf-boolean-intersects/index.ts deleted file mode 100644 index a026c7b096..0000000000 --- a/packages/turf-boolean-intersects/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -import booleanDisjoint from "@turf/boolean-disjoint"; -import { Feature, Geometry } from "@turf/helpers"; -import { flattenEach } from "@turf/meta"; - -/** - * Boolean-intersects returns (TRUE) two geometries intersect. - * - * @name booleanIntersects - * @param {Geometry|Feature} feature1 GeoJSON Feature or Geometry - * @param {Geometry|Feature} feature2 GeoJSON Feature or Geometry - * @returns {boolean} true/false - * @example - * var point = turf.point([2, 2]); - * var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); - * - * turf.booleanIntersects(line, point); - * //=true - */ -export default function booleanIntersects(feature1: Feature | Geometry, feature2: Feature | Geometry) { - let bool = false; - flattenEach(feature1, (flatten1) => { - flattenEach(feature2, (flatten2) => { - if (bool === true) { return true; } - bool = !booleanDisjoint(flatten1.geometry, flatten2.geometry); - }); - }); - return bool; -} diff --git a/packages/turf-boolean-intersects/package.json b/packages/turf-boolean-intersects/package.json deleted file mode 100644 index 4c60008659..0000000000 --- a/packages/turf-boolean-intersects/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "@turf/boolean-intersects", - "version": "6.0.2", - "description": "turf boolean-intersects module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "intersects", - "boolean", - "de-9im" - ], - "author": "Turf Authors", - "contributors": [ - "Rowan Winsemius <@rowanwins>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "boolean-shapely": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/boolean-disjoint": "6.x", - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-boolean-intersects/tsconfig.json b/packages/turf-boolean-intersects/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-boolean-intersects/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-boolean-intersects/tslint.json b/packages/turf-boolean-intersects/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-boolean-intersects/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-boolean-overlap/.gitignore b/packages/turf-boolean-overlap/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-boolean-overlap/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-boolean-overlap/LICENSE b/packages/turf-boolean-overlap/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-boolean-overlap/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-boolean-overlap/README.md b/packages/turf-boolean-overlap/README.md deleted file mode 100755 index 5493958e05..0000000000 --- a/packages/turf-boolean-overlap/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# @turf/boolean-overlap - - - -## booleanOverlap - -Compares two geometries of the same dimension and returns true if their intersection set results in a geometry -different from both but of the same dimension. It applies to Polygon/Polygon, LineString/LineString, -Multipoint/Multipoint, MultiLineString/MultiLineString and MultiPolygon/MultiPolygon. - -**Parameters** - -- `feature1` **([Geometry][1] \| [Feature][2]<([LineString][3] \| [MultiLineString][4] \| [Polygon][5] \| [MultiPolygon][6])>)** input -- `feature2` **([Geometry][1] \| [Feature][2]<([LineString][3] \| [MultiLineString][4] \| [Polygon][5] \| [MultiPolygon][6])>)** input - -**Examples** - -```javascript -var poly1 = turf.polygon([[[0,0],[0,5],[5,5],[5,0],[0,0]]]); -var poly2 = turf.polygon([[[1,1],[1,6],[6,6],[6,1],[1,1]]]); -var poly3 = turf.polygon([[[10,10],[10,15],[15,15],[15,10],[10,10]]]); - -turf.booleanOverlap(poly1, poly2) -//=true -turf.booleanOverlap(poly2, poly3) -//=false -``` - -Returns **[boolean][7]** true/false - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/boolean-overlap -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` - - -### Diagrams - -![esri-overlaps](diagrams/esri-overlaps.gif) \ No newline at end of file diff --git a/packages/turf-boolean-overlap/index.ts b/packages/turf-boolean-overlap/index.ts deleted file mode 100644 index 29f146736c..0000000000 --- a/packages/turf-boolean-overlap/index.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { coordAll, segmentEach } from '@turf/meta'; -import { getGeom } from '@turf/invariant'; -import lineOverlap from '@turf/line-overlap'; -import lineIntersect from '@turf/line-intersect'; -import * as GeojsonEquality from 'geojson-equality'; -import { Feature, LineString, MultiLineString, Polygon, MultiPolygon, Geometry } from '@turf/helpers'; - -/** - * Compares two geometries of the same dimension and returns true if their intersection set results in a geometry - * different from both but of the same dimension. It applies to Polygon/Polygon, LineString/LineString, - * Multipoint/Multipoint, MultiLineString/MultiLineString and MultiPolygon/MultiPolygon. - * - * @name booleanOverlap - * @param {Geometry|Feature} feature1 input - * @param {Geometry|Feature} feature2 input - * @returns {boolean} true/false - * @example - * var poly1 = turf.polygon([[[0,0],[0,5],[5,5],[5,0],[0,0]]]); - * var poly2 = turf.polygon([[[1,1],[1,6],[6,6],[6,1],[1,1]]]); - * var poly3 = turf.polygon([[[10,10],[10,15],[15,15],[15,10],[10,10]]]); - * - * turf.booleanOverlap(poly1, poly2) - * //=true - * turf.booleanOverlap(poly2, poly3) - * //=false - */ -export default function booleanOverlap( - feature1: Feature | Geometry, - feature2: Feature | Geometry, -): boolean { - const geom1 = getGeom(feature1); - const geom2 = getGeom(feature2); - const type1 = geom1.type; - const type2 = geom2.type; - if (type1 !== type2) throw new Error('features must be of the same type'); - if (type1 === 'Point') throw new Error('Point geometry not supported'); - - // features must be not equal - const equality = new GeojsonEquality({precision: 6}); - if (equality.compare(feature1, feature2)) return false; - - let overlap = 0; - - switch (type1) { - case 'MultiPoint': - const coords1 = coordAll(feature1); - const coords2 = coordAll(feature2); - coords1.forEach((coord1) => { - coords2.forEach((coord2) => { - if (coord1[0] === coord2[0] && coord1[1] === coord2[1]) overlap++; - }); - }); - break; - - case 'LineString': - case 'MultiLineString': - segmentEach(feature1, (segment1) => { - segmentEach(feature2, (segment2) => { - if (lineOverlap(segment1, segment2).features.length) overlap++; - }); - }); - break; - - case 'Polygon': - case 'MultiPolygon': - segmentEach(feature1, (segment1) => { - segmentEach(feature2, (segment2) => { - if (lineIntersect(segment1, segment2).features.length) overlap++; - }); - }); - break; - } - - return overlap > 0; -} diff --git a/packages/turf-boolean-overlap/package.json b/packages/turf-boolean-overlap/package.json deleted file mode 100755 index c4e84295d5..0000000000 --- a/packages/turf-boolean-overlap/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "@turf/boolean-overlap", - "version": "6.0.1", - "description": "turf boolean-overlap module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis", - "boolean", - "de-9im", - "overlap", - "boolean-overlap" - ], - "author": "Turf Authors", - "contributors": [ - "Tim Channell <@tcql>", - "Stefano Borghi <@stebogit>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "boolean-shapely": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/line-intersect": "6.x", - "@turf/line-overlap": "6.x", - "@turf/meta": "6.x", - "geojson-equality": "0.1.6" - } -} diff --git a/packages/turf-boolean-overlap/test.js b/packages/turf-boolean-overlap/test.js deleted file mode 100644 index ccf798c2e5..0000000000 --- a/packages/turf-boolean-overlap/test.js +++ /dev/null @@ -1,56 +0,0 @@ -const glob = require('glob'); -const path = require('path'); -const test = require('tape'); -const load = require('load-json-file'); -const shapely = require('boolean-shapely'); -const { point, lineString, polygon } = require('@turf/helpers'); -const overlap = require('./').default; - -test('turf-boolean-overlap', t => { - // True Fixtures - glob.sync(path.join(__dirname, 'test', 'true', '**', '*.geojson')).forEach(filepath => { - const name = path.parse(filepath).name; - const geojson = load.sync(filepath); - const feature1 = geojson.features[0]; - const feature2 = geojson.features[1]; - const result = overlap(feature1, feature2); - - if (process.env.SHAPELY) shapely.contains(feature1, feature2).then(result => t.true(result, '[true] shapely - ' + name)); - t.true(result, '[true] ' + name); - }); - // False Fixtures - glob.sync(path.join(__dirname, 'test', 'false', '**', '*.geojson')).forEach(filepath => { - const name = path.parse(filepath).name; - const geojson = load.sync(filepath); - const feature1 = geojson.features[0]; - const feature2 = geojson.features[1]; - const result = overlap(feature1, feature2); - - if (process.env.SHAPELY) shapely.contains(feature1, feature2).then(result => t.false(result, '[false] shapely - ' + name)); - t.false(result, '[false] ' + name); - }); - t.end(); -}); - -const pt = point([9, 50]); -const line1 = lineString([[7, 50], [8, 50], [9, 50]]); -const line2 = lineString([[8, 50], [9, 50], [10, 50]]); -const poly1 = polygon([[[8.5, 50], [9.5, 50], [9.5, 49], [8.5, 49], [8.5, 50]]]); -const poly2 = polygon([[[8, 50], [9, 50], [9, 49], [8, 49], [8, 50]]]); -const poly3 = polygon([[[10, 50], [10.5, 50], [10.5, 49], [10, 49], [10, 50]]]); - -test('turf-boolean-overlap -- geometries', t => { - t.true(overlap(line1.geometry, line2.geometry), '[true] LineString geometry'); - t.true(overlap(poly1.geometry, poly2.geometry), '[true] Polygon geometry'); - t.false(overlap(poly1.geometry, poly3.geometry), '[false] Polygon geometry'); - t.end(); -}); - -test('turf-boolean-overlap -- throws', t => { - // t.throws(() => overlap(null, line1), /feature1 is required/, 'missing feature1'); - // t.throws(() => overlap(line1, null), /feature2 is required/, 'missing feature2'); - t.throws(() => overlap(pt, line1), /features must be of the same type/, 'different types'); - t.throws(() => overlap(pt, pt), /Point geometry not supported/, 'geometry not supported'); - - t.end(); -}); diff --git a/packages/turf-boolean-parallel/.gitignore b/packages/turf-boolean-parallel/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-boolean-parallel/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-boolean-parallel/LICENSE b/packages/turf-boolean-parallel/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-boolean-parallel/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-boolean-parallel/README.md b/packages/turf-boolean-parallel/README.md deleted file mode 100644 index 6b55e5abc9..0000000000 --- a/packages/turf-boolean-parallel/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# @turf/boolean-parallel - - - -## booleanParallel - -Boolean-Parallel returns True if each segment of `line1` is parallel to the correspondent segment of `line2` - -**Parameters** - -- `line1` **([Geometry][1] \| [Feature][2]<[LineString][3]>)** GeoJSON Feature or Geometry -- `line2` **([Geometry][1] \| [Feature][2]<[LineString][3]>)** GeoJSON Feature or Geometry - -**Examples** - -```javascript -var line1 = turf.lineString([[0, 0], [0, 1]]); -var line2 = turf.lineString([[1, 0], [1, 1]]); - -turf.booleanParallel(line1, line2); -//=true -``` - -Returns **[boolean][4]** true/false if the lines are parallel - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/boolean-parallel -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-boolean-parallel/index.ts b/packages/turf-boolean-parallel/index.ts deleted file mode 100644 index d56feeea70..0000000000 --- a/packages/turf-boolean-parallel/index.ts +++ /dev/null @@ -1,71 +0,0 @@ -import cleanCoords from '@turf/clean-coords'; -import lineSegment from '@turf/line-segment'; -import rhumbBearing from '@turf/rhumb-bearing'; -import { bearingToAzimuth, Feature, LineString } from '@turf/helpers'; - -/** - * Boolean-Parallel returns True if each segment of `line1` is parallel to the correspondent segment of `line2` - * - * @name booleanParallel - * @param {Geometry|Feature} line1 GeoJSON Feature or Geometry - * @param {Geometry|Feature} line2 GeoJSON Feature or Geometry - * @returns {boolean} true/false if the lines are parallel - * @example - * var line1 = turf.lineString([[0, 0], [0, 1]]); - * var line2 = turf.lineString([[1, 0], [1, 1]]); - * - * turf.booleanParallel(line1, line2); - * //=true - */ -function booleanParallel(line1: Feature | LineString, line2: Feature | LineString): boolean { - // validation - if (!line1) throw new Error('line1 is required'); - if (!line2) throw new Error('line2 is required'); - var type1 = getType(line1, 'line1'); - if (type1 !== 'LineString') throw new Error('line1 must be a LineString'); - var type2 = getType(line2, 'line2'); - if (type2 !== 'LineString') throw new Error('line2 must be a LineString'); - - var segments1 = lineSegment(cleanCoords(line1)).features; - var segments2 = lineSegment(cleanCoords(line2)).features; - - for (var i = 0; i < segments1.length; i++) { - var segment1 = segments1[i].geometry.coordinates; - if (!segments2[i]) break; - var segment2 = segments2[i].geometry.coordinates; - if (!isParallel(segment1, segment2)) return false; - } - return true; -} - - -/** - * Compares slopes and return result - * - * @private - * @param {Geometry|Feature} segment1 Geometry or Feature - * @param {Geometry|Feature} segment2 Geometry or Feature - * @returns {boolean} if slopes are equal - */ -function isParallel(segment1, segment2) { - var slope1 = bearingToAzimuth(rhumbBearing(segment1[0], segment1[1])); - var slope2 = bearingToAzimuth(rhumbBearing(segment2[0], segment2[1])); - return slope1 === slope2; -} - - -/** - * Returns Feature's type - * - * @private - * @param {Geometry|Feature} geojson Geometry or Feature - * @param {string} name of the variable - * @returns {string} Feature's type - */ -function getType(geojson, name) { - if (geojson.geometry && geojson.geometry.type) return geojson.geometry.type; - if (geojson.type) return geojson.type; // if GeoJSON geometry - throw new Error('Invalid GeoJSON object for ' + name); -} - -export default booleanParallel; diff --git a/packages/turf-boolean-parallel/package.json b/packages/turf-boolean-parallel/package.json deleted file mode 100644 index 23f57a8eac..0000000000 --- a/packages/turf-boolean-parallel/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "@turf/boolean-parallel", - "version": "6.0.1", - "description": "turf boolean-parallel module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "parallel", - "boolean", - "boolean-parallel" - ], - "author": "Turf Authors", - "contributors": [ - "Stefano Borghi <@stebogit>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/clean-coords": "6.x", - "@turf/helpers": "6.x", - "@turf/line-segment": "6.x", - "@turf/rhumb-bearing": "6.x" - } -} diff --git a/packages/turf-boolean-parallel/test.js b/packages/turf-boolean-parallel/test.js deleted file mode 100644 index edb2d00f01..0000000000 --- a/packages/turf-boolean-parallel/test.js +++ /dev/null @@ -1,45 +0,0 @@ -const glob = require('glob'); -const path = require('path'); -const test = require('tape'); -const load = require('load-json-file'); -const { lineString, polygon } = require('@turf/helpers'); -const booleanParallel = require('.').default; - -test('turf-boolean-parallel', t => { - // True Fixtures - glob.sync(path.join(__dirname, 'test', 'true', '**', '*.geojson')).forEach(filepath => { - const name = path.parse(filepath).name; - const geojson = load.sync(filepath); - const line1 = geojson.features[0]; - const line2 = geojson.features[1]; - const result = booleanParallel(line1, line2); - - t.true(result, '[true] ' + name); - }); - // False Fixtures - glob.sync(path.join(__dirname, 'test', 'false', '**', '*.geojson')).forEach(filepath => { - const name = path.parse(filepath).name; - const geojson = load.sync(filepath); - const line1 = geojson.features[0]; - const line2 = geojson.features[1]; - const result = booleanParallel(line1, line2); - - t.false(result, '[false] ' + name); - }); - t.end(); -}); - - -test('turf-boolean-parallel -- throws', t => { - const line = lineString([[0, 0], [0, 1]]); - const poly = polygon([[[0, 0], [0, 1], [1, 1], [0, 0]]]); - - // t.throws(() => booleanParallel(null, line), /line1 is required/, 'missing line1'); - // t.throws(() => booleanParallel(line, null), /line2 is required/, 'missing line2'); - // t.throws(() => booleanParallel(poly, line), /line1 must be a LineString/, 'different types'); - // t.throws(() => booleanParallel(line, poly), /line2 must be a LineString/, 'different types'); - t.throws(() => booleanParallel({}, line), /Invalid GeoJSON object for line1/, 'invalid types'); - t.throws(() => booleanParallel(line, {}), /Invalid GeoJSON object for line2/, 'invalid types'); - - t.end(); -}); diff --git a/packages/turf-boolean-point-in-polygon/.gitignore b/packages/turf-boolean-point-in-polygon/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-boolean-point-in-polygon/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-boolean-point-in-polygon/LICENSE b/packages/turf-boolean-point-in-polygon/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-boolean-point-in-polygon/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-boolean-point-in-polygon/README.md b/packages/turf-boolean-point-in-polygon/README.md deleted file mode 100644 index 745b2a96fd..0000000000 --- a/packages/turf-boolean-point-in-polygon/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# @turf/boolean-point-in-polygon - - - -## booleanPointInPolygon - -Takes a [Point][1] and a [Polygon][2] or [MultiPolygon][3] and determines if the point resides inside the polygon. The polygon can -be convex or concave. The function accounts for holes. - -**Parameters** - -- `point` **[Coord][4]** input point -- `polygon` **[Feature][5]<([Polygon][6] \| [MultiPolygon][7])>** input polygon or multipolygon -- `options` **[Object][8]** Optional parameters (optional, default `{}`) - - `options.ignoreBoundary` **[boolean][9]** True if polygon boundary should be ignored when determining if the point is inside the polygon otherwise false. (optional, default `false`) - -**Examples** - -```javascript -var pt = turf.point([-77, 44]); -var poly = turf.polygon([[ - [-81, 41], - [-81, 47], - [-72, 47], - [-72, 41], - [-81, 41] -]]); - -turf.booleanPointInPolygon(pt, poly); -//= true -``` - -Returns **[boolean][9]** `true` if the Point is inside the Polygon; `false` if the Point is not inside the Polygon - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/boolean-point-in-polygon -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-boolean-point-in-polygon/index.ts b/packages/turf-boolean-point-in-polygon/index.ts deleted file mode 100644 index c23ae526ff..0000000000 --- a/packages/turf-boolean-point-in-polygon/index.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { BBox, Coord, Feature, MultiPolygon, Polygon, Properties } from "@turf/helpers"; -import { getCoord, getCoords, getGeom } from "@turf/invariant"; - -// http://en.wikipedia.org/wiki/Even%E2%80%93odd_rule -// modified from: https://github.com/substack/point-in-polygon/blob/master/index.js -// which was modified from http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html -/** - * Takes a {@link Point} and a {@link Polygon} or {@link MultiPolygon} and determines if the point - * resides inside the polygon. The polygon can be convex or concave. The function accounts for holes. - * - * @name booleanPointInPolygon - * @param {Coord} point input point - * @param {Feature} polygon input polygon or multipolygon - * @param {Object} [options={}] Optional parameters - * @param {boolean} [options.ignoreBoundary=false] True if polygon boundary should be ignored when determining if - * the point is inside the polygon otherwise false. - * @returns {boolean} `true` if the Point is inside the Polygon; `false` if the Point is not inside the Polygon - * @example - * var pt = turf.point([-77, 44]); - * var poly = turf.polygon([[ - * [-81, 41], - * [-81, 47], - * [-72, 47], - * [-72, 41], - * [-81, 41] - * ]]); - * - * turf.booleanPointInPolygon(pt, poly); - * //= true - */ -export default function booleanPointInPolygon( - point: Coord, - polygon: Feature | G, - options: { - ignoreBoundary?: boolean, - } = {}, -) { - // validation - if (!point) { throw new Error("point is required"); } - if (!polygon) { throw new Error("polygon is required"); } - - const pt = getCoord(point); - const geom = getGeom(polygon); - const type = geom.type; - const bbox = polygon.bbox; - let polys: any[] = geom.coordinates; - - // Quick elimination if point is not inside bbox - if (bbox && inBBox(pt, bbox) === false) { - return false; - } - // normalize to multipolygon - if (type === "Polygon") { - polys = [polys]; - } - let insidePoly = false; - for (let i = 0; i < polys.length && !insidePoly; i++) { - // check if it is in the outer ring first - if (inRing(pt, polys[i][0], options.ignoreBoundary)) { - let inHole = false; - let k = 1; - // check for the point in any of the holes - while (k < polys[i].length && !inHole) { - if (inRing(pt, polys[i][k], !options.ignoreBoundary)) { - inHole = true; - } - k++; - } - if (!inHole) { - insidePoly = true; - } - } - } - return insidePoly; -} - -/** - * inRing - * - * @private - * @param {Array} pt [x,y] - * @param {Array>} ring [[x,y], [x,y],..] - * @param {boolean} ignoreBoundary ignoreBoundary - * @returns {boolean} inRing - */ -function inRing(pt: number[], ring: number[][], ignoreBoundary?: boolean) { - let isInside = false; - if (ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1]) { - ring = ring.slice(0, ring.length - 1); - } - for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) { - const xi = ring[i][0]; - const yi = ring[i][1]; - const xj = ring[j][0]; - const yj = ring[j][1]; - const onBoundary = (pt[1] * (xi - xj) + yi * (xj - pt[0]) + yj * (pt[0] - xi) === 0) && - ((xi - pt[0]) * (xj - pt[0]) <= 0) && ((yi - pt[1]) * (yj - pt[1]) <= 0); - if (onBoundary) { - return !ignoreBoundary; - } - const intersect = ((yi > pt[1]) !== (yj > pt[1])) && - (pt[0] < (xj - xi) * (pt[1] - yi) / (yj - yi) + xi); - if (intersect) { - isInside = !isInside; - } - } - return isInside; -} -/** - * inBBox - * - * @private - * @param {Position} pt point [x,y] - * @param {BBox} bbox BBox [west, south, east, north] - * @returns {boolean} true/false if point is inside BBox - */ -function inBBox(pt: number[], bbox: BBox) { - return bbox[0] <= pt[0] && - bbox[1] <= pt[1] && - bbox[2] >= pt[0] && - bbox[3] >= pt[1]; -} diff --git a/packages/turf-boolean-point-in-polygon/package.json b/packages/turf-boolean-point-in-polygon/package.json deleted file mode 100644 index 75409c4fb5..0000000000 --- a/packages/turf-boolean-point-in-polygon/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "@turf/boolean-point-in-polygon", - "version": "6.0.1", - "description": "turf boolean-point-in-polygon module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "geojson", - "polygon", - "point", - "inside", - "bin", - "gis" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-boolean-point-in-polygon/test.js b/packages/turf-boolean-point-in-polygon/test.js deleted file mode 100644 index 56532465a4..0000000000 --- a/packages/turf-boolean-point-in-polygon/test.js +++ /dev/null @@ -1,170 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const { point } = require('@turf/helpers'); -const { polygon } = require('@turf/helpers'); -const booleanPointInPolygon = require('./').default; - -test('boolean-point-in-polygon -- featureCollection', function (t) { - // test for a simple polygon - var poly = polygon([[[0, 0], [0, 100], [100, 100], [100, 0], [0, 0]]]); - var ptIn = point([50, 50]); - var ptOut = point([140, 150]); - - t.true(booleanPointInPolygon(ptIn, poly), 'point inside simple polygon'); - t.false(booleanPointInPolygon(ptOut, poly), 'point outside simple polygon'); - - // test for a concave polygon - var concavePoly = polygon([[[0, 0], [50, 50], [0, 100], [100, 100], [100, 0], [0, 0]]]); - var ptConcaveIn = point([75, 75]); - var ptConcaveOut = point([25, 50]); - - t.true(booleanPointInPolygon(ptConcaveIn, concavePoly), 'point inside concave polygon'); - t.false(booleanPointInPolygon(ptConcaveOut, concavePoly), 'point outside concave polygon'); - - t.end(); -}); - -test('boolean-point-in-polygon -- poly with hole', function (t) { - var ptInHole = point([-86.69208526611328, 36.20373274711739]); - var ptInPoly = point([-86.72229766845702, 36.20258997094334]); - var ptOutsidePoly = point([-86.75079345703125, 36.18527313913089]); - var polyHole = JSON.parse(fs.readFileSync(__dirname + '/test/in/poly-with-hole.geojson')); - - t.false(booleanPointInPolygon(ptInHole, polyHole)); - t.true(booleanPointInPolygon(ptInPoly, polyHole)); - t.false(booleanPointInPolygon(ptOutsidePoly, polyHole)); - - t.end(); -}); - -test('boolean-point-in-polygon -- multipolygon with hole', function (t) { - var ptInHole = point([-86.69208526611328, 36.20373274711739]); - var ptInPoly = point([-86.72229766845702, 36.20258997094334]); - var ptInPoly2 = point([-86.75079345703125, 36.18527313913089]); - var ptOutsidePoly = point([-86.75302505493164, 36.23015046460186]); - var multiPolyHole = JSON.parse(fs.readFileSync(__dirname + '/test/in/multipoly-with-hole.geojson')); - - t.false(booleanPointInPolygon(ptInHole, multiPolyHole)); - t.true(booleanPointInPolygon(ptInPoly, multiPolyHole)); - t.true(booleanPointInPolygon(ptInPoly2, multiPolyHole)); - t.true(booleanPointInPolygon(ptInPoly, multiPolyHole)); - t.false(booleanPointInPolygon(ptOutsidePoly, multiPolyHole)); - - t.end(); -}); - -test('boolean-point-in-polygon -- Boundary test', function (t) { - var poly1 = polygon([[ - [10, 10], - [30, 20], - [50, 10], - [30, 0], - [10, 10] - ]]); - var poly2 = polygon([[ - [10, 0], - [30, 20], - [50, 0], - [30, 10], - [10, 0] - ]]); - var poly3 = polygon([[ - [10, 0], - [30, 20], - [50, 0], - [30, -20], - [10, 0] - ]]); - var poly4 = polygon([[ - [0, 0], - [0, 20], - [50, 20], - [50, 0], - [40, 0], - [30, 10], - [30, 0], - [20, 10], - [10, 10], - [10, 0], - [0, 0] - ]]); - var poly5 = polygon([[ - [0, 20], - [20, 40], - [40, 20], - [20, 0], - [0, 20] - ], [ - [10, 20], - [20, 30], - [30, 20], - [20, 10], - [10, 20] - ]]); - function runTest(t, ignoreBoundary) { - var isBoundaryIncluded = (ignoreBoundary === false); - var tests = [ - [poly1, point([10, 10]), isBoundaryIncluded], //0 - [poly1, point([30, 20]), isBoundaryIncluded], - [poly1, point([50, 10]), isBoundaryIncluded], - [poly1, point([30, 10]), true], - [poly1, point([0, 10]), false], - [poly1, point([60, 10]), false], - [poly1, point([30, -10]), false], - [poly1, point([30, 30]), false], - [poly2, point([30, 0]), false], - [poly2, point([0, 0]), false], - [poly2, point([60, 0]), false], //10 - [poly3, point([30, 0]), true], - [poly3, point([0, 0]), false], - [poly3, point([60, 0]), false], - [poly4, point([0, 20]), isBoundaryIncluded], - [poly4, point([10, 20]), isBoundaryIncluded], - [poly4, point([50, 20]), isBoundaryIncluded], - [poly4, point([0, 10]), isBoundaryIncluded], - [poly4, point([5, 10]), true], - [poly4, point([25, 10]), true], - [poly4, point([35, 10]), true], //20 - [poly4, point([0, 0]), isBoundaryIncluded], - [poly4, point([20, 0]), false], - [poly4, point([35, 0]), false], - [poly4, point([50, 0]), isBoundaryIncluded], - [poly4, point([50, 10]), isBoundaryIncluded], - [poly4, point([5, 0]), isBoundaryIncluded], - [poly4, point([10, 0]), isBoundaryIncluded], - [poly5, point([20, 30]), isBoundaryIncluded], - [poly5, point([25, 25]), isBoundaryIncluded], - [poly5, point([30, 20]), isBoundaryIncluded], //30 - [poly5, point([25, 15]), isBoundaryIncluded], - [poly5, point([20, 10]), isBoundaryIncluded], - [poly5, point([15, 15]), isBoundaryIncluded], - [poly5, point([10, 20]), isBoundaryIncluded], - [poly5, point([15, 25]), isBoundaryIncluded], - [poly5, point([20, 20]), false] - ]; - - var testTitle = 'Boundary ' + (ignoreBoundary ? 'ignored ' : '') + 'test number '; - for (var i = 0; i < tests.length; i++) { - var item = tests[i]; - t.true(booleanPointInPolygon(item[1], item[0], {ignoreBoundary: ignoreBoundary}) == item[2], testTitle + i); - } - } - runTest(t, false); - runTest(t, true); - t.end(); -}); - -// https://github.com/Turfjs/turf-inside/issues/15 -test('boolean-point-in-polygon -- issue #15', t => { - var pt1 = point([-9.9964077, 53.8040989]); - var poly = polygon([[ - [5.080336744095521, 67.89398938540765], - [0.35070899909145403, 69.32470003971179], - [-24.453622256504122, 41.146696777884564], - [-21.6445524714804, 40.43225902006474], - [5.080336744095521, 67.89398938540765] - ]]); - - t.true(booleanPointInPolygon(pt1, poly)); - t.end(); -}); diff --git a/packages/turf-boolean-point-in-polygon/tsconfig.json b/packages/turf-boolean-point-in-polygon/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-boolean-point-in-polygon/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-boolean-point-in-polygon/tslint.json b/packages/turf-boolean-point-in-polygon/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-boolean-point-in-polygon/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-boolean-point-on-line/.gitignore b/packages/turf-boolean-point-on-line/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-boolean-point-on-line/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-boolean-point-on-line/LICENSE b/packages/turf-boolean-point-on-line/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-boolean-point-on-line/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-boolean-point-on-line/README.md b/packages/turf-boolean-point-on-line/README.md deleted file mode 100644 index faeb05b6d5..0000000000 --- a/packages/turf-boolean-point-on-line/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# @turf/boolean-point-on-line - - - -## booleanPointOnLine - -Returns true if a point is on a line. Accepts a optional parameter to ignore the start and end vertices of the linestring. - -**Parameters** - -- `pt` **[Coord][1]** GeoJSON Point -- `line` **[Feature][2]<[LineString][3]>** GeoJSON LineString -- `options` **[Object][4]** Optional parameters (optional, default `{}`) - - `options.ignoreEndVertices` **[boolean][5]** whether to ignore the start and end vertices. (optional, default `false`) - -**Examples** - -```javascript -var pt = turf.point([0, 0]); -var line = turf.lineString([[-1, -1],[1, 1],[1.5, 2.2]]); -var isPointOnLine = turf.booleanPointOnLine(pt, line); -//=true -``` - -Returns **[boolean][5]** true/false - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/boolean-point-on-line -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-boolean-point-on-line/index.ts b/packages/turf-boolean-point-on-line/index.ts deleted file mode 100644 index 86e03b2661..0000000000 --- a/packages/turf-boolean-point-on-line/index.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { Coord, Feature, LineString } from "@turf/helpers"; -import { getCoord, getCoords } from "@turf/invariant"; - -/** - * Returns true if a point is on a line. Accepts a optional parameter to ignore the - * start and end vertices of the linestring. - * - * @name booleanPointOnLine - * @param {Coord} pt GeoJSON Point - * @param {Feature} line GeoJSON LineString - * @param {Object} [options={}] Optional parameters - * @param {boolean} [options.ignoreEndVertices=false] whether to ignore the start and end vertices. - * @returns {boolean} true/false - * @example - * var pt = turf.point([0, 0]); - * var line = turf.lineString([[-1, -1],[1, 1],[1.5, 2.2]]); - * var isPointOnLine = turf.booleanPointOnLine(pt, line); - * //=true - */ -function booleanPointOnLine(pt: Coord, line: Feature | LineString, options: { - ignoreEndVertices?: boolean, -} = {}): boolean { - // Normalize inputs - const ptCoords = getCoord(pt); - const lineCoords = getCoords(line); - - // Main - for (let i = 0; i < lineCoords.length - 1; i++) { - let ignoreBoundary: boolean|string = false; - if (options.ignoreEndVertices) { - if (i === 0) { ignoreBoundary = "start"; } - if (i === lineCoords.length - 2) { ignoreBoundary = "end"; } - if (i === 0 && i + 1 === lineCoords.length - 1) { ignoreBoundary = "both"; } - } - if (isPointOnLineSegment(lineCoords[i], lineCoords[i + 1], ptCoords, ignoreBoundary)) { return true; } - } - return false; -} - -// See http://stackoverflow.com/a/4833823/1979085 -/** - * @private - * @param {Position} lineSegmentStart coord pair of start of line - * @param {Position} lineSegmentEnd coord pair of end of line - * @param {Position} pt coord pair of point to check - * @param {boolean|string} excludeBoundary whether the point is allowed to fall on the line ends. - * If true which end to ignore. - * @returns {boolean} true/false - */ -function isPointOnLineSegment( - lineSegmentStart: number[], - lineSegmentEnd: number[], - pt: number[], - excludeBoundary: string|boolean, -): boolean { - const x = pt[0]; - const y = pt[1]; - const x1 = lineSegmentStart[0]; - const y1 = lineSegmentStart[1]; - const x2 = lineSegmentEnd[0]; - const y2 = lineSegmentEnd[1]; - const dxc = pt[0] - x1; - const dyc = pt[1] - y1; - const dxl = x2 - x1; - const dyl = y2 - y1; - const cross = dxc * dyl - dyc * dxl; - if (cross !== 0) { - return false; - } - if (!excludeBoundary) { - if (Math.abs(dxl) >= Math.abs(dyl)) { - return dxl > 0 ? x1 <= x && x <= x2 : x2 <= x && x <= x1; - } - return dyl > 0 ? y1 <= y && y <= y2 : y2 <= y && y <= y1; - } else if (excludeBoundary === "start") { - if (Math.abs(dxl) >= Math.abs(dyl)) { - return dxl > 0 ? x1 < x && x <= x2 : x2 <= x && x < x1; - } - return dyl > 0 ? y1 < y && y <= y2 : y2 <= y && y < y1; - } else if (excludeBoundary === "end") { - if (Math.abs(dxl) >= Math.abs(dyl)) { - return dxl > 0 ? x1 <= x && x < x2 : x2 < x && x <= x1; - } - return dyl > 0 ? y1 <= y && y < y2 : y2 < y && y <= y1; - } else if (excludeBoundary === "both") { - if (Math.abs(dxl) >= Math.abs(dyl)) { - return dxl > 0 ? x1 < x && x < x2 : x2 < x && x < x1; - } - return dyl > 0 ? y1 < y && y < y2 : y2 < y && y < y1; - } - return false; -} - -export default booleanPointOnLine; diff --git a/packages/turf-boolean-point-on-line/package.json b/packages/turf-boolean-point-on-line/package.json deleted file mode 100644 index 478e25ea60..0000000000 --- a/packages/turf-boolean-point-on-line/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@turf/boolean-point-on-line", - "version": "6.0.1", - "description": "turf boolean-point-on-line module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "booleanPointOnLine" - ], - "author": "Turf Authors", - "contributors": [ - "Rowan Winsemius <@rowanwins>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-boolean-point-on-line/test.js b/packages/turf-boolean-point-on-line/test.js deleted file mode 100644 index 7707bc212b..0000000000 --- a/packages/turf-boolean-point-on-line/test.js +++ /dev/null @@ -1,31 +0,0 @@ -const glob = require('glob'); -const path = require('path'); -const test = require('tape'); -const load = require('load-json-file'); -const pointOnLine = require('./').default; - -test('turf-boolean-point-on-line', t => { - // True Fixtures - glob.sync(path.join(__dirname, 'test', 'true', '**', '*.geojson')).forEach(filepath => { - const name = path.parse(filepath).name; - const geojson = load.sync(filepath); - const options = geojson.propeties; - const feature1 = geojson.features[0]; - const feature2 = geojson.features[1]; - const result = pointOnLine(feature1, feature2, options); - - t.true(result, '[true] ' + name); - }); - // False Fixtures - glob.sync(path.join(__dirname, 'test', 'false', '**', '*.geojson')).forEach(filepath => { - const name = path.parse(filepath).name; - const geojson = load.sync(filepath); - const options = geojson.properties; - const feature1 = geojson.features[0]; - const feature2 = geojson.features[1]; - const result = pointOnLine(feature1, feature2, options); - - t.false(result, '[false] ' + name); - }); - t.end(); -}); diff --git a/packages/turf-boolean-point-on-line/tsconfig.json b/packages/turf-boolean-point-on-line/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-boolean-point-on-line/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-boolean-point-on-line/tslint.json b/packages/turf-boolean-point-on-line/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-boolean-point-on-line/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-boolean-touches/.gitignore b/packages/turf-boolean-touches/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-boolean-touches/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-boolean-touches/LICENSE b/packages/turf-boolean-touches/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-boolean-touches/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-boolean-touches/README.md b/packages/turf-boolean-touches/README.md deleted file mode 100644 index f09dd52b4b..0000000000 --- a/packages/turf-boolean-touches/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# @turf/boolean-touches - - - -## booleanTouches - -Boolean-touches returns true if the first geometry is completely within the second geometry. -The interiors of both geometries must intersect and, the interior and boundary of the primary (geometry a) -must not intersect the exterior of the secondary (geometry b). - -**Parameters** - -- `feature1` **([Geometry](https://tools.ietf.org/html/rfc7946#section-3.1) \| [Feature](https://tools.ietf.org/html/rfc7946#section-3.2)<any>)** GeoJSON Feature or Geometry -- `feature2` **([Geometry](https://tools.ietf.org/html/rfc7946#section-3.1) \| [Feature](https://tools.ietf.org/html/rfc7946#section-3.2)<any>)** GeoJSON Feature or Geometry - -**Examples** - -```javascript -var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); -var point = turf.point([1, 2]); - -turf.booleanTouches(point, line); -//=true -``` - -Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** true/false - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/boolean-touches -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-boolean-touches/index.ts b/packages/turf-boolean-touches/index.ts deleted file mode 100644 index cb81b2873f..0000000000 --- a/packages/turf-boolean-touches/index.ts +++ /dev/null @@ -1,449 +0,0 @@ -import calcBbox from '@turf/bbox'; -import booleanPointOnLine from '@turf/boolean-point-on-line'; -import booleanPointInPolygon from '@turf/boolean-point-in-polygon'; -import { getGeom, getType } from '@turf/invariant'; -import { Feature, Geometry, LineString } from '@turf/helpers'; - -/** - * Boolean-touches true if none of the points common to both geometries - * intersect the interiors of both geometries. - * @name booleanTouches - * @param {Geometry|Feature} feature1 GeoJSON Feature or Geometry - * @param {Geometry|Feature} feature2 GeoJSON Feature or Geometry - * @returns {boolean} true/false - * @example - * var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); - * var point = turf.point([1, 1]); - * - * turf.booleanTouches(point, line); - * //=true - */ -function booleanTouches(feature1: Feature | Geometry, feature2: Feature | Geometry): boolean { - var geom1 = getGeom(feature1); - var geom2 = getGeom(feature2); - var type1 = geom1.type; - var type2 = geom2.type; - - switch (type1) { - case 'Point': - switch (type2) { - case 'LineString': - return isPointOnLineEnd(geom1, geom2); - case 'MultiLineString': - var foundTouchingPoint = false - for (var ii = 0; ii < geom2.coordinates.length; ii++) { - if (isPointOnLineEnd(geom1, {type: 'LineString', coordinates: geom2.coordinates[ii]})) foundTouchingPoint = true; - } - return foundTouchingPoint - case 'Polygon': - for (var i = 0; i < geom2.coordinates.length; i++) { - if (booleanPointOnLine(geom1, {type:'LineString', coordinates: geom2.coordinates[i]})) return true; - } - return false - case 'MultiPolygon': - for (var i = 0; i < geom2.coordinates.length; i++) { - for (var ii = 0; ii < geom2.coordinates[i].length; ii++) { - if (booleanPointOnLine(geom1, {type:'LineString', coordinates: geom2.coordinates[i][ii]})) return true; - } - } - return false; - default: - throw new Error('feature2 ' + type2 + ' geometry not supported'); - } - case 'MultiPoint': - switch (type2) { - case 'LineString': - var foundTouchingPoint = false; - for (var i = 0; i < geom1.coordinates.length; i++) { - if (!foundTouchingPoint) { - if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[i]}, geom2)) foundTouchingPoint = true; - } - if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i]}, geom2, {ignoreEndVertices: true})) return false; - } - return foundTouchingPoint - case 'MultiLineString': - var foundTouchingPoint = false - for (var i = 0; i < geom1.coordinates.length; i++) { - for (var ii = 0; ii < geom2.coordinates.length; ii++) { - if (!foundTouchingPoint) { - if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[i]}, {type: 'LineString', coordinates: geom2.coordinates[ii]})) foundTouchingPoint = true; - } - if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i]}, {type: 'LineString', coordinates: geom2.coordinates[ii]}, {ignoreEndVertices: true})) return false; - } - } - return foundTouchingPoint - case 'Polygon': - var foundTouchingPoint = false; - for (var i = 0; i < geom1.coordinates.length; i++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i]}, {type:'LineString', coordinates: geom2.coordinates[0]})) foundTouchingPoint = true; - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[i]}, geom2, {ignoreBoundary: true})) return false; - } - return foundTouchingPoint - case 'MultiPolygon': - var foundTouchingPoint = false; - for (var i = 0; i < geom1.coordinates.length; i++) { - for (var ii = 0; ii < geom2.coordinates.length; ii++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i]}, {type:'LineString', coordinates: geom2.coordinates[ii][0]})) foundTouchingPoint = true; - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[i]}, {type: 'Polygon', coordinates: geom2.coordinates[ii]}, {ignoreBoundary: true})) return false; - } - } - return foundTouchingPoint; - default: - throw new Error('feature2 ' + type2 + ' geometry not supported'); - } - case 'LineString': - switch (type2) { - case 'Point': - return isPointOnLineEnd(geom2, geom1); - case 'MultiPoint': - var foundTouchingPoint = false; - for (var i = 0; i < geom2.coordinates.length; i++) { - if (!foundTouchingPoint) { - if (isPointOnLineEnd({type: 'Point', coordinates: geom2.coordinates[i]}, geom1)) foundTouchingPoint = true; - } - if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[i]}, geom1, {ignoreEndVertices: true})) return false; - } - return foundTouchingPoint - case 'LineString': - var endMatch = false; - if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[0]}, geom2)) endMatch = true; - if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[geom1.coordinates.length - 1]}, geom2)) endMatch = true; - if (endMatch === false) return false; - for (var i = 0; i < geom1.coordinates.length; i++) { - if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i]}, geom2, {ignoreEndVertices: true})) return false; - } - return endMatch; - case 'MultiLineString': - var endMatch = false; - for (var i = 0; i < geom2.coordinates.length; i++) { - if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[0]}, {type:'LineString', coordinates: geom2.coordinates[i]})) endMatch = true; - if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[geom1.coordinates.length - 1]}, {type:'LineString', coordinates: geom2.coordinates[i]})) endMatch = true; - for (var ii = 0; ii < geom1.coordinates[i].length; ii++) { - if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[ii]}, {type:'LineString', coordinates: geom2.coordinates[i]}, {ignoreEndVertices: true})) return false; - } - } - return endMatch - case 'Polygon': - var foundTouchingPoint = false; - for (var i = 0; i < geom1.coordinates.length; i++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i]}, {type:'LineString', coordinates: geom2.coordinates[0]})) foundTouchingPoint = true; - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[i]}, geom2, {ignoreBoundary: true})) return false; - } - return foundTouchingPoint; - case 'MultiPolygon': - var foundTouchingPoint = false; - for (var i = 0; i < geom1.coordinates.length; i++) { - for (var ii = 0; ii < geom2.coordinates.length; ii++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i]}, {type:'LineString', coordinates: geom2.coordinates[ii][0]})) foundTouchingPoint = true; - } - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[i]}, geom2, {ignoreBoundary: true})) return false; - } - return foundTouchingPoint; - default: - throw new Error('feature2 ' + type2 + ' geometry not supported'); - } - case 'MultiLineString': - switch (type2) { - case 'Point': - for (var i = 0; i < geom1.coordinates.length; i++) { - if (isPointOnLineEnd(geom2, {type:'LineString', coordinates: geom1.coordinates[i]})) return true; - } - return false; - case 'MultiPoint': - var foundTouchingPoint = false; - for (var i = 0; i < geom1.coordinates.length; i++) { - for (var ii = 0; ii < geom2.coordinates.length; ii++) { - if (!foundTouchingPoint) { - if (isPointOnLineEnd({type: 'Point', coordinates: geom2.coordinates[ii]}, {type:'LineString', coordinates: geom1.coordinates[ii]})) foundTouchingPoint = true; - } - if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[ii]}, {type:'LineString', coordinates: geom1.coordinates[ii]}, {ignoreEndVertices: true})) return false; - } - } - return foundTouchingPoint; - case 'LineString': - var endMatch = false; - for (var i = 0; i < geom1.coordinates.length; i++) { - if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[i][0]}, geom2)) endMatch = true; - if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[i][geom1.coordinates[i].length - 1]}, geom2)) endMatch = true; - for (var ii = 0; ii < geom2.coordinates.length; ii++) { - if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[ii]}, {type:'LineString', coordinates: geom1.coordinates[i]}, {ignoreEndVertices: true})) return false; - } - } - return endMatch - case 'MultiLineString': - var endMatch = false - for (var i = 0; i < geom1.coordinates.length; i++) { - for (var ii = 0; ii < geom2.coordinates.length; ii++) { - if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[i][0]}, {type:'LineString', coordinates: geom2.coordinates[ii]})) endMatch = true - if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[i][geom1.coordinates[i].length - 1]}, {type:'LineString', coordinates: geom2.coordinates[ii]})) endMatch = true - for (var iii = 0; iii < geom1.coordinates[i].length; iii++) { - if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i][iii]}, {type:'LineString', coordinates: geom2.coordinates[ii]}, {ignoreEndVertices: true})) return false - } - } - } - return endMatch - case 'Polygon': - var foundTouchingPoint = false; - for (var i = 0; i < geom1.coordinates.length; i++) { - for (var ii = 0; ii < geom1.coordinates.length; ii++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i][ii]}, {type:'LineString', coordinates: geom2.coordinates[0]})) foundTouchingPoint = true; - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[i][ii]}, geom2, {ignoreBoundary: true})) return false; - } - } - return foundTouchingPoint - case 'MultiPolygon': - var foundTouchingPoint = false; - for (var i = 0; i < geom2.coordinates[0].length; i++) { - for (var ii = 0; ii < geom1.coordinates.length; ii++) { - for (var iii = 0; iii < geom1.coordinates[ii].length; iii++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[ii][iii]}, {type:'LineString', coordinates: geom2.coordinates[0][i]})) foundTouchingPoint = true; - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[ii][iii]}, {type:'Polygon', coordinates: [geom2.coordinates[0][i]]}, {ignoreBoundary: true})) return false; - } - } - } - return foundTouchingPoint; - default: - throw new Error('feature2 ' + type2 + ' geometry not supported'); - } - case 'Polygon': - switch (type2) { - case 'Point': - for (var i = 0; i < geom1.coordinates.length; i++) { - if (booleanPointOnLine(geom2, {type:'LineString', coordinates: geom1.coordinates[i]})) return true; - } - return false - case 'MultiPoint': - var foundTouchingPoint = false - for (var i = 0; i < geom2.coordinates.length; i++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[i]}, {type:'LineString', coordinates: geom1.coordinates[0]})) foundTouchingPoint = true; - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom2.coordinates[i]}, geom1, {ignoreBoundary: true})) return false; - } - return foundTouchingPoint; - case 'LineString': - var foundTouchingPoint = false; - for (var i = 0; i < geom2.coordinates.length; i++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[i]}, {type:'LineString', coordinates: geom1.coordinates[0]})) foundTouchingPoint = true; - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom2.coordinates[i]}, geom1, {ignoreBoundary: true})) return false; - } - return foundTouchingPoint - case 'MultiLineString': - var foundTouchingPoint = false - for (var i = 0; i < geom2.coordinates.length; i++) { - for (var ii = 0; ii < geom2.coordinates[i].length; ii++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[i][ii]}, {type:'LineString', coordinates: geom1.coordinates[0]})) foundTouchingPoint = true; - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom2.coordinates[i][ii]}, geom1, {ignoreBoundary: true})) return false; - } - } - return foundTouchingPoint - case 'Polygon': - var foundTouchingPoint = false - for (var i = 0; i < geom1.coordinates[0].length; i++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[0][i]}, {type:'LineString', coordinates: geom2.coordinates[0]})) foundTouchingPoint = true; - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[0][i]}, geom2, {ignoreBoundary: true})) return false; - } - return foundTouchingPoint - case 'MultiPolygon': - var foundTouchingPoint = false - for (var i = 0; i < geom2.coordinates[0].length; i++) { - for (var ii = 0; ii < geom1.coordinates[0].length; ii++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[0][ii]}, {type:'LineString', coordinates: geom2.coordinates[0][i]})) foundTouchingPoint = true; - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[0][ii]}, {type:'Polygon', coordinates: geom2.coordinates[0][i]}, {ignoreBoundary: true})) return false; - } - } - return foundTouchingPoint - default: - throw new Error('feature2 ' + type2 + ' geometry not supported'); - } - case 'MultiPolygon': - switch (type2) { - case 'Point': - for (var i = 0; i < geom1.coordinates[0].length; i++) { - if (booleanPointOnLine(geom2, {type:'LineString', coordinates: geom1.coordinates[0][i]})) return true; - } - return false - case 'MultiPoint': - var foundTouchingPoint = false - for (var i = 0; i < geom1.coordinates[0].length; i++) { - for (var ii = 0; ii < geom2.coordinates.length; ii++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[ii]}, {type:'LineString', coordinates: geom1.coordinates[0][i]})) foundTouchingPoint = true; - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom2.coordinates[ii]}, {type:'Polygon', coordinates: geom1.coordinates[0][i]}, {ignoreBoundary: true})) return false; - } - } - return foundTouchingPoint - case 'LineString': - var foundTouchingPoint = false - for (var i = 0; i < geom1.coordinates[0].length; i++) { - for (var ii = 0; ii < geom2.coordinates.length; ii++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[ii]}, {type:'LineString', coordinates: geom1.coordinates[0][i]})) foundTouchingPoint = true; - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom2.coordinates[ii]}, {type:'Polygon', coordinates: geom1.coordinates[0][i]}, {ignoreBoundary: true})) return false; - } - } - return foundTouchingPoint - case 'MultiLineString': - var foundTouchingPoint = false - for (var i = 0; i < geom1.coordinates.length; i++) { - for (var ii = 0; ii < geom2.coordinates.length; ii++) { - for (var iii = 0; iii < geom2.coordinates[ii].length; iii++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[ii][iii]}, {type:'LineString', coordinates: geom1.coordinates[i][0]})) foundTouchingPoint = true; - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom2.coordinates[ii][iii]}, {type:'Polygon', coordinates: [geom1.coordinates[i][0]]}, {ignoreBoundary: true})) return false; - } - } - } - - return foundTouchingPoint - case 'Polygon': - var foundTouchingPoint = false - for (var i = 0; i < geom1.coordinates[0].length; i++) { - for (var ii = 0; ii < geom1.coordinates[0][i].length; ii++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[0][i][ii]}, {type:'LineString', coordinates: geom2.coordinates[0]})) foundTouchingPoint = true; - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[0][i][ii]}, geom2, {ignoreBoundary: true})) return false; - } - } - return foundTouchingPoint - case 'MultiPolygon': - var foundTouchingPoint = false - for (var i = 0; i < geom1.coordinates[0].length; i++) { - for (var ii = 0; ii < geom2.coordinates[0].length; ii++) { - for (var iii = 0; iii < geom1.coordinates[0].length; iii++) { - if (!foundTouchingPoint) { - if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[0][i][iii]}, {type:'LineString', coordinates: geom2.coordinates[0][ii]})) foundTouchingPoint = true; - } - if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[0][i][iii]}, {type:'Polygon', coordinates: geom2.coordinates[0][ii]}, {ignoreBoundary: true})) return false; - } - } - } - return foundTouchingPoint - default: - throw new Error('feature2 ' + type2 + ' geometry not supported'); - } - default: - throw new Error('feature1 ' + type1 + ' geometry not supported'); - } -} - -function isPointOnLineEnd(point, line) { - if (compareCoords(line.coordinates[0], point.coordinates)) return true - if (compareCoords(line.coordinates[line.coordinates.length - 1], point.coordinates)) return true - return false -} - - -function isLineOnLine(lineString1, lineString2) { - for (var i = 0; i < lineString1.coordinates.length; i++) { - if (!booleanPointOnLine(lineString1.coordinates[i], lineString2)) { - return false; - } - } - return true; -} - -function isLineInPoly(linestring, polygon) { - var polyBbox = calcBbox(polygon); - var lineBbox = calcBbox(linestring); - if (!doBBoxOverlap(polyBbox, lineBbox)) { - return false; - } - var foundInsidePoint = false; - - for (var i = 0; i < linestring.coordinates.length - 1; i++) { - if (!booleanPointInPolygon(linestring.coordinates[i], polygon)) { - return false; - } - if (!foundInsidePoint) { - foundInsidePoint = booleanPointInPolygon(linestring.coordinates[i], polygon, {ignoreBoundary: true}); - } - if (!foundInsidePoint) { - var midpoint = getMidpoint(linestring.coordinates[i], linestring.coordinates[i + 1]); - foundInsidePoint = booleanPointInPolygon(midpoint, polygon, {ignoreBoundary: true}); - - } - } - return foundInsidePoint; -} - -/** - * Is Polygon2 in Polygon1 - * Only takes into account outer rings - * - * @private - * @param {Geometry|Feature} feature1 Polygon1 - * @param {Geometry|Feature} feature2 Polygon2 - * @returns {boolean} true/false - */ -function isPolyInPoly(feature1, feature2) { - var poly1Bbox = calcBbox(feature1); - var poly2Bbox = calcBbox(feature2); - if (!doBBoxOverlap(poly2Bbox, poly1Bbox)) { - return false; - } - for (var i = 0; i < feature1.coordinates[0].length; i++) { - if (!booleanPointInPolygon(feature1.coordinates[0][i], feature2)) { - return false; - } - } - return true; -} - -function doBBoxOverlap(bbox1, bbox2) { - if (bbox1[0] > bbox2[0]) return false; - if (bbox1[2] < bbox2[2]) return false; - if (bbox1[1] > bbox2[1]) return false; - if (bbox1[3] < bbox2[3]) return false; - return true; -} - -/** - * compareCoords - * - * @private - * @param {Position} pair1 point [x,y] - * @param {Position} pair2 point [x,y] - * @returns {boolean} true/false if coord pairs match - */ -function compareCoords(pair1, pair2) { - return pair1[0] === pair2[0] && pair1[1] === pair2[1]; -} - -/** - * getMidpoint - * - * @private - * @param {Position} pair1 point [x,y] - * @param {Position} pair2 point [x,y] - * @returns {Position} midpoint of pair1 and pair2 - */ -function getMidpoint(pair1, pair2) { - return [(pair1[0] + pair2[0]) / 2, (pair1[1] + pair2[1]) / 2]; -} - -export default booleanTouches; diff --git a/packages/turf-boolean-touches/package.json b/packages/turf-boolean-touches/package.json deleted file mode 100644 index 8c4188b154..0000000000 --- a/packages/turf-boolean-touches/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "@turf/boolean-touches", - "version": "6.0.1", - "description": "turf boolean-touches module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis", - "boolean", - "de-9im", - "touches", - "boolean-touches" - ], - "author": "Turf Authors", - "contributors": [ - "Rowan Winsemius <@rowanwins>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "boolean-jsts": "*", - "boolean-shapely": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/boolean-point-in-polygon": "6.x", - "@turf/boolean-point-on-line": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-boolean-touches/types.ts b/packages/turf-boolean-touches/types.ts deleted file mode 100644 index 66fa830281..0000000000 --- a/packages/turf-boolean-touches/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -import * as helpers from '@turf/helpers' -import booleanWithin from './' - -const pt = helpers.point([0, 0]) -const line = helpers.lineString([[0, 0], [10, 10]]) -booleanWithin(pt, line) \ No newline at end of file diff --git a/packages/turf-boolean-valid/.gitignore b/packages/turf-boolean-valid/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-boolean-valid/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-boolean-valid/LICENSE b/packages/turf-boolean-valid/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-boolean-valid/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-boolean-valid/README.md b/packages/turf-boolean-valid/README.md deleted file mode 100644 index 9ec7b28f6f..0000000000 --- a/packages/turf-boolean-valid/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# @turf/boolean-valid - - - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/boolean-valid -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-boolean-valid/index.ts b/packages/turf-boolean-valid/index.ts deleted file mode 100644 index 3ac8ef18c6..0000000000 --- a/packages/turf-boolean-valid/index.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { segmentEach } from '@turf/meta'; -import { getGeom, getCoords, getType } from '@turf/invariant'; -import { polygon, lineString, Feature, Geometry } from '@turf/helpers'; -import booleanDisjoint from '@turf/boolean-disjoint'; -import booleanCrosses from '@turf/boolean-crosses'; -import lineIntersect from '@turf/line-intersect'; -import isPointOnLine from '@turf/boolean-point-on-line'; - -/** - * booleanValid checks if the geometry is a valid according to the OGC Simple Feature Specification. - * - * @name booleanValid - * @param {Geometry|Feature} feature GeoJSON Feature or Geometry - * @returns {boolean} true/false - * @example - * var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); - * - * turf.booleanValid(line); // => true - * turf.booleanValid({foo: "bar"}); // => false - */ -export default function booleanValid(feature: Feature | Geometry) { - // Automatic False - if (!feature.type) return false; - - // Parse GeoJSON - const geom = getGeom(feature); - const type = geom.type; - const coords = geom.coordinates; - - switch (type) { - case 'Point': - return coords.length > 1; - case 'MultiPoint': - for (var i = 0; i < coords.length; i++) { - if (coords[i].length < 2) return false; - } - return true; - case 'LineString': - if (coords.length < 2) return false - for (var i = 0; i < coords.length; i++) { - if (coords[i].length < 2) return false; - } - return true; - case 'MultiLineString': - if (coords.length < 2) return false - for (var i = 0; i < coords.length; i++) { - if (coords[i].length < 2) return false; - } - return true; - case 'Polygon': - for (var i = 0; i < geom.coordinates.length; i++) { - if (coords[i].length < 4) return false - if (!checkRingsClose(coords[i])) return false - if (checkRingsForSpikesPunctures(coords[i])) return false - if (i > 0) { - if (lineIntersect(polygon([coords[0]]), polygon([coords[i]])).features.length > 1) return false - } - } - return true - case 'MultiPolygon': - for (var i = 0; i < geom.coordinates.length; i++) { - var poly: any = geom.coordinates[i]; - - for (var ii = 0; ii < poly.length; ii++) { - if (poly[ii].length < 4) return false - if (!checkRingsClose(poly[ii])) return false - if (checkRingsForSpikesPunctures(poly[ii])) return false - if (ii === 0) { - if (!checkPolygonAgainstOthers(poly, geom.coordinates, i)) return false - } - if (ii > 0) { - if (lineIntersect(polygon([poly[0]]), polygon([poly[ii]])).features.length > 1) return false - } - } - } - return true - default: return false; - } -} - -function checkRingsClose(geom) { - return geom[0][0] === geom[geom.length - 1][0] || geom[0][1] === geom[geom.length - 1][1] -} - -function checkRingsForSpikesPunctures(geom) { - for (var i = 0; i < geom.length - 1; i++) { - var point = geom[i] - for (var ii = i + 1; ii < geom.length - 2; ii++) { - var seg = [geom[ii], geom[ii + 1]] - if (isPointOnLine(point, lineString(seg))) return true - } - } - return false -} - -function checkPolygonAgainstOthers(poly, geom, index) { - var polyToCheck = polygon(poly) - for (var i = index + 1; i < geom.length; i++) { - if (!booleanDisjoint(polyToCheck, polygon(geom[i]))) { - if (booleanCrosses(polyToCheck, lineString(geom[i][0]))) return false - } - } - return true -} \ No newline at end of file diff --git a/packages/turf-boolean-valid/package.json b/packages/turf-boolean-valid/package.json deleted file mode 100644 index 754c0ae6df..0000000000 --- a/packages/turf-boolean-valid/package.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "name": "@turf/boolean-valid", - "version": "6.0.1", - "description": "turf boolean-valid module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "valid", - "boolean", - "ogc" - ], - "author": "Turf Authors", - "contributors": [ - "Rowan Winsemius <@rowanwins>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "boolean-jsts": "*", - "boolean-shapely": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/boolean-crosses": "6.x", - "@turf/boolean-overlap": "6.x", - "@turf/boolean-point-in-polygon": "6.x", - "@turf/boolean-point-on-line": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/line-intersect": "6.x", - "geojson-polygon-self-intersections": "1.2.x" - } -} diff --git a/packages/turf-boolean-within/.gitignore b/packages/turf-boolean-within/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-boolean-within/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-boolean-within/LICENSE b/packages/turf-boolean-within/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-boolean-within/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-boolean-within/README.md b/packages/turf-boolean-within/README.md deleted file mode 100644 index ea31d00011..0000000000 --- a/packages/turf-boolean-within/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# @turf/boolean-within - - - -## booleanWithin - -Boolean-within returns true if the first geometry is completely within the second geometry. -The interiors of both geometries must intersect and, the interior and boundary of the primary (geometry a) -must not intersect the exterior of the secondary (geometry b). -Boolean-within returns the exact opposite result of the `@turf/boolean-contains`. - -**Parameters** - -- `feature1` **([Geometry][1] \| [Feature][2]<any>)** GeoJSON Feature or Geometry -- `feature2` **([Geometry][1] \| [Feature][2]<any>)** GeoJSON Feature or Geometry - -**Examples** - -```javascript -var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); -var point = turf.point([1, 2]); - -turf.booleanWithin(point, line); -//=true -``` - -Returns **[boolean][3]** true/false - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/boolean-within -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-boolean-within/index.ts b/packages/turf-boolean-within/index.ts deleted file mode 100644 index 9af64da2cf..0000000000 --- a/packages/turf-boolean-within/index.ts +++ /dev/null @@ -1,223 +0,0 @@ -import calcBbox from '@turf/bbox'; -import booleanPointOnLine from '@turf/boolean-point-on-line'; -import booleanPointInPolygon from '@turf/boolean-point-in-polygon'; -import { getGeom, getType } from '@turf/invariant'; -import { Feature, Geometry } from '@turf/helpers'; - -/** - * Boolean-within returns true if the first geometry is completely within the second geometry. - * The interiors of both geometries must intersect and, the interior and boundary of the primary (geometry a) - * must not intersect the exterior of the secondary (geometry b). - * Boolean-within returns the exact opposite result of the `@turf/boolean-contains`. - * - * @name booleanWithin - * @param {Geometry|Feature} feature1 GeoJSON Feature or Geometry - * @param {Geometry|Feature} feature2 GeoJSON Feature or Geometry - * @returns {boolean} true/false - * @example - * var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); - * var point = turf.point([1, 2]); - * - * turf.booleanWithin(point, line); - * //=true - */ -function booleanWithin(feature1: Feature | Geometry, feature2: Feature | Geometry): boolean { - var geom1 = getGeom(feature1); - var geom2 = getGeom(feature2); - var type1 = geom1.type; - var type2 = geom2.type; - - switch (type1) { - case 'Point': - switch (type2) { - case 'MultiPoint': - return isPointInMultiPoint(geom1, geom2); - case 'LineString': - return booleanPointOnLine(geom1, geom2, {ignoreEndVertices: true}); - case 'Polygon': - case 'MultiPolygon': - return booleanPointInPolygon(geom1, geom2, {ignoreBoundary: true}); - default: - throw new Error('feature2 ' + type2 + ' geometry not supported'); - } - case 'MultiPoint': - switch (type2) { - case 'MultiPoint': - return isMultiPointInMultiPoint(geom1, geom2); - case 'LineString': - return isMultiPointOnLine(geom1, geom2); - case 'Polygon': - case 'MultiPolygon': - return isMultiPointInPoly(geom1, geom2); - default: - throw new Error('feature2 ' + type2 + ' geometry not supported'); - } - case 'LineString': - switch (type2) { - case 'LineString': - return isLineOnLine(geom1, geom2); - case 'Polygon': - case 'MultiPolygon': - return isLineInPoly(geom1, geom2); - default: - throw new Error('feature2 ' + type2 + ' geometry not supported'); - } - case 'Polygon': - switch (type2) { - case 'Polygon': - case 'MultiPolygon': - return isPolyInPoly(geom1, geom2); - default: - throw new Error('feature2 ' + type2 + ' geometry not supported'); - } - default: - throw new Error('feature1 ' + type1 + ' geometry not supported'); - } -} - -function isPointInMultiPoint(point, multiPoint) { - var i; - var output = false; - for (i = 0; i < multiPoint.coordinates.length; i++) { - if (compareCoords(multiPoint.coordinates[i], point.coordinates)) { - output = true; - break; - } - } - return output; -} - -function isMultiPointInMultiPoint(multiPoint1, multiPoint2) { - for (var i = 0; i < multiPoint1.coordinates.length; i++) { - var anyMatch = false; - for (var i2 = 0; i2 < multiPoint2.coordinates.length; i2++) { - if (compareCoords(multiPoint1.coordinates[i], multiPoint2.coordinates[i2])) { - anyMatch = true; - } - } - if (!anyMatch) { - return false; - } - } - return true; -} - -function isMultiPointOnLine(multiPoint, lineString) { - var foundInsidePoint = false; - - for (var i = 0; i < multiPoint.coordinates.length; i++) { - if (!booleanPointOnLine(multiPoint.coordinates[i], lineString)) { - return false; - } - if (!foundInsidePoint) { - foundInsidePoint = booleanPointOnLine(multiPoint.coordinates[i], lineString, {ignoreEndVertices: true}); - } - } - return foundInsidePoint; -} - -function isMultiPointInPoly(multiPoint, polygon) { - var output = true; - var oneInside = false; - for (var i = 0; i < multiPoint.coordinates.length; i++) { - var isInside = booleanPointInPolygon(multiPoint.coordinates[1], polygon); - if (!isInside) { - output = false; - break; - } - if (!oneInside) { - isInside = booleanPointInPolygon(multiPoint.coordinates[1], polygon, {ignoreBoundary: true}); - } - } - return output && isInside; -} - -function isLineOnLine(lineString1, lineString2) { - for (var i = 0; i < lineString1.coordinates.length; i++) { - if (!booleanPointOnLine(lineString1.coordinates[i], lineString2)) { - return false; - } - } - return true; -} - -function isLineInPoly(linestring, polygon) { - var polyBbox = calcBbox(polygon); - var lineBbox = calcBbox(linestring); - if (!doBBoxOverlap(polyBbox, lineBbox)) { - return false; - } - var foundInsidePoint = false; - - for (var i = 0; i < linestring.coordinates.length - 1; i++) { - if (!booleanPointInPolygon(linestring.coordinates[i], polygon)) { - return false; - } - if (!foundInsidePoint) { - foundInsidePoint = booleanPointInPolygon(linestring.coordinates[i], polygon, {ignoreBoundary: true}); - } - if (!foundInsidePoint) { - var midpoint = getMidpoint(linestring.coordinates[i], linestring.coordinates[i + 1]); - foundInsidePoint = booleanPointInPolygon(midpoint, polygon, {ignoreBoundary: true}); - - } - } - return foundInsidePoint; -} - -/** - * Is Polygon2 in Polygon1 - * Only takes into account outer rings - * - * @private - * @param {Geometry|Feature} feature1 Polygon1 - * @param {Geometry|Feature} feature2 Polygon2 - * @returns {boolean} true/false - */ -function isPolyInPoly(feature1, feature2) { - var poly1Bbox = calcBbox(feature1); - var poly2Bbox = calcBbox(feature2); - if (!doBBoxOverlap(poly2Bbox, poly1Bbox)) { - return false; - } - for (var i = 0; i < feature1.coordinates[0].length; i++) { - if (!booleanPointInPolygon(feature1.coordinates[0][i], feature2)) { - return false; - } - } - return true; -} - -function doBBoxOverlap(bbox1, bbox2) { - if (bbox1[0] > bbox2[0]) return false; - if (bbox1[2] < bbox2[2]) return false; - if (bbox1[1] > bbox2[1]) return false; - if (bbox1[3] < bbox2[3]) return false; - return true; -} - -/** - * compareCoords - * - * @private - * @param {Position} pair1 point [x,y] - * @param {Position} pair2 point [x,y] - * @returns {boolean} true/false if coord pairs match - */ -function compareCoords(pair1, pair2) { - return pair1[0] === pair2[0] && pair1[1] === pair2[1]; -} - -/** - * getMidpoint - * - * @private - * @param {Position} pair1 point [x,y] - * @param {Position} pair2 point [x,y] - * @returns {Position} midpoint of pair1 and pair2 - */ -function getMidpoint(pair1, pair2) { - return [(pair1[0] + pair2[0]) / 2, (pair1[1] + pair2[1]) / 2]; -} - -export default booleanWithin; diff --git a/packages/turf-boolean-within/package.json b/packages/turf-boolean-within/package.json deleted file mode 100644 index 8a6ba6e93d..0000000000 --- a/packages/turf-boolean-within/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "@turf/boolean-within", - "version": "6.0.1", - "description": "turf boolean-within module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis", - "boolean", - "de-9im", - "within", - "boolean-within" - ], - "author": "Turf Authors", - "contributors": [ - "Rowan Winsemius <@rowanwins>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "boolean-jsts": "*", - "boolean-shapely": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/boolean-point-in-polygon": "6.x", - "@turf/boolean-point-on-line": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-boolean-within/types.ts b/packages/turf-boolean-within/types.ts deleted file mode 100644 index 66fa830281..0000000000 --- a/packages/turf-boolean-within/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -import * as helpers from '@turf/helpers' -import booleanWithin from './' - -const pt = helpers.point([0, 0]) -const line = helpers.lineString([[0, 0], [10, 10]]) -booleanWithin(pt, line) \ No newline at end of file diff --git a/packages/turf-buffer/LICENSE b/packages/turf-buffer/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-buffer/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-buffer/README.md b/packages/turf-buffer/README.md deleted file mode 100644 index 912152468f..0000000000 --- a/packages/turf-buffer/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# @turf/buffer - - - -## buffer - -Calculates a buffer for input features for a given radius. Units supported are miles, kilometers, and degrees. - -When using a negative radius, the resulting geometry may be invalid if -it's too small compared to the radius magnitude. If the input is a -FeatureCollection, only valid members will be returned in the output -FeatureCollection - i.e., the output collection may have fewer members than -the input, or even be empty. - -**Parameters** - -- `geojson` **([FeatureCollection][1] \| [Geometry][2] \| [Feature][3]<any>)** input to be buffered -- `radius` **[number][4]** distance to draw the buffer (negative values are allowed) -- `options` **[Object][5]** Optional parameters (optional, default `{}`) - - `options.units` **[string][6]** any of the options supported by turf units (optional, default `"kilometers"`) - - `options.steps` **[number][4]** number of steps (optional, default `64`) - -**Examples** - -```javascript -var point = turf.point([-90.548630, 14.616599]); -var buffered = turf.buffer(point, 500, {units: 'miles'}); - -//addToMap -var addToMap = [point, buffered] -``` - -Returns **([FeatureCollection][1] \| [Feature][3]<([Polygon][7] \| [MultiPolygon][8])> | [undefined][9])** buffered features - -[1]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[8]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/buffer -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-buffer/bench.js b/packages/turf-buffer/bench.js deleted file mode 100644 index 164c9e67ec..0000000000 --- a/packages/turf-buffer/bench.js +++ /dev/null @@ -1,54 +0,0 @@ -import fs from 'fs'; -import path from 'path'; -import load from 'load-json-file'; -import Benchmark from 'benchmark'; -import buffer from './'; - -const directory = path.join(__dirname, 'test', 'in') + path.sep; -const fixtures = fs.readdirSync(directory).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directory + filename) - }; -}); - -/** - * Benchmark Results - * - * feature-collection-points: 139.101ms - * geometry-collection-points: 20.334ms - * issue-#783: 33.209ms - * linestring: 6.371ms - * multi-linestring: 48.786ms - * multi-point: 7.627ms - * multi-polygon: 38.921ms - * negative-buffer: 5.621ms - * north-latitude-points: 71.144ms - * northern-polygon: 2.644ms - * point: 8.155ms - * polygon-with-holes: 6.965ms - * feature-collection-points x 722 ops/sec ±14.28% (65 runs sampled) - * geometry-collection-points x 1,314 ops/sec ±7.87% (66 runs sampled) - * issue-#783 x 1,404 ops/sec ±6.81% (64 runs sampled) - * linestring x 2,936 ops/sec ±6.94% (72 runs sampled) - * multi-linestring x 623 ops/sec ±4.35% (79 runs sampled) - * multi-point x 1,735 ops/sec ±8.60% (65 runs sampled) - * multi-polygon x 1,125 ops/sec ±3.93% (80 runs sampled) - * north-latitude-points x 1,649 ops/sec ±2.09% (86 runs sampled) - * northern-polygon x 4,658 ops/sec ±3.08% (78 runs sampled) - * point x 65,020 ops/sec ±1.29% (85 runs sampled) - * polygon-with-holes x 2,795 ops/sec ±2.98% (81 runs sampled) - */ -const suite = new Benchmark.Suite('turf-buffer'); -for (const {name, geojson} of fixtures) { - console.time(name); - buffer(geojson, 50, 'miles'); - console.timeEnd(name); - suite.add(name, () => buffer(geojson, 50, 'miles')); -} - -suite - .on('cycle', e => console.log(String(e.target))) - .on('complete', () => {}) - .run(); diff --git a/packages/turf-buffer/index.d.ts b/packages/turf-buffer/index.d.ts deleted file mode 100644 index 51927e650c..0000000000 --- a/packages/turf-buffer/index.d.ts +++ /dev/null @@ -1,31 +0,0 @@ - -import { - Point, - LineString, - Polygon, - MultiPoint, - MultiLineString, - MultiPolygon, - GeometryObject, - GeometryCollection, - Feature, - FeatureCollection, - Units, -} from '@turf/helpers'; - -interface Options { - units?: Units; - steps?: number -} - -/** - * http://turfjs.org/docs/#buffer - */ -declare function buffer(feature: Feature|Geom, radius?: number, options?: Options): Feature; -declare function buffer(feature: Feature|Geom, radius?: number, options?: Options): Feature; -declare function buffer(feature: FeatureCollection, radius?: number, options?: Options): FeatureCollection; -declare function buffer(feature: FeatureCollection, radius?: number, options?: Options): FeatureCollection; -declare function buffer(feature: FeatureCollection | Feature | GeometryCollection, radius?: number, options?: Options): FeatureCollection; -declare function buffer(feature: Feature | GeometryObject, radius?: number, options?: Options): Feature; - -export default buffer; diff --git a/packages/turf-buffer/index.js b/packages/turf-buffer/index.js deleted file mode 100644 index 4666c81053..0000000000 --- a/packages/turf-buffer/index.js +++ /dev/null @@ -1,194 +0,0 @@ -import center from '@turf/center'; -import turfBbox from '@turf/bbox'; -import { BufferOp, GeoJSONReader, GeoJSONWriter } from 'turf-jsts'; -import { toWgs84, toMercator } from '@turf/projection'; -import { geomEach, featureEach } from '@turf/meta'; -import { geoTransverseMercator } from 'd3-geo'; -import { feature, featureCollection, radiansToLength, lengthToRadians, earthRadius } from '@turf/helpers'; - -/** - * Calculates a buffer for input features for a given radius. Units supported are miles, kilometers, and degrees. - * - * When using a negative radius, the resulting geometry may be invalid if - * it's too small compared to the radius magnitude. If the input is a - * FeatureCollection, only valid members will be returned in the output - * FeatureCollection - i.e., the output collection may have fewer members than - * the input, or even be empty. - * - * @name buffer - * @param {FeatureCollection|Geometry|Feature} geojson input to be buffered - * @param {number} radius distance to draw the buffer (negative values are allowed) - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units="kilometers"] any of the options supported by turf units - * @param {number} [options.steps=64] number of steps - * @returns {FeatureCollection|Feature|undefined} buffered features - * @example - * var point = turf.point([-90.548630, 14.616599]); - * var buffered = turf.buffer(point, 500, {units: 'miles'}); - * - * //addToMap - * var addToMap = [point, buffered] - */ -function buffer(geojson, radius, options) { - // Optional params - options = options || {}; - var units = options.units; - var steps = options.steps || 64; - - // validation - if (!geojson) throw new Error('geojson is required'); - if (typeof options !== 'object') throw new Error('options must be an object'); - if (typeof steps !== 'number') throw new Error('steps must be an number'); - - // Allow negative buffers ("erosion") or zero-sized buffers ("repair geometry") - if (radius === undefined) throw new Error('radius is required'); - if (steps <= 0) throw new Error('steps must be greater than 0'); - - // default params - steps = steps || 64; - units = units || 'kilometers'; - - var results = []; - switch (geojson.type) { - case 'GeometryCollection': - geomEach(geojson, function (geometry) { - var buffered = bufferFeature(geometry, radius, units, steps); - if (buffered) results.push(buffered); - }); - return featureCollection(results); - case 'FeatureCollection': - featureEach(geojson, function (feature) { - var multiBuffered = bufferFeature(feature, radius, units, steps); - if (multiBuffered) { - featureEach(multiBuffered, function (buffered) { - if (buffered) results.push(buffered); - }); - } - }); - return featureCollection(results); - } - return bufferFeature(geojson, radius, units, steps); -} - -/** - * Buffer single Feature/Geometry - * - * @private - * @param {Feature} geojson input to be buffered - * @param {number} radius distance to draw the buffer - * @param {string} [units='kilometers'] any of the options supported by turf units - * @param {number} [steps=64] number of steps - * @returns {Feature} buffered feature - */ -function bufferFeature(geojson, radius, units, steps) { - var properties = geojson.properties || {}; - var geometry = (geojson.type === 'Feature') ? geojson.geometry : geojson; - - // Geometry Types faster than jsts - if (geometry.type === 'GeometryCollection') { - var results = []; - geomEach(geojson, function (geometry) { - var buffered = bufferFeature(geometry, radius, units, steps); - if (buffered) results.push(buffered); - }); - return featureCollection(results); - } - - // Project GeoJSON to Transverse Mercator projection (convert to Meters) - var projected; - var bbox = turfBbox(geojson); - var needsTransverseMercator = bbox[1] > 50 && bbox[3] > 50; - - if (needsTransverseMercator) { - projected = { - type: geometry.type, - coordinates: projectCoords(geometry.coordinates, defineProjection(geometry)) - }; - } else { - projected = toMercator(geometry); - } - - // JSTS buffer operation - var reader = new GeoJSONReader(); - var geom = reader.read(projected); - var distance = radiansToLength(lengthToRadians(radius, units), 'meters'); - var buffered = BufferOp.bufferOp(geom, distance); - var writer = new GeoJSONWriter(); - buffered = writer.write(buffered); - - // Detect if empty geometries - if (coordsIsNaN(buffered.coordinates)) return undefined; - - // Unproject coordinates (convert to Degrees) - var result; - if (needsTransverseMercator) { - result = { - type: buffered.type, - coordinates: unprojectCoords(buffered.coordinates, defineProjection(geometry)) - }; - } else { - result = toWgs84(buffered); - } - - return (result.geometry) ? result : feature(result, properties); -} - -/** - * Coordinates isNaN - * - * @private - * @param {Array} coords GeoJSON Coordinates - * @returns {boolean} if NaN exists - */ -function coordsIsNaN(coords) { - if (Array.isArray(coords[0])) return coordsIsNaN(coords[0]); - return isNaN(coords[0]); -} - -/** - * Project coordinates to projection - * - * @private - * @param {Array} coords to project - * @param {GeoProjection} proj D3 Geo Projection - * @returns {Array} projected coordinates - */ -function projectCoords(coords, proj) { - if (typeof coords[0] !== 'object') return proj(coords); - return coords.map(function (coord) { - return projectCoords(coord, proj); - }); -} - -/** - * Un-Project coordinates to projection - * - * @private - * @param {Array} coords to un-project - * @param {GeoProjection} proj D3 Geo Projection - * @returns {Array} un-projected coordinates - */ -function unprojectCoords(coords, proj) { - if (typeof coords[0] !== 'object') return proj.invert(coords); - return coords.map(function (coord) { - return unprojectCoords(coord, proj); - }); -} - -/** - * Define Transverse Mercator projection - * - * @private - * @param {Geometry|Feature} geojson Base projection on center of GeoJSON - * @returns {GeoProjection} D3 Geo Transverse Mercator Projection - */ -function defineProjection(geojson) { - var coords = center(geojson).geometry.coordinates.reverse(); - var rotate = coords.map(function (coord) { return -coord; }); - return geoTransverseMercator() - .center(coords) - .rotate(rotate) - .scale(earthRadius); -} - -export default buffer; diff --git a/packages/turf-buffer/package.json b/packages/turf-buffer/package.json deleted file mode 100644 index 3873d72b48..0000000000 --- a/packages/turf-buffer/package.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "@turf/buffer", - "version": "5.1.5", - "description": "turf buffer module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "buffer", - "offset", - "polygon", - "linestring", - "point", - "geojson", - "turf" - ], - "author": "Turf Authors", - "contributors": [ - "Tom MacWright <@tmcw>", - "Denis Carriere <@DenisCarriere>", - "Stefano Borghi <@stebogit>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/truncate": "*", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/center": "6.x", - "@turf/helpers": "6.x", - "@turf/meta": "6.x", - "@turf/projection": "6.x", - "d3-geo": "1.7.1", - "turf-jsts": "*" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-buffer/test.js b/packages/turf-buffer/test.js deleted file mode 100644 index eff9485eef..0000000000 --- a/packages/turf-buffer/test.js +++ /dev/null @@ -1,105 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import truncate from '@turf/truncate'; -import { featureEach } from '@turf/meta'; -import { featureCollection, point, polygon, geometryCollection } from '@turf/helpers'; -import buffer from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -var fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); -// fixtures = fixtures.filter(({name}) => name === 'feature-collection-points'); - -test('turf-buffer', t => { - fixtures.forEach(fixture => { - const filename = fixture.filename; - const name = fixture.name; - const geojson = fixture.geojson; - const properties = geojson.properties || {}; - const radius = properties.radius || 50; - const units = properties.units || 'miles'; - const steps = properties.steps; - - const buffered = truncate(buffer(geojson, radius, {units: units, steps: steps})); - - // Add Results to FeatureCollection - const results = featureCollection([]); - featureEach(buffered, feature => results.features.push(colorize(feature, '#F00'))); - featureEach(geojson, feature => results.features.push(colorize(feature, '#00F'))); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEqual(results, load.sync(directories.out + filename), name); - }); - t.end(); -}); - -// https://github.com/Turfjs/turf/pull/736 -test('turf-buffer - Support Negative Buffer', t => { - const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); - - t.assert(buffer(poly, -50), 'allow negative buffer param'); - t.end(); -}); - -test('turf-buffer - Support Geometry Objects', t => { - const pt = point([61, 5]); - const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); - const gc = geometryCollection([pt.geometry, poly.geometry]); - - t.assert(buffer(gc, 10), 'support Geometry Collection'); - t.assert(buffer(pt.geometry, 10), 'support Point Geometry'); - t.assert(buffer(poly.geometry, 10), 'support Polygon Geometry'); - t.end(); -}); - -test('turf-buffer - Prevent Input Mutation', t => { - const pt = point([61, 5]); - const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); - const collection = featureCollection([pt, poly]); - - const beforePt = JSON.parse(JSON.stringify(pt)); - const beforePoly = JSON.parse(JSON.stringify(poly)); - const beforeCollection = JSON.parse(JSON.stringify(collection)); - - buffer(pt, 10); - buffer(poly, 10); - buffer(collection, 10); - - t.deepEqual(pt, beforePt, 'pt should not mutate'); - t.deepEqual(poly, beforePoly, 'poly should not mutate'); - t.deepEqual(collection, beforeCollection, 'collection should not mutate'); - t.end(); -}); - -// https://github.com/Turfjs/turf/issues/745 -// https://github.com/Turfjs/turf/pull/736#issuecomment-301937747 -test('turf-buffer - morphological closing', t => { - const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); - - t.equal(buffer(poly, -500, {units: 'miles'}), undefined, 'empty geometry should be undefined'); - t.deepEqual(buffer(featureCollection([poly]), -500, {units: 'miles'}), featureCollection([]), 'empty geometries should be an empty FeatureCollection'); - t.end(); -}); - -function colorize(feature, color) { - color = color || '#F00'; - if (feature.properties) { - feature.properties.stroke = color; - feature.properties.fill = color; - feature.properties['marker-color'] = color; - feature.properties['fill-opacity'] = 0.3; - } - return feature; -} diff --git a/packages/turf-buffer/test/in/issue-#801-Ecuador.geojson b/packages/turf-buffer/test/in/issue-#801-Ecuador.geojson deleted file mode 100644 index aafa4a6186..0000000000 --- a/packages/turf-buffer/test/in/issue-#801-Ecuador.geojson +++ /dev/null @@ -1,51 +0,0 @@ -{ - "type": "FeatureCollection", - "properties": { - "radius": 1, - "units": "miles" - }, - "features": [ - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Point", - "coordinates": [ - -78.50966334342957, - -0.22245649236909099 - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -78.5096874833107, - -0.22245917455788858 - ], - [ - -78.50966066122055, - -0.22246453893548376 - ], - [ - -78.5096526145935, - -0.2224484458026982 - ], - [ - -78.50967675447464, - -0.2224403992362927 - ], - [ - -78.5096874833107, - -0.22245917455788858 - ] - ] - ] - } - } - ] -} \ No newline at end of file diff --git a/packages/turf-buffer/test/out/feature-collection-points.geojson b/packages/turf-buffer/test/out/feature-collection-points.geojson deleted file mode 100644 index 8dfef9f8f8..0000000000 --- a/packages/turf-buffer/test/out/feature-collection-points.geojson +++ /dev/null @@ -1,849 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "marker-color": "#F00", - "stroke": "#F00", - "fill": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - 135.722849, - -25 - ], - [ - 135.70896, - -25.127742 - ], - [ - 135.667826, - -25.250449 - ], - [ - 135.601027, - -25.363426 - ], - [ - 135.511132, - -25.462365 - ], - [ - 135.401593, - -25.543502 - ], - [ - 135.276622, - -25.603756 - ], - [ - 135.141021, - -25.640845 - ], - [ - 135, - -25.653366 - ], - [ - 134.858979, - -25.640845 - ], - [ - 134.723378, - -25.603756 - ], - [ - 134.598407, - -25.543502 - ], - [ - 134.488868, - -25.462365 - ], - [ - 134.398973, - -25.363426 - ], - [ - 134.332174, - -25.250449 - ], - [ - 134.29104, - -25.127742 - ], - [ - 134.277151, - -25 - ], - [ - 134.29104, - -24.872125 - ], - [ - 134.332174, - -24.74904 - ], - [ - 134.398973, - -24.635496 - ], - [ - 134.488868, - -24.535888 - ], - [ - 134.598407, - -24.454083 - ], - [ - 134.723378, - -24.393263 - ], - [ - 134.858979, - -24.355795 - ], - [ - 135, - -24.343141 - ], - [ - 135.141021, - -24.355795 - ], - [ - 135.276622, - -24.393263 - ], - [ - 135.401593, - -24.454083 - ], - [ - 135.511132, - -24.535888 - ], - [ - 135.601027, - -24.635496 - ], - [ - 135.667826, - -24.74904 - ], - [ - 135.70896, - -24.872125 - ], - [ - 135.722849, - -25 - ] - ] - ], - [ - [ - [ - 130.722849, - -20 - ], - [ - 130.70896, - -20.13246 - ], - [ - 130.667826, - -20.259725 - ], - [ - 130.601027, - -20.37692 - ], - [ - 130.511132, - -20.479569 - ], - [ - 130.401593, - -20.56376 - ], - [ - 130.276622, - -20.626289 - ], - [ - 130.141021, - -20.664782 - ], - [ - 130, - -20.677777 - ], - [ - 129.858979, - -20.664782 - ], - [ - 129.723378, - -20.626289 - ], - [ - 129.598407, - -20.56376 - ], - [ - 129.488868, - -20.479569 - ], - [ - 129.398973, - -20.37692 - ], - [ - 129.332174, - -20.259725 - ], - [ - 129.29104, - -20.13246 - ], - [ - 129.277151, - -20 - ], - [ - 129.29104, - -19.867428 - ], - [ - 129.332174, - -19.739846 - ], - [ - 129.398973, - -19.622176 - ], - [ - 129.488868, - -19.518966 - ], - [ - 129.598407, - -19.434214 - ], - [ - 129.723378, - -19.371209 - ], - [ - 129.858979, - -19.332399 - ], - [ - 130, - -19.319292 - ], - [ - 130.141021, - -19.332399 - ], - [ - 130.276622, - -19.371209 - ], - [ - 130.401593, - -19.434214 - ], - [ - 130.511132, - -19.518966 - ], - [ - 130.601027, - -19.622176 - ], - [ - 130.667826, - -19.739846 - ], - [ - 130.70896, - -19.867428 - ], - [ - 130.722849, - -20 - ] - ] - ], - [ - [ - [ - 125.5, - -24.527577 - ], - [ - 125.598407, - -24.454083 - ], - [ - 125.723378, - -24.393263 - ], - [ - 125.858979, - -24.355795 - ], - [ - 126, - -24.343141 - ], - [ - 126.141021, - -24.355795 - ], - [ - 126.276622, - -24.393263 - ], - [ - 126.401593, - -24.454083 - ], - [ - 126.511132, - -24.535888 - ], - [ - 126.601027, - -24.635496 - ], - [ - 126.667826, - -24.74904 - ], - [ - 126.70896, - -24.872125 - ], - [ - 126.722849, - -25 - ], - [ - 126.70896, - -25.127742 - ], - [ - 126.667826, - -25.250449 - ], - [ - 126.601027, - -25.363426 - ], - [ - 126.511132, - -25.462365 - ], - [ - 126.401593, - -25.543502 - ], - [ - 126.276622, - -25.603756 - ], - [ - 126.141021, - -25.640845 - ], - [ - 126, - -25.653366 - ], - [ - 125.858979, - -25.640845 - ], - [ - 125.723378, - -25.603756 - ], - [ - 125.598407, - -25.543502 - ], - [ - 125.5, - -25.470613 - ], - [ - 125.401593, - -25.543502 - ], - [ - 125.276622, - -25.603756 - ], - [ - 125.141021, - -25.640845 - ], - [ - 125, - -25.653366 - ], - [ - 124.858979, - -25.640845 - ], - [ - 124.723378, - -25.603756 - ], - [ - 124.598407, - -25.543502 - ], - [ - 124.488868, - -25.462365 - ], - [ - 124.398973, - -25.363426 - ], - [ - 124.332174, - -25.250449 - ], - [ - 124.29104, - -25.127742 - ], - [ - 124.277151, - -25 - ], - [ - 124.29104, - -24.872125 - ], - [ - 124.332174, - -24.74904 - ], - [ - 124.398973, - -24.635496 - ], - [ - 124.488868, - -24.535888 - ], - [ - 124.598407, - -24.454083 - ], - [ - 124.723378, - -24.393263 - ], - [ - 124.858979, - -24.355795 - ], - [ - 125, - -24.343141 - ], - [ - 125.141021, - -24.355795 - ], - [ - 125.276622, - -24.393263 - ], - [ - 125.401593, - -24.454083 - ], - [ - 125.5, - -24.527577 - ] - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#F00", - "stroke": "#F00", - "fill": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 130.722849, - -27.5 - ], - [ - 130.70896, - -27.625016 - ], - [ - 130.667826, - -27.745093 - ], - [ - 130.601027, - -27.85564 - ], - [ - 130.511132, - -27.952442 - ], - [ - 130.401593, - -28.031821 - ], - [ - 130.276622, - -28.090767 - ], - [ - 130.141021, - -28.127049 - ], - [ - 130, - -28.139298 - ], - [ - 129.858979, - -28.127049 - ], - [ - 129.723378, - -28.090767 - ], - [ - 129.598407, - -28.031821 - ], - [ - 129.488868, - -27.952442 - ], - [ - 129.398973, - -27.85564 - ], - [ - 129.332174, - -27.745093 - ], - [ - 129.29104, - -27.625016 - ], - [ - 129.277151, - -27.5 - ], - [ - 129.29104, - -27.374842 - ], - [ - 129.332174, - -27.25436 - ], - [ - 129.398973, - -27.143207 - ], - [ - 129.488868, - -27.04569 - ], - [ - 129.598407, - -26.965597 - ], - [ - 129.723378, - -26.906045 - ], - [ - 129.858979, - -26.869358 - ], - [ - 130, - -26.856967 - ], - [ - 130.141021, - -26.869358 - ], - [ - 130.276622, - -26.906045 - ], - [ - 130.401593, - -26.965597 - ], - [ - 130.511132, - -27.04569 - ], - [ - 130.601027, - -27.143207 - ], - [ - 130.667826, - -27.25436 - ], - [ - 130.70896, - -27.374842 - ], - [ - 130.722849, - -27.5 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#F00", - "stroke": "#F00", - "fill": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 126.722849, - -24.5 - ], - [ - 126.70896, - -24.628258 - ], - [ - 126.667826, - -24.751463 - ], - [ - 126.601027, - -24.864901 - ], - [ - 126.511132, - -24.964246 - ], - [ - 126.401593, - -25.045715 - ], - [ - 126.276622, - -25.106218 - ], - [ - 126.141021, - -25.14346 - ], - [ - 126, - -25.156033 - ], - [ - 125.858979, - -25.14346 - ], - [ - 125.723378, - -25.106218 - ], - [ - 125.598407, - -25.045715 - ], - [ - 125.488868, - -24.964246 - ], - [ - 125.398973, - -24.864901 - ], - [ - 125.332174, - -24.751463 - ], - [ - 125.29104, - -24.628258 - ], - [ - 125.277151, - -24.5 - ], - [ - 125.29104, - -24.371611 - ], - [ - 125.332174, - -24.248033 - ], - [ - 125.398973, - -24.134036 - ], - [ - 125.488868, - -24.034034 - ], - [ - 125.598407, - -23.951906 - ], - [ - 125.723378, - -23.890845 - ], - [ - 125.858979, - -23.85323 - ], - [ - 126, - -23.840526 - ], - [ - 126.141021, - -23.85323 - ], - [ - 126.276622, - -23.890845 - ], - [ - 126.401593, - -23.951906 - ], - [ - 126.511132, - -24.034034 - ], - [ - 126.601027, - -24.134036 - ], - [ - 126.667826, - -24.248033 - ], - [ - 126.70896, - -24.371611 - ], - [ - 126.722849, - -24.5 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "stroke": "#00F", - "fill": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "MultiPoint", - "coordinates": [ - [ - 135, - -25 - ], - [ - 130, - -20 - ], - [ - 125, - -25 - ], - [ - 126, - -25 - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "stroke": "#00F", - "fill": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Point", - "coordinates": [ - 130, - -27.5 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "stroke": "#00F", - "fill": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Point", - "coordinates": [ - 126, - -24.5 - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/geometry-collection-points.geojson b/packages/turf-buffer/test/out/geometry-collection-points.geojson deleted file mode 100644 index cff6091e40..0000000000 --- a/packages/turf-buffer/test/out/geometry-collection-points.geojson +++ /dev/null @@ -1,575 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - 135.722849, - -25 - ], - [ - 135.70896, - -25.127742 - ], - [ - 135.667826, - -25.250449 - ], - [ - 135.601027, - -25.363426 - ], - [ - 135.511132, - -25.462365 - ], - [ - 135.401593, - -25.543502 - ], - [ - 135.276622, - -25.603756 - ], - [ - 135.141021, - -25.640845 - ], - [ - 135, - -25.653366 - ], - [ - 134.858979, - -25.640845 - ], - [ - 134.723378, - -25.603756 - ], - [ - 134.598407, - -25.543502 - ], - [ - 134.488868, - -25.462365 - ], - [ - 134.398973, - -25.363426 - ], - [ - 134.332174, - -25.250449 - ], - [ - 134.29104, - -25.127742 - ], - [ - 134.277151, - -25 - ], - [ - 134.29104, - -24.872125 - ], - [ - 134.332174, - -24.74904 - ], - [ - 134.398973, - -24.635496 - ], - [ - 134.488868, - -24.535888 - ], - [ - 134.598407, - -24.454083 - ], - [ - 134.723378, - -24.393263 - ], - [ - 134.858979, - -24.355795 - ], - [ - 135, - -24.343141 - ], - [ - 135.141021, - -24.355795 - ], - [ - 135.276622, - -24.393263 - ], - [ - 135.401593, - -24.454083 - ], - [ - 135.511132, - -24.535888 - ], - [ - 135.601027, - -24.635496 - ], - [ - 135.667826, - -24.74904 - ], - [ - 135.70896, - -24.872125 - ], - [ - 135.722849, - -25 - ] - ] - ], - [ - [ - [ - 130.722849, - -20 - ], - [ - 130.70896, - -20.13246 - ], - [ - 130.667826, - -20.259725 - ], - [ - 130.601027, - -20.37692 - ], - [ - 130.511132, - -20.479569 - ], - [ - 130.401593, - -20.56376 - ], - [ - 130.276622, - -20.626289 - ], - [ - 130.141021, - -20.664782 - ], - [ - 130, - -20.677777 - ], - [ - 129.858979, - -20.664782 - ], - [ - 129.723378, - -20.626289 - ], - [ - 129.598407, - -20.56376 - ], - [ - 129.488868, - -20.479569 - ], - [ - 129.398973, - -20.37692 - ], - [ - 129.332174, - -20.259725 - ], - [ - 129.29104, - -20.13246 - ], - [ - 129.277151, - -20 - ], - [ - 129.29104, - -19.867428 - ], - [ - 129.332174, - -19.739846 - ], - [ - 129.398973, - -19.622176 - ], - [ - 129.488868, - -19.518966 - ], - [ - 129.598407, - -19.434214 - ], - [ - 129.723378, - -19.371209 - ], - [ - 129.858979, - -19.332399 - ], - [ - 130, - -19.319292 - ], - [ - 130.141021, - -19.332399 - ], - [ - 130.276622, - -19.371209 - ], - [ - 130.401593, - -19.434214 - ], - [ - 130.511132, - -19.518966 - ], - [ - 130.601027, - -19.622176 - ], - [ - 130.667826, - -19.739846 - ], - [ - 130.70896, - -19.867428 - ], - [ - 130.722849, - -20 - ] - ] - ], - [ - [ - [ - 125.722849, - -25 - ], - [ - 125.70896, - -25.127742 - ], - [ - 125.667826, - -25.250449 - ], - [ - 125.601027, - -25.363426 - ], - [ - 125.511132, - -25.462365 - ], - [ - 125.401593, - -25.543502 - ], - [ - 125.276622, - -25.603756 - ], - [ - 125.141021, - -25.640845 - ], - [ - 125, - -25.653366 - ], - [ - 124.858979, - -25.640845 - ], - [ - 124.723378, - -25.603756 - ], - [ - 124.598407, - -25.543502 - ], - [ - 124.488868, - -25.462365 - ], - [ - 124.398973, - -25.363426 - ], - [ - 124.332174, - -25.250449 - ], - [ - 124.29104, - -25.127742 - ], - [ - 124.277151, - -25 - ], - [ - 124.29104, - -24.872125 - ], - [ - 124.332174, - -24.74904 - ], - [ - 124.398973, - -24.635496 - ], - [ - 124.488868, - -24.535888 - ], - [ - 124.598407, - -24.454083 - ], - [ - 124.723378, - -24.393263 - ], - [ - 124.858979, - -24.355795 - ], - [ - 125, - -24.343141 - ], - [ - 125.141021, - -24.355795 - ], - [ - 125.276622, - -24.393263 - ], - [ - 125.401593, - -24.454083 - ], - [ - 125.511132, - -24.535888 - ], - [ - 125.601027, - -24.635496 - ], - [ - 125.667826, - -24.74904 - ], - [ - 125.70896, - -24.872125 - ], - [ - 125.722849, - -25 - ] - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 130.722849, - -27.5 - ], - [ - 130.70896, - -27.625016 - ], - [ - 130.667826, - -27.745093 - ], - [ - 130.601027, - -27.85564 - ], - [ - 130.511132, - -27.952442 - ], - [ - 130.401593, - -28.031821 - ], - [ - 130.276622, - -28.090767 - ], - [ - 130.141021, - -28.127049 - ], - [ - 130, - -28.139298 - ], - [ - 129.858979, - -28.127049 - ], - [ - 129.723378, - -28.090767 - ], - [ - 129.598407, - -28.031821 - ], - [ - 129.488868, - -27.952442 - ], - [ - 129.398973, - -27.85564 - ], - [ - 129.332174, - -27.745093 - ], - [ - 129.29104, - -27.625016 - ], - [ - 129.277151, - -27.5 - ], - [ - 129.29104, - -27.374842 - ], - [ - 129.332174, - -27.25436 - ], - [ - 129.398973, - -27.143207 - ], - [ - 129.488868, - -27.04569 - ], - [ - 129.598407, - -26.965597 - ], - [ - 129.723378, - -26.906045 - ], - [ - 129.858979, - -26.869358 - ], - [ - 130, - -26.856967 - ], - [ - 130.141021, - -26.869358 - ], - [ - 130.276622, - -26.906045 - ], - [ - 130.401593, - -26.965597 - ], - [ - 130.511132, - -27.04569 - ], - [ - 130.601027, - -27.143207 - ], - [ - 130.667826, - -27.25436 - ], - [ - 130.70896, - -27.374842 - ], - [ - 130.722849, - -27.5 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/issue-#783.geojson b/packages/turf-buffer/test/out/issue-#783.geojson deleted file mode 100644 index b484488da3..0000000000 --- a/packages/turf-buffer/test/out/issue-#783.geojson +++ /dev/null @@ -1,557 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.946688, - 52.509481 - ], - [ - 4.946741, - 52.50946 - ], - [ - 4.947205, - 52.509314 - ], - [ - 4.947217, - 52.50931 - ], - [ - 4.947287, - 52.50929 - ], - [ - 4.947357, - 52.509276 - ], - [ - 4.947691, - 52.509232 - ], - [ - 4.947754, - 52.509227 - ], - [ - 4.947817, - 52.50923 - ], - [ - 4.947878, - 52.50924 - ], - [ - 4.947935, - 52.509257 - ], - [ - 4.947985, - 52.50928 - ], - [ - 4.948027, - 52.509309 - ], - [ - 4.948059, - 52.509342 - ], - [ - 4.948081, - 52.509378 - ], - [ - 4.94809, - 52.509416 - ], - [ - 4.948088, - 52.509455 - ], - [ - 4.948074, - 52.509492 - ], - [ - 4.948048, - 52.509527 - ], - [ - 4.948012, - 52.509559 - ], - [ - 4.947966, - 52.509585 - ], - [ - 4.947913, - 52.509606 - ], - [ - 4.947483, - 52.509742 - ], - [ - 4.947457, - 52.50975 - ], - [ - 4.946862, - 52.5099 - ], - [ - 4.946802, - 52.509911 - ], - [ - 4.94674, - 52.509915 - ], - [ - 4.946677, - 52.509912 - ], - [ - 4.946616, - 52.509901 - ], - [ - 4.94656, - 52.509884 - ], - [ - 4.94651, - 52.509861 - ], - [ - 4.946469, - 52.509832 - ], - [ - 4.946437, - 52.509799 - ], - [ - 4.946416, - 52.509763 - ], - [ - 4.946406, - 52.509725 - ], - [ - 4.946409, - 52.509687 - ], - [ - 4.946423, - 52.50965 - ], - [ - 4.946449, - 52.509615 - ], - [ - 4.946485, - 52.509583 - ], - [ - 4.946531, - 52.509557 - ], - [ - 4.946688, - 52.509481 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.946985, - 52.509846 - ], - [ - 4.946938, - 52.509873 - ], - [ - 4.946884, - 52.509894 - ], - [ - 4.946823, - 52.509908 - ], - [ - 4.946759, - 52.509914 - ], - [ - 4.946695, - 52.509913 - ], - [ - 4.946632, - 52.509905 - ], - [ - 4.946572, - 52.509888 - ], - [ - 4.94652, - 52.509866 - ], - [ - 4.946475, - 52.509837 - ], - [ - 4.946441, - 52.509804 - ], - [ - 4.946418, - 52.509767 - ], - [ - 4.946407, - 52.509728 - ], - [ - 4.946409, - 52.509689 - ], - [ - 4.946423, - 52.50965 - ], - [ - 4.946449, - 52.509614 - ], - [ - 4.946487, - 52.509582 - ], - [ - 4.946534, - 52.509555 - ], - [ - 4.946588, - 52.509534 - ], - [ - 4.946649, - 52.50952 - ], - [ - 4.946713, - 52.509514 - ], - [ - 4.946777, - 52.509515 - ], - [ - 4.94684, - 52.509523 - ], - [ - 4.9469, - 52.50954 - ], - [ - 4.946952, - 52.509562 - ], - [ - 4.946997, - 52.509591 - ], - [ - 4.947031, - 52.509624 - ], - [ - 4.947054, - 52.509661 - ], - [ - 4.947065, - 52.5097 - ], - [ - 4.947063, - 52.509739 - ], - [ - 4.947049, - 52.509778 - ], - [ - 4.947023, - 52.509814 - ], - [ - 4.946985, - 52.509846 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.94801, - 52.50956 - ], - [ - 4.947963, - 52.509587 - ], - [ - 4.947909, - 52.509608 - ], - [ - 4.947848, - 52.509622 - ], - [ - 4.947784, - 52.509628 - ], - [ - 4.94772, - 52.509627 - ], - [ - 4.947657, - 52.509619 - ], - [ - 4.947597, - 52.509602 - ], - [ - 4.947545, - 52.50958 - ], - [ - 4.9475, - 52.509551 - ], - [ - 4.947466, - 52.509518 - ], - [ - 4.947443, - 52.509481 - ], - [ - 4.947432, - 52.509442 - ], - [ - 4.947434, - 52.509403 - ], - [ - 4.947448, - 52.509364 - ], - [ - 4.947474, - 52.509328 - ], - [ - 4.947512, - 52.509296 - ], - [ - 4.947559, - 52.509269 - ], - [ - 4.947613, - 52.509248 - ], - [ - 4.947674, - 52.509234 - ], - [ - 4.947738, - 52.509228 - ], - [ - 4.947802, - 52.509229 - ], - [ - 4.947865, - 52.509237 - ], - [ - 4.947925, - 52.509254 - ], - [ - 4.947977, - 52.509276 - ], - [ - 4.948022, - 52.509305 - ], - [ - 4.948056, - 52.509338 - ], - [ - 4.948079, - 52.509375 - ], - [ - 4.94809, - 52.509414 - ], - [ - 4.948088, - 52.509453 - ], - [ - 4.948074, - 52.509492 - ], - [ - 4.948048, - 52.509528 - ], - [ - 4.94801, - 52.50956 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.946893, - 52.509638 - ], - [ - 4.947357, - 52.509492 - ], - [ - 4.947427, - 52.509472 - ], - [ - 4.947761, - 52.509428 - ], - [ - 4.947331, - 52.509564 - ], - [ - 4.946736, - 52.509714 - ], - [ - 4.946893, - 52.509638 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Point", - "coordinates": [ - 4.946736, - 52.509714 - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Point", - "coordinates": [ - 4.947761, - 52.509428 - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/issue-#801-Ecuador.geojson b/packages/turf-buffer/test/out/issue-#801-Ecuador.geojson deleted file mode 100644 index 127500a93e..0000000000 --- a/packages/turf-buffer/test/out/issue-#801-Ecuador.geojson +++ /dev/null @@ -1,373 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -78.495206, - -0.222456 - ], - [ - -78.495484, - -0.225277 - ], - [ - -78.496307, - -0.227989 - ], - [ - -78.497643, - -0.230488 - ], - [ - -78.499441, - -0.232679 - ], - [ - -78.501631, - -0.234477 - ], - [ - -78.504131, - -0.235813 - ], - [ - -78.506843, - -0.236636 - ], - [ - -78.509663, - -0.236913 - ], - [ - -78.512484, - -0.236636 - ], - [ - -78.515196, - -0.235813 - ], - [ - -78.517695, - -0.234477 - ], - [ - -78.519886, - -0.232679 - ], - [ - -78.521684, - -0.230488 - ], - [ - -78.52302, - -0.227989 - ], - [ - -78.523843, - -0.225277 - ], - [ - -78.52412, - -0.222456 - ], - [ - -78.523843, - -0.219636 - ], - [ - -78.52302, - -0.216924 - ], - [ - -78.521684, - -0.214425 - ], - [ - -78.519886, - -0.212234 - ], - [ - -78.517695, - -0.210436 - ], - [ - -78.515196, - -0.2091 - ], - [ - -78.512484, - -0.208277 - ], - [ - -78.509663, - -0.208 - ], - [ - -78.506843, - -0.208277 - ], - [ - -78.504131, - -0.2091 - ], - [ - -78.501631, - -0.210436 - ], - [ - -78.499441, - -0.212234 - ], - [ - -78.497643, - -0.214425 - ], - [ - -78.496307, - -0.216924 - ], - [ - -78.495484, - -0.219636 - ], - [ - -78.495206, - -0.222456 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -78.52224, - -0.215287 - ], - [ - -78.522229, - -0.215268 - ], - [ - -78.52059, - -0.212958 - ], - [ - -78.518532, - -0.211013 - ], - [ - -78.516134, - -0.209506 - ], - [ - -78.513489, - -0.208495 - ], - [ - -78.510697, - -0.20802 - ], - [ - -78.507866, - -0.208097 - ], - [ - -78.505105, - -0.208725 - ], - [ - -78.505081, - -0.208733 - ], - [ - -78.502569, - -0.209846 - ], - [ - -78.500313, - -0.211413 - ], - [ - -78.498394, - -0.213379 - ], - [ - -78.496882, - -0.215672 - ], - [ - -78.495831, - -0.21821 - ], - [ - -78.495279, - -0.220901 - ], - [ - -78.495245, - -0.223648 - ], - [ - -78.495732, - -0.226351 - ], - [ - -78.496722, - -0.228914 - ], - [ - -78.49673, - -0.22893 - ], - [ - -78.498152, - -0.231214 - ], - [ - -78.499972, - -0.233195 - ], - [ - -78.502128, - -0.234804 - ], - [ - -78.504545, - -0.235986 - ], - [ - -78.507139, - -0.2367 - ], - [ - -78.50982, - -0.236921 - ], - [ - -78.512496, - -0.236641 - ], - [ - -78.512523, - -0.236635 - ], - [ - -78.515139, - -0.235849 - ], - [ - -78.517561, - -0.234584 - ], - [ - -78.519701, - -0.232887 - ], - [ - -78.521484, - -0.230816 - ], - [ - -78.522846, - -0.228448 - ], - [ - -78.523737, - -0.225866 - ], - [ - -78.524127, - -0.223162 - ], - [ - -78.524002, - -0.220433 - ], - [ - -78.523365, - -0.217776 - ], - [ - -78.52224, - -0.215287 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Point", - "coordinates": [ - -78.50966334342957, - -0.22245649236909099 - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -78.5096874833107, - -0.22245917455788858 - ], - [ - -78.50966066122055, - -0.22246453893548376 - ], - [ - -78.5096526145935, - -0.2224484458026982 - ], - [ - -78.50967675447464, - -0.2224403992362927 - ], - [ - -78.5096874833107, - -0.22245917455788858 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/issue-#801.geojson b/packages/turf-buffer/test/out/issue-#801.geojson deleted file mode 100644 index 9ff81928d5..0000000000 --- a/packages/turf-buffer/test/out/issue-#801.geojson +++ /dev/null @@ -1,373 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "stroke-width": 2, - "stroke-opacity": 1, - "fill": "#F00", - "fill-opacity": 0.3, - "marker-color": "#F00" - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 5.82622, - 50.759174 - ], - [ - 5.822487, - 50.758114 - ], - [ - 5.819163, - 50.756605 - ], - [ - 5.816379, - 50.754708 - ], - [ - 5.814248, - 50.752498 - ], - [ - 5.812855, - 50.750064 - ], - [ - 5.812254, - 50.747504 - ], - [ - 5.81247, - 50.74492 - ], - [ - 5.812475, - 50.744897 - ], - [ - 5.813477, - 50.742431 - ], - [ - 5.815221, - 50.740137 - ], - [ - 5.817641, - 50.738103 - ], - [ - 5.820643, - 50.736407 - ], - [ - 5.82411, - 50.735117 - ], - [ - 5.82791, - 50.73428 - ], - [ - 5.831895, - 50.73393 - ], - [ - 5.835911, - 50.734081 - ], - [ - 5.839803, - 50.734726 - ], - [ - 5.843421, - 50.73584 - ], - [ - 5.843456, - 50.735853 - ], - [ - 5.846762, - 50.737455 - ], - [ - 5.849487, - 50.739447 - ], - [ - 5.851519, - 50.741746 - ], - [ - 5.852774, - 50.744259 - ], - [ - 5.853199, - 50.74688 - ], - [ - 5.853199, - 50.746897 - ], - [ - 5.852835, - 50.749333 - ], - [ - 5.851753, - 50.751682 - ], - [ - 5.849991, - 50.753861 - ], - [ - 5.847613, - 50.755791 - ], - [ - 5.844703, - 50.757403 - ], - [ - 5.841365, - 50.758641 - ], - [ - 5.837719, - 50.759458 - ], - [ - 5.833895, - 50.759827 - ], - [ - 5.830029, - 50.759734 - ], - [ - 5.82626, - 50.759183 - ], - [ - 5.82622, - 50.759174 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 5.848918, - 50.754799 - ], - [ - 5.846166, - 50.756647 - ], - [ - 5.842898, - 50.75812 - ], - [ - 5.839238, - 50.759161 - ], - [ - 5.835327, - 50.75973 - ], - [ - 5.831315, - 50.759806 - ], - [ - 5.827358, - 50.759384 - ], - [ - 5.823607, - 50.758483 - ], - [ - 5.820206, - 50.757135 - ], - [ - 5.817287, - 50.755394 - ], - [ - 5.81496, - 50.753326 - ], - [ - 5.813317, - 50.751011 - ], - [ - 5.812419, - 50.748537 - ], - [ - 5.812301, - 50.746 - ], - [ - 5.812967, - 50.743497 - ], - [ - 5.814392, - 50.741124 - ], - [ - 5.816521, - 50.738973 - ], - [ - 5.819272, - 50.737126 - ], - [ - 5.822539, - 50.735654 - ], - [ - 5.826197, - 50.734614 - ], - [ - 5.830105, - 50.734045 - ], - [ - 5.834113, - 50.733969 - ], - [ - 5.838068, - 50.73439 - ], - [ - 5.841818, - 50.73529 - ], - [ - 5.845218, - 50.736637 - ], - [ - 5.848138, - 50.738377 - ], - [ - 5.850466, - 50.740444 - ], - [ - 5.852112, - 50.742759 - ], - [ - 5.853012, - 50.745233 - ], - [ - 5.853133, - 50.74777 - ], - [ - 5.852469, - 50.750274 - ], - [ - 5.851046, - 50.752647 - ], - [ - 5.848918, - 50.754799 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "stroke-width": 2, - "stroke-opacity": 1, - "fill": "#00F", - "fill-opacity": 0.3, - "marker-color": "#00F" - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 5.832694172859192, - 50.74689044349633 - ], - [ - 5.832699537277222, - 50.74686838040257 - ], - [ - 5.832734405994415, - 50.746881957692274 - ], - [ - 5.832734405994415, - 50.746898929298894 - ], - [ - 5.832694172859192, - 50.74689044349633 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Point", - "coordinates": [ - 5.83271563053131, - 50.746887049174894 - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/issue-#815.geojson b/packages/turf-buffer/test/out/issue-#815.geojson deleted file mode 100644 index 0a06fba33c..0000000000 --- a/packages/turf-buffer/test/out/issue-#815.geojson +++ /dev/null @@ -1,267 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "radius": 850, - "units": "meters", - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 9.404639, - 52.005 - ], - [ - 9.406648, - 52.005149 - ], - [ - 9.408582, - 52.005517 - ], - [ - 9.410378, - 52.006092 - ], - [ - 9.411978, - 52.006856 - ], - [ - 9.41333, - 52.007783 - ], - [ - 10.288951, - 52.71603 - ], - [ - 11.380072, - 52.715979 - ], - [ - 12.432972, - 52.516208 - ], - [ - 12.435187, - 52.515915 - ], - [ - 12.437454, - 52.515891 - ], - [ - 12.439685, - 52.516136 - ], - [ - 12.441795, - 52.516641 - ], - [ - 12.443702, - 52.517387 - ], - [ - 12.445333, - 52.518345 - ], - [ - 12.446626, - 52.519479 - ], - [ - 12.447531, - 52.520744 - ], - [ - 12.448013, - 52.522092 - ], - [ - 12.448054, - 52.523472 - ], - [ - 12.447651, - 52.524829 - ], - [ - 12.44682, - 52.526113 - ], - [ - 12.445594, - 52.527274 - ], - [ - 12.444019, - 52.528267 - ], - [ - 12.442156, - 52.529054 - ], - [ - 12.440076, - 52.529604 - ], - [ - 11.385189, - 52.729702 - ], - [ - 11.381941, - 52.730001 - ], - [ - 10.283098, - 52.729972 - ], - [ - 10.281011, - 52.729845 - ], - [ - 10.278997, - 52.729492 - ], - [ - 10.277122, - 52.728923 - ], - [ - 10.275447, - 52.728158 - ], - [ - 10.27403, - 52.727222 - ], - [ - 9.398517, - 52.018772 - ], - [ - 7.162332, - 51.951124 - ], - [ - 7.160175, - 51.950902 - ], - [ - 7.15813, - 51.950424 - ], - [ - 7.156276, - 51.94971 - ], - [ - 7.154683, - 51.948786 - ], - [ - 7.153414, - 51.947689 - ], - [ - 7.152517, - 51.94646 - ], - [ - 7.152025, - 51.945147 - ], - [ - 7.151959, - 51.9438 - ], - [ - 7.15232, - 51.94247 - ], - [ - 7.153095, - 51.94121 - ], - [ - 7.154254, - 51.940067 - ], - [ - 7.155752, - 51.939086 - ], - [ - 7.157531, - 51.938303 - ], - [ - 7.159525, - 51.93775 - ], - [ - 7.161655, - 51.937447 - ], - [ - 7.163839, - 51.937406 - ], - [ - 9.404639, - 52.005 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "radius": 850, - "units": "meters", - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - 7.163085937499999, - 51.944264879028765 - ], - [ - 9.404296875, - 52.01193653675363 - ], - [ - 10.283203125, - 52.72298552457069 - ], - [ - 11.3818359375, - 52.72298552457069 - ], - [ - 12.436523437499998, - 52.522905940278065 - ] - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/issue-#900.geojson b/packages/turf-buffer/test/out/issue-#900.geojson deleted file mode 100644 index c7dfcaff96..0000000000 --- a/packages/turf-buffer/test/out/issue-#900.geojson +++ /dev/null @@ -1,1247 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -87.240659, - 22.529386 - ], - [ - -87.157969, - 22.899479 - ], - [ - -87.057861, - 23.344518 - ], - [ - -87.055853, - 23.353139 - ], - [ - -86.855853, - 24.182233 - ], - [ - -86.824536, - 24.277074 - ], - [ - -86.777988, - 24.366501 - ], - [ - -86.039684, - 25.540779 - ], - [ - -85.986863, - 26.085619 - ], - [ - -85.953603, - 26.437944 - ], - [ - -85.908199, - 26.615088 - ], - [ - -85.861036, - 26.72492 - ], - [ - -85.46371, - 27.709667 - ], - [ - -85.39886, - 27.829004 - ], - [ - -85.307628, - 27.93386 - ], - [ - -85.193923, - 28.019788 - ], - [ - -85.06262, - 28.083152 - ], - [ - -83.825769, - 28.539299 - ], - [ - -83.727256, - 28.625098 - ], - [ - -83.344523, - 28.961834 - ], - [ - -83.32229, - 29.454764 - ], - [ - -83.272263, - 30.53007 - ], - [ - -83.253335, - 30.648629 - ], - [ - -83.208392, - 30.761741 - ], - [ - -83.139096, - 30.865246 - ], - [ - -81.786431, - 32.484045 - ], - [ - -80.291108, - 34.511808 - ], - [ - -80.144523, - 34.783603 - ], - [ - -79.600281, - 35.793326 - ], - [ - -79.455143, - 36.08922 - ], - [ - -79.372862, - 36.211547 - ], - [ - -79.122862, - 36.495321 - ], - [ - -79.118262, - 36.500474 - ], - [ - -78.752367, - 36.904511 - ], - [ - -78.486458, - 37.199025 - ], - [ - -78.484901, - 37.200739 - ], - [ - -77.901571, - 37.837868 - ], - [ - -77.876673, - 37.863394 - ], - [ - -77.393333, - 38.329434 - ], - [ - -77.316978, - 38.392278 - ], - [ - -77.142041, - 38.515613 - ], - [ - -76.944906, - 38.66331 - ], - [ - -76.600846, - 39.026522 - ], - [ - -76.503308, - 39.131695 - ], - [ - -76.49731, - 39.138063 - ], - [ - -76.36397, - 39.277402 - ], - [ - -76.357149, - 39.284407 - ], - [ - -76.253686, - 39.388862 - ], - [ - -76.199156, - 39.451278 - ], - [ - -76.194411, - 39.456639 - ], - [ - -76.111081, - 39.549555 - ], - [ - -76.027365, - 39.626808 - ], - [ - -75.926979, - 39.691125 - ], - [ - -74.830577, - 40.270359 - ], - [ - -74.117474, - 40.654189 - ], - [ - -74.105964, - 40.66024 - ], - [ - -72.722634, - 41.368722 - ], - [ - -72.607247, - 41.416577 - ], - [ - -71.857247, - 41.663031 - ], - [ - -71.749709, - 41.690978 - ], - [ - -71.63763, - 41.705961 - ], - [ - -70.249995, - 41.808072 - ], - [ - -67.373069, - 43.087163 - ], - [ - -67.264327, - 43.126332 - ], - [ - -56.730997, - 46.072052 - ], - [ - -56.667531, - 46.087031 - ], - [ - -52.225183, - 46.97108 - ], - [ - -50.698953, - 47.35177 - ], - [ - -50.693671, - 47.353066 - ], - [ - -50.243671, - 47.462112 - ], - [ - -50.118883, - 47.484057 - ], - [ - -42.985553, - 48.281688 - ], - [ - -42.939641, - 48.285781 - ], - [ - -40.16339, - 48.472885 - ], - [ - -38.282053, - 48.927911 - ], - [ - -38.234557, - 48.938136 - ], - [ - -30.201227, - 50.444202 - ], - [ - -30.148882, - 50.452528 - ], - [ - -27.998882, - 50.739784 - ], - [ - -27.95207, - 50.745008 - ], - [ - -20.10207, - 51.448163 - ], - [ - -20.020101, - 51.452502 - ], - [ - -19.353431, - 51.464058 - ], - [ - -19.330236, - 51.464228 - ], - [ - -14.998453, - 51.452676 - ], - [ - -8, - 51.452676 - ], - [ - -7.964794, - 51.452142 - ], - [ - -5.848124, - 51.387777 - ], - [ - -5.828205, - 51.386998 - ], - [ - -3.928205, - 51.296222 - ], - [ - -3.912196, - 51.295344 - ], - [ - -2.578866, - 51.212823 - ], - [ - -2.564899, - 51.211872 - ], - [ - -2.431569, - 51.201969 - ], - [ - -2.311436, - 51.186477 - ], - [ - -1.911436, - 51.112178 - ], - [ - -1.905734, - 51.111102 - ], - [ - -1.690321, - 51.069824 - ], - [ - -1.296084, - 51.213329 - ], - [ - -1.142502, - 51.255085 - ], - [ - -0.959172, - 51.289758 - ], - [ - -0.861021, - 51.301202 - ], - [ - -0.851156, - 51.321531 - ], - [ - -0.784357, - 51.399565 - ], - [ - -0.694462, - 51.467853 - ], - [ - -0.584923, - 51.52382 - ], - [ - -0.459952, - 51.565362 - ], - [ - -0.324351, - 51.590925 - ], - [ - -0.18333, - 51.599553 - ], - [ - -0.042309, - 51.590925 - ], - [ - 0.093292, - 51.565362 - ], - [ - 0.218263, - 51.52382 - ], - [ - 0.327802, - 51.467853 - ], - [ - 0.417697, - 51.399565 - ], - [ - 0.484496, - 51.321531 - ], - [ - 0.52563, - 51.236709 - ], - [ - 0.539519, - 51.14833 - ], - [ - 0.539519, - 51.11472 - ], - [ - 0.587373, - 51.056421 - ], - [ - 0.625906, - 50.97467 - ], - [ - 0.639503, - 50.889679 - ], - [ - 0.627687, - 50.804426 - ], - [ - 0.590872, - 50.721917 - ], - [ - 0.530353, - 50.645075 - ], - [ - 0.448257, - 50.576637 - ], - [ - 0.347472, - 50.51905 - ], - [ - 0.23154, - 50.474382 - ], - [ - 0.104538, - 50.444243 - ], - [ - -0.02907, - 50.429721 - ], - [ - -0.6167, - 50.401534 - ], - [ - -0.643479, - 50.396374 - ], - [ - -1.237246, - 50.176258 - ], - [ - -1.372435, - 50.137267 - ], - [ - -1.517198, - 50.116754 - ], - [ - -1.665443, - 50.115606 - ], - [ - -1.810936, - 50.133874 - ], - [ - -2.324758, - 50.234252 - ], - [ - -2.66289, - 50.298253 - ], - [ - -2.728125, - 50.303194 - ], - [ - -4.046467, - 50.38639 - ], - [ - -5.928504, - 50.478081 - ], - [ - -8.017613, - 50.542864 - ], - [ - -15, - 50.542864 - ], - [ - -15.003094, - 50.542868 - ], - [ - -19.324824, - 50.554621 - ], - [ - -19.938716, - 50.543769 - ], - [ - -27.724388, - 49.832765 - ], - [ - -29.824702, - 49.546779 - ], - [ - -37.808086, - 48.022345 - ], - [ - -39.751277, - 47.543854 - ], - [ - -39.927029, - 47.516545 - ], - [ - -42.770644, - 47.321313 - ], - [ - -49.817269, - 46.518843 - ], - [ - -50.203684, - 46.423553 - ], - [ - -51.751047, - 46.030857 - ], - [ - -51.799139, - 46.019918 - ], - [ - -56.233575, - 45.122002 - ], - [ - -66.679044, - 42.152888 - ], - [ - -69.643601, - 40.814747 - ], - [ - -69.78907, - 40.764061 - ], - [ - -69.94571, - 40.738853 - ], - [ - -71.381331, - 40.631466 - ], - [ - -71.965478, - 40.436557 - ], - [ - -73.288242, - 39.749706 - ], - [ - -73.999196, - 39.361917 - ], - [ - -74.006361, - 39.358048 - ], - [ - -74.997501, - 38.827682 - ], - [ - -75.003196, - 38.82127 - ], - [ - -75.067514, - 38.746984 - ], - [ - -75.092851, - 38.719515 - ], - [ - -75.206065, - 38.604119 - ], - [ - -75.333002, - 38.470214 - ], - [ - -75.430032, - 38.364615 - ], - [ - -75.434995, - 38.359276 - ], - [ - -75.818325, - 37.950712 - ], - [ - -75.899806, - 37.877582 - ], - [ - -76.149806, - 37.688194 - ], - [ - -76.166352, - 37.676029 - ], - [ - -76.308427, - 37.574722 - ], - [ - -76.743762, - 37.150789 - ], - [ - -77.314318, - 36.521953 - ], - [ - -77.580212, - 36.224843 - ], - [ - -77.581738, - 36.223141 - ], - [ - -77.94608, - 35.817275 - ], - [ - -78.14356, - 35.591262 - ], - [ - -78.261517, - 35.349357 - ], - [ - -78.271683, - 35.329535 - ], - [ - -78.821683, - 34.303213 - ], - [ - -78.822595, - 34.301509 - ], - [ - -78.989265, - 33.990615 - ], - [ - -79.034242, - 33.919724 - ], - [ - -80.567572, - 31.825535 - ], - [ - -80.594234, - 31.791304 - ], - [ - -81.836387, - 30.294726 - ], - [ - -81.877723, - 29.40494 - ], - [ - -81.91104, - 28.665052 - ], - [ - -81.92876, - 28.548203 - ], - [ - -81.970791, - 28.436126 - ], - [ - -82.035681, - 28.332709 - ], - [ - -82.121192, - 28.241552 - ], - [ - -82.704532, - 27.72438 - ], - [ - -82.707646, - 27.72163 - ], - [ - -82.907646, - 27.545895 - ], - [ - -83.015111, - 27.468003 - ], - [ - -83.13738, - 27.409726 - ], - [ - -84.21045, - 27.009956 - ], - [ - -84.50295, - 26.281321 - ], - [ - -84.508461, - 26.26801 - ], - [ - -84.521711, - 26.237042 - ], - [ - -84.546397, - 25.975194 - ], - [ - -84.546558, - 25.973515 - ], - [ - -84.613218, - 25.284858 - ], - [ - -84.643317, - 25.14685 - ], - [ - -84.705342, - 25.017717 - ], - [ - -85.467762, - 23.799773 - ], - [ - -85.643112, - 23.071021 - ], - [ - -85.742085, - 22.630146 - ], - [ - -85.825361, - 22.256694 - ], - [ - -85.826669, - 22.250946 - ], - [ - -86.143339, - 20.882938 - ], - [ - -86.186595, - 20.756809 - ], - [ - -86.255345, - 20.640899 - ], - [ - -86.346948, - 20.539691 - ], - [ - -86.457882, - 20.457107 - ], - [ - -86.583885, - 20.396353 - ], - [ - -86.720115, - 20.359792 - ], - [ - -86.861337, - 20.348845 - ], - [ - -87.002122, - 20.363939 - ], - [ - -87.137062, - 20.404486 - ], - [ - -87.26097, - 20.468909 - ], - [ - -87.369085, - 20.554704 - ], - [ - -87.457252, - 20.658541 - ], - [ - -87.522082, - 20.776396 - ], - [ - -87.561084, - 20.903713 - ], - [ - -87.57276, - 21.035582 - ], - [ - -87.556661, - 21.166927 - ], - [ - -87.240659, - 22.529386 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - -86.85, - 21.025 - ], - [ - -86.53333, - 22.39167 - ], - [ - -86.45, - 22.765 - ], - [ - -86.35, - 23.21 - ], - [ - -86.15, - 24.04 - ], - [ - -85.33333, - 25.34167 - ], - [ - -85.26667, - 26.03 - ], - [ - -85.23333, - 26.38333 - ], - [ - -85.18333, - 26.5 - ], - [ - -84.78333, - 27.49333 - ], - [ - -83.41667, - 28 - ], - [ - -83.21667, - 28.175 - ], - [ - -82.63333, - 28.69 - ], - [ - -82.6, - 29.43 - ], - [ - -82.55, - 30.505 - ], - [ - -81.18333, - 32.14667 - ], - [ - -79.65, - 34.23333 - ], - [ - -79.48333, - 34.54333 - ], - [ - -78.93333, - 35.56667 - ], - [ - -78.78333, - 35.87333 - ], - [ - -78.53333, - 36.15833 - ], - [ - -78.16667, - 36.565 - ], - [ - -77.9, - 36.86167 - ], - [ - -77.31667, - 37.50167 - ], - [ - -76.83333, - 37.97 - ], - [ - -76.65, - 38.1 - ], - [ - -76.4, - 38.28833 - ], - [ - -76.01667, - 38.695 - ], - [ - -75.91667, - 38.80333 - ], - [ - -75.78333, - 38.94333 - ], - [ - -75.66667, - 39.06167 - ], - [ - -75.6, - 39.13833 - ], - [ - -75.51667, - 39.23167 - ], - [ - -74.41667, - 39.81667 - ], - [ - -73.7, - 40.205 - ], - [ - -72.31667, - 40.91833 - ], - [ - -71.56667, - 41.16667 - ], - [ - -70.01667, - 41.28167 - ], - [ - -67, - 42.63333 - ], - [ - -56.46667, - 45.60333 - ], - [ - -52, - 46.5 - ], - [ - -50.45, - 46.89 - ], - [ - -50, - 47 - ], - [ - -42.86667, - 47.805 - ], - [ - -40, - 48 - ], - [ - -38.03333, - 48.48 - ], - [ - -30, - 50 - ], - [ - -27.85, - 50.29 - ], - [ - -20, - 51 - ], - [ - -19.33333, - 51.01167 - ], - [ - -15, - 51 - ], - [ - -14, - 51 - ], - [ - -8.5, - 51 - ], - [ - -8.25, - 51 - ], - [ - -8, - 51 - ], - [ - -5.88333, - 50.935 - ], - [ - -3.98333, - 50.84333 - ], - [ - -2.65, - 50.76 - ], - [ - -2.51667, - 50.75 - ], - [ - -2.11667, - 50.675 - ], - [ - -1.6, - 50.575 - ], - [ - -0.93333, - 50.82 - ], - [ - -0.75, - 50.855 - ], - [ - -0.08333, - 50.88667 - ], - [ - -0.18333, - 50.985 - ], - [ - -0.18333, - 51.14833 - ] - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/issue-#916.geojson b/packages/turf-buffer/test/out/issue-#916.geojson deleted file mode 100644 index f22d43dc73..0000000000 --- a/packages/turf-buffer/test/out/issue-#916.geojson +++ /dev/null @@ -1,351 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 123.950002, - -24.846565 - ], - [ - 123.950002, - -23.402765 - ], - [ - 123.964208, - -23.27183 - ], - [ - 124.006266, - -23.145921 - ], - [ - 124.074524, - -23.030006 - ], - [ - 124.166298, - -22.928676 - ], - [ - 124.277982, - -22.845948 - ], - [ - 129.331693, - -19.775896 - ], - [ - 129.454172, - -19.715568 - ], - [ - 129.586612, - -19.678277 - ], - [ - 129.72417, - -19.665401 - ], - [ - 129.861816, - -19.677419 - ], - [ - 133.553223, - -20.338103 - ], - [ - 133.689748, - -20.375859 - ], - [ - 133.815734, - -20.437946 - ], - [ - 133.926297, - -20.521928 - ], - [ - 134.017149, - -20.624515 - ], - [ - 134.084767, - -20.741697 - ], - [ - 134.12653, - -20.8689 - ], - [ - 135.093326, - -25.274332 - ], - [ - 135.107518, - -25.392899 - ], - [ - 135.097627, - -25.511705 - ], - [ - 135.063983, - -25.626797 - ], - [ - 135.007708, - -25.734354 - ], - [ - 134.930675, - -25.830817 - ], - [ - 134.835453, - -25.913002 - ], - [ - 131.363773, - -28.376332 - ], - [ - 131.226717, - -28.452075 - ], - [ - 131.073934, - -28.499068 - ], - [ - 130.913086, - -28.514994 - ], - [ - 125.375977, - -28.514994 - ], - [ - 125.237002, - -28.503144 - ], - [ - 125.103213, - -28.468028 - ], - [ - 124.979601, - -28.410934 - ], - [ - 124.870779, - -28.333959 - ], - [ - 124.780806, - -28.239935 - ], - [ - 124.713041, - -28.132332 - ], - [ - 124.67001, - -28.015129 - ], - [ - 124.186611, - -26.058134 - ], - [ - 124.169961, - -25.935002 - ], - [ - 124.179648, - -25.81114 - ], - [ - 124.21532, - -25.691068 - ], - [ - 124.275677, - -25.579182 - ], - [ - 124.358518, - -25.479587 - ], - [ - 124.388944, - -25.454719 - ], - [ - 124.305117, - -25.409985 - ], - [ - 124.184842, - -25.329507 - ], - [ - 124.085488, - -25.228298 - ], - [ - 124.011312, - -25.110652 - ], - [ - 123.965496, - -24.981571 - ], - [ - 123.950002, - -24.846565 - ] - ], - [ - [ - 126.163013, - -25.809545 - ], - [ - 126.64513, - -26.050424 - ], - [ - 130.683749, - -25.870666 - ], - [ - 132.202728, - -24.984704 - ], - [ - 131.620171, - -22.705583 - ], - [ - 130.04241, - -22.228929 - ], - [ - 126.824159, - -24.073894 - ], - [ - 126.331568, - -25.552755 - ], - [ - 126.275801, - -25.673646 - ], - [ - 126.194365, - -25.781944 - ], - [ - 126.163013, - -25.809545 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 124.67285156250001, - -24.846565348219734 - ], - [ - 125.63964843750001, - -25.36388227274024 - ], - [ - 126.21093749999999, - -23.644524198573677 - ], - [ - 129.9462890625, - -21.493963563064455 - ], - [ - 132.2314453125, - -22.187404991398775 - ], - [ - 133.0224609375, - -25.28443774698303 - ], - [ - 130.9130859375, - -26.509904531413916 - ], - [ - 126.474609375, - -26.706359857633526 - ], - [ - 124.892578125, - -25.918526162075153 - ], - [ - 125.3759765625, - -27.877928333679495 - ], - [ - 130.9130859375, - -27.877928333679495 - ], - [ - 134.38476562499997, - -25.403584973186703 - ], - [ - 133.41796874999997, - -21.002471054356715 - ], - [ - 129.7265625, - -20.34462694382967 - ], - [ - 124.67285156250001, - -23.40276490540795 - ], - [ - 124.67285156250001, - -24.846565348219734 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/linestring.geojson b/packages/turf-buffer/test/out/linestring.geojson deleted file mode 100644 index 4c955d1005..0000000000 --- a/packages/turf-buffer/test/out/linestring.geojson +++ /dev/null @@ -1,295 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 126.05193, - -23.997281 - ], - [ - 126.142934, - -23.897325 - ], - [ - 126.253598, - -23.815538 - ], - [ - 132.14227, - -20.231313 - ], - [ - 132.299657, - -20.158253 - ], - [ - 132.471171, - -20.122951 - ], - [ - 137.129374, - -19.709783 - ], - [ - 137.260227, - -19.709361 - ], - [ - 137.389017, - -19.731153 - ], - [ - 137.511524, - -19.774436 - ], - [ - 142.60918, - -22.072893 - ], - [ - 142.716933, - -22.132275 - ], - [ - 142.811991, - -22.207978 - ], - [ - 142.891495, - -22.297701 - ], - [ - 147.461807, - -28.33191 - ], - [ - 147.522957, - -28.427219 - ], - [ - 147.564628, - -28.530243 - ], - [ - 147.585587, - -28.637915 - ], - [ - 147.849259, - -31.377427 - ], - [ - 147.847128, - -31.498315 - ], - [ - 147.817397, - -31.616375 - ], - [ - 147.761208, - -31.727088 - ], - [ - 147.680719, - -31.826232 - ], - [ - 147.579025, - -31.910039 - ], - [ - 147.460033, - -31.975333 - ], - [ - 147.328316, - -32.019648 - ], - [ - 147.188936, - -32.04131 - ], - [ - 147.047248, - -32.039505 - ], - [ - 146.908699, - -32.014299 - ], - [ - 146.778613, - -31.966642 - ], - [ - 146.661987, - -31.898334 - ], - [ - 146.563306, - -31.811957 - ], - [ - 146.48636, - -31.710784 - ], - [ - 146.434107, - -31.598663 - ], - [ - 146.408554, - -31.479872 - ], - [ - 146.160752, - -28.910073 - ], - [ - 141.80715, - -23.1972 - ], - [ - 137.064507, - -21.076581 - ], - [ - 132.785746, - -21.452754 - ], - [ - 127.167872, - -24.844392 - ], - [ - 121.711742, - -31.923271 - ], - [ - 121.621151, - -32.015709 - ], - [ - 121.511043, - -32.091308 - ], - [ - 121.38565, - -32.147208 - ], - [ - 121.249789, - -32.181298 - ], - [ - 121.108683, - -32.192293 - ], - [ - 120.967753, - -32.17978 - ], - [ - 120.832416, - -32.144228 - ], - [ - 120.707873, - -32.086979 - ], - [ - 120.598909, - -32.010195 - ], - [ - 120.509712, - -31.916781 - ], - [ - 120.44371, - -31.810283 - ], - [ - 120.403439, - -31.694757 - ], - [ - 120.390447, - -31.574618 - ], - [ - 120.405233, - -31.454474 - ], - [ - 120.447229, - -31.338953 - ], - [ - 120.514821, - -31.23252 - ], - [ - 126.05193, - -23.997281 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - 121.11328124999999, - -31.57853542647337 - ], - [ - 126.65039062499999, - -24.367113562651262 - ], - [ - 132.5390625, - -20.797201434306984 - ], - [ - 137.197265625, - -20.385825381874263 - ], - [ - 142.294921875, - -22.67484735118852 - ], - [ - 146.865234375, - -28.690587654250685 - ], - [ - 147.12890625, - -31.42866311735861 - ] - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/multi-linestring.geojson b/packages/turf-buffer/test/out/multi-linestring.geojson deleted file mode 100644 index 0589f10ec4..0000000000 --- a/packages/turf-buffer/test/out/multi-linestring.geojson +++ /dev/null @@ -1,865 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - 145.301141, - -25.357707 - ], - [ - 145.29792, - -25.480286 - ], - [ - 145.269379, - -25.600037 - ], - [ - 145.216526, - -25.712753 - ], - [ - 142.755588, - -29.756686 - ], - [ - 142.69051, - -29.843523 - ], - [ - 142.609851, - -29.91982 - ], - [ - 140.280749, - -31.768449 - ], - [ - 140.167773, - -31.84114 - ], - [ - 140.04028, - -31.893667 - ], - [ - 139.903171, - -31.924048 - ], - [ - 139.761714, - -31.931137 - ], - [ - 139.621346, - -31.914667 - ], - [ - 139.48746, - -31.875259 - ], - [ - 139.365202, - -31.814399 - ], - [ - 139.259271, - -31.734386 - ], - [ - 139.173737, - -31.63825 - ], - [ - 139.111887, - -31.529642 - ], - [ - 139.076098, - -31.412702 - ], - [ - 139.067745, - -31.2919 - ], - [ - 139.08715, - -31.171874 - ], - [ - 139.133566, - -31.05725 - ], - [ - 139.20521, - -30.95246 - ], - [ - 139.299329, - -30.861571 - ], - [ - 141.539872, - -29.067124 - ], - [ - 143.844296, - -25.260575 - ], - [ - 143.639288, - -22.600035 - ], - [ - 143.643237, - -22.469202 - ], - [ - 143.674744, - -22.341475 - ], - [ - 143.732598, - -22.221779 - ], - [ - 143.814577, - -22.114741 - ], - [ - 143.917529, - -22.024507 - ], - [ - 144.037499, - -21.95458 - ], - [ - 144.169876, - -21.907681 - ], - [ - 144.309572, - -21.885633 - ], - [ - 144.451221, - -21.889297 - ], - [ - 144.589377, - -21.91853 - ], - [ - 144.718732, - -21.972192 - ], - [ - 144.834314, - -22.048196 - ], - [ - 144.931682, - -22.143587 - ], - [ - 145.007095, - -22.254664 - ], - [ - 145.057653, - -22.377126 - ], - [ - 145.081415, - -22.506244 - ], - [ - 145.301141, - -25.357707 - ] - ] - ], - [ - [ - [ - 125.556256, - -19.88403 - ], - [ - 124.927262, - -18.866106 - ], - [ - 124.868243, - -18.744155 - ], - [ - 124.835492, - -18.613551 - ], - [ - 124.830266, - -18.479298 - ], - [ - 124.852766, - -18.346555 - ], - [ - 124.902129, - -18.220433 - ], - [ - 124.976456, - -18.1058 - ], - [ - 125.072892, - -18.007086 - ], - [ - 125.18773, - -17.928117 - ], - [ - 125.316558, - -17.871955 - ], - [ - 125.454424, - -17.840781 - ], - [ - 125.596031, - -17.835807 - ], - [ - 125.735937, - -17.857225 - ], - [ - 125.868764, - -17.904203 - ], - [ - 125.989409, - -17.974916 - ], - [ - 126.093236, - -18.066621 - ], - [ - 126.176253, - -18.175764 - ], - [ - 126.857986, - -19.283334 - ], - [ - 128.661534, - -18.447426 - ], - [ - 128.828034, - -18.392739 - ], - [ - 134.365144, - -17.263215 - ], - [ - 134.512158, - -17.247905 - ], - [ - 134.659358, - -17.261488 - ], - [ - 134.800583, - -17.303389 - ], - [ - 134.929921, - -17.371837 - ], - [ - 137.830312, - -19.29063 - ], - [ - 137.930076, - -19.369755 - ], - [ - 138.013162, - -19.464447 - ], - [ - 138.07687, - -19.571603 - ], - [ - 138.119129, - -19.687719 - ], - [ - 138.543001, - -21.310303 - ], - [ - 139.066197, - -21.355789 - ], - [ - 139.241185, - -21.391773 - ], - [ - 141.218724, - -22.044981 - ], - [ - 141.346943, - -22.100889 - ], - [ - 141.460928, - -22.178867 - ], - [ - 141.5563, - -22.275884 - ], - [ - 141.629392, - -22.388176 - ], - [ - 141.677397, - -22.511397 - ], - [ - 141.698469, - -22.640786 - ], - [ - 141.691798, - -22.771362 - ], - [ - 141.657642, - -22.898109 - ], - [ - 141.597311, - -23.016173 - ], - [ - 141.513126, - -23.121043 - ], - [ - 141.408321, - -23.208725 - ], - [ - 141.286924, - -23.275886 - ], - [ - 141.1536, - -23.319976 - ], - [ - 141.013472, - -23.339326 - ], - [ - 140.871926, - -23.333201 - ], - [ - 140.734401, - -23.301834 - ], - [ - 138.911118, - -22.70511 - ], - [ - 139.129871, - -23.527351 - ], - [ - 139.149923, - -23.656481 - ], - [ - 139.141977, - -23.78658 - ], - [ - 139.106341, - -23.912607 - ], - [ - 139.044396, - -24.029695 - ], - [ - 138.958544, - -24.133333 - ], - [ - 134.12456, - -28.81254 - ], - [ - 134.018637, - -28.894983 - ], - [ - 133.896385, - -28.957698 - ], - [ - 133.762504, - -28.998313 - ], - [ - 133.622137, - -29.015294 - ], - [ - 133.480679, - -29.008 - ], - [ - 133.343567, - -28.976706 - ], - [ - 133.216069, - -28.922594 - ], - [ - 133.103085, - -28.84771 - ], - [ - 133.008958, - -28.75489 - ], - [ - 132.937303, - -28.647659 - ], - [ - 132.890875, - -28.5301 - ], - [ - 132.871458, - -28.406707 - ], - [ - 132.879799, - -28.282209 - ], - [ - 132.915576, - -28.161396 - ], - [ - 132.977416, - -28.048932 - ], - [ - 133.06294, - -27.949173 - ], - [ - 133.338181, - -27.685822 - ], - [ - 130.517791, - -27.22235 - ], - [ - 130.369194, - -27.182825 - ], - [ - 130.233499, - -27.115984 - ], - [ - 130.116952, - -27.024859 - ], - [ - 130.024918, - -26.913592 - ], - [ - 128.023283, - -23.811267 - ], - [ - 127.442086, - -24.026415 - ], - [ - 122.459168, - -27.267825 - ], - [ - 122.336691, - -27.331155 - ], - [ - 122.202663, - -27.372016 - ], - [ - 122.062236, - -27.388863 - ], - [ - 121.920805, - -27.38106 - ], - [ - 121.783807, - -27.348901 - ], - [ - 121.656505, - -27.293603 - ], - [ - 121.543792, - -27.217256 - ], - [ - 121.45, - -27.122757 - ], - [ - 121.378732, - -27.013695 - ], - [ - 121.332728, - -26.894227 - ], - [ - 121.313755, - -26.768918 - ], - [ - 121.322543, - -26.642575 - ], - [ - 121.358754, - -26.520057 - ], - [ - 121.420996, - -26.406094 - ], - [ - 121.506877, - -26.305097 - ], - [ - 121.613098, - -26.220986 - ], - [ - 126.666809, - -22.90425 - ], - [ - 126.818523, - -22.826976 - ], - [ - 127.287721, - -22.651739 - ], - [ - 126.286219, - -21.057189 - ], - [ - 122.837489, - -22.625048 - ], - [ - 122.704734, - -22.670784 - ], - [ - 122.564862, - -22.691733 - ], - [ - 122.423247, - -22.687103 - ], - [ - 122.285333, - -22.657069 - ], - [ - 122.156419, - -22.602768 - ], - [ - 122.041459, - -22.526261 - ], - [ - 121.944871, - -22.430454 - ], - [ - 121.870367, - -22.318992 - ], - [ - 121.82081, - -22.196129 - ], - [ - 121.798105, - -22.066562 - ], - [ - 121.803123, - -21.93526 - ], - [ - 121.835673, - -21.807273 - ], - [ - 121.894503, - -21.687534 - ], - [ - 121.977352, - -21.580672 - ], - [ - 122.081037, - -21.490827 - ], - [ - 122.201573, - -21.421486 - ], - [ - 125.556256, - -19.88403 - ] - ], - [ - [ - 134.48524, - -26.581507 - ], - [ - 137.63329, - -23.496485 - ], - [ - 137.383447, - -22.556763 - ], - [ - 132.515356, - -22.136531 - ], - [ - 129.377092, - -23.308732 - ], - [ - 131.106976, - -26.005436 - ], - [ - 134.340607, - -26.542388 - ], - [ - 134.476742, - -26.577573 - ], - [ - 134.48524, - -26.581507 - ] - ], - [ - [ - 128.641531, - -22.144865 - ], - [ - 132.135906, - -20.828168 - ], - [ - 132.302169, - -20.785937 - ], - [ - 132.474401, - -20.781686 - ], - [ - 137.019872, - -21.177804 - ], - [ - 136.779731, - -20.259843 - ], - [ - 134.360952, - -18.670445 - ], - [ - 129.217739, - -19.711298 - ], - [ - 127.587949, - -20.461003 - ], - [ - 128.641531, - -22.144865 - ] - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 122.03613281249999, - -26.74561038219901 - ], - [ - 127.08984375000001, - -23.443088931121775 - ], - [ - 132.4072265625, - -21.453068633086772 - ], - [ - 138.9990234375, - -22.024545601240337 - ], - [ - 140.9765625, - -22.67484735118852 - ] - ], - [ - [ - 125.5517578125, - -18.521283325496263 - ], - [ - 130.6494140625, - -26.588527147308614 - ], - [ - 134.208984375, - -27.17646913189887 - ] - ], - [ - [ - 122.51953124999999, - -22.024545601240337 - ], - [ - 128.9794921875, - -19.062117883514652 - ], - [ - 134.5166015625, - -17.936928637549432 - ], - [ - 137.4169921875, - -19.84939395842278 - ], - [ - 138.427734375, - -23.68477416688374 - ], - [ - 133.59375, - -28.38173504322308 - ] - ], - [ - [ - 144.3603515625, - -22.55314747840318 - ], - [ - 144.580078125, - -25.403584973186703 - ], - [ - 142.11914062499997, - -29.458731185355315 - ], - [ - 139.7900390625, - -31.316101383495635 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/multi-point.geojson b/packages/turf-buffer/test/out/multi-point.geojson deleted file mode 100644 index 0230196ea9..0000000000 --- a/packages/turf-buffer/test/out/multi-point.geojson +++ /dev/null @@ -1,407 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "radius": 300, - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - 149.337095, - -25 - ], - [ - 149.253759, - -25.764439 - ], - [ - 149.006953, - -26.49489 - ], - [ - 148.606163, - -27.163995 - ], - [ - 148.066789, - -27.747195 - ], - [ - 147.409561, - -28.223496 - ], - [ - 146.659734, - -28.57605 - ], - [ - 145.846125, - -28.792567 - ], - [ - 145, - -28.865575 - ], - [ - 144.153875, - -28.792567 - ], - [ - 143.340266, - -28.57605 - ], - [ - 142.590439, - -28.223496 - ], - [ - 141.933211, - -27.747195 - ], - [ - 141.393837, - -27.163995 - ], - [ - 140.993047, - -26.49489 - ], - [ - 140.746241, - -25.764439 - ], - [ - 140.662905, - -25 - ], - [ - 140.746241, - -24.230775 - ], - [ - 140.993047, - -23.4867 - ], - [ - 141.393837, - -22.797215 - ], - [ - 141.933211, - -22.189991 - ], - [ - 142.590439, - -21.689682 - ], - [ - 143.340266, - -21.316789 - ], - [ - 144.153875, - -21.086689 - ], - [ - 145, - -21.008913 - ], - [ - 145.846125, - -21.086689 - ], - [ - 146.659734, - -21.316789 - ], - [ - 147.409561, - -21.689682 - ], - [ - 148.066789, - -22.189991 - ], - [ - 148.606163, - -22.797215 - ], - [ - 149.006953, - -23.4867 - ], - [ - 149.253759, - -24.230775 - ], - [ - 149.337095, - -25 - ] - ] - ], - [ - [ - [ - 125.84147, - -21.086261 - ], - [ - 125.746241, - -20.793068 - ], - [ - 125.662905, - -20 - ], - [ - 125.746241, - -19.202917 - ], - [ - 125.993047, - -18.432803 - ], - [ - 126.393837, - -17.719991 - ], - [ - 126.933211, - -17.092863 - ], - [ - 127.590439, - -16.576607 - ], - [ - 128.340266, - -16.192093 - ], - [ - 129.153875, - -15.954936 - ], - [ - 130, - -15.874794 - ], - [ - 130.846125, - -15.954936 - ], - [ - 131.659734, - -16.192093 - ], - [ - 132.409561, - -16.576607 - ], - [ - 133.066789, - -17.092863 - ], - [ - 133.606163, - -17.719991 - ], - [ - 134.006953, - -18.432803 - ], - [ - 134.253759, - -19.202917 - ], - [ - 134.337095, - -20 - ], - [ - 134.253759, - -20.793068 - ], - [ - 134.006953, - -21.551749 - ], - [ - 133.606163, - -22.247462 - ], - [ - 133.066789, - -22.854434 - ], - [ - 132.409561, - -23.35055 - ], - [ - 131.659734, - -23.718002 - ], - [ - 130.846125, - -23.943766 - ], - [ - 130, - -24.019908 - ], - [ - 129.15853, - -23.944185 - ], - [ - 129.253759, - -24.230775 - ], - [ - 129.337095, - -25 - ], - [ - 129.253759, - -25.764439 - ], - [ - 129.006953, - -26.49489 - ], - [ - 128.606163, - -27.163995 - ], - [ - 128.066789, - -27.747195 - ], - [ - 127.409561, - -28.223496 - ], - [ - 126.659734, - -28.57605 - ], - [ - 125.846125, - -28.792567 - ], - [ - 125, - -28.865575 - ], - [ - 124.153875, - -28.792567 - ], - [ - 123.340266, - -28.57605 - ], - [ - 122.590439, - -28.223496 - ], - [ - 121.933211, - -27.747195 - ], - [ - 121.393837, - -27.163995 - ], - [ - 120.993047, - -26.49489 - ], - [ - 120.746241, - -25.764439 - ], - [ - 120.662905, - -25 - ], - [ - 120.746241, - -24.230775 - ], - [ - 120.993047, - -23.4867 - ], - [ - 121.393837, - -22.797215 - ], - [ - 121.933211, - -22.189991 - ], - [ - 122.590439, - -21.689682 - ], - [ - 123.340266, - -21.316789 - ], - [ - 124.153875, - -21.086689 - ], - [ - 125, - -21.008913 - ], - [ - 125.84147, - -21.086261 - ] - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "radius": 300, - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "MultiPoint", - "coordinates": [ - [ - 145, - -25 - ], - [ - 130, - -20 - ], - [ - 125, - -25 - ] - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/multi-polygon.geojson b/packages/turf-buffer/test/out/multi-polygon.geojson deleted file mode 100644 index b32f331bd9..0000000000 --- a/packages/turf-buffer/test/out/multi-polygon.geojson +++ /dev/null @@ -1,595 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - 121.269338, - -31.466154 - ], - [ - 121.269338, - -18.729502 - ], - [ - 121.283228, - -18.595896 - ], - [ - 121.324362, - -18.467326 - ], - [ - 121.39116, - -18.348749 - ], - [ - 121.481056, - -18.244749 - ], - [ - 121.590594, - -18.159352 - ], - [ - 121.715565, - -18.095869 - ], - [ - 121.851167, - -18.056765 - ], - [ - 121.992188, - -18.043559 - ], - [ - 125.859556, - -18.043559 - ], - [ - 124.759183, - -16.323397 - ], - [ - 124.697453, - -16.20081 - ], - [ - 124.661848, - -16.068926 - ], - [ - 124.653736, - -15.932811 - ], - [ - 124.673431, - -15.797702 - ], - [ - 124.720174, - -15.668809 - ], - [ - 124.792166, - -15.551111 - ], - [ - 124.886634, - -15.449164 - ], - [ - 124.999942, - -15.366919 - ], - [ - 125.127728, - -15.307567 - ], - [ - 131.0164, - -13.220764 - ], - [ - 131.078748, - -13.201633 - ], - [ - 136.527967, - -11.785818 - ], - [ - 136.683314, - -11.762648 - ], - [ - 136.840106, - -11.772891 - ], - [ - 136.990932, - -11.816059 - ], - [ - 137.128664, - -11.890096 - ], - [ - 143.588625, - -16.279179 - ], - [ - 143.694908, - -16.366517 - ], - [ - 143.781667, - -16.471819 - ], - [ - 143.84565, - -16.591111 - ], - [ - 143.88446, - -16.719903 - ], - [ - 143.896643, - -16.853354 - ], - [ - 143.720862, - -33.106653 - ], - [ - 143.706611, - -33.220454 - ], - [ - 143.667023, - -33.329835 - ], - [ - 143.603513, - -33.430908 - ], - [ - 143.518354, - -33.520092 - ], - [ - 143.414588, - -33.59424 - ], - [ - 143.295928, - -33.650741 - ], - [ - 143.166617, - -33.68761 - ], - [ - 143.031277, - -33.703556 - ], - [ - 142.894749, - -33.69802 - ], - [ - 134.676976, - -32.705221 - ], - [ - 134.532238, - -32.674529 - ], - [ - 134.398075, - -32.619446 - ], - [ - 134.280209, - -32.542279 - ], - [ - 134.183665, - -32.446265 - ], - [ - 134.11256, - -32.335447 - ], - [ - 134.069925, - -32.214505 - ], - [ - 134.057578, - -32.088566 - ], - [ - 134.05777, - -32.080669 - ], - [ - 121.992188, - -32.080669 - ], - [ - 121.851167, - -32.0689 - ], - [ - 121.715565, - -32.034036 - ], - [ - 121.590594, - -31.977391 - ], - [ - 121.481056, - -31.901105 - ], - [ - 121.39116, - -31.808064 - ], - [ - 121.324362, - -31.701801 - ], - [ - 121.283228, - -31.58636 - ], - [ - 121.269338, - -31.466154 - ] - ], - [ - [ - 133.431886, - -18.043559 - ], - [ - 134.428711, - -18.043559 - ], - [ - 134.569732, - -18.056765 - ], - [ - 134.705333, - -18.095869 - ], - [ - 134.830304, - -18.159352 - ], - [ - 134.939842, - -18.244749 - ], - [ - 135.029738, - -18.348749 - ], - [ - 135.096536, - -18.467326 - ], - [ - 135.137671, - -18.595896 - ], - [ - 135.15156, - -18.729502 - ], - [ - 135.15156, - -23.229524 - ], - [ - 138.683546, - -18.656552 - ], - [ - 135.714057, - -15.563831 - ], - [ - 133.431886, - -18.043559 - ] - ] - ], - [ - [ - [ - 128.388479, - -36.279707 - ], - [ - 128.388479, - -34.234512 - ], - [ - 128.402368, - -34.117844 - ], - [ - 128.443503, - -34.005507 - ], - [ - 128.510301, - -33.901845 - ], - [ - 128.600197, - -33.81088 - ], - [ - 128.709735, - -33.736155 - ], - [ - 128.834706, - -33.680587 - ], - [ - 128.970307, - -33.646351 - ], - [ - 129.111328, - -33.634788 - ], - [ - 131.879883, - -33.634788 - ], - [ - 132.020904, - -33.646351 - ], - [ - 132.156505, - -33.680587 - ], - [ - 132.281476, - -33.736155 - ], - [ - 132.391014, - -33.81088 - ], - [ - 132.48091, - -33.901845 - ], - [ - 132.547708, - -34.005507 - ], - [ - 132.588843, - -34.117844 - ], - [ - 132.602732, - -34.234512 - ], - [ - 132.602732, - -36.279707 - ], - [ - 132.588843, - -36.393307 - ], - [ - 132.547708, - -36.502384 - ], - [ - 132.48091, - -36.602775 - ], - [ - 132.391014, - -36.690661 - ], - [ - 132.281476, - -36.762712 - ], - [ - 132.156505, - -36.816207 - ], - [ - 132.020904, - -36.84913 - ], - [ - 131.879883, - -36.860244 - ], - [ - 129.111328, - -36.860244 - ], - [ - 128.970307, - -36.84913 - ], - [ - 128.834706, - -36.816207 - ], - [ - 128.709735, - -36.762712 - ], - [ - 128.600197, - -36.690661 - ], - [ - 128.510301, - -36.602775 - ], - [ - 128.443503, - -36.502384 - ], - [ - 128.402368, - -36.393307 - ], - [ - 128.388479, - -36.279707 - ] - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - 121.9921875, - -31.466153715024284 - ], - [ - 134.4287109375, - -31.466153715024284 - ], - [ - 134.4287109375, - -18.729501999072138 - ], - [ - 121.9921875, - -18.729501999072138 - ], - [ - 121.9921875, - -31.466153715024284 - ] - ] - ], - [ - [ - [ - 125.3759765625, - -15.961329081596647 - ], - [ - 126.826171875, - -18.22935133838667 - ], - [ - 132.451171875, - -18.062312304546715 - ], - [ - 135.703125, - -14.519780046326085 - ], - [ - 139.6142578125, - -18.60460138845525 - ], - [ - 134.9560546875, - -24.607069137709694 - ], - [ - 134.7802734375, - -32.10118973232094 - ], - [ - 142.998046875, - -33.100745405144245 - ], - [ - 143.173828125, - -16.84660510639629 - ], - [ - 136.7138671875, - -12.46876014482322 - ], - [ - 131.2646484375, - -13.88074584202559 - ], - [ - 125.3759765625, - -15.961329081596647 - ] - ] - ], - [ - [ - [ - 129.111328125, - -36.27970720524016 - ], - [ - 131.8798828125, - -36.27970720524016 - ], - [ - 131.8798828125, - -34.234512362369856 - ], - [ - 129.111328125, - -34.234512362369856 - ], - [ - 129.111328125, - -36.27970720524016 - ] - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/negative-buffer.geojson b/packages/turf-buffer/test/out/negative-buffer.geojson deleted file mode 100644 index 856a55d267..0000000000 --- a/packages/turf-buffer/test/out/negative-buffer.geojson +++ /dev/null @@ -1,105 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "radius": -200, - "units": "miles", - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 134.465993, - -17.644107 - ], - [ - 141.570425, - -19.321421 - ], - [ - 142.06181, - -26.173775 - ], - [ - 141.502481, - -28.273604 - ], - [ - 135.065683, - -28.273604 - ], - [ - 131.100397, - -25.837527 - ], - [ - 129.949198, - -20.57624 - ], - [ - 134.465993, - -17.644107 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "radius": -200, - "units": "miles", - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 133.90136718749997, - -14.647368383896618 - ], - [ - 126.73828125, - -19.352610894378625 - ], - [ - 128.49609375, - -27.371767300523032 - ], - [ - 134.1650390625, - -30.789036751261136 - ], - [ - 143.7890625, - -30.789036751261136 - ], - [ - 144.9755859375, - -26.391869671769022 - ], - [ - 144.31640625, - -17.14079039331664 - ], - [ - 133.90136718749997, - -14.647368383896618 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/north-latitude-points.geojson b/packages/turf-buffer/test/out/north-latitude-points.geojson deleted file mode 100644 index 56edc16385..0000000000 --- a/packages/turf-buffer/test/out/north-latitude-points.geojson +++ /dev/null @@ -1,211 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -97.430762, - 74.428523 - ], - [ - -97.361193, - 74.378549 - ], - [ - -97.086327, - 74.257817 - ], - [ - -96.734093, - 74.153407 - ], - [ - -96.318223, - 74.068983 - ], - [ - -95.853944, - 74.00746 - ], - [ - -95.35753, - 73.97093 - ], - [ - -94.845904, - 73.960619 - ], - [ - -94.336271, - 73.976866 - ], - [ - -94.079491, - 73.99915 - ], - [ - -94.045157, - 73.998293 - ], - [ - -93.533734, - 74.012632 - ], - [ - -93.04027, - 74.053034 - ], - [ - -92.581594, - 74.11812 - ], - [ - -92.17381, - 74.205665 - ], - [ - -91.831899, - 74.312637 - ], - [ - -91.569267, - 74.435274 - ], - [ - -91.39724, - 74.569177 - ], - [ - -91.324493, - 74.709433 - ], - [ - -91.356461, - 74.850762 - ], - [ - -91.494758, - 74.987699 - ], - [ - -91.736671, - 75.114805 - ], - [ - -92.074829, - 75.226893 - ], - [ - -92.497122, - 75.319276 - ], - [ - -92.986962, - 75.388004 - ], - [ - -93.523933, - 75.430087 - ], - [ - -94.084817, - 75.443664 - ], - [ - -94.292126, - 75.438074 - ], - [ - -94.48136, - 75.451876 - ], - [ - -95.043939, - 75.463169 - ], - [ - -95.60377, - 75.445346 - ], - [ - -96.136226, - 75.399188 - ], - [ - -96.61833, - 75.326713 - ], - [ - -97.030062, - 75.231057 - ], - [ - -97.355353, - 75.116296 - ], - [ - -97.582692, - 74.987218 - ], - [ - -97.705345, - 74.84908 - ], - [ - -97.721242, - 74.707364 - ], - [ - -97.632615, - 74.567548 - ], - [ - -97.445477, - 74.43489 - ], - [ - -97.430762, - 74.428523 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "MultiPoint", - "coordinates": [ - [ - -94.97955322265625, - 74.74046209428195 - ], - [ - -94.90264892578125, - 74.68325030051861 - ], - [ - -94.06494140625, - 74.7209322003536 - ] - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/northern-polygon.geojson b/packages/turf-buffer/test/out/northern-polygon.geojson deleted file mode 100644 index 221065be3a..0000000000 --- a/packages/turf-buffer/test/out/northern-polygon.geojson +++ /dev/null @@ -1,233 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -94.585649, - 73.970668 - ], - [ - -94.060867, - 73.997501 - ], - [ - -93.563804, - 74.051942 - ], - [ - -93.113004, - 74.131982 - ], - [ - -92.725942, - 74.234647 - ], - [ - -92.418504, - 74.356063 - ], - [ - -92.204406, - 74.491561 - ], - [ - -92.180703, - 74.511942 - ], - [ - -92.079369, - 74.635523 - ], - [ - -92.05993, - 74.761907 - ], - [ - -92.124976, - 74.887248 - ], - [ - -92.14698, - 74.912484 - ], - [ - -92.307136, - 75.038994 - ], - [ - -92.557645, - 75.15553 - ], - [ - -92.891418, - 75.257861 - ], - [ - -93.29767, - 75.342188 - ], - [ - -93.762169, - 75.405315 - ], - [ - -94.267747, - 75.44481 - ], - [ - -94.795069, - 75.459132 - ], - [ - -94.872834, - 75.459333 - ], - [ - -95.399954, - 75.447804 - ], - [ - -95.907728, - 75.41111 - ], - [ - -96.376756, - 75.350664 - ], - [ - -96.457031, - 75.337679 - ], - [ - -96.872497, - 75.254835 - ], - [ - -97.215887, - 75.153369 - ], - [ - -97.475801, - 75.037104 - ], - [ - -97.644623, - 74.910329 - ], - [ - -97.71854, - 74.777609 - ], - [ - -97.697366, - 74.643606 - ], - [ - -97.584203, - 74.51291 - ], - [ - -97.385019, - 74.389885 - ], - [ - -97.318087, - 74.356893 - ], - [ - -96.9989, - 74.231284 - ], - [ - -96.594781, - 74.125927 - ], - [ - -96.123523, - 74.045073 - ], - [ - -95.604689, - 73.99193 - ], - [ - -95.058992, - 73.968576 - ], - [ - -95.012377, - 73.96789 - ], - [ - -94.629644, - 73.969621 - ], - [ - -94.585649, - 73.970668 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -94.81887817382812, - 74.69068515369659 - ], - [ - -94.79827880859375, - 74.71133916265154 - ], - [ - -94.82437133789062, - 74.73630499357218 - ], - [ - -94.89852905273438, - 74.73648576006866 - ], - [ - -94.976806640625, - 74.72400796764163 - ], - [ - -94.91363525390625, - 74.69032255967197 - ], - [ - -94.86488342285156, - 74.68959734647507 - ], - [ - -94.81887817382812, - 74.69068515369659 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/point.geojson b/packages/turf-buffer/test/out/point.geojson deleted file mode 100644 index 2743964175..0000000000 --- a/packages/turf-buffer/test/out/point.geojson +++ /dev/null @@ -1,169 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 135.722849, - -25 - ], - [ - 135.70896, - -25.127742 - ], - [ - 135.667826, - -25.250449 - ], - [ - 135.601027, - -25.363426 - ], - [ - 135.511132, - -25.462365 - ], - [ - 135.401593, - -25.543502 - ], - [ - 135.276622, - -25.603756 - ], - [ - 135.141021, - -25.640845 - ], - [ - 135, - -25.653366 - ], - [ - 134.858979, - -25.640845 - ], - [ - 134.723378, - -25.603756 - ], - [ - 134.598407, - -25.543502 - ], - [ - 134.488868, - -25.462365 - ], - [ - 134.398973, - -25.363426 - ], - [ - 134.332174, - -25.250449 - ], - [ - 134.29104, - -25.127742 - ], - [ - 134.277151, - -25 - ], - [ - 134.29104, - -24.872125 - ], - [ - 134.332174, - -24.74904 - ], - [ - 134.398973, - -24.635496 - ], - [ - 134.488868, - -24.535888 - ], - [ - 134.598407, - -24.454083 - ], - [ - 134.723378, - -24.393263 - ], - [ - 134.858979, - -24.355795 - ], - [ - 135, - -24.343141 - ], - [ - 135.141021, - -24.355795 - ], - [ - 135.276622, - -24.393263 - ], - [ - 135.401593, - -24.454083 - ], - [ - 135.511132, - -24.535888 - ], - [ - 135.601027, - -24.635496 - ], - [ - 135.667826, - -24.74904 - ], - [ - 135.70896, - -24.872125 - ], - [ - 135.722849, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Point", - "coordinates": [ - 135, - -25 - ] - } - } - ] -} diff --git a/packages/turf-buffer/test/out/polygon-with-holes.geojson b/packages/turf-buffer/test/out/polygon-with-holes.geojson deleted file mode 100644 index 4eb3f37118..0000000000 --- a/packages/turf-buffer/test/out/polygon-with-holes.geojson +++ /dev/null @@ -1,281 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "fill": "#F00", - "marker-color": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 123.46799, - -24.566384 - ], - [ - 124.171115, - -13.879973 - ], - [ - 124.195615, - -13.73725 - ], - [ - 124.249728, - -13.602357 - ], - [ - 124.331155, - -13.481046 - ], - [ - 124.436435, - -13.378493 - ], - [ - 124.561096, - -13.299085 - ], - [ - 124.699841, - -13.246219 - ], - [ - 124.846775, - -13.222159 - ], - [ - 130.383885, - -12.879678 - ], - [ - 130.441733, - -12.87836 - ], - [ - 135.715171, - -12.964025 - ], - [ - 135.8351, - -12.975767 - ], - [ - 135.95136, - -13.006763 - ], - [ - 136.060717, - -13.056144 - ], - [ - 141.773608, - -16.202222 - ], - [ - 141.891232, - -16.282407 - ], - [ - 141.989929, - -16.383374 - ], - [ - 142.065768, - -16.501072 - ], - [ - 145.493502, - -23.11175 - ], - [ - 145.545559, - -23.243779 - ], - [ - 145.566271, - -23.382775 - ], - [ - 145.554713, - -23.522518 - ], - [ - 145.511402, - -23.656771 - ], - [ - 145.438271, - -23.779565 - ], - [ - 138.934365, - -32.077223 - ], - [ - 138.838817, - -32.171942 - ], - [ - 138.722607, - -32.248246 - ], - [ - 138.590545, - -32.303026 - ], - [ - 138.448102, - -32.334053 - ], - [ - 138.301175, - -32.340067 - ], - [ - 128.457425, - -31.893427 - ], - [ - 128.31488, - -31.874705 - ], - [ - 128.17955, - -31.832311 - ], - [ - 128.056825, - -31.7679 - ], - [ - 127.95159, - -31.683995 - ], - [ - 127.868036, - -31.583889 - ], - [ - 123.561395, - -24.931994 - ], - [ - 123.504356, - -24.816505 - ], - [ - 123.47283, - -24.693109 - ], - [ - 123.46799, - -24.566384 - ] - ], - [ - [ - 130.390216, - -26.3742 - ], - [ - 138.364065, - -26.3742 - ], - [ - 138.364065, - -18.081063 - ], - [ - 128.667834, - -18.081063 - ], - [ - 130.390216, - -26.3742 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "fill": "#00F", - "marker-color": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 124.18945312500001, - -24.607069137709694 - ], - [ - 128.49609375, - -31.278550858946517 - ], - [ - 138.33984375, - -31.728167146023935 - ], - [ - 144.84375, - -23.40276490540795 - ], - [ - 141.416015625, - -16.804541076383455 - ], - [ - 135.703125, - -13.667338259654947 - ], - [ - 130.4296875, - -13.581920900545844 - ], - [ - 124.892578125, - -13.923403897723334 - ], - [ - 124.18945312500001, - -24.607069137709694 - ] - ], - [ - [ - 129.79296875, - -27.019984007982554 - ], - [ - 139.0869140625, - -27.019984007982554 - ], - [ - 139.0869140625, - -17.392579271057766 - ], - [ - 127.79296875, - -17.392579271057766 - ], - [ - 129.79296875, - -27.019984007982554 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-buffer/types.ts b/packages/turf-buffer/types.ts deleted file mode 100644 index 878de6388b..0000000000 --- a/packages/turf-buffer/types.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - point, lineString, polygon, - multiPoint, multiLineString, multiPolygon, - featureCollection, geometryCollection, - Point, LineString -} from '@turf/helpers' -import buffer from './' - -// Standard Geometry -const pt = point([100, 0]); -const line = lineString([[100, 0], [50, 0]]); -const poly = polygon([[[100, 0], [50, 0], [0, 50], [100, 0]]]); - -buffer(pt, 5); -buffer(line, 5); -buffer(poly, 5); -buffer(pt, 5, {units: 'miles'}); -buffer(pt, 10, {units: 'meters', steps: 64}); - -// Multi Geometry -const multiPt = multiPoint([[100, 0], [0, 100]]); -const multiLine = multiLineString([[[100, 0], [50, 0]], [[100, 0], [50, 0]]]); -const multiPoly = multiPolygon([[[[100, 0], [50, 0], [0, 50], [100, 0]]], [[[100, 0], [50, 0], [0, 50], [100, 0]]]]); - -buffer(multiPt, 5); -buffer(multiLine, 5); -buffer(multiPoly, 5); - -// Collections -const fc = featureCollection([pt, line]); -const gc = geometryCollection([pt.geometry, line.geometry]); - -buffer(fc, 5); -buffer(gc, 5); - -// Mixed Collections -const fcMixed = featureCollection([pt, line, multiPt, multiLine]); -const gcMixed = geometryCollection([pt.geometry, line.geometry, multiPt.geometry, multiLine.geometry]); - -buffer(fcMixed, 5); -buffer(gcMixed, 5); \ No newline at end of file diff --git a/packages/turf-center-mean/.gitignore b/packages/turf-center-mean/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-center-mean/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-center-mean/LICENSE b/packages/turf-center-mean/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-center-mean/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-center-mean/README.md b/packages/turf-center-mean/README.md deleted file mode 100644 index 4b60914e1c..0000000000 --- a/packages/turf-center-mean/README.md +++ /dev/null @@ -1,75 +0,0 @@ -# @turf/center-mean - - - -## centerMean - -Takes a [Feature][1] or [FeatureCollection][2] and returns the mean center. Can be weighted. - -**Parameters** - -- `geojson` **[GeoJSON][3]** GeoJSON to be centered -- `options` **[Object][4]** Optional parameters (optional, default `{}`) - - `options.properties` **[Object][4]** Translate GeoJSON Properties to Point (optional, default `{}`) - - `options.bbox` **[Object][4]** Translate GeoJSON BBox to Point (optional, default `{}`) - - `options.id` **[Object][4]** Translate GeoJSON Id to Point (optional, default `{}`) - - `options.weight` **[string][5]?** the property name used to weight the center - -**Examples** - -```javascript -var features = turf.featureCollection([ - turf.point([-97.522259, 35.4691], {value: 10}), - turf.point([-97.502754, 35.463455], {value: 3}), - turf.point([-97.508269, 35.463245], {value: 5}) -]); - -var options = {weight: "value"} -var mean = turf.centerMean(features, options); - -//addToMap -var addToMap = [features, mean] -mean.properties['marker-size'] = 'large'; -mean.properties['marker-color'] = '#000'; -``` - -Returns **[Feature][6]<[Point][7]>** a Point feature at the mean center point of all input features - -[1]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[3]: https://tools.ietf.org/html/rfc7946#section-3 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[6]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/center-mean -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-center-mean/index.ts b/packages/turf-center-mean/index.ts deleted file mode 100644 index 801a955a4b..0000000000 --- a/packages/turf-center-mean/index.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { geomEach, coordEach } from '@turf/meta'; -import { isNumber, point, Feature, Point, Properties, BBox, Id, AllGeoJSON } from '@turf/helpers'; - -/** - * Takes a {@link Feature} or {@link FeatureCollection} and returns the mean center. Can be weighted. - * - * @name centerMean - * @param {GeoJSON} geojson GeoJSON to be centered - * @param {Object} [options={}] Optional parameters - * @param {Object} [options.properties={}] Translate GeoJSON Properties to Point - * @param {Object} [options.bbox={}] Translate GeoJSON BBox to Point - * @param {Object} [options.id={}] Translate GeoJSON Id to Point - * @param {string} [options.weight] the property name used to weight the center - * @returns {Feature} a Point feature at the mean center point of all input features - * @example - * var features = turf.featureCollection([ - * turf.point([-97.522259, 35.4691], {value: 10}), - * turf.point([-97.502754, 35.463455], {value: 3}), - * turf.point([-97.508269, 35.463245], {value: 5}) - * ]); - * - * var options = {weight: "value"} - * var mean = turf.centerMean(features, options); - * - * //addToMap - * var addToMap = [features, mean] - * mean.properties['marker-size'] = 'large'; - * mean.properties['marker-color'] = '#000'; - */ -function centerMean

( - geojson: any, // To-Do include Typescript AllGeoJSON - options: {properties?: P, bbox?: BBox, id?: Id, weight?: string} = {}, -): Feature { - let sumXs = 0; - let sumYs = 0; - let sumNs = 0; - geomEach(geojson, function (geom, featureIndex, properties) { - let weight = properties[options.weight]; - weight = (weight === undefined || weight === null) ? 1 : weight; - if (!isNumber(weight)) throw new Error('weight value must be a number for feature index ' + featureIndex); - weight = Number(weight); - if (weight > 0) { - coordEach(geom, function (coord) { - sumXs += coord[0] * weight; - sumYs += coord[1] * weight; - sumNs += weight; - }); - } - }); - return point([sumXs / sumNs, sumYs / sumNs], options.properties, options); -} - -export default centerMean; diff --git a/packages/turf-center-mean/package.json b/packages/turf-center-mean/package.json deleted file mode 100644 index 43eddcc28c..0000000000 --- a/packages/turf-center-mean/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "@turf/center-mean", - "version": "6.0.1", - "description": "turf center-mean module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "center", - "mean", - "geojson", - "gis", - "geospatial", - "geo", - "turf" - ], - "author": "Turf Authors", - "contributors": [ - "Moacir P. de Sá Pereira <@muziejus>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/center": "*", - "@turf/truncate": "*", - "benchmark": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-center-mean/test.js b/packages/turf-center-mean/test.js deleted file mode 100644 index f60e744317..0000000000 --- a/packages/turf-center-mean/test.js +++ /dev/null @@ -1,39 +0,0 @@ -const test = require('tape'); -const glob = require('glob'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const truncate = require('@turf/truncate').default; -const { featureEach, coordEach } = require('@turf/meta'); -const { lineString, featureCollection } = require('@turf/helpers'); -const center = require('@turf/center').default; -const centerMean = require('./').default; - -test('turf-center-mean', t => { - glob.sync(path.join(__dirname, 'test', 'in', '*.geojson')).forEach(filepath => { - const geojson = load.sync(filepath); - const options = geojson.options || {}; - options.properties = {'marker-symbol': 'star', 'marker-color': '#F00'}; - const centered = truncate(centerMean(geojson, options)); - - // Display Results - const results = featureCollection([]); - featureEach(geojson, feature => results.features.push(feature)); - coordEach(geojson, coord => results.features.push(lineString([coord, centered.geometry.coordinates], {stroke: '#00F', 'stroke-width': 1}))); - // Add @turf/center to compare position - results.features.push(truncate(center(geojson, {properties: {'marker-symbol': 'circle', 'marker-color': '#00F'}}))); - results.features.push(centered); - - const out = filepath.replace(path.join('test', 'in'), path.join('test', 'out')); - if (process.env.REGEN) write.sync(out, results); - t.deepEqual(results, load.sync(out), path.parse(filepath).name); - }); - t.end(); -}); - -test('turf-center-mean -- properties', t => { - const line = lineString([[0, 0], [1, 1]]); - const pt = centerMean(line, {properties: {foo: 'bar'}}); - t.equal(pt.properties.foo, 'bar', 'translate properties'); - t.end(); -}); diff --git a/packages/turf-center-mean/types.ts b/packages/turf-center-mean/types.ts deleted file mode 100644 index f5bfd8166d..0000000000 --- a/packages/turf-center-mean/types.ts +++ /dev/null @@ -1,8 +0,0 @@ -import {lineString} from '@turf/helpers' -import centerMean from './' - -const line = lineString([[0, 0], [10, 10]]); - -centerMean(line) -centerMean(line, {properties: {foo: 'bar'}}) -centerMean(line, {weight: 'foo'}) diff --git a/packages/turf-center-median/.gitignore b/packages/turf-center-median/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-center-median/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-center-median/LICENSE b/packages/turf-center-median/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-center-median/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-center-median/README.md b/packages/turf-center-median/README.md deleted file mode 100644 index 41e291c201..0000000000 --- a/packages/turf-center-median/README.md +++ /dev/null @@ -1,103 +0,0 @@ -# @turf/center-median - - - -## centerMedian - -Takes a [FeatureCollection][1] of points and calculates the median center, -algorithimically. The median center is understood as the point that is -requires the least total travel from all other points. - -Turfjs has four different functions for calculating the center of a set of -data. Each is useful depending on circumstance. - -`@turf/center` finds the simple center of a dataset, by finding the -midpoint between the extents of the data. That is, it divides in half the -farthest east and farthest west point as well as the farthest north and -farthest south. - -`@turf/center-of-mass` imagines that the dataset is a sheet of paper. -The center of mass is where the sheet would balance on a fingertip. - -`@turf/center-mean` takes the averages of all the coordinates and -produces a value that respects that. Unlike `@turf/center`, it is -sensitive to clusters and outliers. It lands in the statistical middle of a -dataset, not the geographical. It can also be weighted, meaning certain -points are more important than others. - -`@turf/center-median` takes the mean center and tries to find, iteratively, -a new point that requires the least amount of travel from all the points in -the dataset. It is not as sensitive to outliers as `@turf/center`, but it is -attracted to clustered data. It, too, can be weighted. - -**Bibliography** - -Harold W. Kuhn and Robert E. Kuenne, “An Efficient Algorithm for the -Numerical Solution of the Generalized Weber Problem in Spatial -Economics,” _Journal of Regional Science_ 4, no. 2 (1962): 21–33, -doi:[https://doi.org/10.1111/j.1467-9787.1962.tb00902.x][2]. - -James E. Burt, Gerald M. Barber, and David L. Rigby, _Elementary -Statistics for Geographers_, 3rd ed., New York: The Guilford -Press, 2009, 150–151. - -**Parameters** - -- `features` **[FeatureCollection][3]<any>** Any GeoJSON Feature Collection -- `options` **[Object][4]** Optional parameters (optional, default `{}`) - - `options.weight` **[string][5]?** the property name used to weight the center - - `options.tolerance` **[number][6]** the difference in distance between candidate medians at which point the algorighim stops iterating. (optional, default `0.001`) - - `options.counter` **[number][6]** how many attempts to find the median, should the tolerance be insufficient. (optional, default `10`) - -**Examples** - -```javascript -var points = turf.points([[0, 0], [1, 0], [0, 1], [5, 8]]); -var medianCenter = turf.centerMedian(points); - -//addToMap -var addToMap = [points, medianCenter] -``` - -Returns **[Feature][7]<[Point][8]>** The median center of the collection - -[1]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[2]: https://doi.org/10.1111/j.1467-9787.1962.tb00902.x - -[3]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[7]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[8]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/center-median -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-center-median/index.ts b/packages/turf-center-median/index.ts deleted file mode 100644 index 7fd4879bc4..0000000000 --- a/packages/turf-center-median/index.ts +++ /dev/null @@ -1,135 +0,0 @@ -import centerMean from '@turf/center-mean'; -import distance from '@turf/distance'; -import centroid from '@turf/centroid'; -import { - isNumber, point, isObject, featureCollection, - FeatureCollection, Feature, Point -} from '@turf/helpers'; -import { featureEach } from '@turf/meta'; - -/** - * Takes a {@link FeatureCollection} of points and calculates the median center, - * algorithimically. The median center is understood as the point that is - * requires the least total travel from all other points. - * - * Turfjs has four different functions for calculating the center of a set of - * data. Each is useful depending on circumstance. - * - * `@turf/center` finds the simple center of a dataset, by finding the - * midpoint between the extents of the data. That is, it divides in half the - * farthest east and farthest west point as well as the farthest north and - * farthest south. - * - * `@turf/center-of-mass` imagines that the dataset is a sheet of paper. - * The center of mass is where the sheet would balance on a fingertip. - * - * `@turf/center-mean` takes the averages of all the coordinates and - * produces a value that respects that. Unlike `@turf/center`, it is - * sensitive to clusters and outliers. It lands in the statistical middle of a - * dataset, not the geographical. It can also be weighted, meaning certain - * points are more important than others. - * - * `@turf/center-median` takes the mean center and tries to find, iteratively, - * a new point that requires the least amount of travel from all the points in - * the dataset. It is not as sensitive to outliers as `@turf/center-mean`, but it is - * attracted to clustered data. It, too, can be weighted. - * - * **Bibliography** - * - * Harold W. Kuhn and Robert E. Kuenne, “An Efficient Algorithm for the - * Numerical Solution of the Generalized Weber Problem in Spatial - * Economics,” _Journal of Regional Science_ 4, no. 2 (1962): 21–33, - * doi:{@link https://doi.org/10.1111/j.1467-9787.1962.tb00902.x}. - * - * James E. Burt, Gerald M. Barber, and David L. Rigby, _Elementary - * Statistics for Geographers_, 3rd ed., New York: The Guilford - * Press, 2009, 150–151. - * - * @name centerMedian - * @param {FeatureCollection} features Any GeoJSON Feature Collection - * @param {Object} [options={}] Optional parameters - * @param {string} [options.weight] the property name used to weight the center - * @param {number} [options.tolerance=0.001] the difference in distance between candidate medians at which point the algorighim stops iterating. - * @param {number} [options.counter=10] how many attempts to find the median, should the tolerance be insufficient. - * @returns {Feature} The median center of the collection - * @example - * var points = turf.points([[0, 0], [1, 0], [0, 1], [5, 8]]); - * var medianCenter = turf.centerMedian(points); - * - * //addToMap - * var addToMap = [points, medianCenter] - */ -function centerMedian( - features: FeatureCollection, - options: { weight?: string, tolerance?: number, counter?: number} = {} -): Feature, - [key: string]: any -}> { - // Optional params - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var counter = options.counter || 10; - if (!isNumber(counter)) throw new Error('counter must be a number'); - var weightTerm = options.weight; - - // Calculate mean center: - var meanCenter = centerMean(features, {weight: options.weight}); - - // Calculate center of every feature: - var centroids: any = featureCollection([]); - featureEach(features, function (feature) { - centroids.features.push(centroid(feature, {properties: {weight: feature.properties[weightTerm]}})); - }); - - centroids.properties = { - tolerance: options.tolerance, - medianCandidates: [] - }; - return findMedian(meanCenter.geometry.coordinates, [0, 0], centroids, counter); -} - -/** - * Recursive function to find new candidate medians. - * - * @private - * @param {Position} candidateMedian current candidate median - * @param {Position} previousCandidate the previous candidate median - * @param {FeatureCollection} centroids the collection of centroids whose median we are determining - * @param {number} counter how many attempts to try before quitting. - * @returns {Feature} the median center of the dataset. - */ -function findMedian(candidateMedian, previousCandidate, centroids, counter) { - var tolerance = centroids.properties.tolerance || 0.001; - var candidateXsum = 0; - var candidateYsum = 0; - var kSum = 0; - var centroidCount = 0; - featureEach(centroids, function (theCentroid: any) { - var weightValue = theCentroid.properties.weight; - var weight = (weightValue === undefined || weightValue === null) ? 1 : weightValue; - weight = Number(weight); - if (!isNumber(weight)) throw new Error('weight value must be a number'); - if (weight > 0) { - centroidCount += 1; - var distanceFromCandidate = weight * distance(theCentroid, candidateMedian); - if (distanceFromCandidate === 0) distanceFromCandidate = 1; - var k = weight / distanceFromCandidate; - candidateXsum += theCentroid.geometry.coordinates[0] * k; - candidateYsum += theCentroid.geometry.coordinates[1] * k; - kSum += k; - } - }); - if (centroidCount < 1) throw new Error('no features to measure'); - var candidateX = candidateXsum / kSum; - var candidateY = candidateYsum / kSum; - if (centroidCount === 1 || counter === 0 || (Math.abs(candidateX - previousCandidate[0]) < tolerance && Math.abs(candidateY - previousCandidate[1]) < tolerance)) { - return point([candidateX, candidateY], {medianCandidates: centroids.properties.medianCandidates}); - } else { - centroids.properties.medianCandidates.push([candidateX, candidateY]); - return findMedian([candidateX, candidateY], candidateMedian, centroids, counter - 1); - } -} - -export default centerMedian; - diff --git a/packages/turf-center-median/package.json b/packages/turf-center-median/package.json deleted file mode 100644 index d1a1cf345c..0000000000 --- a/packages/turf-center-median/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "@turf/center-median", - "version": "6.0.1", - "description": "turf center-median module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "center-median" - ], - "author": "Turf Authors", - "contributors": [ - "Moacir P. de Sá Pereira <@muziejus>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/center": "*", - "@turf/center-of-mass": "*", - "@turf/random": "*", - "@turf/truncate": "*", - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/center-mean": "6.x", - "@turf/centroid": "6.x", - "@turf/distance": "6.x", - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-center-median/test.js b/packages/turf-center-median/test.js deleted file mode 100644 index 33e6c7141f..0000000000 --- a/packages/turf-center-median/test.js +++ /dev/null @@ -1,49 +0,0 @@ -const test = require('tape'); -const glob = require('glob'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const center = require('@turf/center').default; -const truncate = require('@turf/truncate').default; -const centerMean = require('@turf/center-mean').default; -const centerOfMass = require('@turf/center-of-mass').default; -const { featureCollection, round } = require('@turf/helpers'); -const centerMedian = require('./').default; - -test('turf-center-median', t => { - glob.sync(path.join(__dirname, 'test', 'in', '*.json')).forEach(filepath => { - // Define params - const {name} = path.parse(filepath); - const geojson = load.sync(filepath); - const options = geojson.properties; - - // Calculate Centers - const meanCenter = centerMean(geojson, options); - const medianCenter = centerMedian(geojson, options); - const extentCenter = center(geojson); - const massCenter = centerOfMass(geojson); - - // Truncate median properties - medianCenter.properties.medianCandidates.forEach((candidate, index) => { - medianCenter.properties.medianCandidates[index] = [round(candidate[0], 6), round(candidate[1], 6)]; - }); - const results = featureCollection([ - ...geojson.features, - colorize(meanCenter, '#a00'), - colorize(medianCenter, '#0a0'), - colorize(extentCenter, '#00a'), - colorize(massCenter, '#aaa') - ]); - - const out = filepath.replace(path.join('test', 'in'), path.join('test', 'out')); - if (process.env.REGEN) write.sync(out, results); - t.deepEqual(results, load.sync(out), name); - }); - t.end(); -}); - -function colorize(point, color) { - point.properties['marker-color'] = color; - point.properties['marker-symbol'] = 'cross'; - return truncate(point); -} diff --git a/packages/turf-center-median/test/out/squares.json b/packages/turf-center-median/test/out/squares.json deleted file mode 100644 index a12a628f11..0000000000 --- a/packages/turf-center-median/test/out/squares.json +++ /dev/null @@ -1,1123 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299992605418552, - 38.12013592725509 - ], - [ - -9.299992605418552, - 38.16510194544132 - ], - [ - -9.242851861013252, - 38.16510194544132 - ], - [ - -9.242851861013252, - 38.12013592725509 - ], - [ - -9.299992605418552, - 38.12013592725509 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299992605418552, - 38.16510194544132 - ], - [ - -9.299992605418552, - 38.21006796362755 - ], - [ - -9.242851861013252, - 38.21006796362755 - ], - [ - -9.242851861013252, - 38.16510194544132 - ], - [ - -9.299992605418552, - 38.16510194544132 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299992605418552, - 38.21006796362755 - ], - [ - -9.299992605418552, - 38.25503398181378 - ], - [ - -9.242851861013252, - 38.25503398181378 - ], - [ - -9.242851861013252, - 38.21006796362755 - ], - [ - -9.299992605418552, - 38.21006796362755 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299992605418552, - 38.25503398181378 - ], - [ - -9.299992605418552, - 38.30000000000001 - ], - [ - -9.242851861013252, - 38.30000000000001 - ], - [ - -9.242851861013252, - 38.25503398181378 - ], - [ - -9.299992605418552, - 38.25503398181378 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299992605418552, - 38.30000000000001 - ], - [ - -9.299992605418552, - 38.34496601818624 - ], - [ - -9.242851861013252, - 38.34496601818624 - ], - [ - -9.242851861013252, - 38.30000000000001 - ], - [ - -9.299992605418552, - 38.30000000000001 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299992605418552, - 38.34496601818624 - ], - [ - -9.299992605418552, - 38.38993203637247 - ], - [ - -9.242851861013252, - 38.38993203637247 - ], - [ - -9.242851861013252, - 38.34496601818624 - ], - [ - -9.299992605418552, - 38.34496601818624 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299992605418552, - 38.38993203637247 - ], - [ - -9.299992605418552, - 38.4348980545587 - ], - [ - -9.242851861013252, - 38.4348980545587 - ], - [ - -9.242851861013252, - 38.38993203637247 - ], - [ - -9.299992605418552, - 38.38993203637247 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299992605418552, - 38.4348980545587 - ], - [ - -9.299992605418552, - 38.47986407274493 - ], - [ - -9.242851861013252, - 38.47986407274493 - ], - [ - -9.242851861013252, - 38.4348980545587 - ], - [ - -9.299992605418552, - 38.4348980545587 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242851861013252, - 38.12013592725509 - ], - [ - -9.242851861013252, - 38.16510194544132 - ], - [ - -9.185711116607951, - 38.16510194544132 - ], - [ - -9.185711116607951, - 38.12013592725509 - ], - [ - -9.242851861013252, - 38.12013592725509 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242851861013252, - 38.16510194544132 - ], - [ - -9.242851861013252, - 38.21006796362755 - ], - [ - -9.185711116607951, - 38.21006796362755 - ], - [ - -9.185711116607951, - 38.16510194544132 - ], - [ - -9.242851861013252, - 38.16510194544132 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242851861013252, - 38.21006796362755 - ], - [ - -9.242851861013252, - 38.25503398181378 - ], - [ - -9.185711116607951, - 38.25503398181378 - ], - [ - -9.185711116607951, - 38.21006796362755 - ], - [ - -9.242851861013252, - 38.21006796362755 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242851861013252, - 38.25503398181378 - ], - [ - -9.242851861013252, - 38.30000000000001 - ], - [ - -9.185711116607951, - 38.30000000000001 - ], - [ - -9.185711116607951, - 38.25503398181378 - ], - [ - -9.242851861013252, - 38.25503398181378 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242851861013252, - 38.30000000000001 - ], - [ - -9.242851861013252, - 38.34496601818624 - ], - [ - -9.185711116607951, - 38.34496601818624 - ], - [ - -9.185711116607951, - 38.30000000000001 - ], - [ - -9.242851861013252, - 38.30000000000001 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242851861013252, - 38.34496601818624 - ], - [ - -9.242851861013252, - 38.38993203637247 - ], - [ - -9.185711116607951, - 38.38993203637247 - ], - [ - -9.185711116607951, - 38.34496601818624 - ], - [ - -9.242851861013252, - 38.34496601818624 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242851861013252, - 38.38993203637247 - ], - [ - -9.242851861013252, - 38.4348980545587 - ], - [ - -9.185711116607951, - 38.4348980545587 - ], - [ - -9.185711116607951, - 38.38993203637247 - ], - [ - -9.242851861013252, - 38.38993203637247 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242851861013252, - 38.4348980545587 - ], - [ - -9.242851861013252, - 38.47986407274493 - ], - [ - -9.185711116607951, - 38.47986407274493 - ], - [ - -9.185711116607951, - 38.4348980545587 - ], - [ - -9.242851861013252, - 38.4348980545587 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711116607951, - 38.12013592725509 - ], - [ - -9.185711116607951, - 38.16510194544132 - ], - [ - -9.12857037220265, - 38.16510194544132 - ], - [ - -9.12857037220265, - 38.12013592725509 - ], - [ - -9.185711116607951, - 38.12013592725509 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711116607951, - 38.16510194544132 - ], - [ - -9.185711116607951, - 38.21006796362755 - ], - [ - -9.12857037220265, - 38.21006796362755 - ], - [ - -9.12857037220265, - 38.16510194544132 - ], - [ - -9.185711116607951, - 38.16510194544132 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711116607951, - 38.21006796362755 - ], - [ - -9.185711116607951, - 38.25503398181378 - ], - [ - -9.12857037220265, - 38.25503398181378 - ], - [ - -9.12857037220265, - 38.21006796362755 - ], - [ - -9.185711116607951, - 38.21006796362755 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711116607951, - 38.25503398181378 - ], - [ - -9.185711116607951, - 38.30000000000001 - ], - [ - -9.12857037220265, - 38.30000000000001 - ], - [ - -9.12857037220265, - 38.25503398181378 - ], - [ - -9.185711116607951, - 38.25503398181378 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711116607951, - 38.30000000000001 - ], - [ - -9.185711116607951, - 38.34496601818624 - ], - [ - -9.12857037220265, - 38.34496601818624 - ], - [ - -9.12857037220265, - 38.30000000000001 - ], - [ - -9.185711116607951, - 38.30000000000001 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711116607951, - 38.34496601818624 - ], - [ - -9.185711116607951, - 38.38993203637247 - ], - [ - -9.12857037220265, - 38.38993203637247 - ], - [ - -9.12857037220265, - 38.34496601818624 - ], - [ - -9.185711116607951, - 38.34496601818624 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711116607951, - 38.38993203637247 - ], - [ - -9.185711116607951, - 38.4348980545587 - ], - [ - -9.12857037220265, - 38.4348980545587 - ], - [ - -9.12857037220265, - 38.38993203637247 - ], - [ - -9.185711116607951, - 38.38993203637247 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711116607951, - 38.4348980545587 - ], - [ - -9.185711116607951, - 38.47986407274493 - ], - [ - -9.12857037220265, - 38.47986407274493 - ], - [ - -9.12857037220265, - 38.4348980545587 - ], - [ - -9.185711116607951, - 38.4348980545587 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857037220265, - 38.12013592725509 - ], - [ - -9.12857037220265, - 38.16510194544132 - ], - [ - -9.07142962779735, - 38.16510194544132 - ], - [ - -9.07142962779735, - 38.12013592725509 - ], - [ - -9.12857037220265, - 38.12013592725509 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857037220265, - 38.16510194544132 - ], - [ - -9.12857037220265, - 38.21006796362755 - ], - [ - -9.07142962779735, - 38.21006796362755 - ], - [ - -9.07142962779735, - 38.16510194544132 - ], - [ - -9.12857037220265, - 38.16510194544132 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857037220265, - 38.21006796362755 - ], - [ - -9.12857037220265, - 38.25503398181378 - ], - [ - -9.07142962779735, - 38.25503398181378 - ], - [ - -9.07142962779735, - 38.21006796362755 - ], - [ - -9.12857037220265, - 38.21006796362755 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857037220265, - 38.25503398181378 - ], - [ - -9.12857037220265, - 38.30000000000001 - ], - [ - -9.07142962779735, - 38.30000000000001 - ], - [ - -9.07142962779735, - 38.25503398181378 - ], - [ - -9.12857037220265, - 38.25503398181378 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857037220265, - 38.30000000000001 - ], - [ - -9.12857037220265, - 38.34496601818624 - ], - [ - -9.07142962779735, - 38.34496601818624 - ], - [ - -9.07142962779735, - 38.30000000000001 - ], - [ - -9.12857037220265, - 38.30000000000001 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857037220265, - 38.34496601818624 - ], - [ - -9.12857037220265, - 38.38993203637247 - ], - [ - -9.07142962779735, - 38.38993203637247 - ], - [ - -9.07142962779735, - 38.34496601818624 - ], - [ - -9.12857037220265, - 38.34496601818624 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857037220265, - 38.38993203637247 - ], - [ - -9.12857037220265, - 38.4348980545587 - ], - [ - -9.07142962779735, - 38.4348980545587 - ], - [ - -9.07142962779735, - 38.38993203637247 - ], - [ - -9.12857037220265, - 38.38993203637247 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "weight": 1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857037220265, - 38.4348980545587 - ], - [ - -9.12857037220265, - 38.47986407274493 - ], - [ - -9.07142962779735, - 38.47986407274493 - ], - [ - -9.07142962779735, - 38.4348980545587 - ], - [ - -9.12857037220265, - 38.4348980545587 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#a00", - "marker-symbol": "cross" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.191425, - 38.295503 - ] - } - }, - { - "type": "Feature", - "properties": { - "medianCandidates": [ - [ - -9.191425, - 38.29551 - ] - ], - "marker-color": "#0a0", - "marker-symbol": "cross" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.191425, - 38.295515 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00a", - "marker-symbol": "cross" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.185711, - 38.3 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#aaa", - "marker-symbol": "cross" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.185711, - 38.3 - ] - } - } - ] -} diff --git a/packages/turf-center-of-mass/.gitignore b/packages/turf-center-of-mass/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-center-of-mass/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-center-of-mass/LICENSE b/packages/turf-center-of-mass/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-center-of-mass/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-center-of-mass/README.md b/packages/turf-center-of-mass/README.md deleted file mode 100644 index 6cc45c199e..0000000000 --- a/packages/turf-center-of-mass/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# @turf/center-of-mass - - - -## centerOfMass - -Takes any [Feature][1] or a [FeatureCollection][2] and returns its [center of mass][3] using this formula: [Centroid of Polygon][4]. - -**Parameters** - -- `geojson` **[GeoJSON][5]** GeoJSON to be centered -- `options` **[Object][6]** Optional Parameters (optional, default `{}`) - - `options.properties` **[Object][6]** Translate Properties to Feature (optional, default `{}`) - -**Examples** - -```javascript -var polygon = turf.polygon([[[-81, 41], [-88, 36], [-84, 31], [-80, 33], [-77, 39], [-81, 41]]]); - -var center = turf.centerOfMass(polygon); - -//addToMap -var addToMap = [polygon, center] -``` - -Returns **[Feature][7]<[Point][8]>** the center of mass - -[1]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[3]: https://en.wikipedia.org/wiki/Center_of_mass - -[4]: https://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon - -[5]: https://tools.ietf.org/html/rfc7946#section-3 - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[7]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[8]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/center-of-mass -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-center-of-mass/index.ts b/packages/turf-center-of-mass/index.ts deleted file mode 100644 index 61377d0d5b..0000000000 --- a/packages/turf-center-of-mass/index.ts +++ /dev/null @@ -1,97 +0,0 @@ -import convex from '@turf/convex'; -import centroid from '@turf/centroid'; -import { point, Properties, AllGeoJSON, Feature, Point } from '@turf/helpers'; -import { getType, getCoord } from '@turf/invariant'; -import { coordEach } from '@turf/meta'; - -/** - * Takes any {@link Feature} or a {@link FeatureCollection} and returns its [center of mass](https://en.wikipedia.org/wiki/Center_of_mass) using this formula: [Centroid of Polygon](https://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon). - * - * @name centerOfMass - * @param {GeoJSON} geojson GeoJSON to be centered - * @param {Object} [options={}] Optional Parameters - * @param {Object} [options.properties={}] Translate Properties to Feature - * @returns {Feature} the center of mass - * @example - * var polygon = turf.polygon([[[-81, 41], [-88, 36], [-84, 31], [-80, 33], [-77, 39], [-81, 41]]]); - * - * var center = turf.centerOfMass(polygon); - * - * //addToMap - * var addToMap = [polygon, center] - */ -function centerOfMass

(geojson: any, options: { - properties?: P, -} = {}): Feature { - switch (getType(geojson)) { - case 'Point': - return point(getCoord(geojson), options.properties); - case 'Polygon': - var coords = []; - coordEach(geojson, function (coord) { - coords.push(coord); - }); - - // First, we neutralize the feature (set it around coordinates [0,0]) to prevent rounding errors - // We take any point to translate all the points around 0 - var centre = centroid(geojson, {properties: options.properties}); - var translation = centre.geometry.coordinates; - var sx = 0; - var sy = 0; - var sArea = 0; - var i, pi, pj, xi, xj, yi, yj, a; - - var neutralizedPoints = coords.map(function (point) { - return [ - point[0] - translation[0], - point[1] - translation[1] - ]; - }); - - for (i = 0; i < coords.length - 1; i++) { - // pi is the current point - pi = neutralizedPoints[i]; - xi = pi[0]; - yi = pi[1]; - - // pj is the next point (pi+1) - pj = neutralizedPoints[i + 1]; - xj = pj[0]; - yj = pj[1]; - - // a is the common factor to compute the signed area and the final coordinates - a = xi * yj - xj * yi; - - // sArea is the sum used to compute the signed area - sArea += a; - - // sx and sy are the sums used to compute the final coordinates - sx += (xi + xj) * a; - sy += (yi + yj) * a; - } - - // Shape has no area: fallback on turf.centroid - if (sArea === 0) { - return centre; - } else { - // Compute the signed area, and factorize 1/6A - var area = sArea * 0.5; - var areaFactor = 1 / (6 * area); - - // Compute the final coordinates, adding back the values that have been neutralized - return point([ - translation[0] + areaFactor * sx, - translation[1] + areaFactor * sy - ], options.properties); - } - default: - // Not a polygon: Compute the convex hull and work with that - var hull = convex(geojson); - - if (hull) return centerOfMass(hull, {properties: options.properties}); - // Hull is empty: fallback on the centroid - else return centroid(geojson, {properties: options.properties}); - } -} - -export default centerOfMass; diff --git a/packages/turf-center-of-mass/package.json b/packages/turf-center-of-mass/package.json deleted file mode 100644 index c3dd3083dd..0000000000 --- a/packages/turf-center-of-mass/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@turf/center-of-mass", - "version": "6.0.1", - "description": "turf center-of-mass module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/centroid": "6.x", - "@turf/convex": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-center-of-mass/test.js b/packages/turf-center-of-mass/test.js deleted file mode 100644 index a20d9251d9..0000000000 --- a/packages/turf-center-of-mass/test.js +++ /dev/null @@ -1,80 +0,0 @@ -const path = require('path'); -const test = require('tape'); -const glob = require('glob'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { featureEach } = require('@turf/meta'); -const { - point, - lineString, - polygon, - featureCollection, - } = require('@turf/helpers'); -const centerOfMass = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep, -}; - -const fixtures = glob.sync(directories.in + '*.geojson').map(input => { - const base = path.parse(input).base; - return { - name: path.parse(input).name, - filename: base, - geojson: load.sync(input), - out: directories.out + base, - }; -}); - -test('center of mass', t => { - fixtures.forEach(fixture => { - const name = fixture.name; - const out = fixture.out; - const geojson = fixture.geojson; - const centered = centerOfMass(geojson, {'marker-symbol': 'circle'}); - const result = featureCollection([centered]); - featureEach(geojson, feature => result.features.push(feature)); - - if (process.env.REGEN) write.sync(out, result); - t.deepEqual(result, load.sync(out), name); - }); - t.end(); -}); - -test('center of mass -- Geometry Support', t => { - const line = lineString([[0, 0], [1, 1]]); - const poly = polygon([[[0, 0], [3, 3], [-5, -5], [0, 0]]]); - - t.deepEqual(centerOfMass(poly.geometry), centerOfMass(poly), 'polygon geometry/feature should be equal'); - t.deepEqual(centerOfMass(line.geometry), centerOfMass(line), 'lineString geometry/feature should be equal'); - t.end(); -}); - -test('center of mass -- no area', t => { - const poly = polygon([[[0, 0], [0, 0], [0, 0], [0, 0]]]); - const pt = centerOfMass(poly); - t.deepEqual(pt, point([0, 0]), 'polygon has no area'); - t.end(); -}); - -test('center of mass -- point', t => { - const p = point([0, 0]); - const pt = centerOfMass(p); - t.deepEqual(pt, point([0, 0]), 'point returns pt'); - t.end(); -}); - -test('center of mass -- point geom', t => { - const geomPoint = {type: 'Point', coordinates: [0, 0]}; - const pt = centerOfMass(geomPoint); - t.deepEqual(pt, point([0, 0]), 'point geom returns pt'); - t.end(); -}); - -test('center of mass -- properties', t => { - const line = lineString([[0, 0], [1, 1]]); - const pt = centerOfMass(line, {properties: {foo: 'bar'}}); - t.equal(pt.properties.foo, 'bar', 'translate properties'); - t.end(); -}); diff --git a/packages/turf-center-of-mass/types.ts b/packages/turf-center-of-mass/types.ts deleted file mode 100644 index c8c4fd57fe..0000000000 --- a/packages/turf-center-of-mass/types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {lineString} from '@turf/helpers' -import centerOfMass from './' - -const line = lineString([[0, 0], [10, 10]]); - -centerOfMass(line) -centerOfMass(line, {properties: {foo: 'bar'}}) diff --git a/packages/turf-center/.gitignore b/packages/turf-center/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-center/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-center/LICENSE b/packages/turf-center/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-center/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-center/README.md b/packages/turf-center/README.md deleted file mode 100644 index 8657301702..0000000000 --- a/packages/turf-center/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# @turf/center - - - -## center - -Takes a [Feature][1] or [FeatureCollection][2] and returns the absolute center point of all features. - -**Parameters** - -- `geojson` **[GeoJSON][3]** GeoJSON to be centered -- `options` **[Object][4]** Optional parameters (optional, default `{}`) - - `options.properties` **[Object][4]** Translate GeoJSON Properties to Point (optional, default `{}`) - - `options.bbox` **[Object][4]** Translate GeoJSON BBox to Point (optional, default `{}`) - - `options.id` **[Object][4]** Translate GeoJSON Id to Point (optional, default `{}`) - -**Examples** - -```javascript -var features = turf.points([ - [-97.522259, 35.4691], - [-97.502754, 35.463455], - [-97.508269, 35.463245] -]); - -var center = turf.center(features); - -//addToMap -var addToMap = [features, center] -center.properties['marker-size'] = 'large'; -center.properties['marker-color'] = '#000'; -``` - -Returns **[Feature][5]<[Point][6]>** a Point feature at the absolute center point of all input features - -[1]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[3]: https://tools.ietf.org/html/rfc7946#section-3 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[5]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/center -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-center/index.ts b/packages/turf-center/index.ts deleted file mode 100644 index d0fae6ceba..0000000000 --- a/packages/turf-center/index.ts +++ /dev/null @@ -1,38 +0,0 @@ -import bbox from '@turf/bbox'; -import { point, BBox, Id, AllGeoJSON, Feature, Point, Properties } from '@turf/helpers'; - -/** - * Takes a {@link Feature} or {@link FeatureCollection} and returns the absolute center point of all features. - * - * @name center - * @param {GeoJSON} geojson GeoJSON to be centered - * @param {Object} [options={}] Optional parameters - * @param {Object} [options.properties={}] Translate GeoJSON Properties to Point - * @param {Object} [options.bbox={}] Translate GeoJSON BBox to Point - * @param {Object} [options.id={}] Translate GeoJSON Id to Point - * @returns {Feature} a Point feature at the absolute center point of all input features - * @example - * var features = turf.points([ - * [-97.522259, 35.4691], - * [-97.502754, 35.463455], - * [-97.508269, 35.463245] - * ]); - * - * var center = turf.center(features); - * - * //addToMap - * var addToMap = [features, center] - * center.properties['marker-size'] = 'large'; - * center.properties['marker-color'] = '#000'; - */ -function center

( - geojson: AllGeoJSON, - options: {properties?: P, bbox?: BBox, id?: Id } = {} -): Feature { - const ext = bbox(geojson); - const x = (ext[0] + ext[2]) / 2; - const y = (ext[1] + ext[3]) / 2; - return point([x, y], options.properties, options); -} - -export default center; diff --git a/packages/turf-center/package.json b/packages/turf-center/package.json deleted file mode 100644 index 12ede8c8ec..0000000000 --- a/packages/turf-center/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "@turf/center", - "version": "6.0.1", - "description": "turf center module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "centroid", - "geojson", - "gis", - "geospatial", - "geo", - "turf" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/bbox-polygon": "*", - "@turf/meta": "*", - "benchmark": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/helpers": "6.x" - } -} diff --git a/packages/turf-center/test.js b/packages/turf-center/test.js deleted file mode 100644 index 4c4ca3c409..0000000000 --- a/packages/turf-center/test.js +++ /dev/null @@ -1,40 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const glob = require('glob'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const bboxPolygon = require('@turf/bbox-polygon').default; -const bbox = require('@turf/bbox').default; -const { featureEach, coordEach } = require('@turf/meta'); -const { lineString, featureCollection } = require('@turf/helpers'); -const center = require('./').default; - -test('turf-center', t => { - glob.sync(path.join(__dirname, 'test', 'in', '*.geojson')).forEach(filepath => { - const geojson = load.sync(filepath); - const options = geojson.options || {}; - options.properties = {'marker-symbol': 'star', 'marker-color': '#F00'}; - const centered = center(geojson, options); - - // Display Results - const results = featureCollection([centered]) - featureEach(geojson, feature => results.features.push(feature)) - const extent = bboxPolygon(bbox(geojson)) - extent.properties = {stroke: '#00F', 'stroke-width': 1, 'fill-opacity': 0} - coordEach(extent, coord => results.features.push(lineString([coord, centered.geometry.coordinates], {stroke: '#00F', 'stroke-width': 1}))) - results.features.push(extent) - - const out = filepath.replace(path.join('test', 'in'), path.join('test', 'out')) - if (process.env.REGEN) write.sync(out, results); - t.deepEqual(results, load.sync(out), path.parse(filepath).name); - }); - t.end(); -}); - -test('turf-center -- properties', t => { - const line = lineString([[0, 0], [1, 1]]); - const pt = center(line, {properties: {foo: 'bar'}}); - t.equal(pt.properties.foo, 'bar', 'translate properties'); - t.end(); -}); diff --git a/packages/turf-center/types.ts b/packages/turf-center/types.ts deleted file mode 100644 index e376031d09..0000000000 --- a/packages/turf-center/types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {lineString} from '@turf/helpers' -import center from './' - -const line = lineString([[0, 0], [10, 10]]); - -center(line) -center(line, {properties: {foo: 'bar'}}) diff --git a/packages/turf-centroid/.gitignore b/packages/turf-centroid/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-centroid/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-centroid/LICENSE b/packages/turf-centroid/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-centroid/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-centroid/README.md b/packages/turf-centroid/README.md deleted file mode 100644 index 06bca41504..0000000000 --- a/packages/turf-centroid/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# @turf/centroid - - - -## centroid - -Takes one or more features and calculates the centroid using the mean of all vertices. -This lessens the effect of small islands and artifacts when calculating the centroid of a set of polygons. - -**Parameters** - -- `geojson` **[GeoJSON][1]** GeoJSON to be centered -- `options` **[Object][2]** Optional Parameters (optional, default `{}`) - - `options.properties` **[Object][2]** an Object that is used as the [Feature][3]'s properties (optional, default `{}`) - -**Examples** - -```javascript -var polygon = turf.polygon([[[-81, 41], [-88, 36], [-84, 31], [-80, 33], [-77, 39], [-81, 41]]]); - -var centroid = turf.centroid(polygon); - -//addToMap -var addToMap = [polygon, centroid] -``` - -Returns **[Feature][4]<[Point][5]>** the centroid of the input features - -[1]: https://tools.ietf.org/html/rfc7946#section-3 - -[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/centroid -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-centroid/index.ts b/packages/turf-centroid/index.ts deleted file mode 100644 index e72c8ab7e4..0000000000 --- a/packages/turf-centroid/index.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { coordEach } from '@turf/meta'; -import { point, AllGeoJSON, Feature, Point, Properties } from '@turf/helpers'; - -/** - * Takes one or more features and calculates the centroid using the mean of all vertices. - * This lessens the effect of small islands and artifacts when calculating the centroid of a set of polygons. - * - * @name centroid - * @param {GeoJSON} geojson GeoJSON to be centered - * @param {Object} [options={}] Optional Parameters - * @param {Object} [options.properties={}] an Object that is used as the {@link Feature}'s properties - * @returns {Feature} the centroid of the input features - * @example - * var polygon = turf.polygon([[[-81, 41], [-88, 36], [-84, 31], [-80, 33], [-77, 39], [-81, 41]]]); - * - * var centroid = turf.centroid(polygon); - * - * //addToMap - * var addToMap = [polygon, centroid] - */ -function centroid

(geojson: AllGeoJSON, options: { - properties?: P -} = {}): Feature { - let xSum = 0; - let ySum = 0; - let len = 0; - coordEach(geojson, function (coord) { - xSum += coord[0]; - ySum += coord[1]; - len++; - }); - return point([xSum / len, ySum / len], options.properties); -} - -export default centroid; diff --git a/packages/turf-centroid/package.json b/packages/turf-centroid/package.json deleted file mode 100644 index 84c0fb75bd..0000000000 --- a/packages/turf-centroid/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@turf/centroid", - "version": "6.0.2", - "description": "turf centroid module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "geo", - "gis" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "geojson-fixtures": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-centroid/test.js b/packages/turf-centroid/test.js deleted file mode 100644 index ac1a481fd7..0000000000 --- a/packages/turf-centroid/test.js +++ /dev/null @@ -1,46 +0,0 @@ -const path = require('path'); -const test = require('tape'); -const glob = require('glob'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { featureEach } = require('@turf/meta'); -const { featureCollection, lineString } = require('@turf/helpers'); -const centroid = require('.').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep, -}; - -const fixtures = glob.sync(directories.in + '*.geojson').map(input => { - const name = path.parse(input).name; - const base = path.parse(input).base; - return { - name, - filename: base, - geojson: load.sync(input), - out: directories.out + base, - }; -}); - -test('centroid', t => { - fixtures.forEach(fixture => { - const name = fixture.name; - const geojson = fixture.geojson; - const out = fixture.out; - const centered = centroid(geojson, {properties: {'marker-symbol': 'circle'}}); - const result = featureCollection([centered]); - featureEach(geojson, feature => result.features.push(feature)); - - if (process.env.REGEN) write.sync(out, result); - t.deepEqual(result, load.sync(out), name); - }); - t.end(); -}); - -test('centroid -- properties', t => { - const line = lineString([[0, 0], [1, 1]]); - const pt = centroid(line, {properties: {foo: 'bar'}}); - t.equal(pt.properties.foo, 'bar', 'translate properties'); - t.end(); -}); diff --git a/packages/turf-centroid/test/out/polygon.geojson b/packages/turf-centroid/test/out/polygon.geojson deleted file mode 100644 index bdd2010e8b..0000000000 --- a/packages/turf-centroid/test/out/polygon.geojson +++ /dev/null @@ -1,61 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "marker-symbol": "circle" - }, - "geometry": { - "type": "Point", - "coordinates": [ - 4.839177131652832, - 45.76256007199914 - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.8250579833984375, - 45.79398056386735 - ], - [ - 4.882392883300781, - 45.79254427435898 - ], - [ - 4.910373687744141, - 45.76081677972451 - ], - [ - 4.894924163818359, - 45.7271539426975 - ], - [ - 4.824199676513671, - 45.71337148333104 - ], - [ - 4.773387908935547, - 45.74021417890731 - ], - [ - 4.778022766113281, - 45.778418789239055 - ], - [ - 4.8250579833984375, - 45.79398056386735 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-centroid/types.ts b/packages/turf-centroid/types.ts deleted file mode 100644 index 5a661b59fa..0000000000 --- a/packages/turf-centroid/types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {lineString} from '@turf/helpers' -import centroid from './' - -const line = lineString([[0, 0], [10, 10]]); - -centroid(line) -centroid(line, {properties: {foo: 'bar'}}) diff --git a/packages/turf-circle/.gitignore b/packages/turf-circle/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-circle/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-circle/LICENSE b/packages/turf-circle/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-circle/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-circle/README.md b/packages/turf-circle/README.md deleted file mode 100644 index 193d93172e..0000000000 --- a/packages/turf-circle/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# @turf/circle - - - -## circle - -Takes a [Point][1] and calculates the circle polygon given a radius in degrees, radians, miles, or kilometers; and steps for precision. - -**Parameters** - -- `center` **([Feature][2]<[Point][3]> | [Array][4]<[number][5]>)** center point -- `radius` **[number][5]** radius of the circle -- `options` **[Object][6]** Optional parameters (optional, default `{}`) - - `options.steps` **[number][5]** number of steps (optional, default `64`) - - `options.units` **[string][7]** miles, kilometers, degrees, or radians (optional, default `'kilometers'`) - - `options.properties` **[Object][6]** properties (optional, default `{}`) - -**Examples** - -```javascript -var center = [-75.343, 39.984]; -var radius = 5; -var options = {steps: 10, units: 'kilometers', properties: {foo: 'bar'}}; -var circle = turf.circle(center, radius, options); - -//addToMap -var addToMap = [turf.point(center), circle] -``` - -Returns **[Feature][2]<[Polygon][8]>** circle polygon - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[8]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/circle -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-circle/index.ts b/packages/turf-circle/index.ts deleted file mode 100644 index cc1d55d92c..0000000000 --- a/packages/turf-circle/index.ts +++ /dev/null @@ -1,43 +0,0 @@ -import destination from '@turf/destination'; -import { polygon, Coord, Units, Point, Properties, Feature, Polygon } from '@turf/helpers'; - -/** - * Takes a {@link Point} and calculates the circle polygon given a radius in degrees, radians, miles, or kilometers; and steps for precision. - * - * @name circle - * @param {Feature|number[]} center center point - * @param {number} radius radius of the circle - * @param {Object} [options={}] Optional parameters - * @param {number} [options.steps=64] number of steps - * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians - * @param {Object} [options.properties={}] properties - * @returns {Feature} circle polygon - * @example - * var center = [-75.343, 39.984]; - * var radius = 5; - * var options = {steps: 10, units: 'kilometers', properties: {foo: 'bar'}}; - * var circle = turf.circle(center, radius, options); - * - * //addToMap - * var addToMap = [turf.point(center), circle] - */ -function circle

(center: number[] | Point | Feature, radius: number, options: { - steps?: number, - units?: Units, - properties?: P -} = {}): Feature { - // default params - const steps = options.steps || 64; - const properties: any = options.properties ? options.properties : (!Array.isArray(center) && center.type === 'Feature' && center.properties) ? center.properties : {}; - - // main - const coordinates = []; - for (let i = 0; i < steps; i++) { - coordinates.push(destination(center, radius, i * -360 / steps, options).geometry.coordinates); - } - coordinates.push(coordinates[0]); - - return polygon([coordinates], properties); -} - -export default circle; diff --git a/packages/turf-circle/package.json b/packages/turf-circle/package.json deleted file mode 100644 index ac7e612223..0000000000 --- a/packages/turf-circle/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "@turf/circle", - "version": "6.0.1", - "description": "turf circle module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "circle", - "radius", - "polygon", - "miles", - "km" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@mapbox/geojsonhint": "*", - "@turf/truncate": "*", - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/destination": "6.x", - "@turf/helpers": "6.x" - } -} diff --git a/packages/turf-circle/test.js b/packages/turf-circle/test.js deleted file mode 100644 index 986857a445..0000000000 --- a/packages/turf-circle/test.js +++ /dev/null @@ -1,47 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const truncate = require('@turf/truncate').default; -const { featureCollection } = require('@turf/helpers'); -const geojsonhint = require('@mapbox/geojsonhint'); -const circle = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-circle', t => { - fixtures.forEach(fixture => { - const filename = fixture.filename; - const name = fixture.name; - const geojson = fixture.geojson; - const properties = geojson.properties || {}; - const radius = properties.radius; - const steps = properties.steps || 64; - const units = properties.units; - - const C = truncate(circle(geojson, radius, {steps: steps, units: units})); - const results = featureCollection([geojson, C]); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEquals(results, load.sync(directories.out + filename), name); - }); - t.end(); -}); - -test('turf-circle -- validate geojson', t => { - const C = circle([0, 0], 100); - geojsonhint.hint(C).forEach(hint => t.fail(hint.message)); - t.end(); -}); diff --git a/packages/turf-circle/types.ts b/packages/turf-circle/types.ts deleted file mode 100644 index 14ddd92e43..0000000000 --- a/packages/turf-circle/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { point } from '@turf/helpers' -import circle from '.' - -const center = point([-75.343, 39.984]); -const units = 'kilometers'; -const radius = 5; -const steps = 10; - -circle(center, radius); -circle(center, radius, {steps}); -circle(center, radius, {steps, units}); -circle([-75, 39], radius, {steps, units, properties: {foo: 'bar'}}); \ No newline at end of file diff --git a/packages/turf-clean-coords/.gitignore b/packages/turf-clean-coords/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-clean-coords/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-clean-coords/LICENSE b/packages/turf-clean-coords/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-clean-coords/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-clean-coords/README.md b/packages/turf-clean-coords/README.md deleted file mode 100644 index 488c065a6f..0000000000 --- a/packages/turf-clean-coords/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# @turf/clean-coords - - - -## cleanCoords - -Removes redundant coordinates from any GeoJSON Geometry. - -**Parameters** - -- `geojson` **([Geometry][1] \| [Feature][2])** Feature or Geometry -- `options` **[Object][3]** Optional parameters (optional, default `{}`) - - `options.mutate` **[boolean][4]** allows GeoJSON input to be mutated (optional, default `false`) - -**Examples** - -```javascript -var line = turf.lineString([[0, 0], [0, 2], [0, 5], [0, 8], [0, 8], [0, 10]]); -var multiPoint = turf.multiPoint([[0, 0], [0, 0], [2, 2]]); - -turf.cleanCoords(line).geometry.coordinates; -//= [[0, 0], [0, 10]] - -turf.cleanCoords(multiPoint).geometry.coordinates; -//= [[0, 0], [2, 2]] -``` - -Returns **([Geometry][1] \| [Feature][2])** the cleaned input Feature/Geometry - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/clean-coords -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-clean-coords/index.ts b/packages/turf-clean-coords/index.ts deleted file mode 100644 index f0db27b725..0000000000 --- a/packages/turf-clean-coords/index.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { feature, AllGeoJSON } from '@turf/helpers'; -import { getCoords, getType } from '@turf/invariant'; - -// To-Do => Improve Typescript GeoJSON handling - -/** - * Removes redundant coordinates from any GeoJSON Geometry. - * - * @name cleanCoords - * @param {Geometry|Feature} geojson Feature or Geometry - * @param {Object} [options={}] Optional parameters - * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated - * @returns {Geometry|Feature} the cleaned input Feature/Geometry - * @example - * var line = turf.lineString([[0, 0], [0, 2], [0, 5], [0, 8], [0, 8], [0, 10]]); - * var multiPoint = turf.multiPoint([[0, 0], [0, 0], [2, 2]]); - * - * turf.cleanCoords(line).geometry.coordinates; - * //= [[0, 0], [0, 10]] - * - * turf.cleanCoords(multiPoint).geometry.coordinates; - * //= [[0, 0], [2, 2]] - */ -function cleanCoords(geojson: any, options: { - mutate?: boolean, -} = {}) { - // Backwards compatible with v4.0 - var mutate = (typeof options === 'object') ? options.mutate : options; - if (!geojson) throw new Error('geojson is required'); - var type = getType(geojson); - - // Store new "clean" points in this Array - var newCoords = []; - - switch (type) { - case 'LineString': - newCoords = cleanLine(geojson); - break; - case 'MultiLineString': - case 'Polygon': - getCoords(geojson).forEach(function (line) { - newCoords.push(cleanLine(line)); - }); - break; - case 'MultiPolygon': - getCoords(geojson).forEach(function (polygons: any) { - var polyPoints = []; - polygons.forEach(function (ring) { - polyPoints.push(cleanLine(ring)); - }); - newCoords.push(polyPoints); - }); - break; - case 'Point': - return geojson; - case 'MultiPoint': - var existing = {}; - getCoords(geojson).forEach(function (coord: any) { - var key = coord.join('-'); - if (!existing.hasOwnProperty(key)) { - newCoords.push(coord); - existing[key] = true; - } - }); - break; - default: - throw new Error(type + ' geometry not supported'); - } - - // Support input mutation - if (geojson.coordinates) { - if (mutate === true) { - geojson.coordinates = newCoords; - return geojson; - } - return {type: type, coordinates: newCoords}; - } else { - if (mutate === true) { - geojson.geometry.coordinates = newCoords; - return geojson; - } - return feature({type: type, coordinates: newCoords}, geojson.properties, {bbox: geojson.bbox, id: geojson.id}); - } -} - -/** - * Clean Coords - * - * @private - * @param {Array|LineString} line Line - * @returns {Array} Cleaned coordinates - */ -function cleanLine(line) { - - var points = getCoords(line); - // handle "clean" segment - if (points.length === 2 && !equals(points[0], points[1])) return points; - - var newPoints = []; - var secondToLast = points.length - 1; - var newPointsLength = newPoints.length; - - newPoints.push(points[0]); - for (var i = 1; i < secondToLast; i++) { - var prevAddedPoint = newPoints[newPoints.length - 1]; - if ((points[i][0] === prevAddedPoint[0]) && (points[i][1] === prevAddedPoint[1])) continue; - else { - newPoints.push(points[i]); - newPointsLength = newPoints.length; - if (newPointsLength > 2) { - if (isPointOnLineSegment(newPoints[newPointsLength - 3], newPoints[newPointsLength - 1], newPoints[newPointsLength - 2])) newPoints.splice(newPoints.length - 2, 1); - } - } - } - newPoints.push(points[points.length - 1]); - - newPointsLength = newPoints.length; - if (equals(points[0], points[points.length - 1]) && newPointsLength < 4) throw new Error('invalid polygon'); - if (isPointOnLineSegment(newPoints[newPointsLength - 3], newPoints[newPointsLength - 1], newPoints[newPointsLength - 2])) newPoints.splice(newPoints.length - 2, 1); - - return newPoints; -} - -/** - * Compares two points and returns if they are equals - * - * @private - * @param {Position} pt1 point - * @param {Position} pt2 point - * @returns {boolean} true if they are equals - */ -function equals(pt1, pt2) { - return pt1[0] === pt2[0] && pt1[1] === pt2[1]; -} - -/** - * Returns if `point` is on the segment between `start` and `end`. - * Borrowed from `@turf/boolean-point-on-line` to speed up the evaluation (instead of using the module as dependency) - * - * @private - * @param {Position} start coord pair of start of line - * @param {Position} end coord pair of end of line - * @param {Position} point coord pair of point to check - * @returns {boolean} true/false - */ -function isPointOnLineSegment(start, end, point) { - var x = point[0], y = point[1]; - var startX = start[0], startY = start[1]; - var endX = end[0], endY = end[1]; - - var dxc = x - startX; - var dyc = y - startY; - var dxl = endX - startX; - var dyl = endY - startY; - var cross = dxc * dyl - dyc * dxl; - - if (cross !== 0) return false; - else if (Math.abs(dxl) >= Math.abs(dyl)) return dxl > 0 ? startX <= x && x <= endX : endX <= x && x <= startX; - else return dyl > 0 ? startY <= y && y <= endY : endY <= y && y <= startY; -} - -export default cleanCoords; diff --git a/packages/turf-clean-coords/package.json b/packages/turf-clean-coords/package.json deleted file mode 100644 index bfdc0c2891..0000000000 --- a/packages/turf-clean-coords/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@turf/clean-coords", - "version": "6.0.1", - "description": "turf clean-coords module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis", - "clean-coords" - ], - "author": "Turf Authors", - "contributors": [ - "Stefano Borghi <@stebogit>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/truncate": "*", - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-clean-coords/test.js b/packages/turf-clean-coords/test.js deleted file mode 100644 index 57a076f160..0000000000 --- a/packages/turf-clean-coords/test.js +++ /dev/null @@ -1,75 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const truncate = require('@turf/truncate').default; -const { - point, - multiPoint, - lineString, - multiPolygon, - polygon, - } = require('@turf/helpers'); -const write = require('write-json-file'); -const cleanCoords = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-clean-coords', t => { - fixtures.forEach(fixture => { - const filename = fixture.filename; - const name = fixture.name; - const geojson = fixture.geojson; - const results = cleanCoords(geojson); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEqual(results, load.sync(directories.out + filename), name); - }); - t.end(); -}); - -test('turf-clean-coords -- extras', t => { - t.equal(cleanCoords(point([0, 0])).geometry.coordinates.length, 2, 'point'); - t.equal(cleanCoords(lineString([[0, 0], [1, 1], [2, 2]])).geometry.coordinates.length, 2, 'lineString'); - t.equal(cleanCoords(polygon([[[0, 0], [1, 1], [2, 2], [0, 2], [0, 0]]])).geometry.coordinates[0].length, 4, 'polygon'); - t.equal(cleanCoords(multiPoint([[0, 0], [0, 0], [2, 2]])).geometry.coordinates.length, 2, 'multiPoint'); - t.end(); -}); - -test('turf-clean-coords -- truncate', t => { - t.equal(cleanCoords(truncate(lineString([[0, 0], [1.1, 1.123], [2.12, 2.32], [3, 3]]), {precision: 0})).geometry.coordinates.length, 2); - t.end(); -}); - -test('turf-clean-coords -- throws', t => { - t.throws(() => cleanCoords(null), /geojson is required/, 'missing geojson'); - t.end(); -}); - -test('turf-clean-coords -- prevent input mutation', t => { - const line = lineString([[0, 0], [1, 1], [2, 2]], {foo: 'bar'}); - const lineBefore = JSON.parse(JSON.stringify(line)); - - cleanCoords(line); - t.deepEqual(lineBefore, line, 'line should NOT be mutated'); - - const multiPoly = multiPolygon([ - [[[0, 0], [1, 1], [2, 2], [2, 0], [0, 0]]], - [[[0, 0], [0, 5], [5, 5], [5, 5], [5, 0], [0, 0]]] - ], {hello: 'world'}); - const multiPolyBefore = JSON.parse(JSON.stringify(multiPoly)); - cleanCoords(multiPoly); - t.deepEqual(multiPolyBefore, multiPoly, 'multiPolygon should NOT be mutated'); - t.end(); -}); diff --git a/packages/turf-clean-coords/types.ts b/packages/turf-clean-coords/types.ts deleted file mode 100644 index 90a7cc650a..0000000000 --- a/packages/turf-clean-coords/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {multiPoint} from '@turf/helpers' -import cleanCoords from './' - -// Fixtures -const multiPt = multiPoint([[0, 0], [0, 0], [2, 2]]) - -// Feature -cleanCoords(multiPt).geometry -cleanCoords(multiPt).properties - -// Geometry -cleanCoords(multiPt.geometry).coordinates -cleanCoords(multiPt.geometry).type - -// Input mutation -cleanCoords(multiPt.geometry, {mutate: true}) diff --git a/packages/turf-clone/.gitignore b/packages/turf-clone/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-clone/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-clone/LICENSE b/packages/turf-clone/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-clone/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-clone/README.md b/packages/turf-clone/README.md deleted file mode 100644 index 3f08a98183..0000000000 --- a/packages/turf-clone/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# @turf/clone - - - -## clone - -Returns a cloned copy of the passed GeoJSON Object, including possible 'Foreign Members'. -~3-5x faster than the common JSON.parse + JSON.stringify combo method. - -**Parameters** - -- `geojson` **[GeoJSON][1]** GeoJSON Object - -**Examples** - -```javascript -var line = turf.lineString([[-74, 40], [-78, 42], [-82, 35]], {color: 'red'}); - -var lineCloned = turf.clone(line); -``` - -Returns **[GeoJSON][1]** cloned GeoJSON Object - -[1]: https://tools.ietf.org/html/rfc7946#section-3 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/clone -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-clone/index.ts b/packages/turf-clone/index.ts deleted file mode 100644 index f2703400b3..0000000000 --- a/packages/turf-clone/index.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { AllGeoJSON, Feature, FeatureCollection, Properties } from "@turf/helpers"; - -/** - * Returns a cloned copy of the passed GeoJSON Object, including possible 'Foreign Members'. - * ~3-5x faster than the common JSON.parse + JSON.stringify combo method. - * - * @name clone - * @param {GeoJSON} geojson GeoJSON Object - * @returns {GeoJSON} cloned GeoJSON Object - * @example - * var line = turf.lineString([[-74, 40], [-78, 42], [-82, 35]], {color: 'red'}); - * - * var lineCloned = turf.clone(line); - */ -function clone(geojson: AllGeoJSON) { - if (!geojson) { throw new Error("geojson is required"); } - - switch (geojson.type) { - case "Feature": - return cloneFeature(geojson); - case "FeatureCollection": - return cloneFeatureCollection(geojson); - case "Point": - case "LineString": - case "Polygon": - case "MultiPoint": - case "MultiLineString": - case "MultiPolygon": - case "GeometryCollection": - return cloneGeometry(geojson); - default: - throw new Error("unknown GeoJSON type"); - } -} - -/** - * Clone Feature - * - * @private - * @param {Feature} geojson GeoJSON Feature - * @returns {Feature} cloned Feature - */ -function cloneFeature(geojson: any) { - const cloned: any = {type: "Feature"}; - // Preserve Foreign Members - Object.keys(geojson).forEach((key) => { - switch (key) { - case "type": - case "properties": - case "geometry": - return; - default: - cloned[key] = geojson[key]; - } - }); - // Add properties & geometry last - cloned.properties = cloneProperties(geojson.properties); - cloned.geometry = cloneGeometry(geojson.geometry); - return cloned; -} - -/** - * Clone Properties - * - * @private - * @param {Object} properties GeoJSON Properties - * @returns {Object} cloned Properties - */ -function cloneProperties(properties: Properties) { - const cloned: {[key: string]: any} = {}; - if (!properties) { return cloned; } - Object.keys(properties).forEach((key) => { - const value = properties[key]; - if (typeof value === "object") { - if (value === null) { - // handle null - cloned[key] = null; - } else if (Array.isArray(value)) { - // handle Array - cloned[key] = value.map((item) => { - return item; - }); - } else { - // handle generic Object - cloned[key] = cloneProperties(value); - } - } else { cloned[key] = value; } - }); - return cloned; -} - -/** - * Clone Feature Collection - * - * @private - * @param {FeatureCollection} geojson GeoJSON Feature Collection - * @returns {FeatureCollection} cloned Feature Collection - */ -function cloneFeatureCollection(geojson: any) { - const cloned: any = {type: "FeatureCollection"}; - - // Preserve Foreign Members - Object.keys(geojson).forEach((key) => { - switch (key) { - case "type": - case "features": - return; - default: - cloned[key] = geojson[key]; - } - }); - // Add features - cloned.features = geojson.features.map((feature: Feature) => { - return cloneFeature(feature); - }); - return cloned; -} - -/** - * Clone Geometry - * - * @private - * @param {Geometry} geometry GeoJSON Geometry - * @returns {Geometry} cloned Geometry - */ -function cloneGeometry(geometry: any) { - const geom: any = {type: geometry.type}; - if (geometry.bbox) { geom.bbox = geometry.bbox; } - - if (geometry.type === "GeometryCollection") { - geom.geometries = geometry.geometries.map((g: any) => { - return cloneGeometry(g); - }); - return geom; - } - geom.coordinates = deepSlice(geometry.coordinates); - return geom; -} - -/** - * Deep Slice coordinates - * - * @private - * @param {Coordinates} coords Coordinates - * @returns {Coordinates} all coordinates sliced - */ -function deepSlice(coords: C): C { - const cloned: any = coords; - if (typeof cloned[0] !== "object") { return cloned.slice(); } - return cloned.map((coord: any) => { - return deepSlice(coord); - }); -} - -export default clone; diff --git a/packages/turf-clone/package.json b/packages/turf-clone/package.json deleted file mode 100644 index ab0cefaf20..0000000000 --- a/packages/turf-clone/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "@turf/clone", - "version": "6.0.2", - "description": "turf clone module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "clone" - ], - "author": "Turf Authors", - "contributors": [ - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/meta": "*", - "benchmark": "*", - "tape": "*", - "typescript": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x" - } -} diff --git a/packages/turf-clone/test.js b/packages/turf-clone/test.js deleted file mode 100644 index 84d2fefebc..0000000000 --- a/packages/turf-clone/test.js +++ /dev/null @@ -1,194 +0,0 @@ -const test = require('tape'); -const { - point, - lineString, - polygon, - featureCollection, - geometryCollection, - } = require('@turf/helpers'); -const { coordEach } = require('@turf/meta'); -const clone = require('./').default; - - -test('turf-clone', t => { - // Define Features - const pt = point([0, 20]); - const line = lineString([[10, 40], [0, 20]]); - const poly = polygon([[[10, 40], [0, 20], [20, 0], [10, 40]]]); - const fc = featureCollection([ - point([0, 20]), - lineString([[10, 40], [0, 20]]), - polygon([[[10, 40], [0, 20], [20, 0], [10, 40]]]) - ]); - const gc = geometryCollection([ - point([0, 20]).geometry, - lineString([[10, 40], [0, 20]]).geometry, - polygon([[[10, 40], [0, 20], [20, 0], [10, 40]]]).geometry - ]).geometry; - - // Clone Features - const ptCloned = clone(pt); - const lineCloned = clone(line); - const polyCloned = clone(poly, true); - const fcCloned = clone(fc); - const gcCloned = clone(gc); - - // Apply Mutation - ptCloned.geometry.coordinates.reverse(); - lineCloned.geometry.coordinates.reverse(); - polyCloned.geometry.coordinates.reverse(); - coordEach(fcCloned, coord => coord.reverse()); - coordEach(gcCloned, coord => coord.reverse()); - - // Original Geometries should not be mutated - t.deepEqual(pt.geometry.coordinates, [0, 20], 'point'); - t.deepEqual(line.geometry.coordinates, [[10, 40], [0, 20]], 'lineString'); - t.deepEqual(poly.geometry.coordinates, [[[10, 40], [0, 20], [20, 0], [10, 40]]], 'polygon'); - - // Feature Collection - t.deepEqual(fc.features[0].geometry.coordinates, [0, 20], 'fc - point'); - t.deepEqual(fc.features[1].geometry.coordinates, [[10, 40], [0, 20]], 'fc - lineString'); - t.deepEqual(fc.features[2].geometry.coordinates, [[[10, 40], [0, 20], [20, 0], [10, 40]]], 'fc - polygon'); - - // Geometry Collection - t.deepEqual(gc.geometries[0].coordinates, [0, 20], 'gc - point'); - t.deepEqual(gc.geometries[1].coordinates, [[10, 40], [0, 20]], 'gc - lineString'); - t.deepEqual(gc.geometries[2].coordinates, [[[10, 40], [0, 20], [20, 0], [10, 40]]], 'gc - polygon'); - t.end(); -}); - -test('turf-clone -- throws', t => { - t.throws(() => clone(), /geojson is required/); - t.end(); -}); - -test('turf-clone -- optional properties', t => { - const pt = point([0, 20]); - pt.properties = undefined; - pt.id = 300; - pt.bbox = [0, 20, 0, 20]; - - const ptCloned = clone(pt); - t.deepEqual(ptCloned.bbox, [0, 20, 0, 20]); - t.equal(ptCloned.id, 300); - t.end(); -}); - -test('turf-clone -- Geometry Objects', t => { - const pt = point([0, 20]).geometry; - const line = lineString([[10, 40], [0, 20]]).geometry; - const poly = polygon([[[10, 40], [0, 20], [20, 0], [10, 40]]]).geometry; - - const ptCloned = clone(pt); - const lineCloned = clone(line); - const polyCloned = clone(poly); - - ptCloned.coordinates.reverse(); - lineCloned.coordinates.reverse(); - polyCloned.coordinates.reverse(); - - t.deepEqual(pt.coordinates, [0, 20], 'geometry point'); - t.deepEqual(line.coordinates, [[10, 40], [0, 20]], 'geometry line'); - t.deepEqual(poly.coordinates, [[[10, 40], [0, 20], [20, 0], [10, 40]]], 'geometry polygon'); - t.end(); -}); - -test('turf-clone -- Preserve Foreign Members -- Feature', t => { - const properties = {foo: 'bar'}; - const bbox = [0, 20, 0, 20]; - const id = 12345; - const pt = point([0, 20], properties, {bbox, id}); - pt.custom = 'foreign members'; - - const cloned = clone(pt); - t.equal(cloned.id, id); - t.equal(cloned.custom, pt.custom); - t.deepEqual(cloned.bbox, bbox); - t.deepEqual(cloned.properties, properties); - t.end(); -}); - -test('turf-clone -- Preserve Foreign Members -- FeatureCollection', t => { - const properties = {foo: 'bar'}; - const bbox = [0, 20, 0, 20]; - const id = 12345; - const fc = featureCollection([point([0, 20])], {bbox, id}); - fc.custom = 'foreign members'; - fc.properties = properties; - - const cloned = clone(fc); - t.equal(cloned.id, id); - t.equal(cloned.custom, fc.custom); - t.deepEqual(cloned.bbox, bbox); - t.deepEqual(cloned.properties, properties); - t.end(); -}); - - -test('turf-clone -- Preserve all properties -- Feature', t => { - const id = 12345; - const bbox = [0, 20, 0, 20]; - const properties = { - foo: 'bar', - object: {property: 1}, - array: [0, 1, 2], - number: 1, - nullity: null, - boolean: true - }; - const pt = point([0, 20], properties, {bbox, id}); - pt.hello = 'world'; // Foreign member - - // Clone and mutate - const cloned = clone(pt); - - // Clone properly translated all properties - t.equal(cloned.hello, 'world'); - t.equal(cloned.properties.foo, 'bar'); - t.equal(cloned.id, 12345); - t.deepEqual(cloned.bbox, [0, 20, 0, 20]); - t.equal(cloned.properties.object.property, 1); - t.deepEqual(cloned.properties.array, [0, 1, 2]); - t.equal(cloned.properties.number, 1); - t.equal(cloned.properties.nullity, null); - t.equal(cloned.properties.boolean, true); - - // Mutate clone properties - cloned['hello'] = 'universe'; - cloned.properties['foo'] = 'foo'; - cloned['id'] = 54321; - cloned['bbox'] = [30, 40, 30, 40]; - cloned.properties.object['property'] = 2; - cloned.properties.array[0] = 500; - cloned.properties.number = -99; - cloned.properties.boolean = false; - - // Test if original point hasn't been mutated - t.equal(pt.hello, 'world'); - t.equal(pt.properties.foo, 'bar'); - t.equal(pt.id, 12345); - t.deepEqual(pt.bbox, [0, 20, 0, 20]); - t.equal(pt.properties.object.property, 1); - t.deepEqual(pt.properties.array, [0, 1, 2]); - t.equal(pt.properties.number, 1); - t.equal(pt.properties.boolean, true); - t.end(); -}); - -test('turf-clone -- Preserve all properties -- FeatureCollection', t => { - const bbox = [0, 20, 0, 20]; - const id = 12345; - const fc = featureCollection([point([0, 20])], {bbox, id}); - fc.hello = 'world'; // Foreign member - - // Clone and mutate - const cloned = clone(fc); - cloned['hello'] = 'universe'; - cloned['id'] = 54321; - cloned['bbox'] = [30, 40, 30, 40]; - - t.equal(fc.hello, 'world'); - t.equal(fc.id, 12345); - t.deepEqual(fc.bbox, [0, 20, 0, 20]); - t.end(); -}); diff --git a/packages/turf-clone/tsconfig.json b/packages/turf-clone/tsconfig.json deleted file mode 100644 index 91cffcbf55..0000000000 --- a/packages/turf-clone/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - }, - "files": [ - "index.ts" - ] -} \ No newline at end of file diff --git a/packages/turf-clone/tslint.json b/packages/turf-clone/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-clone/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-clone/types.ts b/packages/turf-clone/types.ts deleted file mode 100644 index 1df9a69d09..0000000000 --- a/packages/turf-clone/types.ts +++ /dev/null @@ -1,8 +0,0 @@ -import {Feature, lineString, LineString, point, Point} from "@turf/helpers"; -import clone from "./"; - -const pt = point([0, 20]); -const ptCloned: Feature = clone(pt); - -const line = lineString([[0, 20], [10, 10]]).geometry; -const lineCloned: LineString = clone(line); diff --git a/packages/turf-clusters-dbscan/.gitignore b/packages/turf-clusters-dbscan/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-clusters-dbscan/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-clusters-dbscan/LICENSE b/packages/turf-clusters-dbscan/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-clusters-dbscan/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-clusters-dbscan/README.md b/packages/turf-clusters-dbscan/README.md deleted file mode 100644 index a41c7ef288..0000000000 --- a/packages/turf-clusters-dbscan/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# @turf/clusters-dbscan - - - -## clustersDbscan - -Takes a set of [points][1] and partition them into clusters according to [https://en.wikipedia.org/wiki/DBSCAN][2] data clustering algorithm. - -**Parameters** - -- `points` **[FeatureCollection][3]<[Point][4]>** to be clustered -- `maxDistance` **[number][5]** Maximum Distance between any point of the cluster to generate the clusters (kilometers only) -- `options` **[Object][6]** Optional parameters (optional, default `{}`) - - `options.units` **[string][7]** in which `maxDistance` is expressed, can be degrees, radians, miles, or kilometers (optional, default `"kilometers"`) - - `options.mutate` **[boolean][8]** Allows GeoJSON input to be mutated (optional, default `false`) - - `options.minPoints` **[number][5]** Minimum number of points to generate a single cluster, - points which do not meet this requirement will be classified as an 'edge' or 'noise'. (optional, default `3`) - -**Examples** - -```javascript -// create random points with random z-values in their properties -var points = turf.randomPoint(100, {bbox: [0, 30, 20, 50]}); -var maxDistance = 100; -var clustered = turf.clustersDbscan(points, maxDistance); - -//addToMap -var addToMap = [clustered]; -``` - -Returns **[FeatureCollection][3]<[Point][4]>** Clustered Points with an additional two properties associated to each Feature:- {number} cluster - the associated clusterId -- {string} dbscan - type of point it has been classified as ('core'|'edge'|'noise') - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: DBSCAN's - -[3]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/clusters-dbscan -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-clusters-dbscan/index.ts b/packages/turf-clusters-dbscan/index.ts deleted file mode 100644 index fe85142256..0000000000 --- a/packages/turf-clusters-dbscan/index.ts +++ /dev/null @@ -1,83 +0,0 @@ -import clone from '@turf/clone'; -import distance from '@turf/distance'; -import { coordAll } from '@turf/meta'; -import { convertLength, Properties, Units, FeatureCollection, Feature, Point } from '@turf/helpers'; -import { collectionOf } from '@turf/invariant'; -import * as clustering from 'density-clustering'; - -export type Dbscan = 'core' | 'edge' | 'noise' -export interface DbscanProps extends Properties { - dbscan?: Dbscan; - cluster?: number; -} - -/** - * Takes a set of {@link Point|points} and partition them into clusters according to {@link DBSCAN's|https://en.wikipedia.org/wiki/DBSCAN} data clustering algorithm. - * - * @name clustersDbscan - * @param {FeatureCollection} points to be clustered - * @param {number} maxDistance Maximum Distance between any point of the cluster to generate the clusters (kilometers only) - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units="kilometers"] in which `maxDistance` is expressed, can be degrees, radians, miles, or kilometers - * @param {boolean} [options.mutate=false] Allows GeoJSON input to be mutated - * @param {number} [options.minPoints=3] Minimum number of points to generate a single cluster, - * points which do not meet this requirement will be classified as an 'edge' or 'noise'. - * @returns {FeatureCollection} Clustered Points with an additional two properties associated to each Feature: - * - {number} cluster - the associated clusterId - * - {string} dbscan - type of point it has been classified as ('core'|'edge'|'noise') - * @example - * // create random points with random z-values in their properties - * var points = turf.randomPoint(100, {bbox: [0, 30, 20, 50]}); - * var maxDistance = 100; - * var clustered = turf.clustersDbscan(points, maxDistance); - * - * //addToMap - * var addToMap = [clustered]; - */ -function clustersDbscan(points: FeatureCollection, maxDistance: number, options: { - units?: Units, - minPoints?: number, - mutate?: boolean -} = {}): FeatureCollection { - // Input validation being handled by Typescript - // collectionOf(points, 'Point', 'points must consist of a FeatureCollection of only Points'); - // if (maxDistance === null || maxDistance === undefined) throw new Error('maxDistance is required'); - // if (!(Math.sign(maxDistance) > 0)) throw new Error('maxDistance is invalid'); - // if (!(minPoints === undefined || minPoints === null || Math.sign(minPoints) > 0)) throw new Error('options.minPoints is invalid'); - - // Clone points to prevent any mutations - if (options.mutate !== true) points = clone(points); - - // Defaults - options.minPoints = options.minPoints || 3; - - // create clustered ids - var dbscan = new clustering.DBSCAN(); - var clusteredIds = dbscan.run(coordAll(points), convertLength(maxDistance, options.units), options.minPoints, distance); - - // Tag points to Clusters ID - var clusterId = -1; - clusteredIds.forEach(function (clusterIds) { - clusterId++; - // assign cluster ids to input points - clusterIds.forEach(function (idx) { - var clusterPoint = points.features[idx]; - if (!clusterPoint.properties) clusterPoint.properties = {}; - clusterPoint.properties.cluster = clusterId; - clusterPoint.properties.dbscan = 'core'; - }); - }); - - // handle noise points, if any - // edges points are tagged by DBSCAN as both 'noise' and 'cluster' as they can "reach" less than 'minPoints' number of points - dbscan.noise.forEach(function (noiseId) { - var noisePoint = points.features[noiseId]; - if (!noisePoint.properties) noisePoint.properties = {}; - if (noisePoint.properties.cluster) noisePoint.properties.dbscan = 'edge'; - else noisePoint.properties.dbscan = 'noise'; - }); - - return points; -} - -export default clustersDbscan; diff --git a/packages/turf-clusters-dbscan/package.json b/packages/turf-clusters-dbscan/package.json deleted file mode 100644 index a9daf85e0c..0000000000 --- a/packages/turf-clusters-dbscan/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "@turf/clusters-dbscan", - "version": "6.0.1", - "description": "turf clusters-dbscan module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "cluster", - "clusters", - "clustering", - "density", - "dbscan" - ], - "author": "Turf Authors", - "contributors": [ - "Lukasz <@uhho>", - "Denis Carriere <@DenisCarriere>", - "Stefano Borghi <@stebogit>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/centroid": "*", - "@turf/clusters": "*", - "benchmark": "*", - "chromatism": "*", - "concaveman": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/clone": "6.x", - "@turf/distance": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x", - "density-clustering": "1.3.0" - } -} diff --git a/packages/turf-clusters-dbscan/test.js b/packages/turf-clusters-dbscan/test.js deleted file mode 100644 index 996926c210..0000000000 --- a/packages/turf-clusters-dbscan/test.js +++ /dev/null @@ -1,144 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const centroid = require('@turf/centroid').default; -const chromatism = require('chromatism'); -const concaveman = require('concaveman'); -const { point, polygon, featureCollection } = require('@turf/helpers'); -const { clusterReduce, clusterEach } = require('@turf/clusters'); -const { coordAll, featureEach } = require('@turf/meta'); -const clustersDbscan = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('clusters-dbscan', t => { - fixtures.forEach(fixture => { - const name = fixture.name; - const filename = fixture.filename; - const geojson = fixture.geojson; - const properties = geojson.properties || {}; - const distance = properties.distance || 100; - const minPoints = properties.minPoints; - const units = properties.units; - - // console.log(geojson.features.length); - const clustered = clustersDbscan(geojson, distance, {units: units, minPoints: minPoints}); - const result = styleResult(clustered); - - if (process.env.REGEN) write.sync(directories.out + filename, result); - t.deepEqual(result, load.sync(directories.out + filename), name); - }); - - t.end(); -}); - -const points = featureCollection([ - point([0, 0], {foo: 'bar'}), - point([2, 4], {foo: 'bar'}), - point([3, 6], {foo: 'bar'}) -]); - -test('clusters-dbscan -- throws', t => { - const poly = polygon([[[0, 0], [10, 10], [0, 10], [0, 0]]]); - // Types being handled by Typescript - // t.throws(() => clustersDbscan(poly, 1), /points must consist of a FeatureCollection of only Points/); - // t.throws(() => clustersDbscan(points), /maxDistance is required/); - // t.throws(() => clustersDbscan(points, -4), /maxDistance is invalid/); - // t.throws(() => clustersDbscan(points, 'foo'), /maxDistance is invalid/); - // t.throws(() => clustersDbscan(points, 1, {units: 'nanometers'}), /units is invalid/); - // t.throws(() => clustersDbscan(points, 1, {units: null, minPoints: 0}), /minPoints is invalid/); - // t.throws(() => clustersDbscan(points, 1, {units: 'miles', minPoints: 'baz'}), /minPoints is invalid/); - t.end(); -}); - -test('clusters-dbscan -- prevent input mutation', t => { - clustersDbscan(points, 2, {units: 'kilometers', minPoints: 1}); - t.true(points.features[0].properties.cluster === undefined, 'cluster properties should be undefined'); - t.end(); -}); - -test('clusters-dbscan -- translate properties', t => { - t.equal(clustersDbscan(points, 2, {units: 'kilometers', minPoints: 1}).features[0].properties.foo, 'bar'); - t.end(); -}); - -// style result -function styleResult(clustered) { - const count = clusterReduce(clustered, 'cluster', i => i + 1, 0); - const colours = chromatism.adjacent(360 / count, count, '#0000FF').hex; - const features = []; - - // Add all clusterd points - featureEach(clustered, function (pt) { - const dbscan = pt.properties.dbscan; - const clusterId = pt.properties.cluster; - - switch (dbscan) { - case 'core': - case 'edge': { - const coreColor = colours[clusterId]; - const edgeColor = chromatism.brightness(-20, colours[clusterId]).hex; - pt.properties['marker-color'] = (dbscan === 'core') ? coreColor : edgeColor; - pt.properties['marker-size'] = 'small'; - break; - } - case 'noise': { - pt.properties['marker-color'] = '#AEAEAE'; - pt.properties['marker-symbol'] = 'circle-stroked'; - pt.properties['marker-size'] = 'medium'; - break; - } - } - features.push(pt); - }); - - // Iterate over each Cluster - clusterEach(clustered, 'cluster', (cluster, clusterValue, clusterId) => { - const color = chromatism.brightness(-25, colours[clusterId]).hex; - - // Add Centroid - features.push(centroid(cluster, {properties: { - 'marker-color': colours[clusterId], - 'marker-symbol': 'star-stroked', - 'marker-size': 'large' - }})); - - // Add concave polygon - features.push(polygon([concaveman(coordAll(cluster))], { - fill: color, - stroke: color, - 'fill-opacity': 0.3 - })); - }); - return featureCollection(features); -} - -test('clusters-dbscan -- allow input mutation', t => { - const oldPoints = featureCollection([ - point([0, 0], {foo: 'bar'}), - point([2, 4], {foo: 'bar'}), - point([3, 6], {foo: 'bar'}) - ]); - // No mutation - const newPoints = clustersDbscan(points, 2, {minPoints: 1}); - t.equal(newPoints.features[1].properties.cluster, 1, 'cluster is 1') - t.equal(oldPoints.features[1].properties.cluster, undefined, 'cluster is undefined') - - // Allow mutation - clustersDbscan(oldPoints, 2, {minPoints: 1, mutate: true}); - t.equal(oldPoints.features[1].properties.cluster, 1, 'cluster is 1') - t.end() -}) \ No newline at end of file diff --git a/packages/turf-clusters-dbscan/types.ts b/packages/turf-clusters-dbscan/types.ts deleted file mode 100644 index 756ffd2ed4..0000000000 --- a/packages/turf-clusters-dbscan/types.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { featureCollection, point } from '@turf/helpers' -import clustersDbscan from './' - -// Fixtures -const points = featureCollection([ - point([0, 0]), - point([2, 2]) -]); - -// Default -const maxDistance = 5; -const clustered = clustersDbscan(points, maxDistance); - -// Enforce strict properties when using the dbscan property -const output = clustersDbscan(points, maxDistance); -let {dbscan, cluster} = output.features[0].properties -dbscan = 'edge' -dbscan = 'core' -dbscan = 'noise' -// dbscan = 'foo' //= [ts] Type '"foo"' is not assignable to type '"core" | "edge" | "noise"'. -clustersDbscan(output, maxDistance); - -// Options -const minPoints = 3; -const units = 'miles'; -clustersDbscan(points, maxDistance); -clustersDbscan(points, maxDistance, {units}); -clustersDbscan(points, maxDistance, {units, minPoints}); - -// Custom Properties -clustered.features[0].properties.cluster -clustered.features[0].properties.dbscan -clustered.features[0].properties.foo diff --git a/packages/turf-clusters-kmeans/.gitignore b/packages/turf-clusters-kmeans/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-clusters-kmeans/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-clusters-kmeans/LICENSE b/packages/turf-clusters-kmeans/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-clusters-kmeans/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-clusters-kmeans/README.md b/packages/turf-clusters-kmeans/README.md deleted file mode 100644 index 0babb73aec..0000000000 --- a/packages/turf-clusters-kmeans/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# @turf/clusters-kmeans - - - -## clustersKmeans - -Takes a set of [points][1] and partition them into clusters using the k-mean . -It uses the [k-means algorithm][2] - -**Parameters** - -- `points` **[FeatureCollection][3]<[Point][4]>** to be clustered -- `options` **[Object][5]** Optional parameters (optional, default `{}`) - - `options.numberOfClusters` **[number][6]** numberOfClusters that will be generated (optional, default `Math.sqrt(numberOfPoints/2)`) - - `options.mutate` **[boolean][7]** allows GeoJSON input to be mutated (significant performance increase if true) (optional, default `false`) - -**Examples** - -```javascript -// create random points with random z-values in their properties -var points = turf.randomPoint(100, {bbox: [0, 30, 20, 50]}); -var options = {numberOfClusters: 7}; -var clustered = turf.clustersKmeans(points, options); - -//addToMap -var addToMap = [clustered]; -``` - -Returns **[FeatureCollection][3]<[Point][4]>** Clustered Points with an additional two properties associated to each Feature:- {number} cluster - the associated clusterId -- {[number, number]} centroid - Centroid of the cluster [Longitude, Latitude] - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://en.wikipedia.org/wiki/K-means_clustering - -[3]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/clusters-kmeans -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-clusters-kmeans/index.ts b/packages/turf-clusters-kmeans/index.ts deleted file mode 100644 index f67940a540..0000000000 --- a/packages/turf-clusters-kmeans/index.ts +++ /dev/null @@ -1,72 +0,0 @@ -import clone from '@turf/clone'; -import { coordAll, featureEach } from '@turf/meta'; -import { FeatureCollection, Feature, Point, Properties } from '@turf/helpers'; -import * as skmeans from 'skmeans'; - -export interface KmeansProps extends Properties { - cluster?: number; - centroid?: [number, number]; -} - -/** - * Takes a set of {@link Point|points} and partition them into clusters using the k-mean . - * It uses the [k-means algorithm](https://en.wikipedia.org/wiki/K-means_clustering) - * - * @name clustersKmeans - * @param {FeatureCollection} points to be clustered - * @param {Object} [options={}] Optional parameters - * @param {number} [options.numberOfClusters=Math.sqrt(numberOfPoints/2)] numberOfClusters that will be generated - * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) - * @returns {FeatureCollection} Clustered Points with an additional two properties associated to each Feature: - * - {number} cluster - the associated clusterId - * - {[number, number]} centroid - Centroid of the cluster [Longitude, Latitude] - * @example - * // create random points with random z-values in their properties - * var points = turf.randomPoint(100, {bbox: [0, 30, 20, 50]}); - * var options = {numberOfClusters: 7}; - * var clustered = turf.clustersKmeans(points, options); - * - * //addToMap - * var addToMap = [clustered]; - */ -function clustersKmeans(points: FeatureCollection, options: { - numberOfClusters?: number, - mutate?: boolean -} = {}): FeatureCollection { - // Default Params - var count = points.features.length; - options.numberOfClusters = options.numberOfClusters || Math.round(Math.sqrt(count / 2)); - - // numberOfClusters can't be greater than the number of points - // fallbacks to count - if (options.numberOfClusters > count) options.numberOfClusters = count; - - // Clone points to prevent any mutations (enabled by default) - if (options.mutate !== true) points = clone(points); - - // collect points coordinates - var data = coordAll(points); - - // create seed to avoid skmeans to drift - var initialCentroids = data.slice(0, options.numberOfClusters); - - // create skmeans clusters - var skmeansResult = skmeans(data, options.numberOfClusters, initialCentroids); - - // store centroids {clusterId: [number, number]} - var centroids = {}; - skmeansResult.centroids.forEach(function (coord, idx) { - centroids[idx] = coord; - }); - - // add associated cluster number - featureEach(points, function (point, index) { - var clusterId = skmeansResult.idxs[index]; - point.properties.cluster = clusterId; - point.properties.centroid = centroids[clusterId]; - }); - - return points; -} - -export default clustersKmeans; diff --git a/packages/turf-clusters-kmeans/package.json b/packages/turf-clusters-kmeans/package.json deleted file mode 100644 index adbadd5441..0000000000 --- a/packages/turf-clusters-kmeans/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "@turf/clusters-kmeans", - "version": "6.0.1", - "description": "turf clusters-kmeans module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "cluster", - "clusters", - "clustering", - "k-means" - ], - "author": "Turf Authors", - "contributors": [ - "David Gómez Matarrodona <@solzimer>", - "Stefano Borghi <@stebogit>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/centroid": "*", - "@turf/clusters": "*", - "@turf/random": "*", - "benchmark": "*", - "chromatism": "*", - "concaveman": "*", - "load-json-file": "*", - "matrix-to-grid": "*", - "tape": "*", - "write-json-file": "*", - "typescript": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/clone": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x", - "skmeans": "0.9.7" - } -} diff --git a/packages/turf-clusters-kmeans/test.js b/packages/turf-clusters-kmeans/test.js deleted file mode 100644 index 8a4d9230ba..0000000000 --- a/packages/turf-clusters-kmeans/test.js +++ /dev/null @@ -1,113 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const centroid = require('@turf/centroid').default; -const chromatism = require('chromatism'); -const concaveman = require('concaveman'); -const { point, polygon, featureCollection } = require('@turf/helpers'); -const { clusterReduce, clusterEach } = require('@turf/clusters'); -const { coordAll, featureEach } = require('@turf/meta'); -const clustersKmeans = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('clusters-kmeans', t => { - fixtures.forEach(fixture => { - const name = fixture.name; - const geojson = fixture.geojson; - const numberOfClusters = (geojson.properties || {}).numberOfClusters; - - const clustered = clustersKmeans(geojson, {numberOfClusters: numberOfClusters}); - const result = styleResult(clustered); - - if (process.env.REGEN) write.sync(directories.out + name + '.geojson', result); - t.deepEqual(result, load.sync(directories.out + name + '.geojson'), name); - }); - - t.end(); -}); - -const points = featureCollection([ - point([0, 0], {foo: 'bar'}), - point([2, 4], {foo: 'bar'}), - point([3, 6], {foo: 'bar'}) -]); - -test('clusters-kmeans -- throws', t => { - const poly = polygon([[[0, 0], [10, 10], [0, 10], [0, 0]]]); - - // Types handled by Typescript - // t.throws(() => clustersKmeans(poly, {numberOfClusters: 1}), /Input must contain Points/); - // t.throws(() => clustersKmeans(points, 5), /numberOfClusters can't be greater than the number of points/); - t.end(); -}); - -test('clusters-kmeans -- translate properties', t => { - t.equal(clustersKmeans(points, {numberOfClusters: 2}).features[0].properties.foo, 'bar'); - t.end(); -}); - -// style result -function styleResult(clustered) { - const count = clusterReduce(clustered, 'cluster', i => i + 1, 0); - const colours = chromatism.adjacent(360 / count, count, '#0000FF').hex; - const features = []; - - // Add all Point - featureEach(clustered, function (pt) { - const clusterId = pt.properties.cluster; - pt.properties['marker-color'] = colours[clusterId]; - pt.properties['marker-size'] = 'small'; - features.push(pt); - }); - - // Iterate over each Cluster - clusterEach(clustered, 'cluster', (cluster, clusterValue, clusterId) => { - const color = chromatism.brightness(-25, colours[clusterId]).hex; - - // Add Centroid - features.push(centroid(cluster, {properties: { - 'marker-color': color, - 'marker-symbol': 'star-stroked', - 'marker-size': 'large' - }})); - - // Add concave polygon - features.push(polygon([concaveman(coordAll(cluster))], { - fill: color, - stroke: color, - 'fill-opacity': 0.3 - })); - }); - return featureCollection(features); -} - -test('clusters-kmeans -- allow input mutation', t => { - const oldPoints = featureCollection([ - point([0, 0], {foo: 'bar'}), - point([2, 4], {foo: 'bar'}), - point([3, 6], {foo: 'bar'}) - ]); - // No mutation - const newPoints = clustersKmeans(points, {numberOfClusters: 3}); - t.equal(newPoints.features[1].properties.cluster, 1, 'cluster is 1'); - t.equal(oldPoints.features[1].properties.cluster, undefined, 'cluster is undefined'); - - // Allow mutation - clustersKmeans(oldPoints, {numberOfClusters: 2, mutate: true}); - t.equal(oldPoints.features[1].properties.cluster, 1, 'cluster is 1'); - t.end() -}) \ No newline at end of file diff --git a/packages/turf-clusters-kmeans/types.ts b/packages/turf-clusters-kmeans/types.ts deleted file mode 100644 index 70e4adc670..0000000000 --- a/packages/turf-clusters-kmeans/types.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { featureCollection, point } from '@turf/helpers' -import clustersKmeans from './' - -// Fixtures -const points = featureCollection([ - point([0, 0]), - point([2, 2]) -]); - -// Default -const numberOfClusters = 5; -const clustered = clustersKmeans(points, {numberOfClusters}) -let {cluster, centroid} = clustered.features[0].properties -cluster = 2 -centroid = [-110, 85] -// cluster = 'foo' // Type Error - Type '"foo"' is not assignable to type 'number'. -// centroid = 'foo' // Type Error - Type '"foo"' is not assignable to type '[number, number]'. - -// Properties option -clustersKmeans(points) -clustersKmeans(points, {numberOfClusters}) -clustersKmeans(points, {numberOfClusters, mutate: true}) - -// Custom Properties -clustered.features[0].properties.centroid -clustered.features[0].properties.cluster -clustered.features[0].properties.foo diff --git a/packages/turf-clusters/.gitignore b/packages/turf-clusters/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-clusters/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-clusters/LICENSE b/packages/turf-clusters/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-clusters/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-clusters/README.md b/packages/turf-clusters/README.md deleted file mode 100644 index a6a9d0c1d4..0000000000 --- a/packages/turf-clusters/README.md +++ /dev/null @@ -1,208 +0,0 @@ -# @turf/clusters - - - -## getCluster - -Get Cluster - -**Parameters** - -- `geojson` **[FeatureCollection][1]** GeoJSON Features -- `filter` **any** Filter used on GeoJSON properties to get Cluster - -**Examples** - -```javascript -var geojson = turf.featureCollection([ - turf.point([0, 0], {'marker-symbol': 'circle'}), - turf.point([2, 4], {'marker-symbol': 'star'}), - turf.point([3, 6], {'marker-symbol': 'star'}), - turf.point([5, 1], {'marker-symbol': 'square'}), - turf.point([4, 2], {'marker-symbol': 'circle'}) -]); - -// Create a cluster using K-Means (adds `cluster` to GeoJSON properties) -var clustered = turf.clustersKmeans(geojson); - -// Retrieve first cluster (0) -var cluster = turf.getCluster(clustered, {cluster: 0}); -//= cluster - -// Retrieve cluster based on custom properties -turf.getCluster(clustered, {'marker-symbol': 'circle'}).length; -//= 2 -turf.getCluster(clustered, {'marker-symbol': 'square'}).length; -//= 1 -``` - -Returns **[FeatureCollection][1]** Single Cluster filtered by GeoJSON Properties - -## clusterEachCallback - -Callback for clusterEach - -Type: [Function][2] - -**Parameters** - -- `cluster` **[FeatureCollection][1]?** The current cluster being processed. -- `clusterValue` **any?** Value used to create cluster being processed. -- `currentIndex` **[number][3]?** The index of the current element being processed in the array.Starts at index 0 - -Returns **void** - -## clusterEach - -clusterEach - -**Parameters** - -- `geojson` **[FeatureCollection][1]** GeoJSON Features -- `property` **([string][4] \| [number][3])** GeoJSON property key/value used to create clusters -- `callback` **[Function][2]** a method that takes (cluster, clusterValue, currentIndex) - -**Examples** - -```javascript -var geojson = turf.featureCollection([ - turf.point([0, 0]), - turf.point([2, 4]), - turf.point([3, 6]), - turf.point([5, 1]), - turf.point([4, 2]) -]); - -// Create a cluster using K-Means (adds `cluster` to GeoJSON properties) -var clustered = turf.clustersKmeans(geojson); - -// Iterate over each cluster -turf.clusterEach(clustered, 'cluster', function (cluster, clusterValue, currentIndex) { - //= cluster - //= clusterValue - //= currentIndex -}) - -// Calculate the total number of clusters -var total = 0 -turf.clusterEach(clustered, 'cluster', function () { - total++; -}); - -// Create an Array of all the values retrieved from the 'cluster' property -var values = [] -turf.clusterEach(clustered, 'cluster', function (cluster, clusterValue) { - values.push(clusterValue); -}); -``` - -Returns **void** - -## clusterReduceCallback - -Callback for clusterReduce - -The first time the callback function is called, the values provided as arguments depend -on whether the reduce method has an initialValue argument. - -If an initialValue is provided to the reduce method: - -- The previousValue argument is initialValue. -- The currentValue argument is the value of the first element present in the array. - -If an initialValue is not provided: - -- The previousValue argument is the value of the first element present in the array. -- The currentValue argument is the value of the second element present in the array. - -Type: [Function][2] - -**Parameters** - -- `previousValue` **any?** The accumulated value previously returned in the last invocation - of the callback, or initialValue, if supplied. -- `cluster` **[FeatureCollection][1]?** The current cluster being processed. -- `clusterValue` **any?** Value used to create cluster being processed. -- `currentIndex` **[number][3]?** The index of the current element being processed in the - array. Starts at index 0, if an initialValue is provided, and at index 1 otherwise. - -## clusterReduce - -Reduce clusters in GeoJSON Features, similar to Array.reduce() - -**Parameters** - -- `geojson` **[FeatureCollection][1]** GeoJSON Features -- `property` **([string][4] \| [number][3])** GeoJSON property key/value used to create clusters -- `callback` **[Function][2]** a method that takes (previousValue, cluster, clusterValue, currentIndex) -- `initialValue` **any?** Value to use as the first argument to the first call of the callback. - -**Examples** - -```javascript -var geojson = turf.featureCollection([ - turf.point([0, 0]), - turf.point([2, 4]), - turf.point([3, 6]), - turf.point([5, 1]), - turf.point([4, 2]) -]); - -// Create a cluster using K-Means (adds `cluster` to GeoJSON properties) -var clustered = turf.clustersKmeans(geojson); - -// Iterate over each cluster and perform a calculation -var initialValue = 0 -turf.clusterReduce(clustered, 'cluster', function (previousValue, cluster, clusterValue, currentIndex) { - //=previousValue - //=cluster - //=clusterValue - //=currentIndex - return previousValue++; -}, initialValue); - -// Calculate the total number of clusters -var total = turf.clusterReduce(clustered, 'cluster', function (previousValue) { - return previousValue++; -}, 0); - -// Create an Array of all the values retrieved from the 'cluster' property -var values = turf.clusterReduce(clustered, 'cluster', function (previousValue, cluster, clusterValue) { - return previousValue.concat(clusterValue); -}, []); -``` - -Returns **any** The value that results from the reduction. - -[1]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/clusters -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-clusters/index.ts b/packages/turf-clusters/index.ts deleted file mode 100644 index 6e33d95a1b..0000000000 --- a/packages/turf-clusters/index.ts +++ /dev/null @@ -1,301 +0,0 @@ -import { featureEach } from '@turf/meta'; -import { featureCollection, Feature, FeatureCollection, Properties, Geometry } from '@turf/helpers'; - -/** - * Get Cluster - * - * @name getCluster - * @param {FeatureCollection} geojson GeoJSON Features - * @param {*} filter Filter used on GeoJSON properties to get Cluster - * @returns {FeatureCollection} Single Cluster filtered by GeoJSON Properties - * @example - * var geojson = turf.featureCollection([ - * turf.point([0, 0], {'marker-symbol': 'circle'}), - * turf.point([2, 4], {'marker-symbol': 'star'}), - * turf.point([3, 6], {'marker-symbol': 'star'}), - * turf.point([5, 1], {'marker-symbol': 'square'}), - * turf.point([4, 2], {'marker-symbol': 'circle'}) - * ]); - * - * // Create a cluster using K-Means (adds `cluster` to GeoJSON properties) - * var clustered = turf.clustersKmeans(geojson); - * - * // Retrieve first cluster (0) - * var cluster = turf.getCluster(clustered, {cluster: 0}); - * //= cluster - * - * // Retrieve cluster based on custom properties - * turf.getCluster(clustered, {'marker-symbol': 'circle'}).length; - * //= 2 - * turf.getCluster(clustered, {'marker-symbol': 'square'}).length; - * //= 1 - */ -export function getCluster( - geojson: FeatureCollection, - filter: any -): FeatureCollection { - // Validation - if (!geojson) throw new Error('geojson is required'); - if (geojson.type !== 'FeatureCollection') throw new Error('geojson must be a FeatureCollection'); - if (filter === undefined || filter === null) throw new Error('filter is required'); - - // Filter Features - var features: Feature[] = []; - featureEach(geojson, function (feature) { - if (applyFilter(feature.properties, filter)) features.push(feature); - }); - return featureCollection(features); -} - -/** - * Callback for clusterEach - * - * @callback clusterEachCallback - * @param {FeatureCollection} [cluster] The current cluster being processed. - * @param {*} [clusterValue] Value used to create cluster being processed. - * @param {number} [currentIndex] The index of the current element being processed in the array.Starts at index 0 - * @returns {void} - */ - -/** - * clusterEach - * - * @name clusterEach - * @param {FeatureCollection} geojson GeoJSON Features - * @param {string|number} property GeoJSON property key/value used to create clusters - * @param {Function} callback a method that takes (cluster, clusterValue, currentIndex) - * @returns {void} - * @example - * var geojson = turf.featureCollection([ - * turf.point([0, 0]), - * turf.point([2, 4]), - * turf.point([3, 6]), - * turf.point([5, 1]), - * turf.point([4, 2]) - * ]); - * - * // Create a cluster using K-Means (adds `cluster` to GeoJSON properties) - * var clustered = turf.clustersKmeans(geojson); - * - * // Iterate over each cluster - * turf.clusterEach(clustered, 'cluster', function (cluster, clusterValue, currentIndex) { - * //= cluster - * //= clusterValue - * //= currentIndex - * }) - * - * // Calculate the total number of clusters - * var total = 0 - * turf.clusterEach(clustered, 'cluster', function () { - * total++; - * }); - * - * // Create an Array of all the values retrieved from the 'cluster' property - * var values = [] - * turf.clusterEach(clustered, 'cluster', function (cluster, clusterValue) { - * values.push(clusterValue); - * }); - */ -export function clusterEach( - geojson: FeatureCollection, - property: number | string, - callback: (cluster?: FeatureCollection, clusterValue?: any, currentIndex?: number) => void -): void { - // Validation - if (!geojson) throw new Error('geojson is required'); - if (geojson.type !== 'FeatureCollection') throw new Error('geojson must be a FeatureCollection'); - if (property === undefined || property === null) throw new Error('property is required'); - - // Create clusters based on property values - var bins = createBins(geojson, property); - var values = Object.keys(bins); - for (var index = 0; index < values.length; index++) { - var value = values[index]; - var bin = bins[value]; - var features = []; - for (var i = 0; i < bin.length; i++) { - features.push(geojson.features[bin[i]]); - } - callback(featureCollection(features), value, index); - } -} - -/** - * Callback for clusterReduce - * - * The first time the callback function is called, the values provided as arguments depend - * on whether the reduce method has an initialValue argument. - * - * If an initialValue is provided to the reduce method: - * - The previousValue argument is initialValue. - * - The currentValue argument is the value of the first element present in the array. - * - * If an initialValue is not provided: - * - The previousValue argument is the value of the first element present in the array. - * - The currentValue argument is the value of the second element present in the array. - * - * @callback clusterReduceCallback - * @param {*} [previousValue] The accumulated value previously returned in the last invocation - * of the callback, or initialValue, if supplied. - * @param {FeatureCollection} [cluster] The current cluster being processed. - * @param {*} [clusterValue] Value used to create cluster being processed. - * @param {number} [currentIndex] The index of the current element being processed in the - * array. Starts at index 0, if an initialValue is provided, and at index 1 otherwise. - */ - -/** - * Reduce clusters in GeoJSON Features, similar to Array.reduce() - * - * @name clusterReduce - * @param {FeatureCollection} geojson GeoJSON Features - * @param {string|number} property GeoJSON property key/value used to create clusters - * @param {Function} callback a method that takes (previousValue, cluster, clusterValue, currentIndex) - * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. - * @returns {*} The value that results from the reduction. - * @example - * var geojson = turf.featureCollection([ - * turf.point([0, 0]), - * turf.point([2, 4]), - * turf.point([3, 6]), - * turf.point([5, 1]), - * turf.point([4, 2]) - * ]); - * - * // Create a cluster using K-Means (adds `cluster` to GeoJSON properties) - * var clustered = turf.clustersKmeans(geojson); - * - * // Iterate over each cluster and perform a calculation - * var initialValue = 0 - * turf.clusterReduce(clustered, 'cluster', function (previousValue, cluster, clusterValue, currentIndex) { - * //=previousValue - * //=cluster - * //=clusterValue - * //=currentIndex - * return previousValue++; - * }, initialValue); - * - * // Calculate the total number of clusters - * var total = turf.clusterReduce(clustered, 'cluster', function (previousValue) { - * return previousValue++; - * }, 0); - * - * // Create an Array of all the values retrieved from the 'cluster' property - * var values = turf.clusterReduce(clustered, 'cluster', function (previousValue, cluster, clusterValue) { - * return previousValue.concat(clusterValue); - * }, []); - */ -export function clusterReduce( - geojson: FeatureCollection, - property: number | string, - callback: (previousValue?: any, cluster?: FeatureCollection, clusterValue?: any, currentIndex?: number) => void, - initialValue?: any -): void { - var previousValue = initialValue; - clusterEach(geojson, property, function (cluster, clusterValue, currentIndex) { - if (currentIndex === 0 && initialValue === undefined) previousValue = cluster; - else previousValue = callback(previousValue, cluster, clusterValue, currentIndex); - }); - return previousValue; -} - -/** - * Create Bins - * - * @private - * @param {FeatureCollection} geojson GeoJSON Features - * @param {string|number} property Property values are used to create bins - * @returns {Object} bins with Feature IDs - * @example - * var geojson = turf.featureCollection([ - * turf.point([0, 0], {cluster: 0, foo: 'null'}), - * turf.point([2, 4], {cluster: 1, foo: 'bar'}), - * turf.point([5, 1], {0: 'foo'}), - * turf.point([3, 6], {cluster: 1}), - * ]); - * createBins(geojson, 'cluster'); - * //= { '0': [ 0 ], '1': [ 1, 3 ] } - */ -export function createBins(geojson: FeatureCollection, property: string | number) { - var bins = {}; - - featureEach(geojson, function (feature, i) { - var properties = feature.properties || {}; - if (properties.hasOwnProperty(String(property))) { - var value = properties[property]; - if (bins.hasOwnProperty(value)) bins[value].push(i); - else bins[value] = [i]; - } - }); - return bins; -} - -/** - * Apply Filter - * - * @private - * @param {*} properties Properties - * @param {*} filter Filter - * @returns {boolean} applied Filter to properties - */ -export function applyFilter(properties: any, filter: any) { - if (properties === undefined) return false; - var filterType = typeof filter; - - // String & Number - if (filterType === 'number' || filterType === 'string') return properties.hasOwnProperty(filter); - // Array - else if (Array.isArray(filter)) { - for (var i = 0; i < filter.length; i++) { - if (!applyFilter(properties, filter[i])) return false; - } - return true; - // Object - } else { - return propertiesContainsFilter(properties, filter); - } -} - -/** - * Properties contains filter (does not apply deepEqual operations) - * - * @private - * @param {*} properties Properties - * @param {Object} filter Filter - * @returns {boolean} does filter equal Properties - * @example - * propertiesContainsFilter({foo: 'bar', cluster: 0}, {cluster: 0}) - * //= true - * propertiesContainsFilter({foo: 'bar', cluster: 0}, {cluster: 1}) - * //= false - */ -export function propertiesContainsFilter(properties: any, filter: any): boolean { - var keys = Object.keys(filter); - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - if (properties[key] !== filter[key]) return false; - } - return true; -} - -/** - * Filter Properties - * - * @private - * @param {*} properties Properties - * @param {Array} keys Used to filter Properties - * @returns {*} filtered Properties - * @example - * filterProperties({foo: 'bar', cluster: 0}, ['cluster']) - * //= {cluster: 0} - */ -export function filterProperties(properties: any, keys: string[]): any { - if (!keys) return {}; - if (!keys.length) return {}; - - var newProperties = {}; - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - if (properties.hasOwnProperty(key)) newProperties[key] = properties[key]; - } - return newProperties; -} diff --git a/packages/turf-clusters/package.json b/packages/turf-clusters/package.json deleted file mode 100644 index 84c5aee14f..0000000000 --- a/packages/turf-clusters/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@turf/clusters", - "version": "6.0.1", - "description": "turf clusters module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "cluster", - "clusters", - "clustering" - ], - "author": "Turf Authors", - "contributors": [ - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-clusters/test.js b/packages/turf-clusters/test.js deleted file mode 100644 index 1938ed87af..0000000000 --- a/packages/turf-clusters/test.js +++ /dev/null @@ -1,88 +0,0 @@ -const test = require('tape'); -const { point, featureCollection } = require('@turf/helpers'); -const { - getCluster, - clusterEach, - clusterReduce, - // Below methods are not exposed in @turf/turf - createBins, - applyFilter, - filterProperties, - propertiesContainsFilter -} = require('./'); - -const properties = {foo: 'bar', cluster: 0}; -const geojson = featureCollection([ - point([0, 0], {cluster: 0, foo: 'null'}), - point([2, 4], {cluster: 1, foo: 'bar'}), - point([3, 6], {cluster: 1}), - point([5, 1], {0: 'foo'}), - point([4, 2], {'bar': 'foo'}), - point([2, 4], {}), - point([4, 3], undefined) -]); - -test('clusters -- getCluster', t => { - t.equal(getCluster(geojson, 0).features.length, 1, 'number1'); - t.equal(getCluster(geojson, 1).features.length, 0, 'number2'); - t.equal(getCluster(geojson, 'bar').features.length, 1, 'string1'); - t.equal(getCluster(geojson, 'cluster').features.length, 3, 'string2'); - t.equal(getCluster(geojson, {cluster: 1}).features.length, 2, 'object1'); - t.equal(getCluster(geojson, {cluster: 0}).features.length, 1, 'object2'); - t.equal(getCluster(geojson, ['cluster', {foo: 'bar'}]).features.length, 1); - t.equal(getCluster(geojson, ['cluster', 'foo']).features.length, 2); - t.equal(getCluster(geojson, ['cluster']).features.length, 3); - t.end(); -}); - -test('clusters -- clusterEach', t => { - const clusters = []; - let total = 0; - clusterEach(geojson, 'cluster', (cluster) => { - total += cluster.features.length; - clusters.push(cluster); - if (!cluster.features[0]) t.fail('if feature is undefined'); - }); - t.equal(total, 3); - t.equal(clusters.length, 2); - t.end(); -}); - -test('clusters -- clusterReduce', t => { - const clusters = []; - const total = clusterReduce(geojson, 'cluster', (previousValue, cluster) => { - clusters.push(cluster); - return previousValue + cluster.features.length; - }, 0); - t.equal(total, 3); - t.equal(clusters.length, 2); - t.end(); -}); - -test('clusters.utils -- applyFilter', t => { - t.true(applyFilter(properties, 'cluster')); - t.true(applyFilter(properties, ['cluster'])); - t.false(applyFilter(properties, {cluster: 1})); - t.true(applyFilter(properties, {cluster: 0})); - t.false(applyFilter(undefined, {cluster: 0})); - t.end(); -}); - -test('clusters.utils -- filterProperties', t => { - t.deepEqual(filterProperties(properties, ['cluster']), {cluster: 0}); - t.deepEqual(filterProperties(properties, []), {}); - t.deepEqual(filterProperties(properties, undefined), {}); - t.end(); -}); - -test('clusters.utils -- propertiesContainsFilter', t => { - t.deepEqual(propertiesContainsFilter(properties, {cluster: 0}), true); - t.deepEqual(propertiesContainsFilter(properties, {cluster: 1}), false); - t.deepEqual(propertiesContainsFilter(properties, {bar: 'foo'}), false); - t.end(); -}); - -test('clusters.utils -- propertiesContainsFilter', t => { - t.deepEqual(createBins(geojson, 'cluster'), {'0': [0], '1': [1, 2]}); - t.end(); -}); diff --git a/packages/turf-clusters/types.ts b/packages/turf-clusters/types.ts deleted file mode 100644 index d421b82614..0000000000 --- a/packages/turf-clusters/types.ts +++ /dev/null @@ -1,90 +0,0 @@ -import * as clusters from './' -import { featureCollection, point, Point} from '@turf/helpers' -import { getCluster, clusterEach, clusterReduce } from './' - -/** - * Fixtures - */ -const geojson = featureCollection([ - point([0, 0], {cluster: 0}), - point([2, 4], {cluster: 1}), - point([3, 6], {cluster: 1}), - point([3, 6], {0: 'foo'}), - point([3, 6], {'bar': 'foo'}) -]); - -/** - * Get Cluster - */ -clusters.getCluster(geojson, {cluster: 1}); -getCluster(geojson, {cluster: 1}); -getCluster(geojson, {0: 'foo'}); -getCluster(geojson, {'bar': 'foo'}); -getCluster(geojson, 'cluster'); -getCluster(geojson, ['cluster', 'bar']); -getCluster(geojson, 0); - -/** - * ClusterEach - */ -clusters.clusterEach(geojson, 'cluster', () => {}); -clusterEach(geojson, 'cluster', (cluster, clusterValue, currentIndex) => { - //= cluster - //= clusterValue - //= currentIndex -}) -// Calculate the total number of clusters -let total = 0 -clusterEach(geojson, 'cluster', () => { - total++; -}); - -// Create an Array of all the values retrieved from the 'cluster' property -const values: number[] = [] -clusterEach(geojson, 'cluster', (cluster, clusterValue: number) => { - values.push(clusterValue); -}); - -/** - * ClusterReduce - */ -const initialValue = 0; -clusterReduce(geojson, 'cluster', () => {}); -clusterReduce(geojson, 'cluster', (previousValue, cluster, clusterValue, currentIndex) => { - //= previousValue - //= cluster - //= clusterValue - //= currentIndex -}, initialValue) - -// Calculate the total number of clusters -const totalReduce = clusterReduce(geojson, 'cluster', function (previousValue) { - return previousValue++; -}, 0); - -// Create an Array of all the values retrieved from the 'cluster' property -const valuesReduce = clusterReduce(geojson, 'cluster', function (previousValue, cluster, clusterValue) { - return previousValue.concat(clusterValue); -}, []); - -/** - * Custom Properties - */ -const customPoints = featureCollection([ - point([0, 0], {cluster: 0}), - point([2, 4], {cluster: 1}), - point([3, 6], {cluster: 1}) -]); - -getCluster(customPoints, {cluster: 1}).features[0].properties.cluster -// getCluster(customPoints, {cluster: 1}).features[0].properties.foo // [ts] Property 'foo' does not exist on type '{ cluster: number; }'. - -clusterEach(customPoints, 'cluster', cluster => { - cluster.features[0].properties.cluster - // cluster.features[0].properties.foo // [ts] Property 'foo' does not exist on type '{ cluster: number; }'. -}) - -clusterReduce(customPoints, 'cluster', (previousValue, cluster) => { - cluster.features[0].properties.cluster - // cluster.features[0].properties.foo // [ts] Property 'foo' does not exist on type '{ cluster: number; }'. -}) \ No newline at end of file diff --git a/packages/turf-collect/.gitignore b/packages/turf-collect/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-collect/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-collect/LICENSE b/packages/turf-collect/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-collect/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-collect/README.md b/packages/turf-collect/README.md deleted file mode 100644 index 90b959d508..0000000000 --- a/packages/turf-collect/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# @turf/collect - - - -## collect - -Merges a specified property from a FeatureCollection of points into a -FeatureCollection of polygons. Given an `inProperty` on points and an `outProperty` -for polygons, this finds every point that lies within each polygon, collects the -`inProperty` values from those points, and adds them as an array to `outProperty` -on the polygon. - -**Parameters** - -- `polygons` **[FeatureCollection][1]<[Polygon][2]>** polygons with values on which to aggregate -- `points` **[FeatureCollection][1]<[Point][3]>** points to be aggregated -- `inProperty` **[string][4]** property to be nested from -- `outProperty` **[string][4]** property to be nested into - -**Examples** - -```javascript -var poly1 = turf.polygon([[[0,0],[10,0],[10,10],[0,10],[0,0]]]); -var poly2 = turf.polygon([[[10,0],[20,10],[20,20],[20,0],[10,0]]]); -var polyFC = turf.featureCollection([poly1, poly2]); -var pt1 = turf.point([5,5], {population: 200}); -var pt2 = turf.point([1,3], {population: 600}); -var pt3 = turf.point([14,2], {population: 100}); -var pt4 = turf.point([13,1], {population: 200}); -var pt5 = turf.point([19,7], {population: 300}); -var pointFC = turf.featureCollection([pt1, pt2, pt3, pt4, pt5]); -var collected = turf.collect(polyFC, pointFC, 'population', 'values'); -var values = collected.features[0].properties.values -//=values => [200, 600] - -//addToMap -var addToMap = [pointFC, collected] -``` - -Returns **[FeatureCollection][1]<[Polygon][2]>** polygons with properties listed based on `outField` - -[1]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/collect -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-collect/index.ts b/packages/turf-collect/index.ts deleted file mode 100644 index 3d8e7c47d4..0000000000 --- a/packages/turf-collect/index.ts +++ /dev/null @@ -1,75 +0,0 @@ -import turfbbox from '@turf/bbox'; -import booleanPointInPolygon from '@turf/boolean-point-in-polygon'; -import rbush from 'rbush'; -import { FeatureCollection, Polygon, Feature, Point } from '@turf/helpers'; - -/** - * Merges a specified property from a FeatureCollection of points into a - * FeatureCollection of polygons. Given an `inProperty` on points and an `outProperty` - * for polygons, this finds every point that lies within each polygon, collects the - * `inProperty` values from those points, and adds them as an array to `outProperty` - * on the polygon. - * - * @name collect - * @param {FeatureCollection} polygons polygons with values on which to aggregate - * @param {FeatureCollection} points points to be aggregated - * @param {string} inProperty property to be nested from - * @param {string} outProperty property to be nested into - * @returns {FeatureCollection} polygons with properties listed based on `outField` - * @example - * var poly1 = turf.polygon([[[0,0],[10,0],[10,10],[0,10],[0,0]]]); - * var poly2 = turf.polygon([[[10,0],[20,10],[20,20],[20,0],[10,0]]]); - * var polyFC = turf.featureCollection([poly1, poly2]); - * var pt1 = turf.point([5,5], {population: 200}); - * var pt2 = turf.point([1,3], {population: 600}); - * var pt3 = turf.point([14,2], {population: 100}); - * var pt4 = turf.point([13,1], {population: 200}); - * var pt5 = turf.point([19,7], {population: 300}); - * var pointFC = turf.featureCollection([pt1, pt2, pt3, pt4, pt5]); - * var collected = turf.collect(polyFC, pointFC, 'population', 'values'); - * var values = collected.features[0].properties.values - * //=values => [200, 600] - * - * //addToMap - * var addToMap = [pointFC, collected] - */ -function collect( - polygons: FeatureCollection, - points: FeatureCollection, - inProperty: string, - outProperty: string -): FeatureCollection { - var rtree = rbush(6); - - var treeItems = points.features.map(function (item) { - return { - minX: item.geometry.coordinates[0], - minY: item.geometry.coordinates[1], - maxX: item.geometry.coordinates[0], - maxY: item.geometry.coordinates[1], - property: item.properties[inProperty] - }; - }); - - rtree.load(treeItems); - polygons.features.forEach(function (poly) { - - if (!poly.properties) { - poly.properties = {}; - } - var bbox = turfbbox(poly); - var potentialPoints = rtree.search({minX: bbox[0], minY: bbox[1], maxX: bbox[2], maxY: bbox[3]}); - var values = []; - potentialPoints.forEach(function (pt) { - if (booleanPointInPolygon([pt.minX, pt.minY], poly)) { - values.push(pt.property); - } - }); - - poly.properties[outProperty] = values; - }); - - return polygons; -} - -export default collect; diff --git a/packages/turf-collect/package.json b/packages/turf-collect/package.json deleted file mode 100644 index a48cbb860a..0000000000 --- a/packages/turf-collect/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "@turf/collect", - "version": "6.0.1", - "description": "turf collect module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "aggregate", - "turf", - "geojson", - "points", - "polygons", - "stats" - ], - "author": "Turf Authors", - "contributors": [ - "Rowan Winsemius <@rowanwins>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/boolean-point-in-polygon": "6.x", - "@turf/helpers": "6.x", - "rbush": "2.x" - } -} diff --git a/packages/turf-collect/test.js b/packages/turf-collect/test.js deleted file mode 100644 index 594392ad8e..0000000000 --- a/packages/turf-collect/test.js +++ /dev/null @@ -1,26 +0,0 @@ -const test = require('tape'); -const { featureCollection, point, polygon } = require('@turf/helpers'); -const collect = require('./').default; - -test('turf collect module', t => { - const poly1 = polygon([[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]); - const poly2 = polygon([[[10, 0], [20, 10], [20, 20], [20, 0], [10, 0]]]); - const poly3 = polygon([[[100, 0], [110, -10], [110, -20], [100, 0]]]); - const polyFC = featureCollection([poly1, poly2, poly3]); - const pt1 = point([5, 5], {population: 200}); - const pt2 = point([1, 3], {population: 600}); - const pt3 = point([14, 2], {population: 100}); - const pt4 = point([13, 1], {population: 200}); - const pt5 = point([19, 7], {population: 300}); - const ptFC = featureCollection([pt1, pt2, pt3, pt4, pt5]); - const aggregated = collect(polyFC, ptFC, 'population', 'values'); - // Check the same number of input and output polys are the same - t.equal(polyFC.features.length, aggregated.features.length); - // Check the right values have been assigned - t.deepEqual(aggregated.features[0].properties.values, [200, 600]); - t.deepEqual(aggregated.features[1].properties.values, [100, 200, 300]); - - // Check the property has been created even if no values have been assigned - t.deepEqual(aggregated.features[2].properties.values, []); - t.end(); -}); diff --git a/packages/turf-combine/.gitignore b/packages/turf-combine/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-combine/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-combine/LICENSE b/packages/turf-combine/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-combine/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-combine/README.md b/packages/turf-combine/README.md deleted file mode 100644 index 5bdd4ef27e..0000000000 --- a/packages/turf-combine/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# @turf/combine - - - -## combine - -Combines a [FeatureCollection][1] of [Point][2], [LineString][3], or [Polygon][4] features -into [MultiPoint][5], [MultiLineString][6], or [MultiPolygon][7] features. - -**Parameters** - -- `fc` **[FeatureCollection][8]<([Point][9] \| [LineString][10] \| [Polygon][11])>** a FeatureCollection of any type - -**Examples** - -```javascript -var fc = turf.featureCollection([ - turf.point([19.026432, 47.49134]), - turf.point([19.074497, 47.509548]) -]); - -var combined = turf.combine(fc); - -//addToMap -var addToMap = [combined] -``` - -Returns **[FeatureCollection][8]<([MultiPoint][12] \| [MultiLineString][13] \| [MultiPolygon][14])>** a FeatureCollection of corresponding type to input - -[1]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.3 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[8]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[9]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[10]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[11]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[12]: https://tools.ietf.org/html/rfc7946#section-3.1.3 - -[13]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[14]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/combine -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-combine/index.ts b/packages/turf-combine/index.ts deleted file mode 100644 index 4b9796f2d7..0000000000 --- a/packages/turf-combine/index.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { feature, featureCollection } from '@turf/helpers'; -import { featureEach } from '@turf/meta'; -import { Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, Feature, FeatureCollection } from '@turf/helpers' - -/** - * Combines a {@link FeatureCollection} of {@link Point}, {@link LineString}, or {@link Polygon} features - * into {@link MultiPoint}, {@link MultiLineString}, or {@link MultiPolygon} features. - * - * @name combine - * @param {FeatureCollection} fc a FeatureCollection of any type - * @returns {FeatureCollection} a FeatureCollection of corresponding type to input - * @example - * var fc = turf.featureCollection([ - * turf.point([19.026432, 47.49134]), - * turf.point([19.074497, 47.509548]) - * ]); - * - * var combined = turf.combine(fc); - * - * //addToMap - * var addToMap = [combined] - */ -function combine(fc: FeatureCollection) { - var groups = { - MultiPoint: {coordinates: [], properties: []}, - MultiLineString: {coordinates: [], properties: []}, - MultiPolygon: {coordinates: [], properties: []} - }; - - var multiMapping = Object.keys(groups).reduce(function (memo, item) { - memo[item.replace('Multi', '')] = item; - return memo; - }, {}); - - function addToGroup(feature, key, multi) { - if (!multi) { - groups[key].coordinates.push(feature.geometry.coordinates); - } else { - groups[key].coordinates = groups[key].coordinates.concat(feature.geometry.coordinates); - } - groups[key].properties.push(feature.properties); - } - - featureEach(fc, function (feature) { - if (!feature.geometry) return; - if (groups[feature.geometry.type]) { - addToGroup(feature, feature.geometry.type, true); - } else if (multiMapping[feature.geometry.type]) { - addToGroup(feature, multiMapping[feature.geometry.type], false); - } - }); - - return featureCollection(Object.keys(groups) - .filter(function (key) { - return groups[key].coordinates.length; - }) - .sort() - .map(function (key) { - var geometry = { type: key, coordinates: groups[key].coordinates }; - var properties = { collectedProperties: groups[key].properties }; - return feature(geometry, properties); - })); -} - -export default combine; diff --git a/packages/turf-combine/package.json b/packages/turf-combine/package.json deleted file mode 100644 index ba02c37dbc..0000000000 --- a/packages/turf-combine/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "@turf/combine", - "version": "6.0.1", - "description": "turf combine module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "multipoint", - "multipolygon", - "combine" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "tape": "*", - "typescript": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-combine/test.js b/packages/turf-combine/test.js deleted file mode 100644 index 72b81fb4c1..0000000000 --- a/packages/turf-combine/test.js +++ /dev/null @@ -1,203 +0,0 @@ -const test = require('tape'); -const { point, multiPoint, polygon, multiPolygon, lineString, multiLineString, featureCollection, feature } = require('@turf/helpers'); -const combine = require('./').default; - -test('combine -- points', t => { - // MultiPoint - const pt1 = point([50, 51]); - const pt2 = point([100, 101]); - - const multiPt = combine(featureCollection([pt1, pt2])); - - t.ok(multiPt, 'should combine two Points into a MultiPoint'); - t.deepEqual(multiPt.features[0].geometry.coordinates, [[50, 51], [100, 101]]); - t.end(); -}); - -test('combine -- mixed multiPoint & point', function (t) { - // MultiPoint - const pt1 = point([50, 51]); - const pt2 = multiPoint([[100, 101], [101, 102]]); - - const multiPt = combine(featureCollection([pt1, pt2])); - - t.ok(multiPt, 'should combine Points + MultiPoint into a MultiPoint'); - t.deepEqual(multiPt.features[0].geometry.coordinates, [[50, 51], [100, 101], [101, 102]]); - t.end(); -}); - -test('combine -- linestrings', function (t) { - // MultiLineString - const l1 = lineString([ - [102.0, - -10.0], - [130.0, - 4.0]]); - const l2 = lineString([ - [40.0, - -20.0], - [150.0, - 18.0]]); - - const multiLine = combine(featureCollection([l1, l2])); - - t.ok(multiLine, 'should combine two LineStrings into a MultiLineString'); - t.equal(multiLine.features[0].geometry.type, 'MultiLineString'); - t.deepEqual(multiLine.features[0].geometry.coordinates, [[[102, -10], [130, 4]], [[40, -20], [150, 18]]]); - t.end(); -}); - -test('combine -- mixed multiLineString & linestring', function (t) { - // MultiLineString - const l1 = lineString([ - [102.0, -10.0], - [130.0, 4.0] - ]); - const l2 = multiLineString([ - [ - [40.0, -20.0], - [150.0, 18.0] - ], - [ - [50, -10], - [160, 28] - ] - ]); - - const multiLine = combine(featureCollection([l1, l2])); - - t.ok(multiLine, 'should combine LineString + MultiLineString into a MultiLineString'); - t.equal(multiLine.features[0].geometry.type, 'MultiLineString'); - t.deepEqual(multiLine.features[0].geometry.coordinates, [[[102, -10], [130, 4]], [[40, -20], [150, 18]], [[50, -10], [160, 28]]]); - t.end(); -}); - -test('combine -- polygons', function (t) { - // MultiPolygon - const p1 = polygon([ - [ - [20.0, 0.0], - [101.0, 0.0], - [101.0, 1.0], - [100.0, 1.0], - [100.0, 0.0], - [20.0, 0.0] - ] - ]); - const p2 = polygon([ - [ - [30.0, 0.0], - [102.0, 0.0], - [103.0, 1.0], - [30.0, 0.0] - ] - ]); - const multiPoly = combine(featureCollection([p1, p2])); - - t.ok(multiPoly, 'should combine two Polygons into a MultiPolygon'); - t.equal(multiPoly.features[0].geometry.type, 'MultiPolygon'); - t.deepEqual(multiPoly.features[0].geometry.coordinates, - [[[[20, 0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0], [20, 0]]], - [[[30.0, 0.0], [102.0, 0.0], [103.0, 1.0], [30.0, 0.0]]]]); - - t.end(); -}); - -test('combine -- polygons', function (t) { - // MultiPolygon - const p1 = polygon([ - [ - [20.0, 0.0], - [101.0, 0.0], - [101.0, 1.0], - [100.0, 1.0], - [100.0, 0.0], - [20.0, 0.0] - ] - ]); - const p2 = multiPolygon([ - [[ - [30.0, 0.0], - [102.0, 0.0], - [103.0, 1.0], - [30.0, 0.0] - ]], - [ - [ - [20.0, 5.0], - [92.0, 5.0], - [93.0, 6.0], - [20.0, 5.0] - ], - [ - [25, 5], - [30, 5], - [30, 5.5], - [25, 5] - ] - ] - ]); - const multiPoly = combine(featureCollection([p1, p2])); - - t.ok(multiPoly, 'should combine two Polygon + MultiPolygon into a MultiPolygon'); - t.equal(multiPoly.features[0].geometry.type, 'MultiPolygon'); - t.deepEqual(multiPoly.features[0].geometry.coordinates, - [[[[20, 0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0], [20, 0]]], - [[[30.0, 0.0], [102.0, 0.0], [103.0, 1.0], [30.0, 0.0]]], - [[[20.0, 5.0], [92.0, 5.0], [93.0, 6.0], [20.0, 5.0]], - [[25, 5], [30, 5], [30, 5.5], [25, 5]]] - ]); - - t.end(); -}); - -test('combine -- heterogenous', function (t) { - // MultiPolygon - const p1 = polygon([ - [ - [20.0, 0.0], - [101.0, 0.0], - [101.0, 1.0], - [100.0, 1.0], - [100.0, 0.0], - [20.0, 0.0] - ] - ]); - const p2 = multiPolygon([ - [[ - [30.0, 0.0], - [102.0, 0.0], - [103.0, 1.0], - [30.0, 0.0] - ]], - [ - [ - [20.0, 5.0], - [92.0, 5.0], - [93.0, 6.0], - [20.0, 5.0] - ], - [ - [25, 5], - [30, 5], - [30, 5.5], - [25, 5] - ] - ] - ]); - const pt1 = point([50, 51]); - const multiPoly = combine(featureCollection([p1, p2, pt1])); - - t.ok(multiPoly, 'should combine two Polygon + MultiPolygon into a MultiPolygon'); - t.equal(multiPoly.features[0].geometry.type, 'MultiPoint'); - - t.equal(multiPoly.features[1].geometry.type, 'MultiPolygon'); - t.deepEqual(multiPoly.features[1].geometry.coordinates, - [[[[20, 0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0], [20, 0]]], - [[[30.0, 0.0], [102.0, 0.0], [103.0, 1.0], [30.0, 0.0]]], - [[[20.0, 5.0], [92.0, 5.0], [93.0, 6.0], [20.0, 5.0]], - [[25, 5], [30, 5], [30, 5.5], [25, 5]]] - ]); - - t.end(); -}); diff --git a/packages/turf-concave/.gitignore b/packages/turf-concave/.gitignore deleted file mode 100644 index 10b7cd00cf..0000000000 --- a/packages/turf-concave/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -index.js -lib/turf-dissolve.js -lib/turf-line-dissolve.js -lib/turf-polygon-dissolve.js \ No newline at end of file diff --git a/packages/turf-concave/LICENSE b/packages/turf-concave/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-concave/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-concave/README.md b/packages/turf-concave/README.md deleted file mode 100644 index 510010cfb4..0000000000 --- a/packages/turf-concave/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# @turf/concave - - - -## concave - -Takes a set of [points][1] and returns a concave hull Polygon or MultiPolygon. -Internally, this uses [turf-tin][2] to generate geometries. - -**Parameters** - -- `points` **[FeatureCollection][3]<[Point][4]>** input points -- `options` **[Object][5]** Optional parameters (optional, default `{}`) - - `options.maxEdge` **[number][6]** the length (in 'units') of an edge necessary for part of the hull to become concave. (optional, default `Infinity`) - - `options.units` **[string][7]** can be degrees, radians, miles, or kilometers (optional, default `'kilometers'`) - -**Examples** - -```javascript -var points = turf.featureCollection([ - turf.point([-63.601226, 44.642643]), - turf.point([-63.591442, 44.651436]), - turf.point([-63.580799, 44.648749]), - turf.point([-63.573589, 44.641788]), - turf.point([-63.587665, 44.64533]), - turf.point([-63.595218, 44.64765]) -]); -var options = {units: 'miles', maxEdge: 1}; - -var hull = turf.concave(points, options); - -//addToMap -var addToMap = [points, hull] -``` - -Returns **([Feature][8]<([Polygon][9] \| [MultiPolygon][10])> | null)** a concave hull (null value is returned if unable to compute hull) - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://github.com/Turfjs/turf-tin - -[3]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[8]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[9]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[10]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/concave -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-concave/index.ts b/packages/turf-concave/index.ts deleted file mode 100644 index aaccfa0b50..0000000000 --- a/packages/turf-concave/index.ts +++ /dev/null @@ -1,91 +0,0 @@ -import distance from "@turf/distance"; -import { feature, featureCollection, isNumber, isObject, polygon } from "@turf/helpers"; -import { Feature, FeatureCollection, MultiPolygon, Point, Polygon, Units} from "@turf/helpers"; -import { featureEach } from "@turf/meta"; -import tin from "@turf/tin"; -import dissolve from "./lib/turf-dissolve"; - -/** - * Takes a set of {@link Point|points} and returns a concave hull Polygon or MultiPolygon. - * Internally, this uses [turf-tin](https://github.com/Turfjs/turf-tin) to generate geometries. - * - * @name concave - * @param {FeatureCollection} points input points - * @param {Object} [options={}] Optional parameters - * @param {number} [options.maxEdge=Infinity] the length (in 'units') of an edge necessary for part of the - * hull to become concave. - * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers - * @returns {Feature<(Polygon|MultiPolygon)>|null} a concave hull (null value is returned if unable to compute hull) - * @example - * var points = turf.featureCollection([ - * turf.point([-63.601226, 44.642643]), - * turf.point([-63.591442, 44.651436]), - * turf.point([-63.580799, 44.648749]), - * turf.point([-63.573589, 44.641788]), - * turf.point([-63.587665, 44.64533]), - * turf.point([-63.595218, 44.64765]) - * ]); - * var options = {units: 'miles', maxEdge: 1}; - * - * var hull = turf.concave(points, options); - * - * //addToMap - * var addToMap = [points, hull] - */ -function concave( - points: FeatureCollection, - options: {maxEdge?: number, units?: Units} = {}, -): Feature | null { - const maxEdge = options.maxEdge || Infinity; - - const cleaned = removeDuplicates(points); - - const tinPolys = tin(cleaned); - // calculate length of all edges and area of all triangles - // and remove triangles that fail the max length test - tinPolys.features = tinPolys.features.filter((triangle) => { - const pt1 = triangle.geometry.coordinates[0][0]; - const pt2 = triangle.geometry.coordinates[0][1]; - const pt3 = triangle.geometry.coordinates[0][2]; - const dist1 = distance(pt1, pt2, options); - const dist2 = distance(pt2, pt3, options); - const dist3 = distance(pt1, pt3, options); - return (dist1 <= maxEdge && dist2 <= maxEdge && dist3 <= maxEdge); - }); - - if (tinPolys.features.length < 1) { return null; } - - // merge the adjacent triangles - const dissolved: any = dissolve(tinPolys); - - // geojson-dissolve always returns a MultiPolygon - if (dissolved.coordinates.length === 1) { - dissolved.coordinates = dissolved.coordinates[0]; - dissolved.type = "Polygon"; - } - return feature(dissolved); -} - -/** - * Removes duplicated points in a collection returning a new collection - * - * @private - * @param {FeatureCollection} points to be cleaned - * @returns {FeatureCollection} cleaned set of points - */ -function removeDuplicates(points: FeatureCollection): FeatureCollection { - const cleaned: Array> = []; - const existing: {[key: string]: boolean} = {}; - - featureEach(points, (pt) => { - if (!pt.geometry) { return; } - const key = pt.geometry.coordinates.join("-"); - if (!existing.hasOwnProperty(key)) { - cleaned.push(pt); - existing[key] = true; - } - }); - return featureCollection(cleaned); -} - -export default concave; diff --git a/packages/turf-concave/lib/turf-dissolve.d.ts b/packages/turf-concave/lib/turf-dissolve.d.ts deleted file mode 100644 index 953acecfce..0000000000 --- a/packages/turf-concave/lib/turf-dissolve.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Feature, FeatureCollection, LineString, MultiLineString, MultiPolygon, Polygon } from "@turf/helpers"; -/** - * Transform function: attempts to dissolve geojson objects where possible - * [GeoJSON] -> GeoJSON geometry - * - * @private - * @param {FeatureCollection} geojson Features to dissolved - * @param {Object} [options={}] Optional parameters - * @param {boolean} [options.mutate=false] Prevent input mutation - * @returns {Feature} Dissolved Features - */ -declare function dissolve(geojson: FeatureCollection, options?: { - mutate?: boolean; -}): Feature | null; -export default dissolve; diff --git a/packages/turf-concave/lib/turf-dissolve.ts b/packages/turf-concave/lib/turf-dissolve.ts deleted file mode 100644 index e1e1a389d6..0000000000 --- a/packages/turf-concave/lib/turf-dissolve.ts +++ /dev/null @@ -1,69 +0,0 @@ -import clone from "@turf/clone"; -import { isObject } from "@turf/helpers"; -import { Feature, FeatureCollection, LineString, MultiLineString, MultiPolygon, Polygon } from "@turf/helpers"; -import { getType } from "@turf/invariant"; -import { flattenEach } from "@turf/meta"; -import lineDissolve from "./turf-line-dissolve"; -import polygonDissolve from "./turf-polygon-dissolve"; - -/** - * Transform function: attempts to dissolve geojson objects where possible - * [GeoJSON] -> GeoJSON geometry - * - * @private - * @param {FeatureCollection} geojson Features to dissolved - * @param {Object} [options={}] Optional parameters - * @param {boolean} [options.mutate=false] Prevent input mutation - * @returns {Feature} Dissolved Features - */ -function dissolve(geojson: FeatureCollection, options: { - mutate?: boolean, -} = {}): Feature | null { - // Optional parameters - options = options || {}; - if (!isObject(options)) { throw new Error("options is invalid"); } - const mutate = options.mutate; - - // Validation - if (getType(geojson) !== "FeatureCollection") { throw new Error("geojson must be a FeatureCollection"); } - if (!geojson.features.length) { throw new Error("geojson is empty"); } - - // Clone geojson to avoid side effects - // Topojson modifies in place, so we need to deep clone first - if (mutate === false || mutate === undefined) { geojson = clone(geojson); } - - // Assert homogenity - const type = getHomogenousType(geojson); - if (!type) { throw new Error("geojson must be homogenous"); } - - // Data => Typescript hack - const data: any = geojson; - - switch (type) { - case "LineString": - return lineDissolve(data, options); - case "Polygon": - return polygonDissolve(data, options); - default: - throw new Error(type + " is not supported"); - } -} - -/** - * Checks if GeoJSON is Homogenous - * - * @private - * @param {GeoJSON} geojson GeoJSON - * @returns {string|null} Homogenous type or null if multiple types - */ -function getHomogenousType(geojson: any) { - const types: {[key: string]: boolean} = {}; - flattenEach(geojson, (feature) => { - types[feature.geometry.type] = true; - }); - const keys = Object.keys(types); - if (keys.length === 1) { return keys[0]; } - return null; -} - -export default dissolve; diff --git a/packages/turf-concave/lib/turf-line-dissolve.d.ts b/packages/turf-concave/lib/turf-line-dissolve.d.ts deleted file mode 100644 index fc5af1da9e..0000000000 --- a/packages/turf-concave/lib/turf-line-dissolve.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Feature, FeatureCollection, LineString, MultiLineString } from "@turf/helpers"; -/** - * Merges all connected (non-forking, non-junctioning) line strings into single lineStrings. - * [LineString] -> LineString|MultiLineString - * - * @param {FeatureCollection} geojson Lines to dissolve - * @param {Object} [options={}] Optional parameters - * @param {boolean} [options.mutate=false] Prevent input mutation - * @returns {Feature} Dissolved lines - */ -declare function lineDissolve(geojson: FeatureCollection, options?: { - mutate?: boolean; -}): Feature | null; -export default lineDissolve; diff --git a/packages/turf-concave/lib/turf-line-dissolve.ts b/packages/turf-concave/lib/turf-line-dissolve.ts deleted file mode 100644 index cc4c5543f1..0000000000 --- a/packages/turf-concave/lib/turf-line-dissolve.ts +++ /dev/null @@ -1,94 +0,0 @@ -import clone from "@turf/clone"; -import { isObject, lineString, multiLineString } from "@turf/helpers"; -import { Feature, FeatureCollection, LineString, MultiLineString } from "@turf/helpers"; -import { getType } from "@turf/invariant"; -import { lineReduce } from "@turf/meta"; - -/** - * Merges all connected (non-forking, non-junctioning) line strings into single lineStrings. - * [LineString] -> LineString|MultiLineString - * - * @param {FeatureCollection} geojson Lines to dissolve - * @param {Object} [options={}] Optional parameters - * @param {boolean} [options.mutate=false] Prevent input mutation - * @returns {Feature} Dissolved lines - */ -function lineDissolve( - geojson: FeatureCollection, - options: {mutate?: boolean} = {}, -): Feature | null { - // Optional parameters - options = options || {}; - if (!isObject(options)) { throw new Error("options is invalid"); } - const mutate = options.mutate; - - // Validation - if (getType(geojson) !== "FeatureCollection") { throw new Error("geojson must be a FeatureCollection"); } - if (!geojson.features.length) { throw new Error("geojson is empty"); } - - // Clone geojson to avoid side effects - if (mutate === false || mutate === undefined) { geojson = clone(geojson); } - - const result: any[] = []; - const lastLine = lineReduce(geojson, (previousLine: any, currentLine: any) => { - // Attempt to merge this LineString with the other LineStrings, updating - // the reference as it is merged with others and grows. - const merged = mergeLineStrings(previousLine, currentLine); - - // Accumulate the merged LineString - if (merged) { return merged; - // Put the unmerged LineString back into the list - } else { - result.push(previousLine); - return currentLine; - } - }); - // Append the last line - if (lastLine) { result.push(lastLine); } - - // Return null if no lines were dissolved - if (!result.length) { - return null; - // Return LineString if only 1 line was dissolved - } else if (result.length === 1) { - return result[0]; - // Return MultiLineString if multiple lines were dissolved with gaps - } else { return multiLineString(result.map((line) => { - return line.coordinates; - })); } -} - -// [Number, Number] -> String -function coordId(coord: number[]) { - return coord[0].toString() + "," + coord[1].toString(); -} - -/** - * LineString, LineString -> LineString - * - * @private - * @param {Feature} a line1 - * @param {Feature} b line2 - * @returns {Feature|null} Merged LineString - */ -function mergeLineStrings(a: Feature, b: Feature) { - const coords1 = a.geometry.coordinates; - const coords2 = b.geometry.coordinates; - - const s1 = coordId(coords1[0]); - const e1 = coordId(coords1[coords1.length - 1]); - const s2 = coordId(coords2[0]); - const e2 = coordId(coords2[coords2.length - 1]); - - // TODO: handle case where more than one of these is true! - let coords; - if (s1 === e2) { coords = coords2.concat(coords1.slice(1)); - } else if (s2 === e1) { coords = coords1.concat(coords2.slice(1)); - } else if (s1 === s2) { coords = coords1.slice(1).reverse().concat(coords2); - } else if (e1 === e2) { coords = coords1.concat(coords2.reverse().slice(1)); - } else { return null; } - - return lineString(coords); -} - -export default lineDissolve; diff --git a/packages/turf-concave/lib/turf-polygon-dissolve.d.ts b/packages/turf-concave/lib/turf-polygon-dissolve.d.ts deleted file mode 100644 index b90fcc2e62..0000000000 --- a/packages/turf-concave/lib/turf-polygon-dissolve.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Feature, FeatureCollection, MultiPolygon, Polygon } from "@turf/helpers"; -/** - * Dissolves all overlapping (Multi)Polygon - * - * @param {FeatureCollection} geojson Polygons to dissolve - * @param {Object} [options={}] Optional parameters - * @param {boolean} [options.mutate=false] Prevent input mutation - * @returns {Feature} Dissolved Polygons - */ -export default function polygonDissolve(geojson: FeatureCollection, options?: { - mutate?: boolean; -}): Feature | null; diff --git a/packages/turf-concave/lib/turf-polygon-dissolve.ts b/packages/turf-concave/lib/turf-polygon-dissolve.ts deleted file mode 100644 index 5e26db539c..0000000000 --- a/packages/turf-concave/lib/turf-polygon-dissolve.ts +++ /dev/null @@ -1,35 +0,0 @@ -import clone from "@turf/clone"; -import { geometryCollection, isObject } from "@turf/helpers"; -import { Feature, FeatureCollection, LineString, MultiLineString, MultiPolygon, Polygon } from "@turf/helpers"; -import { getType } from "@turf/invariant"; -import { flattenEach } from "@turf/meta"; -import { merge, topology } from "topojson"; - -/** - * Dissolves all overlapping (Multi)Polygon - * - * @param {FeatureCollection} geojson Polygons to dissolve - * @param {Object} [options={}] Optional parameters - * @param {boolean} [options.mutate=false] Prevent input mutation - * @returns {Feature} Dissolved Polygons - */ -export default function polygonDissolve( - geojson: FeatureCollection, - options: {mutate?: boolean} = {}, -): Feature | null { - // Validation - if (getType(geojson) !== "FeatureCollection") { throw new Error("geojson must be a FeatureCollection"); } - if (!geojson.features.length) { throw new Error("geojson is empty"); } - - // Clone geojson to avoid side effects - // Topojson modifies in place, so we need to deep clone first - if (options.mutate === false || options.mutate === undefined) { geojson = clone(geojson); } - - const geoms: any[] = []; - flattenEach(geojson, (feature) => { - geoms.push(feature.geometry); - }); - const topo: any = topology({geoms: geometryCollection(geoms).geometry}); - const merged: any = merge(topo, topo.objects.geoms.geometries); - return merged; -} diff --git a/packages/turf-concave/package.json b/packages/turf-concave/package.json deleted file mode 100644 index 0abc892c3d..0000000000 --- a/packages/turf-concave/package.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "name": "@turf/concave", - "version": "6.0.5", - "description": "turf concave module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "lib/turf-dissolve.js", - "lib/turf-dissolve.d.ts", - "lib/turf-line-dissolve.js", - "lib/turf-line-dissolve.d.ts", - "lib/turf-polygon-dissolve.js", - "lib/turf-polygon-dissolve.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis", - "concave", - "geometry" - ], - "author": "Turf Authors", - "contributors": [ - "Tom MacWright <@tmcw>", - "Lyzi Diamond <@lyzidiamond>", - "Denis Carriere <@DenisCarriere>", - "Stefano Borghi <@stebogit>", - "Rowan Winsemius <@rowanwins>", - "Daniel Pulido <@dpmcmlxxvi>", - "Stephen Whitmore <@noffle>", - "Gregor MacLennan <@gmaclennan>", - "Mike Bostock <@mbostock>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@types/tape": "*", - "@types/topojson": "*", - "benchmark": "*", - "load-json-file": "*", - "tape": "*", - "tslint": "*", - "typescript": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/clone": "6.x", - "@turf/distance": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x", - "@turf/tin": "6.x", - "topojson": "3.x" - } -} diff --git a/packages/turf-concave/test.js b/packages/turf-concave/test.js deleted file mode 100644 index a46f871c40..0000000000 --- a/packages/turf-concave/test.js +++ /dev/null @@ -1,59 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { point, featureCollection } = require('@turf/helpers'); -const { featureEach } = require('@turf/meta'); -const concave = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-concave', t => { - fixtures.forEach(fixture => { - const filename = fixture.filename; - const name = fixture.name; - const geojson = fixture.geojson; - const properties = geojson.properties || {}; - const maxEdge = properties.maxEdge || 1; - const units = properties.units; - - const hull = concave(geojson, {units, maxEdge}); - featureEach(geojson, stylePt); - const results = featureCollection(geojson.features.concat(hull)); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEquals(results, load.sync(directories.out + filename), name); - }); - t.end(); -}); - - -const points = featureCollection([point([0, 0]), point([1, 1]), point([1, 0])]); -const onePoint = featureCollection([point([0, 0])]); - -test('concave -- throw', t => { - t.equal(concave(onePoint, {maxEdge: 5.5, units: 'miles'}), null, 'too few polygons found to compute concave hull'); - t.equal(concave(onePoint), null, 'too few polygons found to compute concave hull -- maxEdge too small'); - // t.throws(() => concave(null), /points is required/, 'no points'); - // t.throws(() => concave(points, {units: 'foo'}), /units is invalid/, 'invalid units'); - // t.throws(() => concave(points, {maxEdge: 'foo'}), /maxEdge is invalid/, 'invalid maxEdge'); - - t.end(); -}); - -function stylePt(pt) { - pt.properties['marker-color'] = '#f0f'; - pt.properties['marker-size'] = 'small'; -} diff --git a/packages/turf-concave/tsconfig.json b/packages/turf-concave/tsconfig.json deleted file mode 100644 index 4368468818..0000000000 --- a/packages/turf-concave/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - }, - "files": [ - "index.ts", - "lib/turf-dissolve.ts", - "lib/turf-line-dissolve.ts", - "lib/turf-polygon-dissolve.ts" - ] -} \ No newline at end of file diff --git a/packages/turf-concave/tslint.json b/packages/turf-concave/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-concave/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-convex/.gitignore b/packages/turf-convex/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-convex/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-convex/LICENSE b/packages/turf-convex/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-convex/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-convex/README.md b/packages/turf-convex/README.md deleted file mode 100644 index cae591ce72..0000000000 --- a/packages/turf-convex/README.md +++ /dev/null @@ -1,83 +0,0 @@ -# @turf/convex - - - -## convex - -Takes a [Feature][1] or a [FeatureCollection][2] and returns a convex hull [Polygon][3]. - -Internally this uses -the [convex-hull][4] module that -implements a [monotone chain hull][5]. - -**Parameters** - -- `geojson` **[GeoJSON][6]** input Feature or FeatureCollection -- `options` **[Object][7]** Optional parameters (optional, default `{}`) - - `options.concavity` **[number][8]** 1 - thin shape. Infinity - convex hull. (optional, default `Infinity`) - - `options.properties` **[Object][7]** Translate Properties to Feature (optional, default `{}`) - -**Examples** - -```javascript -var points = turf.featureCollection([ - turf.point([10.195312, 43.755225]), - turf.point([10.404052, 43.8424511]), - turf.point([10.579833, 43.659924]), - turf.point([10.360107, 43.516688]), - turf.point([10.14038, 43.588348]), - turf.point([10.195312, 43.755225]) -]); - -var hull = turf.convex(points); - -//addToMap -var addToMap = [points, hull] -``` - -Returns **[Feature][9]<[Polygon][10]>** a convex hull - -[1]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[4]: https://github.com/mikolalysenko/convex-hull - -[5]: http://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain - -[6]: https://tools.ietf.org/html/rfc7946#section-3 - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[9]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[10]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/convex -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-convex/index.ts b/packages/turf-convex/index.ts deleted file mode 100644 index 854c394849..0000000000 --- a/packages/turf-convex/index.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { AllGeoJSON, Feature, polygon, Polygon, Properties } from "@turf/helpers"; -import { coordEach } from "@turf/meta"; -import concaveman from "concaveman"; - -/** - * Takes a {@link Feature} or a {@link FeatureCollection} and returns a convex hull {@link Polygon}. - * - * Internally this uses - * the [convex-hull](https://github.com/mikolalysenko/convex-hull) module that implements a - * [monotone chain hull](http://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain). - * - * @name convex - * @param {GeoJSON} geojson input Feature or FeatureCollection - * @param {Object} [options={}] Optional parameters - * @param {number} [options.concavity=Infinity] 1 - thin shape. Infinity - convex hull. - * @param {Object} [options.properties={}] Translate Properties to Feature - * @returns {Feature} a convex hull - * @example - * var points = turf.featureCollection([ - * turf.point([10.195312, 43.755225]), - * turf.point([10.404052, 43.8424511]), - * turf.point([10.579833, 43.659924]), - * turf.point([10.360107, 43.516688]), - * turf.point([10.14038, 43.588348]), - * turf.point([10.195312, 43.755225]) - * ]); - * - * var hull = turf.convex(points); - * - * //addToMap - * var addToMap = [points, hull] - */ -export default function convex

(geojson: AllGeoJSON, options: { - concavity?: number, - properties?: P, -} = {}): Feature | null { - // Default parameters - options.concavity = options.concavity || Infinity; - - // Container - const points: number[][] = []; - - // Convert all points to flat 2D coordinate Array - coordEach(geojson, (coord) => { - points.push([coord[0], coord[1]]); - }); - if (!points.length) { return null; } - - const convexHull = concaveman(points, options.concavity); - - // Convex hull should have at least 3 different vertices in order to create a valid polygon - if (convexHull.length > 3) { - return polygon([convexHull]); - } - return null; -} diff --git a/packages/turf-convex/package.json b/packages/turf-convex/package.json deleted file mode 100644 index b273540863..0000000000 --- a/packages/turf-convex/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "@turf/convex", - "version": "6.0.3", - "description": "turf convex module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@types/concaveman": "*", - "@types/tape": "*", - "benchmark": "*", - "glob": "*", - "load-json-file": "*", - "tape": "*", - "tslint": "*", - "typescript": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/meta": "6.x", - "concaveman": "*" - } -} diff --git a/packages/turf-convex/test.js b/packages/turf-convex/test.js deleted file mode 100644 index 5a223f7cd7..0000000000 --- a/packages/turf-convex/test.js +++ /dev/null @@ -1,31 +0,0 @@ -const test = require('tape'); -const glob = require('glob'); -const path = require('path'); -const write = require('write-json-file'); -const load = require('load-json-file'); -const { featureCollection } = require('@turf/helpers'); -const convex = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -test('convex hull', t => { - glob.sync(directories.in + '*.geojson').forEach(filepath => { - const fileout = filepath.replace('/in/', '/out/'); - const geojson = load.sync(filepath); - - const convexHull = convex(geojson); - geojson.features.push(convexHull); - - if (process.env.REGEN) write.sync(fileout, geojson); - t.deepEqual(geojson, load.sync(fileout), path.parse(filepath).name); - }); - t.end(); -}); - -test('turf-convex -- empty', t => { - t.deepEqual(convex(featureCollection([])), null, 'corner case: null hull'); - t.end(); -}); diff --git a/packages/turf-convex/tsconfig.json b/packages/turf-convex/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-convex/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-convex/tslint.json b/packages/turf-convex/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-convex/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-destination/.gitignore b/packages/turf-destination/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-destination/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-destination/LICENSE b/packages/turf-destination/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-destination/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-destination/README.md b/packages/turf-destination/README.md deleted file mode 100644 index 079f8cc36a..0000000000 --- a/packages/turf-destination/README.md +++ /dev/null @@ -1,75 +0,0 @@ -# @turf/destination - - - -## destination - -Takes a [Point][1] and calculates the location of a destination point given a distance in degrees, radians, miles, or kilometers; and bearing in degrees. This uses the [Haversine formula][2] to account for global curvature. - -**Parameters** - -- `origin` **[Coord][3]** starting point -- `distance` **[number][4]** distance from the origin point -- `bearing` **[number][4]** ranging from -180 to 180 -- `options` **[Object][5]** Optional parameters (optional, default `{}`) - - `options.units` **[string][6]** miles, kilometers, degrees, or radians (optional, default `'kilometers'`) - - `options.properties` **[Object][5]** Translate properties to Point (optional, default `{}`) - -**Examples** - -```javascript -var point = turf.point([-75.343, 39.984]); -var distance = 50; -var bearing = 90; -var options = {units: 'miles'}; - -var destination = turf.destination(point, distance, bearing, options); - -//addToMap -var addToMap = [point, destination] -destination.properties['marker-color'] = '#f00'; -point.properties['marker-color'] = '#0f0'; -``` - -Returns **[Feature][7]<[Point][8]>** destination point - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: http://en.wikipedia.org/wiki/Haversine_formula - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[7]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[8]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/destination -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-destination/bench.js b/packages/turf-destination/bench.js deleted file mode 100644 index 85178a8166..0000000000 --- a/packages/turf-destination/bench.js +++ /dev/null @@ -1,14 +0,0 @@ -const fs = require('fs'); -const Benchmark = require('benchmark'); -const destination = require('./').default; - -var pt1 = [-75.0, 39.0] -var dist = 100; -var bear = 180; - -var suite = new Benchmark.Suite('turf-destination'); -suite - .add('turf-destination',() => destination(pt1, dist, bear)) - .on('cycle', e => console.log(String(e.target))) - .on('complete', () => {}) - .run(); \ No newline at end of file diff --git a/packages/turf-destination/index.d.ts b/packages/turf-destination/index.d.ts deleted file mode 100644 index d1f422fbc8..0000000000 --- a/packages/turf-destination/index.d.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Coord, Feature, Point, Properties, Units } from "@turf/helpers"; -/** - * Takes a {@link Point} and calculates the location of a destination point given a distance in - * degrees, radians, miles, or kilometers; and bearing in degrees. - * This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature. - * - * @name destination - * @param {Coord} origin starting point - * @param {number} distance distance from the origin point - * @param {number} bearing ranging from -180 to 180 - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians - * @param {Object} [options.properties={}] Translate properties to Point - * @returns {Feature} destination point - * @example - * var point = turf.point([-75.343, 39.984]); - * var distance = 50; - * var bearing = 90; - * var options = {units: 'miles'}; - * - * var destination = turf.destination(point, distance, bearing, options); - * - * //addToMap - * var addToMap = [point, destination] - * destination.properties['marker-color'] = '#f00'; - * point.properties['marker-color'] = '#0f0'; - */ -export default function destination

(origin: Coord, distance: number, bearing: number, options?: { - units?: Units; - properties?: P; -}): Feature; diff --git a/packages/turf-destination/index.ts b/packages/turf-destination/index.ts deleted file mode 100644 index b90d642127..0000000000 --- a/packages/turf-destination/index.ts +++ /dev/null @@ -1,60 +0,0 @@ -// http://en.wikipedia.org/wiki/Haversine_formula -// http://www.movable-type.co.uk/scripts/latlong.html -import { - Coord, degreesToRadians, Feature, lengthToRadians, - point, Point, Properties, radiansToDegrees, Units, -} from "@turf/helpers"; -import { getCoord } from "@turf/invariant"; - -/** - * Takes a {@link Point} and calculates the location of a destination point given a distance in - * degrees, radians, miles, or kilometers; and bearing in degrees. - * This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature. - * - * @name destination - * @param {Coord} origin starting point - * @param {number} distance distance from the origin point - * @param {number} bearing ranging from -180 to 180 - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians - * @param {Object} [options.properties={}] Translate properties to Point - * @returns {Feature} destination point - * @example - * var point = turf.point([-75.343, 39.984]); - * var distance = 50; - * var bearing = 90; - * var options = {units: 'miles'}; - * - * var destination = turf.destination(point, distance, bearing, options); - * - * //addToMap - * var addToMap = [point, destination] - * destination.properties['marker-color'] = '#f00'; - * point.properties['marker-color'] = '#0f0'; - */ -export default function destination

( - origin: Coord, - distance: number, - bearing: number, - options: { - units?: Units, - properties?: P, - } = {}, -): Feature { - // Handle input - const coordinates1 = getCoord(origin); - const longitude1 = degreesToRadians(coordinates1[0]); - const latitude1 = degreesToRadians(coordinates1[1]); - const bearingRad = degreesToRadians(bearing); - const radians = lengthToRadians(distance, options.units); - - // Main - const latitude2 = Math.asin(Math.sin(latitude1) * Math.cos(radians) + - Math.cos(latitude1) * Math.sin(radians) * Math.cos(bearingRad)); - const longitude2 = longitude1 + Math.atan2(Math.sin(bearingRad) * Math.sin(radians) * Math.cos(latitude1), - Math.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2)); - const lng = radiansToDegrees(longitude2); - const lat = radiansToDegrees(latitude2); - - return point([lng, lat], options.properties); -} diff --git a/packages/turf-destination/package.json b/packages/turf-destination/package.json deleted file mode 100644 index 8e8cb61ecd..0000000000 --- a/packages/turf-destination/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "@turf/destination", - "version": "6.0.1", - "description": "turf destination module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "distance", - "destination", - "bearing", - "miles", - "km" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/truncate": "*", - "benchmark": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-destination/test.js b/packages/turf-destination/test.js deleted file mode 100644 index f6a2461922..0000000000 --- a/packages/turf-destination/test.js +++ /dev/null @@ -1,34 +0,0 @@ -const path = require('path'); -const test = require('tape'); -const glob = require('glob'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { getCoords } = require('@turf/invariant'); -const { lineString, featureCollection, round } = require('@turf/helpers'); -const truncate = require('@turf/truncate').default; -const destination = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -test('turf-destination', t => { - glob.sync(directories.in + '*.geojson').forEach(filepath => { - const geojson = load.sync(filepath); - const name = path.parse(filepath).name; - const base = path.parse(filepath).base; - - // Params - const properties = geojson.properties || {}; - const bearing = (properties.bearing !== undefined) ? properties.bearing : 180; - const dist = (properties.dist !== undefined) ? properties.dist : 100; - - const dest = truncate(destination(geojson, dist, bearing)); - const result = featureCollection([geojson, dest, lineString([getCoords(geojson), getCoords(dest)])]); - - if (process.env.REGEN) write.sync(directories.out + base, result); - t.deepEqual(result, load.sync(directories.out + base), name); - }); - t.end(); -}); diff --git a/packages/turf-destination/tsconfig.json b/packages/turf-destination/tsconfig.json deleted file mode 100644 index f1852b8e46..0000000000 --- a/packages/turf-destination/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-destination/tslint.json b/packages/turf-destination/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-destination/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-difference/.gitignore b/packages/turf-difference/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-difference/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-difference/LICENSE b/packages/turf-difference/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-difference/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-difference/README.md b/packages/turf-difference/README.md deleted file mode 100644 index 611db02945..0000000000 --- a/packages/turf-difference/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# @turf/difference - - - -## difference - -Finds the difference between two [polygons][1] by clipping the second polygon from the first. - -**Parameters** - -- `polygon1` **[Feature][2]<([Polygon][3] \| [MultiPolygon][4])>** input Polygon feature -- `polygon2` **[Feature][2]<([Polygon][3] \| [MultiPolygon][4])>** Polygon feature to difference from polygon1 - -**Examples** - -```javascript -var polygon1 = turf.polygon([[ - [128, -26], - [141, -26], - [141, -21], - [128, -21], - [128, -26] -]], { - "fill": "#F00", - "fill-opacity": 0.1 -}); -var polygon2 = turf.polygon([[ - [126, -28], - [140, -28], - [140, -20], - [126, -20], - [126, -28] -]], { - "fill": "#00F", - "fill-opacity": 0.1 -}); - -var difference = turf.difference(polygon1, polygon2); - -//addToMap -var addToMap = [polygon1, polygon2, difference]; -``` - -Returns **([Feature][2]<([Polygon][3] \| [MultiPolygon][4])> | null)** a Polygon or MultiPolygon feature showing the area of `polygon1` excluding the area of `polygon2` (if empty returns `null`) - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/difference -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-difference/index.d.ts b/packages/turf-difference/index.d.ts deleted file mode 100644 index ef1baae0e1..0000000000 --- a/packages/turf-difference/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Polygon, MultiPolygon, Feature } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#difference - */ -export default function difference( - polygon1: Feature | Polygon | MultiPolygon, - polygon2: Feature | Polygon | MultiPolygon -): Feature | null; - diff --git a/packages/turf-difference/index.mjs b/packages/turf-difference/index.mjs deleted file mode 100644 index 0e07f12770..0000000000 --- a/packages/turf-difference/index.mjs +++ /dev/null @@ -1,79 +0,0 @@ -import * as martinez from 'martinez-polygon-clipping'; -import area from '@turf/area'; -import { feature, multiPolygon, polygon } from '@turf/helpers'; -import { getGeom } from '@turf/invariant'; -import { flattenEach } from '@turf/meta'; - -/** - * Finds the difference between two {@link Polygon|polygons} by clipping the second polygon from the first. - * - * @name difference - * @param {Feature} polygon1 input Polygon feature - * @param {Feature} polygon2 Polygon feature to difference from polygon1 - * @returns {Feature|null} a Polygon or MultiPolygon feature showing the area of `polygon1` excluding the area of `polygon2` (if empty returns `null`) - * @example - * var polygon1 = turf.polygon([[ - * [128, -26], - * [141, -26], - * [141, -21], - * [128, -21], - * [128, -26] - * ]], { - * "fill": "#F00", - * "fill-opacity": 0.1 - * }); - * var polygon2 = turf.polygon([[ - * [126, -28], - * [140, -28], - * [140, -20], - * [126, -20], - * [126, -28] - * ]], { - * "fill": "#00F", - * "fill-opacity": 0.1 - * }); - * - * var difference = turf.difference(polygon1, polygon2); - * - * //addToMap - * var addToMap = [polygon1, polygon2, difference]; - */ -function difference(polygon1, polygon2) { - var geom1 = getGeom(polygon1); - var geom2 = getGeom(polygon2); - var properties = polygon1.properties || {}; - - // Issue #721 - JSTS/Martinez can't handle empty polygons - geom1 = removeEmptyPolygon(geom1); - geom2 = removeEmptyPolygon(geom2); - if (!geom1) return null; - if (!geom2) return feature(geom1, properties); - - var differenced = martinez.diff(geom1.coordinates, geom2.coordinates); - if (differenced.length === 0) return null; - if (differenced.length === 1) return polygon(differenced[0], properties); - return multiPolygon(differenced, properties); -} - -/** - * Detect Empty Polygon - * - * @private - * @param {Geometry} geom Geometry Object - * @returns {Geometry|null} removed any polygons with no areas - */ -function removeEmptyPolygon(geom) { - switch (geom.type) { - case 'Polygon': - if (area(geom) > 1) return geom; - return null; - case 'MultiPolygon': - var coordinates = []; - flattenEach(geom, function (feature) { - if (area(feature) > 1) coordinates.push(feature.geometry.coordinates); - }); - if (coordinates.length) return {type: 'MultiPolygon', coordinates: coordinates}; - } -} - -export default difference; diff --git a/packages/turf-difference/package.json b/packages/turf-difference/package.json deleted file mode 100644 index a3408e0fdb..0000000000 --- a/packages/turf-difference/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "@turf/difference", - "version": "6.0.0", - "description": "turf difference module", - "main": "index", - "module": "index.mjs", - "types": "index.d.ts", - "files": [ - "index.js", - "index.mjs", - "index.d.ts" - ], - "scripts": { - "pretest": "rollup -f cjs -o index.js index.mjs", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "glob": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/area": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x", - "martinez-polygon-clipping": "^0.4.3" - } -} diff --git a/packages/turf-difference/test.js b/packages/turf-difference/test.js deleted file mode 100644 index 1f7640c624..0000000000 --- a/packages/turf-difference/test.js +++ /dev/null @@ -1,67 +0,0 @@ -const path = require('path'); -const test = require('tape'); -const glob = require('glob'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { featureCollection, polygon } = require('@turf/helpers'); -const difference = require('./'); - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -test('turf-difference', t => { - glob.sync(directories.in + '*.geojson').forEach(filepath => { - const { name, base } = path.parse(filepath); - const [polygon1, polygon2] = load.sync(filepath).features; - - if (name.includes('skip')) return t.skip(name); - - // Red Polygon1 - polygon1.properties = Object.assign(polygon1.properties || {}, {'fill-opacity': 0.5, fill: '#F00'}); - // Blue Polygon2 - polygon2.properties = Object.assign(polygon2.properties || {}, {'fill-opacity': 0.5, fill: '#00F'}); - - const results = featureCollection([polygon1, polygon2]); - - const result = difference(polygon1, polygon2); - if (result) { - // Green Polygon - result.properties = {'fill-opacity': 1, fill: '#0F0'}; - results.features.push(result); - } - - if (process.env.REGEN) write.sync(directories.out + base, results); - t.deepEqual(results, load.sync(directories.out + base), name); - }); - t.end(); -}); - -test('turf-difference - support Geometry Objects', t => { - const poly1 = polygon([[[121, -31], [144, -31], [144, -15], [121, -15], [121, -31]]]); - const poly2 = polygon([[[126, -28], [140, -28], [140, -20], [126, -20], [126, -28]]]); - - t.assert(difference(poly1.geometry, poly2.geometry), 'geometry object support'); - t.end(); -}); - -test('turf-difference - prevent input mutation', t => { - const poly1 = polygon([[[121, -31], [144, -31], [144, -15], [121, -15], [121, -31]]]); - const poly2 = polygon([[[126, -28], [140, -28], [140, -20], [126, -20], [126, -28]]]); - const before1 = JSON.parse(JSON.stringify(poly1)); - const before2 = JSON.parse(JSON.stringify(poly2)); - - difference(poly1, poly2); - t.deepEqual(poly1, before1, 'polygon1 should not mutate'); - t.deepEqual(poly2, before2, 'polygon2 should not mutate'); - t.end(); -}); - -test('turf-difference - complete overlap', t => { - const poly = polygon([[[121, -31], [144, -31], [144, -15], [121, -15], [121, -31]]]); - - const result = difference(poly, poly); - t.deepEqual(result, null, 'difference should be null'); - t.end(); -}); diff --git a/packages/turf-difference/test/out/clip-polygons.geojson b/packages/turf-difference/test/out/clip-polygons.geojson deleted file mode 100644 index 544db326d0..0000000000 --- a/packages/turf-difference/test/out/clip-polygons.geojson +++ /dev/null @@ -1,121 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "stroke-width": 6, - "stroke-opacity": 1, - "fill": "#F00", - "fill-opacity": 0.5 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 127.705078125, - -34.52466147177172 - ], - [ - 139.5703125, - -34.52466147177172 - ], - [ - 139.5703125, - -15.28418511407642 - ], - [ - 127.705078125, - -15.28418511407642 - ], - [ - 127.705078125, - -34.52466147177172 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "stroke-width": 6, - "stroke-opacity": 1, - "fill": "#00F", - "fill-opacity": 0.5 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 133.154296875, - -29.075375179558346 - ], - [ - 144.228515625, - -29.075375179558346 - ], - [ - 144.228515625, - -12.983147716796566 - ], - [ - 133.154296875, - -12.983147716796566 - ], - [ - 133.154296875, - -29.075375179558346 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 127.705078125, - -34.52466147177172 - ], - [ - 139.5703125, - -34.52466147177172 - ], - [ - 139.5703125, - -29.075375179558346 - ], - [ - 133.154296875, - -29.075375179558346 - ], - [ - 133.154296875, - -15.28418511407642 - ], - [ - 127.705078125, - -15.28418511407642 - ], - [ - 127.705078125, - -34.52466147177172 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-difference/test/out/create-hole.geojson b/packages/turf-difference/test/out/create-hole.geojson deleted file mode 100644 index e020399627..0000000000 --- a/packages/turf-difference/test/out/create-hole.geojson +++ /dev/null @@ -1,135 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "stroke-width": 6, - "stroke-opacity": 1, - "fill": "#F00", - "fill-opacity": 0.5 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 121, - -31 - ], - [ - 144, - -31 - ], - [ - 144, - -15 - ], - [ - 121, - -15 - ], - [ - 121, - -31 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "stroke-width": 6, - "stroke-opacity": 1, - "fill": "#00F", - "fill-opacity": 0.5 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 126, - -28 - ], - [ - 140, - -28 - ], - [ - 140, - -20 - ], - [ - 126, - -20 - ], - [ - 126, - -28 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 121, - -31 - ], - [ - 144, - -31 - ], - [ - 144, - -15 - ], - [ - 121, - -15 - ], - [ - 121, - -31 - ] - ], - [ - [ - 126, - -28 - ], - [ - 140, - -28 - ], - [ - 140, - -20 - ], - [ - 126, - -20 - ], - [ - 126, - -28 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-difference/test/out/issue-#721.geojson b/packages/turf-difference/test/out/issue-#721.geojson deleted file mode 100644 index 422dca5cdf..0000000000 --- a/packages/turf-difference/test/out/issue-#721.geojson +++ /dev/null @@ -1,375 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "stroke-width": 6, - "stroke-opacity": 1, - "fill": "#F00", - "fill-opacity": 0.5 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -0.6474134, - 44.805326 - ], - [ - -0.6471907, - 44.8053946 - ], - [ - -0.6465049, - 44.8055554 - ], - [ - -0.6464734, - 44.8056645 - ], - [ - -0.6465119, - 44.8057959 - ], - [ - -0.6465922, - 44.8059124 - ], - [ - -0.6466376, - 44.8059546 - ], - [ - -0.6466831, - 44.8059719 - ], - [ - -0.6467005, - 44.8059967 - ], - [ - -0.6466971, - 44.8060413 - ], - [ - -0.64662, - 44.806065 - ], - [ - -0.64649, - 44.80611 - ], - [ - -0.646437, - 44.806159 - ], - [ - -0.6463809, - 44.8061882 - ], - [ - -0.6461987, - 44.8060367 - ], - [ - -0.6461042, - 44.8059451 - ], - [ - -0.6460542, - 44.8057952 - ], - [ - -0.6460421, - 44.8056729 - ], - [ - -0.6460848, - 44.8054585 - ], - [ - -0.6461073, - 44.8053383 - ], - [ - -0.6461218, - 44.8051741 - ], - [ - -0.6460827, - 44.8050017 - ], - [ - -0.6460168, - 44.8047948 - ], - [ - -0.645829, - 44.8043891 - ], - [ - -0.646075, - 44.8042943 - ], - [ - -0.6462847, - 44.8042192 - ], - [ - -0.6465997, - 44.8047375 - ], - [ - -0.6469113, - 44.8048572 - ], - [ - -0.6472295, - 44.8050484 - ], - [ - -0.6474134, - 44.805326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "stroke-width": 6, - "stroke-opacity": 1, - "fill": "#00F", - "fill-opacity": 0.5 - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - -0.6462588068806041, - 44.80608667910215 - ], - [ - -0.6461987, - 44.8060367 - ], - [ - -0.6461042, - 44.8059451 - ], - [ - -0.6461041344154722, - 44.805944903377586 - ], - [ - -0.6461991369724274, - 44.80603699057963 - ], - [ - -0.6462588068806041, - 44.80608667910215 - ] - ] - ], - [ - [ - [ - -0.646069093721612, - 44.80583985137739 - ], - [ - -0.6460542, - 44.8057952 - ], - [ - -0.6460421, - 44.8056729 - ], - [ - -0.6460471709105139, - 44.80564743856641 - ], - [ - -0.6460422277450562, - 44.805672561504906 - ], - [ - -0.6460542976856232, - 44.80579530680288 - ], - [ - -0.646069093721612, - 44.80583985137739 - ] - ] - ], - [ - [ - [ - -0.646093673696575, - 44.80541109474097 - ], - [ - -0.6461073, - 44.8053383 - ], - [ - -0.6461158838109077, - 44.80524109574131 - ], - [ - -0.646107941865921, - 44.80533857879061 - ], - [ - -0.646093673696575, - 44.80541109474097 - ] - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -0.6474134, - 44.805326 - ], - [ - -0.6471907, - 44.8053946 - ], - [ - -0.6465049, - 44.8055554 - ], - [ - -0.6464734, - 44.8056645 - ], - [ - -0.6465119, - 44.8057959 - ], - [ - -0.6465922, - 44.8059124 - ], - [ - -0.6466376, - 44.8059546 - ], - [ - -0.6466831, - 44.8059719 - ], - [ - -0.6467005, - 44.8059967 - ], - [ - -0.6466971, - 44.8060413 - ], - [ - -0.64662, - 44.806065 - ], - [ - -0.64649, - 44.80611 - ], - [ - -0.646437, - 44.806159 - ], - [ - -0.6463809, - 44.8061882 - ], - [ - -0.6461987, - 44.8060367 - ], - [ - -0.6461042, - 44.8059451 - ], - [ - -0.6460542, - 44.8057952 - ], - [ - -0.6460421, - 44.8056729 - ], - [ - -0.6460848, - 44.8054585 - ], - [ - -0.6461073, - 44.8053383 - ], - [ - -0.6461218, - 44.8051741 - ], - [ - -0.6460827, - 44.8050017 - ], - [ - -0.6460168, - 44.8047948 - ], - [ - -0.645829, - 44.8043891 - ], - [ - -0.646075, - 44.8042943 - ], - [ - -0.6462847, - 44.8042192 - ], - [ - -0.6465997, - 44.8047375 - ], - [ - -0.6469113, - 44.8048572 - ], - [ - -0.6472295, - 44.8050484 - ], - [ - -0.6474134, - 44.805326 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-directional-mean/.gitignore b/packages/turf-directional-mean/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-directional-mean/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-directional-mean/LICENSE b/packages/turf-directional-mean/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-directional-mean/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-directional-mean/README.md b/packages/turf-directional-mean/README.md deleted file mode 100644 index ceecfca0b2..0000000000 --- a/packages/turf-directional-mean/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# @turf/directional-mean - - - -## DirectionalMeanLine - -Type: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) - -**Properties** - -- `cartesianAngle` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the mean angle of all lines. (measure from due earth counterclockwise). -- `bearingAngle` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the mean angle of all lines. (bearing). -- `circularVariance` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the extent to which features all point in the same direction. - the value ranges 0-1, the bigger the value, the more variation in directions between lines. -- `averageX` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the centroid of all lines. -- `averageY` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the centroid of all line. -- `averageLength` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the average length of line. -- `countOfLines` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the count of features. - -## directionalMean - -This module calculate the average angle of a set of lines, measuring the trend of it. -It can be used in both project coordinate system and geography coordinate system. -It can handle segments of line or the whole line. - -**Parameters** - -- `lines` **[FeatureCollection](https://tools.ietf.org/html/rfc7946#section-3.3)<[LineString](https://tools.ietf.org/html/rfc7946#section-3.1.4)>** -- `options` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** (optional, default `{}`) - - `options.planar` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** whether the spatial reference system is projected or geographical. (optional, default `true`) - - `options.segment` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** whether treat a LineString as a whole or a set of segments. (optional, default `false`) - -**Examples** - -```javascript -var lines = turf.lineStrings([ - [[110, 45], [120, 50]], - [[100, 50], [115, 55]], -]) -var directionalMeanLine = turf.directionalMean(lines); -// => directionalMeanLine -``` - -Returns **[DirectionalMeanLine](#directionalmeanline)** Directional Mean Line - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/directional-mean -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-directional-mean/index.d.ts b/packages/turf-directional-mean/index.d.ts deleted file mode 100644 index 166783ba25..0000000000 --- a/packages/turf-directional-mean/index.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Feature, FeatureCollection, LineString } from "@turf/helpers"; -export interface DirectionalMeanLine extends Feature { - properties: { - cartesianAngle: number; - bearingAngle: number; - circularVariance: number; - averageX: number; - averageY: number; - averageLength: number; - countOfLines: number; - [key: string]: any; - }; -} -/** - * @typedef {Object} DirectionalMeanLine - * @property {number} cartesianAngle the mean angle of all lines. (measure from due earth counterclockwise). - * @property {number} bearingAngle the mean angle of all lines. (bearing). - * @property {number} circularVariance the extent to which features all point in the same direction. - * the value ranges 0-1, the bigger the value, the more variation in directions between lines. - * @property {number} averageX the centroid of all lines. - * @property {number} averageY the centroid of all line. - * @property {number} averageLength the average length of line. - * @property {number} countOfLines the count of features. - */ -/** - * This module calculate the average angle of a set of lines, measuring the trend of it. - * It can be used in both project coordinate system and geography coordinate system. - * It can handle segments of line or the whole line. - * @name directionalMean - * @param {FeatureCollection} lines - * @param {object} [options={}] - * @param {boolean} [options.planar=true] whether the spatial reference system is projected or geographical. - * @param {boolean} [options.segment=false] whether treat a LineString as a whole or a set of segments. - * @returns {DirectionalMeanLine} Directional Mean Line - * @example - * - * var lines = turf.lineStrings([ - * [[110, 45], [120, 50]], - * [[100, 50], [115, 55]], - * ]) - * var directionalMeanLine = turf.directionalMean(lines); - * // => directionalMeanLine - */ -export default function directionalMean(lines: FeatureCollection, options?: { - planar?: boolean; - segment?: boolean; -}): DirectionalMeanLine; diff --git a/packages/turf-directional-mean/index.ts b/packages/turf-directional-mean/index.ts deleted file mode 100644 index 750513f3cd..0000000000 --- a/packages/turf-directional-mean/index.ts +++ /dev/null @@ -1,255 +0,0 @@ -import bearing from "@turf/bearing"; -import centroid from "@turf/centroid"; -import destination from "@turf/destination"; -import { featureCollection, geometry, lineString, point } from "@turf/helpers"; -import { Coord, Feature, FeatureCollection, Geometry, LineString, Point } from "@turf/helpers"; -import { getCoord } from "@turf/invariant"; -import length from "@turf/length"; -import { featureEach, segmentEach, segmentReduce } from "@turf/meta"; - -export interface DirectionalMeanLine extends Feature { - properties: { - cartesianAngle: number; - bearingAngle: number; - circularVariance: number; - averageX: number; - averageY: number; - averageLength: number; - countOfLines: number; - [key: string]: any; - }; -} - -/** - * @typedef {Object} DirectionalMeanLine - * @property {number} cartesianAngle the mean angle of all lines. (measure from due earth counterclockwise). - * @property {number} bearingAngle the mean angle of all lines. (bearing). - * @property {number} circularVariance the extent to which features all point in the same direction. - * the value ranges 0-1, the bigger the value, the more variation in directions between lines. - * @property {number} averageX the centroid of all lines. - * @property {number} averageY the centroid of all line. - * @property {number} averageLength the average length of line. - * @property {number} countOfLines the count of features. - */ - -/** - * This module calculate the average angle of a set of lines, measuring the trend of it. - * It can be used in both project coordinate system and geography coordinate system. - * It can handle segments of line or the whole line. - * @name directionalMean - * @param {FeatureCollection} lines - * @param {object} [options={}] - * @param {boolean} [options.planar=true] whether the spatial reference system is projected or geographical. - * @param {boolean} [options.segment=false] whether treat a LineString as a whole or a set of segments. - * @returns {DirectionalMeanLine} Directional Mean Line - * @example - * - * var lines = turf.lineStrings([ - * [[110, 45], [120, 50]], - * [[100, 50], [115, 55]], - * ]) - * var directionalMeanLine = turf.directionalMean(lines); - * // => directionalMeanLine - */ -export default function directionalMean(lines: FeatureCollection, options: { - planar?: boolean; - segment?: boolean; -} = {}): DirectionalMeanLine { - - const isPlanar: boolean = !!options.planar; // you can't use options.planar || true here. - const isSegment: boolean = options.segment || false; - let sigmaSin: number = 0; - let sigmaCos: number = 0; - let countOfLines: number = 0; - let sumOfLen: number = 0; - const centroidList: Array> = []; - - if (isSegment) { - segmentEach(lines, (currentSegment: any) => { // todo fix turf-meta's declaration file - const [sin1, cos1]: [number, number] = getCosAndSin(currentSegment.geometry.coordinates, isPlanar); - const lenOfLine = getLengthOfLineString(currentSegment, isPlanar); - if (isNaN(sin1) || isNaN(cos1)) { - return; - } else { - sigmaSin += sin1; - sigmaCos += cos1; - countOfLines += 1; - sumOfLen += lenOfLine; - centroidList.push(centroid(currentSegment)); - } - }); - // planar and segment - } else { - // planar and non-segment - featureEach(lines, (currentFeature: Feature, featureIndex: number) => { - if (currentFeature.geometry.type !== "LineString") { - throw new Error("shold to support MultiLineString?"); - } - const [sin1, cos1]: [number, number] = getCosAndSin(currentFeature.geometry.coordinates, isPlanar); - const lenOfLine = getLengthOfLineString(currentFeature, isPlanar); - if (isNaN(sin1) || isNaN(cos1)) { - return; - } else { - sigmaSin += sin1; - sigmaCos += cos1; - countOfLines += 1; - sumOfLen += lenOfLine; - centroidList.push(centroid(currentFeature)); - } - }); - } - - const cartesianAngle: number = getAngleBySinAndCos(sigmaSin, sigmaCos); - const bearingAngle: number = bearingToCartesian(cartesianAngle); - const circularVariance = getCircularVariance(sigmaSin, sigmaCos, countOfLines); - const averageLength = sumOfLen / countOfLines; - const centroidOfLines = centroid(featureCollection(centroidList)); - const [averageX, averageY]: number[] = getCoord(centroidOfLines); - let meanLinestring; - if (isPlanar) { - meanLinestring = getMeanLineString([averageX, averageY], cartesianAngle, averageLength, isPlanar); - } else { - meanLinestring = getMeanLineString([averageX, averageY], bearingAngle, averageLength, isPlanar); - } - - return lineString(meanLinestring, { - averageLength, - averageX, - averageY, - bearingAngle, - cartesianAngle, - circularVariance, - countOfLines, - }); -} - -/** - * get euclidean distance between two points. - * @private - * @name euclideanDistance - * @param coords - */ -function euclideanDistance(coords: number[][]) { - const [x0, y0]: number[] = coords[0]; - const [x1, y1]: number[] = coords[1]; - const dx: number = x1 - x0; - const dy: number = y1 - y0; - return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); -} - -/** - * get the length of a LineString, both in projected or geographical coordinate system. - * @private - * @name getLengthOfLineString - * @param {Feature} line - * @param {boolean} isPlanar - */ -function getLengthOfLineString(line: Feature, isPlanar: boolean) { - if (isPlanar) { - return segmentReduce(line, (previousValue?: number, segment?: Feature): number => { - const coords = segment.geometry.coordinates; // the signatrue of segmentReduce has problem ? - return previousValue + euclideanDistance(coords); - }, 0); - } else { - return length(line, { - units: "meters", - }); - } -} - -/** - * bearing to xy(from due earth counterclockwise 0-180) - * convert between two forms - * @private - * @name bearingToCartesian - * @param angle - */ -function bearingToCartesian(angle: number): number { - let result = 90 - angle; - if (result > 180) { - result -= 360; - } - return result; -} - -/** - * @private - * @name getCosAndSin - * @param {Array>} coordinates - * @returns {Array} [cos, sin] - */ -function getCosAndSin(coordinates: number[][], isPlanar: boolean): [number, number] { - const beginPoint: number[] = coordinates[0]; - const endPoint: number[] = coordinates[coordinates.length - 1]; - if (isPlanar) { - const [x0, y0]: number[] = beginPoint; - const [x1, y1]: number[] = endPoint; - const dx: number = x1 - x0; - const dy: number = y1 - y0; - const h = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); - if (h < 0.000000001) { - return [NaN, NaN]; - } - const sin1 = dy / h; - const cos1 = dx / h; - return [sin1, cos1]; - } else { - const angle = bearingToCartesian(bearing(beginPoint, endPoint)); - const radian = angle * Math.PI / 180; - return [Math.sin(radian), Math.cos(radian)]; - } - -} - -function getAngleBySinAndCos(sin1: number, cos1: number): number { - let angle: number = 0; - if (Math.abs(cos1) < 0.000000001) { - angle = 90; - } else { - angle = Math.atan2(sin1, cos1) * 180 / Math.PI; - } - if (sin1 >= 0) { - if (cos1 < 0) { - angle += 180; - } - } else { - if (cos1 < 0) { - angle -= 180; - } - } - return angle; -} - -function getCircularVariance(sin1: number, cos1: number, len: number) { - if (len === 0) { - throw new Error("the size of the features set must be greater than 0"); - } - return 1 - (Math.sqrt(Math.pow(sin1, 2) + Math.pow(cos1, 2)) / len); -} - -function getMeanLineString(centroidOfLine: number[], angle: number, lenOfLine: number, isPlanar: boolean) { - if (isPlanar) { - const [averageX, averageY]: number[] = centroidOfLine; - let beginX: number; - let beginY: number; - let endX: number; - let endY: number; - const r: number = angle * Math.PI / 180; - const sin: number = Math.sin(r); - const cos: number = Math.cos(r); - beginX = averageX - lenOfLine / 2 * cos; - beginY = averageY - lenOfLine / 2 * sin; - endX = averageX + lenOfLine / 2 * cos; - endY = averageY + lenOfLine / 2 * sin; - return [ - [beginX, beginY], - [endX, endY], - ]; - } else { - const end = destination(point(centroidOfLine), lenOfLine / 2, angle, { units: "meters" }); - const begin = destination(point(centroidOfLine), -lenOfLine / 2, angle, { units: "meters" }); - return [ - getCoord(begin), getCoord(end), - ]; - } -} diff --git a/packages/turf-directional-mean/package.json b/packages/turf-directional-mean/package.json deleted file mode 100644 index f191a4ff99..0000000000 --- a/packages/turf-directional-mean/package.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "name": "@turf/directional-mean", - "version": "6.0.2", - "description": "turf directional-mean module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "directional-mean" - ], - "author": "Turf Authors", - "contributors": [ - "Haoming Zhuang <@zhuang-hao-ming>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "write-json-file": "*", - "load-json-file": "*", - "tape": "*", - "typescript": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/meta": "6.x", - "@turf/bearing": "6.x", - "@turf/length": "6.x", - "@turf/centroid": "6.x", - "@turf/invariant": "6.x", - "@turf/destination": "6.x" - } -} diff --git a/packages/turf-directional-mean/test.js b/packages/turf-directional-mean/test.js deleted file mode 100644 index 332581a713..0000000000 --- a/packages/turf-directional-mean/test.js +++ /dev/null @@ -1,70 +0,0 @@ -const test = require('tape'); -const glob = require('glob'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const directionalMean = require('.').default; - - - - - - - - - - - -test('turf-directional-mean', t => { - - - const outGpsJsonPath1 = path.join(__dirname, 'test', 'out', 'bus_route_gps1.json'); - const outGpsJsonPath2 = path.join(__dirname, 'test', 'out', 'bus_route_gps2.json'); - const outUtmJsonPath1 = path.join(__dirname, 'test', 'out', 'bus_route_utm1.json'); - const outUtmJsonPath2 = path.join(__dirname, 'test', 'out', 'bus_route_utm2.json'); - - const utmFilepath = path.join(__dirname, 'test', 'in', 'bus_route_utm.json'); - const utmGeojson = load.sync(utmFilepath); - - const gpsFilepath = path.join(__dirname, 'test', 'in', 'bus_route_gps.json'); - const gpsGeojson = load.sync(gpsFilepath); - - // utm - let utmResult1 = directionalMean(utmGeojson, { - planar: true, - segment: false - }); - t.deepEqual(utmResult1, load.sync(outUtmJsonPath1), 'utm'); - // utm segment - let utmResult2 = directionalMean(utmGeojson, { - planar: true, - segment: true - }); - t.deepEqual(utmResult2, load.sync(outUtmJsonPath2), 'utm segment'); - - // gps - let gpsResult1 = directionalMean(gpsGeojson, { - planar: false - }); - t.deepEqual(gpsResult1, load.sync(outGpsJsonPath1), 'gps'); - // gps segment - let gpsResult2 = directionalMean(gpsGeojson, { - planar: false, - segment: true - }); - t.deepEqual(gpsResult2, load.sync(outGpsJsonPath2), 'gps segment'); - - - - - - if (process.env.REGEN) { - write.sync(outGpsJsonPath1, gpsResult1); - write.sync(outGpsJsonPath2, gpsResult2); - write.sync(outUtmJsonPath1, utmResult1); - write.sync(outUtmJsonPath2, utmResult2); - } - - t.end(); - -}); diff --git a/packages/turf-directional-mean/tsconfig.json b/packages/turf-directional-mean/tsconfig.json deleted file mode 100644 index adfc6f96e7..0000000000 --- a/packages/turf-directional-mean/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - // "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-directional-mean/tslint.json b/packages/turf-directional-mean/tslint.json deleted file mode 100644 index 9dd5998b9c..0000000000 --- a/packages/turf-directional-mean/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {"interface-name": false}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-dissolve/LICENSE b/packages/turf-dissolve/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-dissolve/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-dissolve/README.md b/packages/turf-dissolve/README.md deleted file mode 100644 index 6ecdbd27f6..0000000000 --- a/packages/turf-dissolve/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# @turf/dissolve - - - -## dissolve - -Dissolves a FeatureCollection of [polygon][1] features, filtered by an optional property name:value. -Note that [mulitpolygon][2] features within the collection are not supported - -**Parameters** - -- `featureCollection` **[FeatureCollection][3]<[Polygon][4]>** input feature collection to be dissolved -- `options` **[Object][5]** Optional parameters (optional, default `{}`) - - `options.propertyName` **[string][6]?** features with equals 'propertyName' in `properties` will be merged - -**Examples** - -```javascript -var features = turf.featureCollection([ - turf.polygon([[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]], {combine: 'yes'}), - turf.polygon([[[0, -1], [0, 0], [1, 0], [1, -1], [0,-1]]], {combine: 'yes'}), - turf.polygon([[[1,-1],[1, 0], [2, 0], [2, -1], [1, -1]]], {combine: 'no'}), -]); - -var dissolved = turf.dissolve(features, {propertyName: 'combine'}); - -//addToMap -var addToMap = [features, dissolved] -``` - -Returns **[FeatureCollection][3]<[Polygon][4]>** a FeatureCollection containing the dissolved polygons - -[1]: polygon - -[2]: mulitpolygon - -[3]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/dissolve -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-dissolve/index.js b/packages/turf-dissolve/index.js deleted file mode 100644 index 68e6cb8b0f..0000000000 --- a/packages/turf-dissolve/index.js +++ /dev/null @@ -1,123 +0,0 @@ -import rbush from 'geojson-rbush'; -import clone from '@turf/clone'; -import overlap from '@turf/boolean-overlap'; -import turfUnion from '@turf/union'; -import lineIntersect from '@turf/line-intersect'; -import { coordAll } from '@turf/meta'; -import { collectionOf } from '@turf/invariant'; -import { lineString, isObject } from '@turf/helpers'; -import { closestGreaterNumber } from './lib/get-closest'; - -/** - * Dissolves a FeatureCollection of {@link polygon} features, filtered by an optional property name:value. - * Note that {@link mulitpolygon} features within the collection are not supported - * - * @name dissolve - * @param {FeatureCollection} featureCollection input feature collection to be dissolved - * @param {Object} [options={}] Optional parameters - * @param {string} [options.propertyName] features with equals 'propertyName' in `properties` will be merged - * @returns {FeatureCollection} a FeatureCollection containing the dissolved polygons - * @example - * var features = turf.featureCollection([ - * turf.polygon([[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]], {combine: 'yes'}), - * turf.polygon([[[0, -1], [0, 0], [1, 0], [1, -1], [0,-1]]], {combine: 'yes'}), - * turf.polygon([[[1,-1],[1, 0], [2, 0], [2, -1], [1, -1]]], {combine: 'no'}), - * ]); - * - * var dissolved = turf.dissolve(features, {propertyName: 'combine'}); - * - * //addToMap - * var addToMap = [features, dissolved] - */ -function dissolve(featureCollection, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var propertyName = options.propertyName; - - // Input validation - collectionOf(featureCollection, 'Polygon', 'dissolve'); - - // Main - var fc = clone(featureCollection); - var features = fc.features; - - var originalIndexOfItemsRemoved = []; - - features.forEach(function (f, i) { - f.properties.origIndexPosition = i; - }); - var tree = rbush(); - tree.load(fc); - - for (var i in features) { - var polygon = features[i]; - - var featureChanged = false; - - tree.search(polygon).features.forEach(function (potentialMatchingFeature) { - polygon = features[i]; - - var matchFeaturePosition = potentialMatchingFeature.properties.origIndexPosition; - - if (originalIndexOfItemsRemoved.length > 0 && matchFeaturePosition !== 0) { - if (matchFeaturePosition > originalIndexOfItemsRemoved[originalIndexOfItemsRemoved.length - 1]) { - matchFeaturePosition = matchFeaturePosition - (originalIndexOfItemsRemoved.length); - } else { - var closestNumber = closestGreaterNumber(matchFeaturePosition, originalIndexOfItemsRemoved); - if (closestNumber !== 0) { - matchFeaturePosition = matchFeaturePosition - closestNumber; - } - } - } - - if (matchFeaturePosition === +i) return; - - var matchFeature = features[matchFeaturePosition]; - if (!matchFeature || !polygon) return; - - if (propertyName !== undefined && - matchFeature.properties[propertyName] !== polygon.properties[propertyName]) return; - - if (!overlap(polygon, matchFeature) || !ringsIntersect(polygon, matchFeature)) return; - - features[i] = turfUnion(polygon, matchFeature); - - originalIndexOfItemsRemoved.push(potentialMatchingFeature.properties.origIndexPosition); - originalIndexOfItemsRemoved.sort(function (a, b) { - return a - b; - }); - - tree.remove(potentialMatchingFeature); - features.splice(matchFeaturePosition, 1); - polygon.properties.origIndexPosition = i; - tree.remove(polygon, function (a, b) { - return a.properties.origIndexPosition === b.properties.origIndexPosition; - }); - featureChanged = true; - }); - - if (featureChanged) { - if (!polygon) continue; - polygon.properties.origIndexPosition = i; - tree.insert(polygon); - i--; - } - } - - features.forEach(function (f) { - delete f.properties.origIndexPosition; - delete f.bbox; - }); - - return fc; -} - -function ringsIntersect(poly1, poly2) { - var line1 = lineString(coordAll(poly1)); - var line2 = lineString(coordAll(poly2)); - var points = lineIntersect(line1, line2).features; - return points.length > 0; -} - -export default dissolve; diff --git a/packages/turf-dissolve/lib/get-closest.js b/packages/turf-dissolve/lib/get-closest.js deleted file mode 100644 index 1457fa860c..0000000000 --- a/packages/turf-dissolve/lib/get-closest.js +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @license get-closest https://github.com/cosmosio/get-closest - * - * The MIT License (MIT) - * - * Copyright (c) 2014-2017 Olivier Scherrer - */ - -/** - * Get the closest number in an array - * - * @private - * @param {number} item the base number - * @param {Array} array the array to search into - * @param {Function} getDiff returns the difference between the base number and - * and the currently read item in the array. The item which returned the smallest difference wins. - * @returns {Object} Get Closest - */ -function _getClosest(item, array, getDiff) { - var closest, - diff; - - if (!Array.isArray(array)) { - throw new Error('Get closest expects an array as second argument'); - } - - array.forEach(function (comparedItem, comparedItemIndex) { - var thisDiff = getDiff(comparedItem, item); - - if (thisDiff >= 0 && (typeof diff == 'undefined' || thisDiff < diff)) { - diff = thisDiff; - closest = comparedItemIndex; - } - }); - - return closest; -} - -/** - * Get the closest number in an array given a base number - * - * @private - * @param {number} item the base number - * @param {Array} array the array of numbers to search into - * @returns {number} the index of the closest item in the array - * @example - * closestNumber(30, [20, 0, 50, 29]) - * //= will return 3 as 29 is the closest item - */ -export function closestNumber(item, array) { - return _getClosest(item, array, function (comparedItem, item) { - return Math.abs(comparedItem - item); - }); -} - -/** - * Get the closest greater number in an array given a base number - * - * @private - * @param {number} item the base number - * @param {Array} array the array of numbers to search into - * @returns {number} the index of the closest item in the array - * @example - * closestGreaterNumber(30, [20, 0, 50, 29]) - * //= will return 2 as 50 is the closest greater item - */ -export function closestGreaterNumber(item, array) { - return _getClosest(item, array, function (comparedItem, item) { - return comparedItem - item; - }); -} - -/** - * Get the closest lower number in an array given a base number - * - * @private - * @param {number} item the base number - * @param {Array} array the array of numbers to search into - * @returns {number} the index of the closest item in the array - * @example - * closestLowerNumber(30, [20, 0, 50, 29]) - * //= will return 0 as 20 is the closest lower item - */ -export function closestLowerNumber(item, array) { - return _getClosest(item, array, function (comparedItem, item) { - return item - comparedItem; - }); -} - -/** - * Get the closest item in an array given a base item and a comparator function - * - * @private - * @param {*} item the base item - * @param {Array} array an array of items - * @param {Function} comparator a comparatof function to compare the items - * @returns {Object} Closest Custom - * @example - * closestCustom("lundi", ["mundi", "mardi"], getLevenshteinDistance) - * //= will return 0 for "lundi" - * - * // The function looks like: - * - * // comparedItem comes from the array - * // baseItem is the item to compare the others to - * // It returns a number - * function comparator(comparedItem, baseItem) { - * return comparedItem - baseItem; - * } - */ -export function closestCustom(item, array, comparator) { - return _getClosest(item, array, comparator); -} diff --git a/packages/turf-dissolve/package.json b/packages/turf-dissolve/package.json deleted file mode 100644 index db23737ee5..0000000000 --- a/packages/turf-dissolve/package.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "@turf/dissolve", - "version": "5.1.5", - "description": "turf dissolve module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "lib", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "dissolve", - "gis", - "geojson", - "polygon" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/boolean-overlap": "^5.1.5", - "@turf/clone": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/line-intersect": "6.x", - "@turf/meta": "6.x", - "@turf/union": "^5.1.5", - "geojson-rbush": "3.x", - "get-closest": "*" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-dissolve/test.js b/packages/turf-dissolve/test.js deleted file mode 100644 index 6550431a9a..0000000000 --- a/packages/turf-dissolve/test.js +++ /dev/null @@ -1,43 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import {polygon, point, featureCollection} from '@turf/helpers'; -import dissolve from './'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - - -test('turf-dissolve', t => { - for (const {filename, name, geojson} of fixtures) { - const propertyName = geojson.propertyName; - const results = dissolve(geojson, {propertyName}); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEquals(results, load.sync(directories.out + filename), name); - } - t.end(); -}); - - -test('dissolve -- throw', t => { - const poly = polygon([[[-61,27],[-59,27],[-59,29],[-61,29],[-61,27]]]); - const pt = point([-62,29]); - - t.throws(() => dissolve(null), /No featureCollection passed/, 'missing featureCollection'); - t.throws(() => dissolve(poly), /Invalid input to dissolve, FeatureCollection required/, 'invalid featureCollection'); - t.throws(() => dissolve(featureCollection([poly, pt])), /Invalid input to dissolve: must be a Polygon, given Point/, 'invalid collection type'); - t.end(); -}); \ No newline at end of file diff --git a/packages/turf-dissolve/test/in/polysByProperty.geojson b/packages/turf-dissolve/test/in/polysByProperty.geojson deleted file mode 100644 index ce7813d2ff..0000000000 --- a/packages/turf-dissolve/test/in/polysByProperty.geojson +++ /dev/null @@ -1,237 +0,0 @@ -{ - "type": "FeatureCollection", - "propertyName": "combine", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#555555", - "stroke-width": 2, - "stroke-opacity": 1, - "fill": "#ff0000", - "fill-opacity": 0.5, - "combine": "yes" - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0.5, - 0 - ], - [ - 0, - 1 - ], - [ - 1, - 1 - ], - [ - 1, - 0.5 - ], - [ - 0.7, - 0 - ], - [ - 0.5, - 0 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#555555", - "stroke-width": 2, - "stroke-opacity": 1, - "fill": "#ff0000", - "fill-opacity": 0.5, - "combine": "yes" - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 1, - 0 - ], - [ - 1, - 1 - ], - [ - 2, - 1 - ], - [ - 2, - 0 - ], - [ - 1, - 0 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#555555", - "stroke-width": 2, - "stroke-opacity": 1, - "fill": "#ff0000", - "fill-opacity": 0.5, - "combine": "yes" - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0.23620605468749623, - -0.8901516807502449 - ], - [ - 0.23620605468749623, - 0.10986321392741416 - ], - [ - 1.2362060546874962, - 0.10986321392741416 - ], - [ - 1.2362060546874962, - -0.8901516807502449 - ], - [ - 0.23620605468749623, - -0.8901516807502449 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#555555", - "stroke-width": 2, - "stroke-opacity": 1, - "fill": "#00ff00", - "fill-opacity": 0.5, - "combine": "no" - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 1, - -1 - ], - [ - 1, - 0 - ], - [ - 2, - 0 - ], - [ - 2, - -1 - ], - [ - 1, - -1 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#555555", - "stroke-width": 2, - "stroke-opacity": 1, - "fill": "#00ff00", - "fill-opacity": 0.5, - "combine": "no" - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0.851440429687502, - -1.647722051796948 - ], - [ - 0.851440429687502, - 1.4500404973607692 - ], - [ - 1.516113281250002, - 1.4500404973607692 - ], - [ - 1.516113281250002, - -1.647722051796948 - ], - [ - 0.851440429687502, - -1.647722051796948 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#555555", - "stroke-width": 2, - "stroke-opacity": 1, - "fill": "#ffff00", - "fill-opacity": 0.5 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -0.252685546875, - 1.252341676699629 - ], - [ - -0.252685546875, - 1.653212936926045 - ], - [ - 0.28564453125, - 1.653212936926045 - ], - [ - 0.28564453125, - 1.252341676699629 - ], - [ - -0.252685546875, - 1.252341676699629 - ] - ] - ] - } - } - ] -} \ No newline at end of file diff --git a/packages/turf-dissolve/test/in/simplified-issue.geojson b/packages/turf-dissolve/test/in/simplified-issue.geojson deleted file mode 100644 index fb5643c20a..0000000000 --- a/packages/turf-dissolve/test/in/simplified-issue.geojson +++ /dev/null @@ -1,5880 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.705, - 45.362 - ], - [ - -75.714, - 45.36 - ], - [ - -75.717, - 45.353 - ], - [ - -75.714, - 45.347 - ], - [ - -75.705, - 45.344 - ], - [ - -75.696, - 45.347 - ], - [ - -75.692, - 45.353 - ], - [ - -75.696, - 45.36 - ], - [ - -75.705, - 45.362 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.646, - 45.363 - ], - [ - -75.655, - 45.36 - ], - [ - -75.659, - 45.354 - ], - [ - -75.655, - 45.348 - ], - [ - -75.646, - 45.345 - ], - [ - -75.637, - 45.348 - ], - [ - -75.634, - 45.354 - ], - [ - -75.637, - 45.36 - ], - [ - -75.646, - 45.363 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.704, - 45.379 - ], - [ - -75.713, - 45.377 - ], - [ - -75.717, - 45.37 - ], - [ - -75.713, - 45.364 - ], - [ - -75.704, - 45.361 - ], - [ - -75.695, - 45.364 - ], - [ - -75.691, - 45.37 - ], - [ - -75.695, - 45.377 - ], - [ - -75.704, - 45.379 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.724, - 45.344 - ], - [ - -75.733, - 45.342 - ], - [ - -75.736, - 45.335 - ], - [ - -75.733, - 45.329 - ], - [ - -75.724, - 45.326 - ], - [ - -75.715, - 45.329 - ], - [ - -75.711, - 45.335 - ], - [ - -75.715, - 45.342 - ], - [ - -75.724, - 45.344 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.685, - 45.438 - ], - [ - -75.694, - 45.435 - ], - [ - -75.698, - 45.429 - ], - [ - -75.694, - 45.422 - ], - [ - -75.685, - 45.42 - ], - [ - -75.676, - 45.422 - ], - [ - -75.673, - 45.429 - ], - [ - -75.676, - 45.435 - ], - [ - -75.685, - 45.438 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.625, - 45.357 - ], - [ - -75.634, - 45.354 - ], - [ - -75.638, - 45.348 - ], - [ - -75.634, - 45.342 - ], - [ - -75.625, - 45.339 - ], - [ - -75.616, - 45.342 - ], - [ - -75.612, - 45.348 - ], - [ - -75.616, - 45.354 - ], - [ - -75.625, - 45.357 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.702, - 45.378 - ], - [ - -75.711, - 45.375 - ], - [ - -75.714, - 45.369 - ], - [ - -75.711, - 45.362 - ], - [ - -75.702, - 45.36 - ], - [ - -75.692, - 45.362 - ], - [ - -75.689, - 45.369 - ], - [ - -75.692, - 45.375 - ], - [ - -75.702, - 45.378 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.744, - 45.405 - ], - [ - -75.753, - 45.403 - ], - [ - -75.757, - 45.396 - ], - [ - -75.753, - 45.39 - ], - [ - -75.744, - 45.388 - ], - [ - -75.735, - 45.39 - ], - [ - -75.731, - 45.396 - ], - [ - -75.735, - 45.403 - ], - [ - -75.744, - 45.405 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.691, - 45.351 - ], - [ - -75.7, - 45.349 - ], - [ - -75.703, - 45.342 - ], - [ - -75.7, - 45.336 - ], - [ - -75.691, - 45.333 - ], - [ - -75.682, - 45.336 - ], - [ - -75.678, - 45.342 - ], - [ - -75.682, - 45.349 - ], - [ - -75.691, - 45.351 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.706, - 45.42 - ], - [ - -75.715, - 45.417 - ], - [ - -75.719, - 45.411 - ], - [ - -75.715, - 45.405 - ], - [ - -75.706, - 45.402 - ], - [ - -75.697, - 45.405 - ], - [ - -75.693, - 45.411 - ], - [ - -75.697, - 45.417 - ], - [ - -75.706, - 45.42 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.694, - 45.343 - ], - [ - -75.703, - 45.34 - ], - [ - -75.707, - 45.334 - ], - [ - -75.703, - 45.327 - ], - [ - -75.694, - 45.325 - ], - [ - -75.685, - 45.327 - ], - [ - -75.681, - 45.334 - ], - [ - -75.685, - 45.34 - ], - [ - -75.694, - 45.343 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.643, - 45.363 - ], - [ - -75.652, - 45.36 - ], - [ - -75.656, - 45.354 - ], - [ - -75.652, - 45.347 - ], - [ - -75.643, - 45.345 - ], - [ - -75.634, - 45.347 - ], - [ - -75.631, - 45.354 - ], - [ - -75.634, - 45.36 - ], - [ - -75.643, - 45.363 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.697, - 45.427 - ], - [ - -75.706, - 45.425 - ], - [ - -75.71, - 45.418 - ], - [ - -75.706, - 45.412 - ], - [ - -75.697, - 45.409 - ], - [ - -75.688, - 45.412 - ], - [ - -75.684, - 45.418 - ], - [ - -75.688, - 45.425 - ], - [ - -75.697, - 45.427 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.618, - 45.398 - ], - [ - -75.627, - 45.395 - ], - [ - -75.631, - 45.389 - ], - [ - -75.627, - 45.383 - ], - [ - -75.618, - 45.38 - ], - [ - -75.609, - 45.383 - ], - [ - -75.606, - 45.389 - ], - [ - -75.609, - 45.395 - ], - [ - -75.618, - 45.398 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.639, - 45.437 - ], - [ - -75.648, - 45.435 - ], - [ - -75.652, - 45.428 - ], - [ - -75.648, - 45.422 - ], - [ - -75.639, - 45.419 - ], - [ - -75.63, - 45.422 - ], - [ - -75.626, - 45.428 - ], - [ - -75.63, - 45.435 - ], - [ - -75.639, - 45.437 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.754, - 45.386 - ], - [ - -75.763, - 45.383 - ], - [ - -75.767, - 45.377 - ], - [ - -75.763, - 45.371 - ], - [ - -75.754, - 45.368 - ], - [ - -75.745, - 45.371 - ], - [ - -75.741, - 45.377 - ], - [ - -75.745, - 45.383 - ], - [ - -75.754, - 45.386 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.588, - 45.458 - ], - [ - -75.597, - 45.456 - ], - [ - -75.601, - 45.449 - ], - [ - -75.597, - 45.443 - ], - [ - -75.588, - 45.44 - ], - [ - -75.579, - 45.443 - ], - [ - -75.575, - 45.449 - ], - [ - -75.579, - 45.456 - ], - [ - -75.588, - 45.458 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.729, - 45.41 - ], - [ - -75.738, - 45.407 - ], - [ - -75.742, - 45.401 - ], - [ - -75.738, - 45.394 - ], - [ - -75.729, - 45.392 - ], - [ - -75.72, - 45.394 - ], - [ - -75.717, - 45.401 - ], - [ - -75.72, - 45.407 - ], - [ - -75.729, - 45.41 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.642, - 45.363 - ], - [ - -75.651, - 45.36 - ], - [ - -75.655, - 45.354 - ], - [ - -75.651, - 45.347 - ], - [ - -75.642, - 45.345 - ], - [ - -75.633, - 45.347 - ], - [ - -75.629, - 45.354 - ], - [ - -75.633, - 45.36 - ], - [ - -75.642, - 45.363 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.67, - 45.352 - ], - [ - -75.679, - 45.349 - ], - [ - -75.683, - 45.343 - ], - [ - -75.679, - 45.337 - ], - [ - -75.67, - 45.334 - ], - [ - -75.661, - 45.337 - ], - [ - -75.657, - 45.343 - ], - [ - -75.661, - 45.349 - ], - [ - -75.67, - 45.352 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.602, - 45.392 - ], - [ - -75.611, - 45.389 - ], - [ - -75.615, - 45.383 - ], - [ - -75.611, - 45.377 - ], - [ - -75.602, - 45.374 - ], - [ - -75.593, - 45.377 - ], - [ - -75.589, - 45.383 - ], - [ - -75.593, - 45.389 - ], - [ - -75.602, - 45.392 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.594, - 45.457 - ], - [ - -75.603, - 45.454 - ], - [ - -75.607, - 45.448 - ], - [ - -75.603, - 45.441 - ], - [ - -75.594, - 45.439 - ], - [ - -75.585, - 45.441 - ], - [ - -75.581, - 45.448 - ], - [ - -75.585, - 45.454 - ], - [ - -75.594, - 45.457 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.747, - 45.39 - ], - [ - -75.756, - 45.387 - ], - [ - -75.76, - 45.381 - ], - [ - -75.756, - 45.374 - ], - [ - -75.747, - 45.372 - ], - [ - -75.738, - 45.374 - ], - [ - -75.735, - 45.381 - ], - [ - -75.738, - 45.387 - ], - [ - -75.747, - 45.39 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.757, - 45.385 - ], - [ - -75.766, - 45.383 - ], - [ - -75.77, - 45.376 - ], - [ - -75.766, - 45.37 - ], - [ - -75.757, - 45.367 - ], - [ - -75.748, - 45.37 - ], - [ - -75.745, - 45.376 - ], - [ - -75.748, - 45.383 - ], - [ - -75.757, - 45.385 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.631, - 45.392 - ], - [ - -75.64, - 45.389 - ], - [ - -75.644, - 45.383 - ], - [ - -75.64, - 45.377 - ], - [ - -75.631, - 45.374 - ], - [ - -75.622, - 45.377 - ], - [ - -75.618, - 45.383 - ], - [ - -75.622, - 45.389 - ], - [ - -75.631, - 45.392 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.641, - 45.42 - ], - [ - -75.65, - 45.417 - ], - [ - -75.654, - 45.411 - ], - [ - -75.65, - 45.405 - ], - [ - -75.641, - 45.402 - ], - [ - -75.632, - 45.405 - ], - [ - -75.628, - 45.411 - ], - [ - -75.632, - 45.417 - ], - [ - -75.641, - 45.42 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.666, - 45.443 - ], - [ - -75.675, - 45.44 - ], - [ - -75.679, - 45.434 - ], - [ - -75.675, - 45.428 - ], - [ - -75.666, - 45.425 - ], - [ - -75.657, - 45.428 - ], - [ - -75.653, - 45.434 - ], - [ - -75.657, - 45.44 - ], - [ - -75.666, - 45.443 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.668, - 45.442 - ], - [ - -75.677, - 45.44 - ], - [ - -75.681, - 45.433 - ], - [ - -75.677, - 45.427 - ], - [ - -75.668, - 45.424 - ], - [ - -75.659, - 45.427 - ], - [ - -75.656, - 45.433 - ], - [ - -75.659, - 45.44 - ], - [ - -75.668, - 45.442 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.67, - 45.442 - ], - [ - -75.679, - 45.44 - ], - [ - -75.682, - 45.433 - ], - [ - -75.679, - 45.427 - ], - [ - -75.67, - 45.424 - ], - [ - -75.661, - 45.427 - ], - [ - -75.657, - 45.433 - ], - [ - -75.661, - 45.44 - ], - [ - -75.67, - 45.442 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.644, - 45.451 - ], - [ - -75.653, - 45.448 - ], - [ - -75.657, - 45.442 - ], - [ - -75.653, - 45.435 - ], - [ - -75.644, - 45.433 - ], - [ - -75.635, - 45.435 - ], - [ - -75.631, - 45.442 - ], - [ - -75.635, - 45.448 - ], - [ - -75.644, - 45.451 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.654, - 45.448 - ], - [ - -75.663, - 45.445 - ], - [ - -75.667, - 45.439 - ], - [ - -75.663, - 45.433 - ], - [ - -75.654, - 45.43 - ], - [ - -75.645, - 45.433 - ], - [ - -75.641, - 45.439 - ], - [ - -75.645, - 45.445 - ], - [ - -75.654, - 45.448 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.605, - 45.424 - ], - [ - -75.614, - 45.421 - ], - [ - -75.617, - 45.415 - ], - [ - -75.614, - 45.409 - ], - [ - -75.605, - 45.406 - ], - [ - -75.596, - 45.409 - ], - [ - -75.592, - 45.415 - ], - [ - -75.596, - 45.421 - ], - [ - -75.605, - 45.424 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.596, - 45.428 - ], - [ - -75.605, - 45.426 - ], - [ - -75.609, - 45.419 - ], - [ - -75.605, - 45.413 - ], - [ - -75.596, - 45.41 - ], - [ - -75.587, - 45.413 - ], - [ - -75.584, - 45.419 - ], - [ - -75.587, - 45.426 - ], - [ - -75.596, - 45.428 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.702, - 45.343 - ], - [ - -75.711, - 45.34 - ], - [ - -75.715, - 45.334 - ], - [ - -75.711, - 45.327 - ], - [ - -75.702, - 45.325 - ], - [ - -75.693, - 45.327 - ], - [ - -75.689, - 45.334 - ], - [ - -75.693, - 45.34 - ], - [ - -75.702, - 45.343 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.73, - 45.352 - ], - [ - -75.739, - 45.35 - ], - [ - -75.742, - 45.343 - ], - [ - -75.739, - 45.337 - ], - [ - -75.73, - 45.334 - ], - [ - -75.721, - 45.337 - ], - [ - -75.717, - 45.343 - ], - [ - -75.721, - 45.35 - ], - [ - -75.73, - 45.352 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.734, - 45.359 - ], - [ - -75.743, - 45.357 - ], - [ - -75.746, - 45.35 - ], - [ - -75.743, - 45.344 - ], - [ - -75.734, - 45.341 - ], - [ - -75.725, - 45.344 - ], - [ - -75.721, - 45.35 - ], - [ - -75.725, - 45.357 - ], - [ - -75.734, - 45.359 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.736, - 45.363 - ], - [ - -75.745, - 45.361 - ], - [ - -75.749, - 45.354 - ], - [ - -75.745, - 45.348 - ], - [ - -75.736, - 45.345 - ], - [ - -75.727, - 45.348 - ], - [ - -75.723, - 45.354 - ], - [ - -75.727, - 45.361 - ], - [ - -75.736, - 45.363 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.595, - 45.428 - ], - [ - -75.604, - 45.425 - ], - [ - -75.608, - 45.419 - ], - [ - -75.604, - 45.413 - ], - [ - -75.595, - 45.41 - ], - [ - -75.586, - 45.413 - ], - [ - -75.582, - 45.419 - ], - [ - -75.586, - 45.425 - ], - [ - -75.595, - 45.428 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.618, - 45.429 - ], - [ - -75.627, - 45.427 - ], - [ - -75.631, - 45.42 - ], - [ - -75.627, - 45.414 - ], - [ - -75.618, - 45.411 - ], - [ - -75.609, - 45.414 - ], - [ - -75.605, - 45.42 - ], - [ - -75.609, - 45.427 - ], - [ - -75.618, - 45.429 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.605, - 45.426 - ], - [ - -75.614, - 45.423 - ], - [ - -75.617, - 45.417 - ], - [ - -75.614, - 45.411 - ], - [ - -75.605, - 45.408 - ], - [ - -75.596, - 45.411 - ], - [ - -75.592, - 45.417 - ], - [ - -75.596, - 45.423 - ], - [ - -75.605, - 45.426 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.773, - 45.378 - ], - [ - -75.782, - 45.375 - ], - [ - -75.786, - 45.369 - ], - [ - -75.782, - 45.362 - ], - [ - -75.773, - 45.36 - ], - [ - -75.764, - 45.362 - ], - [ - -75.76, - 45.369 - ], - [ - -75.764, - 45.375 - ], - [ - -75.773, - 45.378 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.636, - 45.434 - ], - [ - -75.645, - 45.431 - ], - [ - -75.648, - 45.425 - ], - [ - -75.645, - 45.419 - ], - [ - -75.636, - 45.416 - ], - [ - -75.626, - 45.419 - ], - [ - -75.623, - 45.425 - ], - [ - -75.626, - 45.431 - ], - [ - -75.636, - 45.434 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.637, - 45.434 - ], - [ - -75.646, - 45.432 - ], - [ - -75.65, - 45.425 - ], - [ - -75.646, - 45.419 - ], - [ - -75.637, - 45.416 - ], - [ - -75.628, - 45.419 - ], - [ - -75.625, - 45.425 - ], - [ - -75.628, - 45.432 - ], - [ - -75.637, - 45.434 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.627, - 45.414 - ], - [ - -75.636, - 45.412 - ], - [ - -75.64, - 45.405 - ], - [ - -75.636, - 45.399 - ], - [ - -75.627, - 45.396 - ], - [ - -75.618, - 45.399 - ], - [ - -75.615, - 45.405 - ], - [ - -75.618, - 45.412 - ], - [ - -75.627, - 45.414 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.782, - 45.38 - ], - [ - -75.791, - 45.377 - ], - [ - -75.795, - 45.371 - ], - [ - -75.791, - 45.364 - ], - [ - -75.782, - 45.362 - ], - [ - -75.773, - 45.364 - ], - [ - -75.769, - 45.371 - ], - [ - -75.773, - 45.377 - ], - [ - -75.782, - 45.38 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.757, - 45.385 - ], - [ - -75.766, - 45.382 - ], - [ - -75.77, - 45.376 - ], - [ - -75.766, - 45.369 - ], - [ - -75.757, - 45.367 - ], - [ - -75.748, - 45.369 - ], - [ - -75.744, - 45.376 - ], - [ - -75.748, - 45.382 - ], - [ - -75.757, - 45.385 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.786, - 45.351 - ], - [ - -75.795, - 45.348 - ], - [ - -75.799, - 45.342 - ], - [ - -75.795, - 45.336 - ], - [ - -75.786, - 45.333 - ], - [ - -75.777, - 45.336 - ], - [ - -75.773, - 45.342 - ], - [ - -75.777, - 45.348 - ], - [ - -75.786, - 45.351 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.788, - 45.356 - ], - [ - -75.797, - 45.354 - ], - [ - -75.801, - 45.348 - ], - [ - -75.797, - 45.341 - ], - [ - -75.788, - 45.339 - ], - [ - -75.779, - 45.341 - ], - [ - -75.775, - 45.348 - ], - [ - -75.779, - 45.354 - ], - [ - -75.788, - 45.356 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.62, - 45.373 - ], - [ - -75.629, - 45.371 - ], - [ - -75.633, - 45.364 - ], - [ - -75.629, - 45.358 - ], - [ - -75.62, - 45.355 - ], - [ - -75.611, - 45.358 - ], - [ - -75.607, - 45.364 - ], - [ - -75.611, - 45.371 - ], - [ - -75.62, - 45.373 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.621, - 45.404 - ], - [ - -75.63, - 45.402 - ], - [ - -75.634, - 45.395 - ], - [ - -75.63, - 45.389 - ], - [ - -75.621, - 45.386 - ], - [ - -75.612, - 45.389 - ], - [ - -75.609, - 45.395 - ], - [ - -75.612, - 45.402 - ], - [ - -75.621, - 45.404 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.624, - 45.383 - ], - [ - -75.633, - 45.38 - ], - [ - -75.637, - 45.374 - ], - [ - -75.633, - 45.368 - ], - [ - -75.624, - 45.365 - ], - [ - -75.615, - 45.368 - ], - [ - -75.611, - 45.374 - ], - [ - -75.615, - 45.38 - ], - [ - -75.624, - 45.383 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.677, - 45.448 - ], - [ - -75.686, - 45.446 - ], - [ - -75.689, - 45.439 - ], - [ - -75.686, - 45.433 - ], - [ - -75.677, - 45.43 - ], - [ - -75.668, - 45.433 - ], - [ - -75.664, - 45.439 - ], - [ - -75.668, - 45.446 - ], - [ - -75.677, - 45.448 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.694, - 45.421 - ], - [ - -75.703, - 45.418 - ], - [ - -75.706, - 45.412 - ], - [ - -75.703, - 45.405 - ], - [ - -75.694, - 45.403 - ], - [ - -75.685, - 45.405 - ], - [ - -75.681, - 45.412 - ], - [ - -75.685, - 45.418 - ], - [ - -75.694, - 45.421 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.75, - 45.402 - ], - [ - -75.759, - 45.4 - ], - [ - -75.763, - 45.394 - ], - [ - -75.759, - 45.387 - ], - [ - -75.75, - 45.385 - ], - [ - -75.741, - 45.387 - ], - [ - -75.738, - 45.394 - ], - [ - -75.741, - 45.4 - ], - [ - -75.75, - 45.402 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.788, - 45.35 - ], - [ - -75.797, - 45.348 - ], - [ - -75.801, - 45.341 - ], - [ - -75.797, - 45.335 - ], - [ - -75.788, - 45.332 - ], - [ - -75.779, - 45.335 - ], - [ - -75.775, - 45.341 - ], - [ - -75.779, - 45.348 - ], - [ - -75.788, - 45.35 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.692, - 45.419 - ], - [ - -75.702, - 45.416 - ], - [ - -75.705, - 45.41 - ], - [ - -75.702, - 45.403 - ], - [ - -75.692, - 45.401 - ], - [ - -75.683, - 45.403 - ], - [ - -75.68, - 45.41 - ], - [ - -75.683, - 45.416 - ], - [ - -75.692, - 45.419 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.631, - 45.435 - ], - [ - -75.64, - 45.432 - ], - [ - -75.644, - 45.426 - ], - [ - -75.64, - 45.42 - ], - [ - -75.631, - 45.417 - ], - [ - -75.622, - 45.42 - ], - [ - -75.618, - 45.426 - ], - [ - -75.622, - 45.432 - ], - [ - -75.631, - 45.435 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.786, - 45.376 - ], - [ - -75.795, - 45.374 - ], - [ - -75.799, - 45.367 - ], - [ - -75.795, - 45.361 - ], - [ - -75.786, - 45.359 - ], - [ - -75.777, - 45.361 - ], - [ - -75.773, - 45.367 - ], - [ - -75.777, - 45.374 - ], - [ - -75.786, - 45.376 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.648, - 45.441 - ], - [ - -75.657, - 45.438 - ], - [ - -75.661, - 45.432 - ], - [ - -75.657, - 45.426 - ], - [ - -75.648, - 45.423 - ], - [ - -75.639, - 45.426 - ], - [ - -75.635, - 45.432 - ], - [ - -75.639, - 45.438 - ], - [ - -75.648, - 45.441 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.64, - 45.452 - ], - [ - -75.649, - 45.449 - ], - [ - -75.653, - 45.443 - ], - [ - -75.649, - 45.437 - ], - [ - -75.64, - 45.434 - ], - [ - -75.631, - 45.437 - ], - [ - -75.628, - 45.443 - ], - [ - -75.631, - 45.449 - ], - [ - -75.64, - 45.452 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.61, - 45.427 - ], - [ - -75.619, - 45.425 - ], - [ - -75.623, - 45.419 - ], - [ - -75.619, - 45.412 - ], - [ - -75.61, - 45.41 - ], - [ - -75.601, - 45.412 - ], - [ - -75.597, - 45.419 - ], - [ - -75.601, - 45.425 - ], - [ - -75.61, - 45.427 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.739, - 45.37 - ], - [ - -75.748, - 45.368 - ], - [ - -75.752, - 45.361 - ], - [ - -75.748, - 45.355 - ], - [ - -75.739, - 45.352 - ], - [ - -75.73, - 45.355 - ], - [ - -75.726, - 45.361 - ], - [ - -75.73, - 45.368 - ], - [ - -75.739, - 45.37 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.704, - 45.416 - ], - [ - -75.713, - 45.414 - ], - [ - -75.717, - 45.407 - ], - [ - -75.713, - 45.401 - ], - [ - -75.704, - 45.398 - ], - [ - -75.695, - 45.401 - ], - [ - -75.691, - 45.407 - ], - [ - -75.695, - 45.414 - ], - [ - -75.704, - 45.416 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.595, - 45.457 - ], - [ - -75.604, - 45.454 - ], - [ - -75.608, - 45.448 - ], - [ - -75.604, - 45.441 - ], - [ - -75.595, - 45.439 - ], - [ - -75.586, - 45.441 - ], - [ - -75.582, - 45.448 - ], - [ - -75.586, - 45.454 - ], - [ - -75.595, - 45.457 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.733, - 45.39 - ], - [ - -75.743, - 45.388 - ], - [ - -75.746, - 45.381 - ], - [ - -75.743, - 45.375 - ], - [ - -75.733, - 45.372 - ], - [ - -75.724, - 45.375 - ], - [ - -75.721, - 45.381 - ], - [ - -75.724, - 45.388 - ], - [ - -75.733, - 45.39 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.617, - 45.416 - ], - [ - -75.626, - 45.413 - ], - [ - -75.63, - 45.407 - ], - [ - -75.626, - 45.401 - ], - [ - -75.617, - 45.398 - ], - [ - -75.608, - 45.401 - ], - [ - -75.604, - 45.407 - ], - [ - -75.608, - 45.413 - ], - [ - -75.617, - 45.416 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.67, - 45.452 - ], - [ - -75.679, - 45.45 - ], - [ - -75.683, - 45.444 - ], - [ - -75.679, - 45.437 - ], - [ - -75.67, - 45.435 - ], - [ - -75.661, - 45.437 - ], - [ - -75.657, - 45.444 - ], - [ - -75.661, - 45.45 - ], - [ - -75.67, - 45.452 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.742, - 45.406 - ], - [ - -75.751, - 45.404 - ], - [ - -75.755, - 45.397 - ], - [ - -75.751, - 45.391 - ], - [ - -75.742, - 45.388 - ], - [ - -75.733, - 45.391 - ], - [ - -75.729, - 45.397 - ], - [ - -75.733, - 45.404 - ], - [ - -75.742, - 45.406 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.756, - 45.352 - ], - [ - -75.765, - 45.349 - ], - [ - -75.769, - 45.343 - ], - [ - -75.765, - 45.336 - ], - [ - -75.756, - 45.334 - ], - [ - -75.747, - 45.336 - ], - [ - -75.744, - 45.343 - ], - [ - -75.747, - 45.349 - ], - [ - -75.756, - 45.352 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.809, - 45.363 - ], - [ - -75.818, - 45.36 - ], - [ - -75.822, - 45.354 - ], - [ - -75.818, - 45.347 - ], - [ - -75.809, - 45.345 - ], - [ - -75.8, - 45.347 - ], - [ - -75.796, - 45.354 - ], - [ - -75.8, - 45.36 - ], - [ - -75.809, - 45.363 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.67, - 45.36 - ], - [ - -75.679, - 45.357 - ], - [ - -75.683, - 45.351 - ], - [ - -75.679, - 45.345 - ], - [ - -75.67, - 45.342 - ], - [ - -75.661, - 45.345 - ], - [ - -75.657, - 45.351 - ], - [ - -75.661, - 45.357 - ], - [ - -75.67, - 45.36 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.708, - 45.408 - ], - [ - -75.717, - 45.405 - ], - [ - -75.721, - 45.399 - ], - [ - -75.717, - 45.392 - ], - [ - -75.708, - 45.39 - ], - [ - -75.699, - 45.392 - ], - [ - -75.695, - 45.399 - ], - [ - -75.699, - 45.405 - ], - [ - -75.708, - 45.408 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.701, - 45.413 - ], - [ - -75.71, - 45.41 - ], - [ - -75.714, - 45.404 - ], - [ - -75.71, - 45.397 - ], - [ - -75.701, - 45.395 - ], - [ - -75.692, - 45.397 - ], - [ - -75.688, - 45.404 - ], - [ - -75.692, - 45.41 - ], - [ - -75.701, - 45.413 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.632, - 45.435 - ], - [ - -75.641, - 45.433 - ], - [ - -75.645, - 45.426 - ], - [ - -75.641, - 45.42 - ], - [ - -75.632, - 45.417 - ], - [ - -75.623, - 45.42 - ], - [ - -75.619, - 45.426 - ], - [ - -75.623, - 45.433 - ], - [ - -75.632, - 45.435 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.648, - 45.438 - ], - [ - -75.657, - 45.435 - ], - [ - -75.661, - 45.429 - ], - [ - -75.657, - 45.422 - ], - [ - -75.648, - 45.42 - ], - [ - -75.639, - 45.422 - ], - [ - -75.635, - 45.429 - ], - [ - -75.639, - 45.435 - ], - [ - -75.648, - 45.438 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.73, - 45.407 - ], - [ - -75.74, - 45.404 - ], - [ - -75.743, - 45.398 - ], - [ - -75.739, - 45.391 - ], - [ - -75.73, - 45.389 - ], - [ - -75.721, - 45.391 - ], - [ - -75.718, - 45.398 - ], - [ - -75.721, - 45.404 - ], - [ - -75.73, - 45.407 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.702, - 45.351 - ], - [ - -75.711, - 45.349 - ], - [ - -75.715, - 45.342 - ], - [ - -75.711, - 45.336 - ], - [ - -75.702, - 45.333 - ], - [ - -75.693, - 45.336 - ], - [ - -75.689, - 45.342 - ], - [ - -75.693, - 45.349 - ], - [ - -75.702, - 45.351 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.63, - 45.421 - ], - [ - -75.639, - 45.419 - ], - [ - -75.643, - 45.412 - ], - [ - -75.639, - 45.406 - ], - [ - -75.63, - 45.403 - ], - [ - -75.621, - 45.406 - ], - [ - -75.617, - 45.412 - ], - [ - -75.621, - 45.419 - ], - [ - -75.63, - 45.421 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.613, - 45.442 - ], - [ - -75.622, - 45.44 - ], - [ - -75.625, - 45.433 - ], - [ - -75.622, - 45.427 - ], - [ - -75.613, - 45.424 - ], - [ - -75.604, - 45.427 - ], - [ - -75.6, - 45.433 - ], - [ - -75.604, - 45.44 - ], - [ - -75.613, - 45.442 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.736, - 45.369 - ], - [ - -75.745, - 45.366 - ], - [ - -75.749, - 45.36 - ], - [ - -75.745, - 45.354 - ], - [ - -75.736, - 45.351 - ], - [ - -75.727, - 45.354 - ], - [ - -75.723, - 45.36 - ], - [ - -75.727, - 45.366 - ], - [ - -75.736, - 45.369 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.631, - 45.432 - ], - [ - -75.64, - 45.43 - ], - [ - -75.644, - 45.423 - ], - [ - -75.64, - 45.417 - ], - [ - -75.631, - 45.414 - ], - [ - -75.622, - 45.417 - ], - [ - -75.618, - 45.423 - ], - [ - -75.622, - 45.43 - ], - [ - -75.631, - 45.432 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.68, - 45.441 - ], - [ - -75.689, - 45.438 - ], - [ - -75.692, - 45.432 - ], - [ - -75.689, - 45.425 - ], - [ - -75.68, - 45.423 - ], - [ - -75.671, - 45.425 - ], - [ - -75.667, - 45.432 - ], - [ - -75.671, - 45.438 - ], - [ - -75.68, - 45.441 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.748, - 45.384 - ], - [ - -75.757, - 45.381 - ], - [ - -75.761, - 45.375 - ], - [ - -75.757, - 45.368 - ], - [ - -75.748, - 45.366 - ], - [ - -75.739, - 45.368 - ], - [ - -75.735, - 45.375 - ], - [ - -75.739, - 45.381 - ], - [ - -75.748, - 45.384 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.788, - 45.372 - ], - [ - -75.797, - 45.369 - ], - [ - -75.801, - 45.363 - ], - [ - -75.797, - 45.356 - ], - [ - -75.788, - 45.354 - ], - [ - -75.779, - 45.356 - ], - [ - -75.775, - 45.363 - ], - [ - -75.779, - 45.369 - ], - [ - -75.788, - 45.372 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.621, - 45.406 - ], - [ - -75.63, - 45.403 - ], - [ - -75.634, - 45.397 - ], - [ - -75.63, - 45.39 - ], - [ - -75.621, - 45.388 - ], - [ - -75.612, - 45.39 - ], - [ - -75.608, - 45.397 - ], - [ - -75.612, - 45.403 - ], - [ - -75.621, - 45.406 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.752, - 45.343 - ], - [ - -75.761, - 45.341 - ], - [ - -75.765, - 45.334 - ], - [ - -75.761, - 45.328 - ], - [ - -75.752, - 45.325 - ], - [ - -75.743, - 45.328 - ], - [ - -75.739, - 45.334 - ], - [ - -75.743, - 45.341 - ], - [ - -75.752, - 45.343 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.631, - 45.369 - ], - [ - -75.641, - 45.367 - ], - [ - -75.644, - 45.36 - ], - [ - -75.641, - 45.354 - ], - [ - -75.631, - 45.351 - ], - [ - -75.622, - 45.354 - ], - [ - -75.619, - 45.36 - ], - [ - -75.622, - 45.367 - ], - [ - -75.631, - 45.369 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.605, - 45.445 - ], - [ - -75.614, - 45.443 - ], - [ - -75.617, - 45.436 - ], - [ - -75.614, - 45.43 - ], - [ - -75.605, - 45.427 - ], - [ - -75.596, - 45.43 - ], - [ - -75.592, - 45.436 - ], - [ - -75.596, - 45.443 - ], - [ - -75.605, - 45.445 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.736, - 45.364 - ], - [ - -75.745, - 45.361 - ], - [ - -75.748, - 45.355 - ], - [ - -75.745, - 45.349 - ], - [ - -75.736, - 45.346 - ], - [ - -75.727, - 45.349 - ], - [ - -75.723, - 45.355 - ], - [ - -75.727, - 45.361 - ], - [ - -75.736, - 45.364 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.72, - 45.336 - ], - [ - -75.729, - 45.333 - ], - [ - -75.733, - 45.327 - ], - [ - -75.729, - 45.321 - ], - [ - -75.72, - 45.318 - ], - [ - -75.711, - 45.321 - ], - [ - -75.707, - 45.327 - ], - [ - -75.711, - 45.333 - ], - [ - -75.72, - 45.336 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.65, - 45.454 - ], - [ - -75.659, - 45.452 - ], - [ - -75.662, - 45.445 - ], - [ - -75.659, - 45.439 - ], - [ - -75.65, - 45.436 - ], - [ - -75.641, - 45.439 - ], - [ - -75.637, - 45.445 - ], - [ - -75.641, - 45.452 - ], - [ - -75.65, - 45.454 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.734, - 45.372 - ], - [ - -75.743, - 45.37 - ], - [ - -75.747, - 45.363 - ], - [ - -75.743, - 45.357 - ], - [ - -75.734, - 45.354 - ], - [ - -75.725, - 45.357 - ], - [ - -75.721, - 45.363 - ], - [ - -75.725, - 45.37 - ], - [ - -75.734, - 45.372 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.775, - 45.356 - ], - [ - -75.784, - 45.353 - ], - [ - -75.788, - 45.347 - ], - [ - -75.784, - 45.34 - ], - [ - -75.775, - 45.338 - ], - [ - -75.766, - 45.34 - ], - [ - -75.762, - 45.347 - ], - [ - -75.766, - 45.353 - ], - [ - -75.775, - 45.356 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.775, - 45.356 - ], - [ - -75.784, - 45.353 - ], - [ - -75.787, - 45.347 - ], - [ - -75.784, - 45.341 - ], - [ - -75.775, - 45.338 - ], - [ - -75.766, - 45.341 - ], - [ - -75.762, - 45.347 - ], - [ - -75.766, - 45.353 - ], - [ - -75.775, - 45.356 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.721, - 45.339 - ], - [ - -75.73, - 45.336 - ], - [ - -75.734, - 45.33 - ], - [ - -75.73, - 45.323 - ], - [ - -75.721, - 45.321 - ], - [ - -75.712, - 45.323 - ], - [ - -75.708, - 45.33 - ], - [ - -75.712, - 45.336 - ], - [ - -75.721, - 45.339 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.606, - 45.445 - ], - [ - -75.615, - 45.442 - ], - [ - -75.618, - 45.436 - ], - [ - -75.615, - 45.43 - ], - [ - -75.606, - 45.427 - ], - [ - -75.596, - 45.43 - ], - [ - -75.593, - 45.436 - ], - [ - -75.596, - 45.442 - ], - [ - -75.606, - 45.445 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.643, - 45.363 - ], - [ - -75.652, - 45.361 - ], - [ - -75.656, - 45.354 - ], - [ - -75.652, - 45.348 - ], - [ - -75.643, - 45.345 - ], - [ - -75.634, - 45.348 - ], - [ - -75.63, - 45.354 - ], - [ - -75.634, - 45.361 - ], - [ - -75.643, - 45.363 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.696, - 45.42 - ], - [ - -75.705, - 45.418 - ], - [ - -75.708, - 45.411 - ], - [ - -75.705, - 45.405 - ], - [ - -75.696, - 45.403 - ], - [ - -75.686, - 45.405 - ], - [ - -75.683, - 45.411 - ], - [ - -75.686, - 45.418 - ], - [ - -75.696, - 45.42 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.73, - 45.414 - ], - [ - -75.739, - 45.412 - ], - [ - -75.743, - 45.405 - ], - [ - -75.739, - 45.399 - ], - [ - -75.73, - 45.396 - ], - [ - -75.721, - 45.399 - ], - [ - -75.717, - 45.405 - ], - [ - -75.721, - 45.412 - ], - [ - -75.73, - 45.414 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.753, - 45.402 - ], - [ - -75.762, - 45.399 - ], - [ - -75.766, - 45.393 - ], - [ - -75.762, - 45.386 - ], - [ - -75.753, - 45.384 - ], - [ - -75.744, - 45.386 - ], - [ - -75.74, - 45.393 - ], - [ - -75.744, - 45.399 - ], - [ - -75.753, - 45.402 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.629, - 45.455 - ], - [ - -75.638, - 45.453 - ], - [ - -75.642, - 45.446 - ], - [ - -75.638, - 45.44 - ], - [ - -75.629, - 45.437 - ], - [ - -75.62, - 45.44 - ], - [ - -75.616, - 45.446 - ], - [ - -75.62, - 45.453 - ], - [ - -75.629, - 45.455 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.639, - 45.437 - ], - [ - -75.648, - 45.435 - ], - [ - -75.652, - 45.428 - ], - [ - -75.648, - 45.422 - ], - [ - -75.639, - 45.419 - ], - [ - -75.63, - 45.422 - ], - [ - -75.626, - 45.428 - ], - [ - -75.63, - 45.435 - ], - [ - -75.639, - 45.437 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.754, - 45.386 - ], - [ - -75.763, - 45.384 - ], - [ - -75.767, - 45.377 - ], - [ - -75.763, - 45.371 - ], - [ - -75.754, - 45.368 - ], - [ - -75.745, - 45.371 - ], - [ - -75.741, - 45.377 - ], - [ - -75.745, - 45.384 - ], - [ - -75.754, - 45.386 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.719, - 45.346 - ], - [ - -75.728, - 45.344 - ], - [ - -75.732, - 45.337 - ], - [ - -75.728, - 45.331 - ], - [ - -75.719, - 45.328 - ], - [ - -75.71, - 45.331 - ], - [ - -75.706, - 45.337 - ], - [ - -75.71, - 45.344 - ], - [ - -75.719, - 45.346 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.637, - 45.434 - ], - [ - -75.646, - 45.432 - ], - [ - -75.65, - 45.425 - ], - [ - -75.646, - 45.419 - ], - [ - -75.637, - 45.416 - ], - [ - -75.628, - 45.419 - ], - [ - -75.625, - 45.425 - ], - [ - -75.628, - 45.432 - ], - [ - -75.637, - 45.434 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.691, - 45.351 - ], - [ - -75.7, - 45.349 - ], - [ - -75.703, - 45.342 - ], - [ - -75.7, - 45.336 - ], - [ - -75.691, - 45.333 - ], - [ - -75.682, - 45.336 - ], - [ - -75.678, - 45.342 - ], - [ - -75.682, - 45.349 - ], - [ - -75.691, - 45.351 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.702, - 45.378 - ], - [ - -75.711, - 45.375 - ], - [ - -75.714, - 45.369 - ], - [ - -75.711, - 45.362 - ], - [ - -75.702, - 45.36 - ], - [ - -75.692, - 45.362 - ], - [ - -75.689, - 45.369 - ], - [ - -75.692, - 45.375 - ], - [ - -75.702, - 45.378 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.719, - 45.346 - ], - [ - -75.728, - 45.344 - ], - [ - -75.732, - 45.337 - ], - [ - -75.728, - 45.331 - ], - [ - -75.719, - 45.328 - ], - [ - -75.71, - 45.331 - ], - [ - -75.706, - 45.337 - ], - [ - -75.71, - 45.344 - ], - [ - -75.719, - 45.346 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.72, - 45.336 - ], - [ - -75.729, - 45.333 - ], - [ - -75.733, - 45.327 - ], - [ - -75.729, - 45.321 - ], - [ - -75.72, - 45.318 - ], - [ - -75.711, - 45.321 - ], - [ - -75.707, - 45.327 - ], - [ - -75.711, - 45.333 - ], - [ - -75.72, - 45.336 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.72, - 45.336 - ], - [ - -75.729, - 45.333 - ], - [ - -75.733, - 45.327 - ], - [ - -75.729, - 45.321 - ], - [ - -75.72, - 45.318 - ], - [ - -75.711, - 45.321 - ], - [ - -75.707, - 45.327 - ], - [ - -75.711, - 45.333 - ], - [ - -75.72, - 45.336 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.72, - 45.336 - ], - [ - -75.729, - 45.333 - ], - [ - -75.733, - 45.327 - ], - [ - -75.729, - 45.321 - ], - [ - -75.72, - 45.318 - ], - [ - -75.711, - 45.321 - ], - [ - -75.707, - 45.327 - ], - [ - -75.711, - 45.333 - ], - [ - -75.72, - 45.336 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.72, - 45.336 - ], - [ - -75.729, - 45.333 - ], - [ - -75.733, - 45.327 - ], - [ - -75.729, - 45.321 - ], - [ - -75.72, - 45.318 - ], - [ - -75.711, - 45.321 - ], - [ - -75.707, - 45.327 - ], - [ - -75.711, - 45.333 - ], - [ - -75.72, - 45.336 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.625, - 45.357 - ], - [ - -75.634, - 45.354 - ], - [ - -75.638, - 45.348 - ], - [ - -75.634, - 45.342 - ], - [ - -75.625, - 45.339 - ], - [ - -75.616, - 45.342 - ], - [ - -75.612, - 45.348 - ], - [ - -75.616, - 45.354 - ], - [ - -75.625, - 45.357 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.597, - 45.384 - ], - [ - -75.606, - 45.381 - ], - [ - -75.61, - 45.375 - ], - [ - -75.606, - 45.368 - ], - [ - -75.597, - 45.366 - ], - [ - -75.588, - 45.368 - ], - [ - -75.584, - 45.375 - ], - [ - -75.588, - 45.381 - ], - [ - -75.597, - 45.384 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.67, - 45.442 - ], - [ - -75.679, - 45.44 - ], - [ - -75.682, - 45.433 - ], - [ - -75.679, - 45.427 - ], - [ - -75.67, - 45.424 - ], - [ - -75.661, - 45.427 - ], - [ - -75.657, - 45.433 - ], - [ - -75.661, - 45.44 - ], - [ - -75.67, - 45.442 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.612, - 45.422 - ], - [ - -75.621, - 45.419 - ], - [ - -75.624, - 45.413 - ], - [ - -75.621, - 45.406 - ], - [ - -75.612, - 45.404 - ], - [ - -75.603, - 45.406 - ], - [ - -75.599, - 45.413 - ], - [ - -75.603, - 45.419 - ], - [ - -75.612, - 45.422 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.643, - 45.363 - ], - [ - -75.652, - 45.36 - ], - [ - -75.656, - 45.354 - ], - [ - -75.652, - 45.347 - ], - [ - -75.643, - 45.345 - ], - [ - -75.634, - 45.347 - ], - [ - -75.631, - 45.354 - ], - [ - -75.634, - 45.36 - ], - [ - -75.643, - 45.363 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.643, - 45.363 - ], - [ - -75.652, - 45.36 - ], - [ - -75.656, - 45.354 - ], - [ - -75.652, - 45.347 - ], - [ - -75.643, - 45.345 - ], - [ - -75.634, - 45.347 - ], - [ - -75.631, - 45.354 - ], - [ - -75.634, - 45.36 - ], - [ - -75.643, - 45.363 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.719, - 45.346 - ], - [ - -75.728, - 45.344 - ], - [ - -75.732, - 45.337 - ], - [ - -75.728, - 45.331 - ], - [ - -75.719, - 45.328 - ], - [ - -75.71, - 45.331 - ], - [ - -75.706, - 45.337 - ], - [ - -75.71, - 45.344 - ], - [ - -75.719, - 45.346 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.719, - 45.346 - ], - [ - -75.728, - 45.344 - ], - [ - -75.732, - 45.337 - ], - [ - -75.728, - 45.331 - ], - [ - -75.719, - 45.328 - ], - [ - -75.71, - 45.331 - ], - [ - -75.706, - 45.337 - ], - [ - -75.71, - 45.344 - ], - [ - -75.719, - 45.346 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.627, - 45.414 - ], - [ - -75.636, - 45.412 - ], - [ - -75.64, - 45.405 - ], - [ - -75.636, - 45.399 - ], - [ - -75.627, - 45.396 - ], - [ - -75.618, - 45.399 - ], - [ - -75.615, - 45.405 - ], - [ - -75.618, - 45.412 - ], - [ - -75.627, - 45.414 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.73, - 45.407 - ], - [ - -75.74, - 45.404 - ], - [ - -75.743, - 45.398 - ], - [ - -75.739, - 45.391 - ], - [ - -75.73, - 45.389 - ], - [ - -75.721, - 45.391 - ], - [ - -75.718, - 45.398 - ], - [ - -75.721, - 45.404 - ], - [ - -75.73, - 45.407 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.64, - 45.389 - ], - [ - -75.649, - 45.387 - ], - [ - -75.652, - 45.38 - ], - [ - -75.649, - 45.374 - ], - [ - -75.64, - 45.371 - ], - [ - -75.631, - 45.374 - ], - [ - -75.627, - 45.38 - ], - [ - -75.631, - 45.387 - ], - [ - -75.64, - 45.389 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.705, - 45.362 - ], - [ - -75.714, - 45.359 - ], - [ - -75.717, - 45.353 - ], - [ - -75.714, - 45.347 - ], - [ - -75.705, - 45.344 - ], - [ - -75.696, - 45.347 - ], - [ - -75.692, - 45.353 - ], - [ - -75.696, - 45.359 - ], - [ - -75.705, - 45.362 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.642, - 45.363 - ], - [ - -75.651, - 45.36 - ], - [ - -75.655, - 45.354 - ], - [ - -75.651, - 45.347 - ], - [ - -75.642, - 45.345 - ], - [ - -75.633, - 45.347 - ], - [ - -75.629, - 45.354 - ], - [ - -75.633, - 45.36 - ], - [ - -75.642, - 45.363 - ] - ] - ] - } - } - ] -} \ No newline at end of file diff --git a/packages/turf-dissolve/test/out/hexagons-issue#742.geojson b/packages/turf-dissolve/test/out/hexagons-issue#742.geojson deleted file mode 100644 index bf2c0be393..0000000000 --- a/packages/turf-dissolve/test/out/hexagons-issue#742.geojson +++ /dev/null @@ -1,11646 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.537, - 45.488 - ], - [ - -75.528, - 45.486 - ], - [ - -75.525, - 45.479 - ], - [ - -75.528, - 45.473 - ], - [ - -75.537, - 45.47 - ], - [ - -75.547, - 45.473 - ], - [ - -75.55, - 45.479 - ], - [ - -75.547, - 45.486 - ], - [ - -75.537, - 45.488 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.687, - 45.484 - ], - [ - -76.678, - 45.481 - ], - [ - -76.67446153846154, - 45.475692307692306 - ], - [ - -76.672, - 45.48 - ], - [ - -76.66599999999998, - 45.48133333333334 - ], - [ - -76.66400000000002, - 45.48199999999999 - ], - [ - -76.662, - 45.485 - ], - [ - -76.653, - 45.488 - ], - [ - -76.644, - 45.485 - ], - [ - -76.64, - 45.479 - ], - [ - -76.644, - 45.473 - ], - [ - -76.64964705882352, - 45.471117647058826 - ], - [ - -76.652, - 45.467 - ], - [ - -76.65799999999996, - 45.46566666666668 - ], - [ - -76.6606, - 45.4648 - ], - [ - -76.659, - 45.462 - ], - [ - -76.663, - 45.456 - ], - [ - -76.672, - 45.454 - ], - [ - -76.681, - 45.456 - ], - [ - -76.685, - 45.462 - ], - [ - -76.6820909090909, - 45.46709090909091 - ], - [ - -76.687, - 45.466 - ], - [ - -76.696, - 45.468 - ], - [ - -76.7, - 45.475 - ], - [ - -76.696, - 45.481 - ], - [ - -76.687, - 45.484 - ] - ], - [ - [ - -76.67553846153847, - 45.472307692307695 - ], - [ - -76.67690909090909, - 45.46990909090909 - ], - [ - -76.67432258064517, - 45.47048387096774 - ], - [ - -76.67553846153847, - 45.472307692307695 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.6921724137931, - 45.48655172413793 - ], - [ - -76.687, - 45.485 - ], - [ - -76.6862, - 45.4834 - ], - [ - -76.679, - 45.481 - ], - [ - -76.67671428571428, - 45.47757142857143 - ], - [ - -76.672, - 45.476 - ], - [ - -76.668, - 45.47 - ], - [ - -76.672, - 45.463 - ], - [ - -76.681, - 45.461 - ], - [ - -76.69, - 45.463 - ], - [ - -76.69163157894737, - 45.466807017543864 - ], - [ - -76.697, - 45.468 - ], - [ - -76.69830909090909, - 45.470290909090906 - ], - [ - -76.706, - 45.472 - ], - [ - -76.7068947368421, - 45.47408771929825 - ], - [ - -76.711, - 45.475 - ], - [ - -76.715, - 45.481 - ], - [ - -76.711, - 45.488 - ], - [ - -76.702, - 45.49 - ], - [ - -76.693, - 45.488 - ], - [ - -76.6921724137931, - 45.48655172413793 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.66624, - 45.442919999999994 - ], - [ - -75.666, - 45.443 - ], - [ - -75.657, - 45.44 - ], - [ - -75.653, - 45.434 - ], - [ - -75.657, - 45.428 - ], - [ - -75.65880000000001, - 45.42739999999999 - ], - [ - -75.659, - 45.427 - ], - [ - -75.668, - 45.424 - ], - [ - -75.66900000000001, - 45.42433333333333 - ], - [ - -75.67, - 45.424 - ], - [ - -75.6722, - 45.42473333333333 - ], - [ - -75.6751052631579, - 45.42408771929824 - ], - [ - -75.676, - 45.422 - ], - [ - -75.685, - 45.42 - ], - [ - -75.68516363636364, - 45.42003636363636 - ], - [ - -75.684, - 45.418 - ], - [ - -75.688, - 45.412 - ], - [ - -75.697, - 45.409 - ], - [ - -75.706, - 45.412 - ], - [ - -75.71, - 45.418 - ], - [ - -75.706, - 45.425 - ], - [ - -75.697, - 45.427 - ], - [ - -75.69683636363636, - 45.42696363636363 - ], - [ - -75.698, - 45.429 - ], - [ - -75.694, - 45.435 - ], - [ - -75.68979999999999, - 45.436400000000006 - ], - [ - -75.689, - 45.438 - ], - [ - -75.68857142857142, - 45.43814285714286 - ], - [ - -75.689, - 45.439 - ], - [ - -75.686, - 45.446 - ], - [ - -75.677, - 45.448 - ], - [ - -75.668, - 45.446 - ], - [ - -75.66624, - 45.442919999999994 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.6195, - 45.35516666666667 - ], - [ - -75.616, - 45.354 - ], - [ - -75.612, - 45.348 - ], - [ - -75.616, - 45.342 - ], - [ - -75.625, - 45.339 - ], - [ - -75.634, - 45.342 - ], - [ - -75.638, - 45.348 - ], - [ - -75.634, - 45.354 - ], - [ - -75.6255, - 45.356833333333334 - ], - [ - -75.629, - 45.358 - ], - [ - -75.633, - 45.364 - ], - [ - -75.629, - 45.371 - ], - [ - -75.62, - 45.373 - ], - [ - -75.611, - 45.371 - ], - [ - -75.607, - 45.364 - ], - [ - -75.611, - 45.358 - ], - [ - -75.6195, - 45.35516666666667 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.365, - 45.435 - ], - [ - -76.35829411764706, - 45.432764705882356 - ], - [ - -76.359, - 45.434 - ], - [ - -76.355, - 45.44 - ], - [ - -76.346, - 45.443 - ], - [ - -76.337, - 45.44 - ], - [ - -76.334, - 45.434 - ], - [ - -76.337, - 45.427 - ], - [ - -76.346, - 45.425 - ], - [ - -76.35331249999999, - 45.426624999999994 - ], - [ - -76.353, - 45.426 - ], - [ - -76.356, - 45.42 - ], - [ - -76.35857142857142, - 45.41914285714286 - ], - [ - -76.36, - 45.417 - ], - [ - -76.36471428571427, - 45.41542857142858 - ], - [ - -76.367, - 45.412 - ], - [ - -76.376, - 45.409 - ], - [ - -76.381, - 45.410666666666664 - ], - [ - -76.387, - 45.412 - ], - [ - -76.39, - 45.419 - ], - [ - -76.387, - 45.425 - ], - [ - -76.37971428571429, - 45.427428571428564 - ], - [ - -76.378, - 45.43 - ], - [ - -76.37457142857143, - 45.43114285714286 - ], - [ - -76.374, - 45.432 - ], - [ - -76.365, - 45.435 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.9088, - 45.3156 - ], - [ - -75.907, - 45.315 - ], - [ - -75.903, - 45.308 - ], - [ - -75.90442857142858, - 45.30585714285714 - ], - [ - -75.901, - 45.307 - ], - [ - -75.89399999999996, - 45.304666666666655 - ], - [ - -75.891, - 45.304 - ], - [ - -75.887, - 45.297 - ], - [ - -75.891, - 45.291 - ], - [ - -75.9, - 45.288 - ], - [ - -75.90700000000004, - 45.29033333333334 - ], - [ - -75.91, - 45.291 - ], - [ - -75.914, - 45.298 - ], - [ - -75.91257142857144, - 45.30014285714285 - ], - [ - -75.916, - 45.299 - ], - [ - -75.91829411764705, - 45.29976470588235 - ], - [ - -75.915, - 45.294 - ], - [ - -75.919, - 45.288 - ], - [ - -75.928, - 45.285 - ], - [ - -75.937, - 45.288 - ], - [ - -75.941, - 45.294 - ], - [ - -75.937, - 45.301 - ], - [ - -75.928, - 45.303 - ], - [ - -75.92521818181818, - 45.302381818181814 - ], - [ - -75.92594117647059, - 45.30364705882353 - ], - [ - -75.927, - 45.304 - ], - [ - -75.931, - 45.31 - ], - [ - -75.927, - 45.316 - ], - [ - -75.918, - 45.319 - ], - [ - -75.909, - 45.316 - ], - [ - -75.9088, - 45.3156 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.87000000000005, - 45.31300000000008 - ], - [ - -75.868, - 45.31 - ], - [ - -75.8685, - 45.30925 - ], - [ - -75.865, - 45.304 - ], - [ - -75.869, - 45.297 - ], - [ - -75.8695625, - 45.29687499999999 - ], - [ - -75.87, - 45.296 - ], - [ - -75.87958333333333, - 45.293124999999996 - ], - [ - -75.881, - 45.291 - ], - [ - -75.89, - 45.288 - ], - [ - -75.899, - 45.291 - ], - [ - -75.903, - 45.297 - ], - [ - -75.899, - 45.303 - ], - [ - -75.89085714285714, - 45.30571428571428 - ], - [ - -75.8914, - 45.3068 - ], - [ - -75.892, - 45.307 - ], - [ - -75.895, - 45.313 - ], - [ - -75.892, - 45.32 - ], - [ - -75.883, - 45.322 - ], - [ - -75.874, - 45.32 - ], - [ - -75.87000000000005, - 45.31300000000008 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.87, - 45.3 - ], - [ - -75.861, - 45.297 - ], - [ - -75.85800000000002, - 45.29100000000004 - ], - [ - -75.856, - 45.288 - ], - [ - -75.86, - 45.282 - ], - [ - -75.869, - 45.279 - ], - [ - -75.878, - 45.282 - ], - [ - -75.882, - 45.288 - ], - [ - -75.88161538461539, - 45.288576923076924 - ], - [ - -75.883, - 45.291 - ], - [ - -75.879, - 45.297 - ], - [ - -75.87, - 45.3 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.637, - 45.039 - ], - [ - -75.628, - 45.036 - ], - [ - -75.625, - 45.03 - ], - [ - -75.628, - 45.023 - ], - [ - -75.63078181818182, - 45.02238181818182 - ], - [ - -75.631, - 45.022 - ], - [ - -75.63825806451614, - 45.02038709677419 - ], - [ - -75.638, - 45.02 - ], - [ - -75.642, - 45.013 - ], - [ - -75.651, - 45.011 - ], - [ - -75.66, - 45.013 - ], - [ - -75.66094117647059, - 45.01464705882353 - ], - [ - -75.662, - 45.015 - ], - [ - -75.666, - 45.021 - ], - [ - -75.662, - 45.027 - ], - [ - -75.65857142857143, - 45.02814285714286 - ], - [ - -75.658, - 45.029 - ], - [ - -75.65157142857144, - 45.031142857142854 - ], - [ - -75.649, - 45.035 - ], - [ - -75.646, - 45.035999999999994 - ], - [ - -75.646, - 45.036 - ], - [ - -75.637, - 45.039 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.71815384615384, - 45.39830769230769 - ], - [ - -75.718, - 45.398 - ], - [ - -75.721, - 45.391 - ], - [ - -75.72925000000001, - 45.38916666666667 - ], - [ - -75.724, - 45.388 - ], - [ - -75.721, - 45.381 - ], - [ - -75.724, - 45.375 - ], - [ - -75.733, - 45.372 - ], - [ - -75.73895744680851, - 45.37378723404255 - ], - [ - -75.747, - 45.372 - ], - [ - -75.756, - 45.374 - ], - [ - -75.76, - 45.381 - ], - [ - -75.75735483870967, - 45.38496774193548 - ], - [ - -75.762, - 45.386 - ], - [ - -75.766, - 45.393 - ], - [ - -75.762, - 45.399 - ], - [ - -75.75370588235293, - 45.40176470588236 - ], - [ - -75.753, - 45.403 - ], - [ - -75.75136363636365, - 45.403363636363636 - ], - [ - -75.751, - 45.404 - ], - [ - -75.7424909090909, - 45.40589090909091 - ], - [ - -75.739, - 45.412 - ], - [ - -75.73, - 45.414 - ], - [ - -75.721, - 45.412 - ], - [ - -75.717, - 45.405 - ], - [ - -75.71814285714285, - 45.403285714285715 - ], - [ - -75.717, - 45.401 - ], - [ - -75.71815384615384, - 45.39830769230769 - ] - ], - [ - [ - -75.73378947368423, - 45.389842105263156 - ], - [ - -75.73493548387097, - 45.390096774193545 - ], - [ - -75.735, - 45.39 - ], - [ - -75.73799999999999, - 45.38933333333334 - ], - [ - -75.74033333333334, - 45.388555555555556 - ], - [ - -75.74034375000001, - 45.38853125 - ], - [ - -75.73378947368423, - 45.389842105263156 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.6, - 45.34 - ], - [ - -75.591, - 45.338 - ], - [ - -75.587, - 45.331 - ], - [ - -75.583, - 45.325 - ], - [ - -75.58361538461538, - 45.32392307692308 - ], - [ - -75.581, - 45.32 - ], - [ - -75.585, - 45.313 - ], - [ - -75.594, - 45.311 - ], - [ - -75.603, - 45.313 - ], - [ - -75.60505263157894, - 45.31778947368421 - ], - [ - -75.606, - 45.318 - ], - [ - -75.61, - 45.325 - ], - [ - -75.60942857142857, - 45.325857142857146 - ], - [ - -75.612, - 45.331 - ], - [ - -75.609, - 45.338 - ], - [ - -75.6, - 45.34 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.706, - 45.42 - ], - [ - -75.702, - 45.41866666666667 - ], - [ - -75.699, - 45.419333333333334 - ], - [ - -75.694, - 45.421 - ], - [ - -75.685, - 45.418 - ], - [ - -75.68385714285714, - 45.416285714285706 - ], - [ - -75.683, - 45.416 - ], - [ - -75.68100000000004, - 45.41200000000006 - ], - [ - -75.681, - 45.412 - ], - [ - -75.681, - 45.41199999999999 - ], - [ - -75.68, - 45.41 - ], - [ - -75.683, - 45.403 - ], - [ - -75.68938181818181, - 45.40158181818182 - ], - [ - -75.692, - 45.397 - ], - [ - -75.69674545454545, - 45.395945454545455 - ], - [ - -75.699, - 45.392 - ], - [ - -75.708, - 45.39 - ], - [ - -75.717, - 45.392 - ], - [ - -75.721, - 45.399 - ], - [ - -75.717, - 45.405 - ], - [ - -75.7159090909091, - 45.40536363636364 - ], - [ - -75.717, - 45.407 - ], - [ - -75.7166923076923, - 45.407538461538465 - ], - [ - -75.719, - 45.411 - ], - [ - -75.715, - 45.417 - ], - [ - -75.706, - 45.42 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.68227272727272, - 45.33590909090909 - ], - [ - -75.681, - 45.334 - ], - [ - -75.685, - 45.327 - ], - [ - -75.694, - 45.325 - ], - [ - -75.703, - 45.327 - ], - [ - -75.707, - 45.334 - ], - [ - -75.70663636363636, - 45.33454545454545 - ], - [ - -75.70745454545455, - 45.33481818181818 - ], - [ - -75.71, - 45.331 - ], - [ - -75.7147142857143, - 45.32942857142857 - ], - [ - -75.715, - 45.329 - ], - [ - -75.724, - 45.326 - ], - [ - -75.733, - 45.329 - ], - [ - -75.736, - 45.335 - ], - [ - -75.735625, - 45.335875 - ], - [ - -75.739, - 45.337 - ], - [ - -75.742, - 45.343 - ], - [ - -75.739, - 45.35 - ], - [ - -75.73, - 45.352 - ], - [ - -75.721, - 45.35 - ], - [ - -75.71867272727272, - 45.34592727272727 - ], - [ - -75.71342253521127, - 45.344760563380284 - ], - [ - -75.71244, - 45.34648 - ], - [ - -75.714, - 45.347 - ], - [ - -75.717, - 45.353 - ], - [ - -75.714, - 45.36 - ], - [ - -75.708, - 45.361333333333334 - ], - [ - -75.711, - 45.362 - ], - [ - -75.71166666666667, - 45.36355555555556 - ], - [ - -75.713, - 45.364 - ], - [ - -75.717, - 45.37 - ], - [ - -75.713, - 45.377 - ], - [ - -75.704, - 45.379 - ], - [ - -75.695, - 45.377 - ], - [ - -75.69424137931034, - 45.375672413793104 - ], - [ - -75.692, - 45.375 - ], - [ - -75.689, - 45.369 - ], - [ - -75.692, - 45.362 - ], - [ - -75.69884210526315, - 45.36063157894737 - ], - [ - -75.696, - 45.36 - ], - [ - -75.692, - 45.353 - ], - [ - -75.69373913043478, - 45.35039130434782 - ], - [ - -75.691, - 45.351 - ], - [ - -75.682, - 45.349 - ], - [ - -75.6806153846154, - 45.346576923076924 - ], - [ - -75.68033333333334, - 45.347 - ], - [ - -75.683, - 45.351 - ], - [ - -75.679, - 45.357 - ], - [ - -75.67, - 45.36 - ], - [ - -75.661, - 45.357 - ], - [ - -75.659, - 45.354000000000006 - ], - [ - -75.655, - 45.36 - ], - [ - -75.646, - 45.363 - ], - [ - -75.6448, - 45.3626 - ], - [ - -75.643, - 45.363 - ], - [ - -75.64273913043479, - 45.36294202898551 - ], - [ - -75.641, - 45.367 - ], - [ - -75.631, - 45.369 - ], - [ - -75.622, - 45.367 - ], - [ - -75.619, - 45.36 - ], - [ - -75.62114285714286, - 45.355714285714285 - ], - [ - -75.616, - 45.354 - ], - [ - -75.612, - 45.348 - ], - [ - -75.616, - 45.342 - ], - [ - -75.625, - 45.339 - ], - [ - -75.634, - 45.342 - ], - [ - -75.63677419354839, - 45.34616129032258 - ], - [ - -75.642, - 45.345 - ], - [ - -75.6425, - 45.34511111111111 - ], - [ - -75.643, - 45.345 - ], - [ - -75.6448, - 45.3454 - ], - [ - -75.646, - 45.345 - ], - [ - -75.655, - 45.348 - ], - [ - -75.657, - 45.35099999999999 - ], - [ - -75.65966666666667, - 45.347 - ], - [ - -75.657, - 45.343 - ], - [ - -75.661, - 45.337 - ], - [ - -75.67, - 45.334 - ], - [ - -75.679, - 45.337 - ], - [ - -75.68016666666666, - 45.33875 - ], - [ - -75.682, - 45.336 - ], - [ - -75.68227272727272, - 45.33590909090909 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.618, - 45.398 - ], - [ - -75.609, - 45.395 - ], - [ - -75.606, - 45.389 - ], - [ - -75.609, - 45.383 - ], - [ - -75.618, - 45.38 - ], - [ - -75.627, - 45.383 - ], - [ - -75.631, - 45.389 - ], - [ - -75.627, - 45.395 - ], - [ - -75.618, - 45.398 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.63419999999999, - 45.43593333333333 - ], - [ - -75.63, - 45.435 - ], - [ - -75.62976470588235, - 45.43458823529412 - ], - [ - -75.629, - 45.434333333333335 - ], - [ - -75.623, - 45.433 - ], - [ - -75.62252941176472, - 45.43217647058824 - ], - [ - -75.622, - 45.432 - ], - [ - -75.61974193548387, - 45.428612903225805 - ], - [ - -75.618, - 45.429 - ], - [ - -75.609, - 45.427 - ], - [ - -75.605, - 45.42 - ], - [ - -75.609, - 45.414 - ], - [ - -75.61757142857144, - 45.411142857142856 - ], - [ - -75.621, - 45.406 - ], - [ - -75.63, - 45.403 - ], - [ - -75.634, - 45.404333333333334 - ], - [ - -75.641, - 45.402 - ], - [ - -75.65, - 45.405 - ], - [ - -75.654, - 45.411 - ], - [ - -75.65, - 45.417 - ], - [ - -75.64500000000001, - 45.41866666666667 - ], - [ - -75.646, - 45.419 - ], - [ - -75.64683870967743, - 45.420258064516126 - ], - [ - -75.648, - 45.42 - ], - [ - -75.657, - 45.422 - ], - [ - -75.661, - 45.429 - ], - [ - -75.66, - 45.4305 - ], - [ - -75.661, - 45.432 - ], - [ - -75.66081818181819, - 45.43227272727273 - ], - [ - -75.663, - 45.433 - ], - [ - -75.667, - 45.439 - ], - [ - -75.663, - 45.445 - ], - [ - -75.66183333333333, - 45.445388888888886 - ], - [ - -75.659, - 45.452 - ], - [ - -75.65, - 45.454 - ], - [ - -75.641, - 45.452 - ], - [ - -75.64084, - 45.451719999999995 - ], - [ - -75.64, - 45.452 - ], - [ - -75.6388, - 45.4516 - ], - [ - -75.638, - 45.453 - ], - [ - -75.629, - 45.455 - ], - [ - -75.62, - 45.453 - ], - [ - -75.616, - 45.446 - ], - [ - -75.62, - 45.44 - ], - [ - -75.629, - 45.437 - ], - [ - -75.63071428571429, - 45.437571428571424 - ], - [ - -75.631, - 45.437 - ], - [ - -75.63419999999999, - 45.43593333333333 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.75475, - 45.3675 - ], - [ - -75.757, - 45.367 - ], - [ - -75.76067605633803, - 45.367816901408446 - ], - [ - -75.764, - 45.362 - ], - [ - -75.773, - 45.36 - ], - [ - -75.782, - 45.362 - ], - [ - -75.786, - 45.369 - ], - [ - -75.782, - 45.375 - ], - [ - -75.773, - 45.378 - ], - [ - -75.76952, - 45.37684 - ], - [ - -75.766, - 45.383 - ], - [ - -75.76321818181819, - 45.383618181818186 - ], - [ - -75.763, - 45.384 - ], - [ - -75.754, - 45.386 - ], - [ - -75.745, - 45.384 - ], - [ - -75.74429411764706, - 45.38276470588235 - ], - [ - -75.739, - 45.381 - ], - [ - -75.735, - 45.375 - ], - [ - -75.739, - 45.368 - ], - [ - -75.748, - 45.366 - ], - [ - -75.75475, - 45.3675 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.588, - 45.458 - ], - [ - -75.579, - 45.456 - ], - [ - -75.575, - 45.449 - ], - [ - -75.579, - 45.443 - ], - [ - -75.588, - 45.44 - ], - [ - -75.5886, - 45.4402 - ], - [ - -75.59374647887324, - 45.439056338028166 - ], - [ - -75.592, - 45.436 - ], - [ - -75.596, - 45.43 - ], - [ - -75.605, - 45.427 - ], - [ - -75.60547368421052, - 45.42715789473684 - ], - [ - -75.606, - 45.427 - ], - [ - -75.615, - 45.43 - ], - [ - -75.618, - 45.436 - ], - [ - -75.615, - 45.442 - ], - [ - -75.61433333333333, - 45.44222222222222 - ], - [ - -75.614, - 45.443 - ], - [ - -75.60799999999996, - 45.44433333333334 - ], - [ - -75.60624, - 45.444919999999996 - ], - [ - -75.608, - 45.448 - ], - [ - -75.604, - 45.454 - ], - [ - -75.595, - 45.457 - ], - [ - -75.5945, - 45.456833333333336 - ], - [ - -75.594, - 45.457 - ], - [ - -75.5934, - 45.4568 - ], - [ - -75.588, - 45.458 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.602, - 45.392 - ], - [ - -75.593, - 45.389 - ], - [ - -75.589, - 45.383 - ], - [ - -75.58990909090909, - 45.38163636363637 - ], - [ - -75.588, - 45.381 - ], - [ - -75.584, - 45.375 - ], - [ - -75.588, - 45.368 - ], - [ - -75.597, - 45.366 - ], - [ - -75.606, - 45.368 - ], - [ - -75.61, - 45.375 - ], - [ - -75.60909090909091, - 45.376363636363635 - ], - [ - -75.611, - 45.377 - ], - [ - -75.615, - 45.383 - ], - [ - -75.611, - 45.389 - ], - [ - -75.602, - 45.392 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.28999999999999, - 45.538000000000004 - ], - [ - -75.292, - 45.535 - ], - [ - -75.301, - 45.532 - ], - [ - -75.31, - 45.535 - ], - [ - -75.314, - 45.541 - ], - [ - -75.3133846153846, - 45.54207692307691 - ], - [ - -75.316, - 45.546 - ], - [ - -75.312, - 45.553 - ], - [ - -75.30663157894737, - 45.55419298245614 - ], - [ - -75.305, - 45.558 - ], - [ - -75.296, - 45.56 - ], - [ - -75.286, - 45.558 - ], - [ - -75.283, - 45.551 - ], - [ - -75.2846, - 45.5478 - ], - [ - -75.283, - 45.545 - ], - [ - -75.287, - 45.539 - ], - [ - -75.28999999999999, - 45.538000000000004 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.00870588235294, - 44.911235294117645 - ], - [ - -76.002, - 44.909 - ], - [ - -75.999, - 44.903 - ], - [ - -76.002, - 44.896 - ], - [ - -76.0104193548387, - 44.894129032258064 - ], - [ - -76.007, - 44.889 - ], - [ - -76.011, - 44.882 - ], - [ - -76.02, - 44.88 - ], - [ - -76.02780000000001, - 44.88173333333334 - ], - [ - -76.033, - 44.88 - ], - [ - -76.042, - 44.883 - ], - [ - -76.046, - 44.889 - ], - [ - -76.042, - 44.895 - ], - [ - -76.04028571428572, - 44.89557142857144 - ], - [ - -76.038, - 44.899 - ], - [ - -76.041, - 44.9 - ], - [ - -76.045, - 44.906 - ], - [ - -76.041, - 44.913 - ], - [ - -76.032, - 44.915 - ], - [ - -76.03123943661971, - 44.91483098591549 - ], - [ - -76.03, - 44.917 - ], - [ - -76.021, - 44.919 - ], - [ - -76.012, - 44.917 - ], - [ - -76.00870588235294, - 44.911235294117645 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.246, - 44.908 - ], - [ - -76.24571428571427, - 44.90757142857142 - ], - [ - -76.244, - 44.907 - ], - [ - -76.24, - 44.901 - ], - [ - -76.24012903225805, - 44.90080645161291 - ], - [ - -76.232, - 44.899 - ], - [ - -76.228, - 44.892 - ], - [ - -76.232, - 44.886 - ], - [ - -76.241, - 44.883 - ], - [ - -76.25, - 44.886 - ], - [ - -76.253, - 44.892 - ], - [ - -76.258, - 44.89366666666667 - ], - [ - -76.264, - 44.895 - ], - [ - -76.267, - 44.902 - ], - [ - -76.2667, - 44.9026 - ], - [ - -76.273, - 44.904 - ], - [ - -76.277, - 44.911 - ], - [ - -76.273, - 44.917 - ], - [ - -76.264, - 44.92 - ], - [ - -76.255, - 44.917 - ], - [ - -76.251, - 44.911 - ], - [ - -76.25164000000001, - 44.90988000000001 - ], - [ - -76.246, - 44.908 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.564, - 45.441 - ], - [ - -75.555, - 45.438 - ], - [ - -75.551, - 45.432 - ], - [ - -75.555, - 45.425 - ], - [ - -75.564, - 45.423 - ], - [ - -75.573, - 45.425 - ], - [ - -75.577, - 45.432 - ], - [ - -75.573, - 45.438 - ], - [ - -75.564, - 45.441 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.65564285714285, - 45.379875000000006 - ], - [ - -75.654, - 45.377 - ], - [ - -75.65454545454546, - 45.37618181818182 - ], - [ - -75.654, - 45.376 - ], - [ - -75.65, - 45.37 - ], - [ - -75.654, - 45.364 - ], - [ - -75.663, - 45.361 - ], - [ - -75.672, - 45.364 - ], - [ - -75.676, - 45.37 - ], - [ - -75.67554838709677, - 45.37067741935484 - ], - [ - -75.677, - 45.371 - ], - [ - -75.67733333333334, - 45.37177777777778 - ], - [ - -75.678, - 45.372 - ], - [ - -75.682, - 45.378 - ], - [ - -75.68053846153846, - 45.38019230769231 - ], - [ - -75.68092727272727, - 45.380872727272724 - ], - [ - -75.686, - 45.382 - ], - [ - -75.69, - 45.389 - ], - [ - -75.686, - 45.395 - ], - [ - -75.677, - 45.398 - ], - [ - -75.668, - 45.395 - ], - [ - -75.664, - 45.389 - ], - [ - -75.66416000000001, - 45.38872 - ], - [ - -75.659, - 45.387 - ], - [ - -75.655, - 45.381 - ], - [ - -75.65564285714285, - 45.379875000000006 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.51211764705882, - 45.46829411764706 - ], - [ - -75.514, - 45.465 - ], - [ - -75.52268421052632, - 45.463070175438595 - ], - [ - -75.524, - 45.46 - ], - [ - -75.52947826086957, - 45.45878260869565 - ], - [ - -75.53, - 45.458 - ], - [ - -75.53066666666668, - 45.45777777777777 - ], - [ - -75.531, - 45.457 - ], - [ - -75.53699999999998, - 45.45566666666667 - ], - [ - -75.539, - 45.455 - ], - [ - -75.548, - 45.453 - ], - [ - -75.558, - 45.455 - ], - [ - -75.561, - 45.462 - ], - [ - -75.558, - 45.468 - ], - [ - -75.548, - 45.471 - ], - [ - -75.54252173913044, - 45.47221739130435 - ], - [ - -75.542, - 45.473 - ], - [ - -75.53342857142857, - 45.475857142857144 - ], - [ - -75.532, - 45.478 - ], - [ - -75.5272, - 45.479600000000005 - ], - [ - -75.526, - 45.482 - ], - [ - -75.52288524590165, - 45.482934426229505 - ], - [ - -75.522, - 45.485 - ], - [ - -75.513, - 45.487 - ], - [ - -75.503, - 45.485 - ], - [ - -75.5, - 45.478 - ], - [ - -75.503, - 45.472 - ], - [ - -75.50652941176472, - 45.47094117647059 - ], - [ - -75.507, - 45.47 - ], - [ - -75.51211764705882, - 45.46829411764706 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.62018181818182, - 45.38627272727273 - ], - [ - -75.618, - 45.383 - ], - [ - -75.6190909090909, - 45.38136363636364 - ], - [ - -75.615, - 45.38 - ], - [ - -75.611, - 45.374 - ], - [ - -75.615, - 45.368 - ], - [ - -75.624, - 45.365 - ], - [ - -75.633, - 45.368 - ], - [ - -75.6359090909091, - 45.37236363636364 - ], - [ - -75.64, - 45.371 - ], - [ - -75.649, - 45.374 - ], - [ - -75.652, - 45.38 - ], - [ - -75.649, - 45.387 - ], - [ - -75.64, - 45.389 - ], - [ - -75.63181818181818, - 45.39172727272727 - ], - [ - -75.634, - 45.395 - ], - [ - -75.63342857142857, - 45.396 - ], - [ - -75.634, - 45.397 - ], - [ - -75.63, - 45.403 - ], - [ - -75.621, - 45.406 - ], - [ - -75.612, - 45.403 - ], - [ - -75.608, - 45.397 - ], - [ - -75.60906122448979, - 45.395142857142865 - ], - [ - -75.609, - 45.395 - ], - [ - -75.612, - 45.389 - ], - [ - -75.62018181818182, - 45.38627272727273 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.91438709677419, - 45.35041935483871 - ], - [ - -75.908, - 45.349 - ], - [ - -75.90588235294118, - 45.34529411764706 - ], - [ - -75.902, - 45.344 - ], - [ - -75.899, - 45.338 - ], - [ - -75.902, - 45.331 - ], - [ - -75.911, - 45.329 - ], - [ - -75.92, - 45.331 - ], - [ - -75.92211764705883, - 45.33470588235294 - ], - [ - -75.926, - 45.336 - ], - [ - -75.93, - 45.342 - ], - [ - -75.92952000000001, - 45.342839999999995 - ], - [ - -75.936, - 45.345 - ], - [ - -75.94, - 45.351 - ], - [ - -75.936, - 45.357 - ], - [ - -75.927, - 45.36 - ], - [ - -75.918, - 45.357 - ], - [ - -75.914, - 45.351 - ], - [ - -75.91438709677419, - 45.35041935483871 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.5954, - 45.42786666666667 - ], - [ - -75.595, - 45.428 - ], - [ - -75.593, - 45.42733333333333 - ], - [ - -75.587, - 45.426 - ], - [ - -75.58666666666667, - 45.42522222222222 - ], - [ - -75.586, - 45.425 - ], - [ - -75.582, - 45.419 - ], - [ - -75.586, - 45.413 - ], - [ - -75.595, - 45.41 - ], - [ - -75.59527272727273, - 45.410090909090904 - ], - [ - -75.596, - 45.409 - ], - [ - -75.60252941176469, - 45.406823529411774 - ], - [ - -75.603, - 45.406 - ], - [ - -75.60495652173914, - 45.4055652173913 - ], - [ - -75.608, - 45.401 - ], - [ - -75.617, - 45.398 - ], - [ - -75.619, - 45.398666666666664 - ], - [ - -75.627, - 45.396 - ], - [ - -75.636, - 45.399 - ], - [ - -75.64, - 45.405 - ], - [ - -75.636, - 45.412 - ], - [ - -75.627, - 45.414 - ], - [ - -75.62459999999999, - 45.413466666666665 - ], - [ - -75.6236, - 45.413799999999995 - ], - [ - -75.62193333333333, - 45.417133333333325 - ], - [ - -75.623, - 45.419 - ], - [ - -75.619, - 45.425 - ], - [ - -75.61, - 45.427 - ], - [ - -75.60520000000001, - 45.42593333333333 - ], - [ - -75.605, - 45.426 - ], - [ - -75.596, - 45.428 - ], - [ - -75.5954, - 45.42786666666667 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.359, - 45.267 - ], - [ - -75.35, - 45.264 - ], - [ - -75.346, - 45.258 - ], - [ - -75.35, - 45.252 - ], - [ - -75.359, - 45.249 - ], - [ - -75.368, - 45.252 - ], - [ - -75.372, - 45.258 - ], - [ - -75.368, - 45.264 - ], - [ - -75.359, - 45.267 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.11358823529412, - 45.12547058823529 - ], - [ - -76.115, - 45.123 - ], - [ - -76.124, - 45.121 - ], - [ - -76.133, - 45.123 - ], - [ - -76.135875, - 45.12970833333333 - ], - [ - -76.141, - 45.128 - ], - [ - -76.142, - 45.12833333333333 - ], - [ - -76.143, - 45.128 - ], - [ - -76.152, - 45.131 - ], - [ - -76.155, - 45.137 - ], - [ - -76.152, - 45.143 - ], - [ - -76.143, - 45.146 - ], - [ - -76.142, - 45.14566666666667 - ], - [ - -76.141, - 45.146 - ], - [ - -76.13690909090909, - 45.14463636363636 - ], - [ - -76.136, - 45.146 - ], - [ - -76.127, - 45.149 - ], - [ - -76.118, - 45.146 - ], - [ - -76.115, - 45.14 - ], - [ - -76.1151304347826, - 45.13969565217391 - ], - [ - -76.112, - 45.139 - ], - [ - -76.108, - 45.132 - ], - [ - -76.112, - 45.126 - ], - [ - -76.11358823529412, - 45.12547058823529 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.141, - 45.159 - ], - [ - -76.132, - 45.157 - ], - [ - -76.129, - 45.15 - ], - [ - -76.132, - 45.144 - ], - [ - -76.141, - 45.141 - ], - [ - -76.15, - 45.144 - ], - [ - -76.154, - 45.15 - ], - [ - -76.15, - 45.157 - ], - [ - -76.141, - 45.159 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.411, - 45.527 - ], - [ - -75.402, - 45.524 - ], - [ - -75.40142857142858, - 45.523142857142865 - ], - [ - -75.401, - 45.523 - ], - [ - -75.397, - 45.517 - ], - [ - -75.401, - 45.51 - ], - [ - -75.41, - 45.508 - ], - [ - -75.419, - 45.51 - ], - [ - -75.41950909090909, - 45.51089090909091 - ], - [ - -75.42, - 45.511 - ], - [ - -75.424, - 45.518 - ], - [ - -75.42, - 45.524 - ], - [ - -75.411, - 45.527 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.702, - 45.343 - ], - [ - -75.693, - 45.34 - ], - [ - -75.689, - 45.334 - ], - [ - -75.693, - 45.327 - ], - [ - -75.702, - 45.325 - ], - [ - -75.70751612903226, - 45.32622580645161 - ], - [ - -75.711, - 45.321 - ], - [ - -75.72, - 45.318 - ], - [ - -75.729, - 45.321 - ], - [ - -75.733, - 45.327 - ], - [ - -75.73261538461539, - 45.327576923076926 - ], - [ - -75.734, - 45.33 - ], - [ - -75.73, - 45.336 - ], - [ - -75.721, - 45.339 - ], - [ - -75.71336363636364, - 45.336454545454544 - ], - [ - -75.711, - 45.34 - ], - [ - -75.702, - 45.343 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.72315384615385, - 45.35376923076923 - ], - [ - -75.721, - 45.35 - ], - [ - -75.725, - 45.344 - ], - [ - -75.734, - 45.341 - ], - [ - -75.743, - 45.344 - ], - [ - -75.74499999999999, - 45.34799999999999 - ], - [ - -75.745, - 45.348 - ], - [ - -75.749, - 45.354 - ], - [ - -75.74823076923077, - 45.35534615384615 - ], - [ - -75.752, - 45.361 - ], - [ - -75.748, - 45.368 - ], - [ - -75.74358181818181, - 45.36898181818182 - ], - [ - -75.743, - 45.37 - ], - [ - -75.734, - 45.372 - ], - [ - -75.725, - 45.37 - ], - [ - -75.721, - 45.363 - ], - [ - -75.723, - 45.36 - ], - [ - -75.72466666666666, - 45.357499999999995 - ], - [ - -75.723, - 45.355 - ], - [ - -75.72330769230769, - 45.35453846153846 - ], - [ - -75.723, - 45.354 - ], - [ - -75.72315384615385, - 45.35376923076923 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.545, - 44.852 - ], - [ - -75.536, - 44.849 - ], - [ - -75.532, - 44.843 - ], - [ - -75.536, - 44.836 - ], - [ - -75.545, - 44.834 - ], - [ - -75.554, - 44.836 - ], - [ - -75.558, - 44.843 - ], - [ - -75.554, - 44.849 - ], - [ - -75.545, - 44.852 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.444, - 45.354 - ], - [ - -75.435, - 45.351 - ], - [ - -75.43185714285714, - 45.34628571428571 - ], - [ - -75.431, - 45.346 - ], - [ - -75.427, - 45.34 - ], - [ - -75.431, - 45.334 - ], - [ - -75.44, - 45.331 - ], - [ - -75.449, - 45.334 - ], - [ - -75.45214285714286, - 45.33871428571428 - ], - [ - -75.453, - 45.339 - ], - [ - -75.456, - 45.345 - ], - [ - -75.453, - 45.351 - ], - [ - -75.444, - 45.354 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.636, - 45.434 - ], - [ - -75.626, - 45.431 - ], - [ - -75.623, - 45.425 - ], - [ - -75.626, - 45.419 - ], - [ - -75.636, - 45.416 - ], - [ - -75.645, - 45.419 - ], - [ - -75.648, - 45.425 - ], - [ - -75.645, - 45.431 - ], - [ - -75.636, - 45.434 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.921, - 45.287 - ], - [ - -75.912, - 45.284 - ], - [ - -75.908, - 45.278 - ], - [ - -75.912, - 45.271 - ], - [ - -75.91356521739131, - 45.27065217391304 - ], - [ - -75.914, - 45.27 - ], - [ - -75.92085714285714, - 45.26771428571429 - ], - [ - -75.922, - 45.266 - ], - [ - -75.92757142857143, - 45.26414285714285 - ], - [ - -75.929, - 45.262 - ], - [ - -75.938, - 45.259 - ], - [ - -75.947, - 45.262 - ], - [ - -75.951, - 45.268 - ], - [ - -75.947, - 45.274 - ], - [ - -75.94133333333333, - 45.27588888888889 - ], - [ - -75.94, - 45.279 - ], - [ - -75.93530434782609, - 45.28004347826087 - ], - [ - -75.934, - 45.282 - ], - [ - -75.93216666666667, - 45.2826111111111 - ], - [ - -75.932, - 45.283 - ], - [ - -75.9304347826087, - 45.28334782608696 - ], - [ - -75.93, - 45.284 - ], - [ - -75.921, - 45.287 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.782, - 45.38 - ], - [ - -75.773, - 45.377 - ], - [ - -75.769, - 45.371 - ], - [ - -75.773, - 45.364 - ], - [ - -75.77532258064517, - 45.36348387096774 - ], - [ - -75.775, - 45.363 - ], - [ - -75.779, - 45.356 - ], - [ - -75.788, - 45.354 - ], - [ - -75.797, - 45.356 - ], - [ - -75.801, - 45.363 - ], - [ - -75.79866666666668, - 45.366499999999995 - ], - [ - -75.799, - 45.367 - ], - [ - -75.795, - 45.374 - ], - [ - -75.79265217391304, - 45.37452173913044 - ], - [ - -75.791, - 45.377 - ], - [ - -75.782, - 45.38 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.77558064516128, - 45.33812903225807 - ], - [ - -75.777, - 45.336 - ], - [ - -75.77871428571429, - 45.33542857142857 - ], - [ - -75.779, - 45.335 - ], - [ - -75.788, - 45.332 - ], - [ - -75.797, - 45.335 - ], - [ - -75.801, - 45.341 - ], - [ - -75.79899999999999, - 45.3445 - ], - [ - -75.801, - 45.348 - ], - [ - -75.797, - 45.354 - ], - [ - -75.788, - 45.356 - ], - [ - -75.78020000000001, - 45.35426666666667 - ], - [ - -75.775, - 45.356 - ], - [ - -75.766, - 45.353 - ], - [ - -75.762, - 45.347 - ], - [ - -75.766, - 45.34 - ], - [ - -75.775, - 45.338 - ], - [ - -75.77558064516128, - 45.33812903225807 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.675, - 45.243 - ], - [ - -75.666, - 45.24 - ], - [ - -75.662, - 45.234 - ], - [ - -75.666, - 45.228 - ], - [ - -75.675, - 45.225 - ], - [ - -75.684, - 45.228 - ], - [ - -75.688, - 45.234 - ], - [ - -75.684, - 45.24 - ], - [ - -75.675, - 45.243 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.69879999999999, - 45.278933333333335 - ], - [ - -75.69, - 45.276 - ], - [ - -75.686, - 45.27 - ], - [ - -75.69, - 45.263 - ], - [ - -75.699, - 45.261 - ], - [ - -75.708, - 45.263 - ], - [ - -75.71168, - 45.26944 - ], - [ - -75.719, - 45.267 - ], - [ - -75.728, - 45.27 - ], - [ - -75.732, - 45.276 - ], - [ - -75.728, - 45.282 - ], - [ - -75.719, - 45.285 - ], - [ - -75.71388235294118, - 45.28329411764706 - ], - [ - -75.716, - 45.287 - ], - [ - -75.712, - 45.293 - ], - [ - -75.703, - 45.296 - ], - [ - -75.694, - 45.293 - ], - [ - -75.69, - 45.287 - ], - [ - -75.694, - 45.28 - ], - [ - -75.69879999999999, - 45.278933333333335 - ] - ], - [ - [ - -75.70636363636363, - 45.276545454545456 - ], - [ - -75.70000000000003, - 45.27866666666666 - ], - [ - -75.703, - 45.278 - ], - [ - -75.70808695652174, - 45.27913043478261 - ], - [ - -75.70636363636363, - 45.276545454545456 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.7454, - 45.283199999999994 - ], - [ - -75.74614285714286, - 45.28171428571429 - ], - [ - -75.738, - 45.279 - ], - [ - -75.734, - 45.273 - ], - [ - -75.738, - 45.266 - ], - [ - -75.747, - 45.264 - ], - [ - -75.756, - 45.266 - ], - [ - -75.76, - 45.273 - ], - [ - -75.7570909090909, - 45.27736363636364 - ], - [ - -75.765, - 45.28 - ], - [ - -75.76560869565218, - 45.28091304347826 - ], - [ - -75.766, - 45.281 - ], - [ - -75.77, - 45.287 - ], - [ - -75.766, - 45.294 - ], - [ - -75.76169565217391, - 45.29495652173913 - ], - [ - -75.761, - 45.296 - ], - [ - -75.752, - 45.299 - ], - [ - -75.743, - 45.296 - ], - [ - -75.739, - 45.29 - ], - [ - -75.743, - 45.284 - ], - [ - -75.7454, - 45.283199999999994 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.732, - 45.307 - ], - [ - -75.723, - 45.304 - ], - [ - -75.719, - 45.298 - ], - [ - -75.71523529411765, - 45.29141176470588 - ], - [ - -75.714, - 45.291 - ], - [ - -75.71, - 45.285 - ], - [ - -75.714, - 45.278 - ], - [ - -75.723, - 45.276 - ], - [ - -75.732, - 45.278 - ], - [ - -75.73576470588236, - 45.284588235294116 - ], - [ - -75.737, - 45.285 - ], - [ - -75.741, - 45.291 - ], - [ - -75.744, - 45.298 - ], - [ - -75.741, - 45.304 - ], - [ - -75.732, - 45.307 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.47142857142856, - 45.497142857142855 - ], - [ - -75.471, - 45.497 - ], - [ - -75.467, - 45.491 - ], - [ - -75.471, - 45.485 - ], - [ - -75.48, - 45.482 - ], - [ - -75.489, - 45.485 - ], - [ - -75.48957142857144, - 45.48585714285714 - ], - [ - -75.49, - 45.486 - ], - [ - -75.494, - 45.492 - ], - [ - -75.49, - 45.498 - ], - [ - -75.481, - 45.501 - ], - [ - -75.472, - 45.498 - ], - [ - -75.47142857142856, - 45.497142857142855 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.595, - 45.279 - ], - [ - -75.586, - 45.276 - ], - [ - -75.582, - 45.27 - ], - [ - -75.586, - 45.263 - ], - [ - -75.595, - 45.261 - ], - [ - -75.604, - 45.263 - ], - [ - -75.607, - 45.27 - ], - [ - -75.604, - 45.276 - ], - [ - -75.595, - 45.279 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.527, - 45.456 - ], - [ - -75.52372727272727, - 45.4549090909091 - ], - [ - -75.521, - 45.459 - ], - [ - -75.51447058823528, - 45.46117647058824 - ], - [ - -75.514, - 45.462 - ], - [ - -75.506125, - 45.46375 - ], - [ - -75.506, - 45.464 - ], - [ - -75.50272727272727, - 45.46509090909091 - ], - [ - -75.504, - 45.467 - ], - [ - -75.50373333333333, - 45.46746666666666 - ], - [ - -75.504, - 45.468 - ], - [ - -75.501, - 45.474 - ], - [ - -75.492, - 45.477 - ], - [ - -75.48500000000001, - 45.47466666666667 - ], - [ - -75.482, - 45.474 - ], - [ - -75.47865454545455, - 45.46814545454546 - ], - [ - -75.478, - 45.468 - ], - [ - -75.475, - 45.461 - ], - [ - -75.47657142857142, - 45.457857142857144 - ], - [ - -75.474, - 45.457 - ], - [ - -75.47, - 45.451 - ], - [ - -75.474, - 45.444 - ], - [ - -75.483, - 45.442 - ], - [ - -75.492, - 45.444 - ], - [ - -75.49439130434783, - 45.449579710144924 - ], - [ - -75.49582608695651, - 45.449260869565215 - ], - [ - -75.496, - 45.449 - ], - [ - -75.49952941176471, - 45.447823529411764 - ], - [ - -75.5, - 45.447 - ], - [ - -75.509, - 45.445 - ], - [ - -75.512, - 45.444 - ], - [ - -75.51527272727273, - 45.44509090909091 - ], - [ - -75.518, - 45.441 - ], - [ - -75.527, - 45.438 - ], - [ - -75.5342, - 45.4404 - ], - [ - -75.536, - 45.44 - ], - [ - -75.545, - 45.442 - ], - [ - -75.548, - 45.449 - ], - [ - -75.545, - 45.455 - ], - [ - -75.536, - 45.458 - ], - [ - -75.52850000000001, - 45.4555 - ], - [ - -75.527, - 45.456 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.82, - 45.336 - ], - [ - -75.811, - 45.334 - ], - [ - -75.807, - 45.327 - ], - [ - -75.811, - 45.321 - ], - [ - -75.82, - 45.318 - ], - [ - -75.8205, - 45.31816666666666 - ], - [ - -75.821, - 45.318 - ], - [ - -75.83, - 45.321 - ], - [ - -75.834, - 45.327 - ], - [ - -75.83, - 45.334 - ], - [ - -75.821, - 45.336 - ], - [ - -75.8205, - 45.33588888888889 - ], - [ - -75.82, - 45.336 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.67, - 45.452 - ], - [ - -75.661, - 45.45 - ], - [ - -75.657, - 45.444 - ], - [ - -75.661, - 45.437 - ], - [ - -75.67, - 45.435 - ], - [ - -75.679, - 45.437 - ], - [ - -75.683, - 45.444 - ], - [ - -75.679, - 45.45 - ], - [ - -75.67, - 45.452 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.756, - 45.352 - ], - [ - -75.747, - 45.349 - ], - [ - -75.744, - 45.343 - ], - [ - -75.74469565217392, - 45.3413768115942 - ], - [ - -75.743, - 45.341 - ], - [ - -75.739, - 45.334 - ], - [ - -75.743, - 45.328 - ], - [ - -75.752, - 45.325 - ], - [ - -75.761, - 45.328 - ], - [ - -75.765, - 45.334 - ], - [ - -75.76398591549295, - 45.33577464788733 - ], - [ - -75.765, - 45.336 - ], - [ - -75.769, - 45.343 - ], - [ - -75.765, - 45.349 - ], - [ - -75.756, - 45.352 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.809, - 45.363 - ], - [ - -75.8, - 45.36 - ], - [ - -75.796, - 45.354 - ], - [ - -75.8, - 45.347 - ], - [ - -75.809, - 45.345 - ], - [ - -75.818, - 45.347 - ], - [ - -75.822, - 45.354 - ], - [ - -75.818, - 45.36 - ], - [ - -75.809, - 45.363 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.955, - 45.288 - ], - [ - -75.946, - 45.286 - ], - [ - -75.94435294117646, - 45.283117647058816 - ], - [ - -75.941, - 45.282 - ], - [ - -75.937, - 45.276 - ], - [ - -75.941, - 45.269 - ], - [ - -75.95, - 45.267 - ], - [ - -75.959, - 45.269 - ], - [ - -75.96023636363637, - 45.27116363636364 - ], - [ - -75.964, - 45.272 - ], - [ - -75.9652, - 45.2748 - ], - [ - -75.968, - 45.279 - ], - [ - -75.964, - 45.286 - ], - [ - -75.955, - 45.288 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.916, - 45.263 - ], - [ - -75.907, - 45.261 - ], - [ - -75.904, - 45.254 - ], - [ - -75.907, - 45.248 - ], - [ - -75.916, - 45.245 - ], - [ - -75.926, - 45.248 - ], - [ - -75.929, - 45.254 - ], - [ - -75.926, - 45.261 - ], - [ - -75.916, - 45.263 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.05, - 45.327 - ], - [ - -76.041, - 45.324 - ], - [ - -76.037, - 45.318 - ], - [ - -76.041, - 45.311 - ], - [ - -76.05, - 45.309 - ], - [ - -76.059, - 45.311 - ], - [ - -76.063, - 45.318 - ], - [ - -76.059, - 45.324 - ], - [ - -76.05, - 45.327 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.06907692307692, - 45.30438461538461 - ], - [ - -75.066, - 45.299 - ], - [ - -75.07, - 45.293 - ], - [ - -75.079, - 45.29 - ], - [ - -75.088, - 45.293 - ], - [ - -75.092, - 45.299 - ], - [ - -75.09152, - 45.299839999999996 - ], - [ - -75.092, - 45.3 - ], - [ - -75.095, - 45.306 - ], - [ - -75.09447826086956, - 45.30721739130435 - ], - [ - -75.098, - 45.308 - ], - [ - -75.101, - 45.315 - ], - [ - -75.098, - 45.321 - ], - [ - -75.089, - 45.324 - ], - [ - -75.079, - 45.321 - ], - [ - -75.076, - 45.315 - ], - [ - -75.07643478260869, - 45.31398550724637 - ], - [ - -75.072, - 45.313 - ], - [ - -75.068, - 45.306 - ], - [ - -75.06907692307692, - 45.30438461538461 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.814, - 45.32 - ], - [ - -75.81549994039575, - 45.31950001986808 - ], - [ - -75.82, - 45.318 - ], - [ - -75.82042857142856, - 45.317857142857136 - ], - [ - -75.821, - 45.317 - ], - [ - -75.827, - 45.315 - ], - [ - -75.836, - 45.312 - ], - [ - -75.845, - 45.315 - ], - [ - -75.849, - 45.321 - ], - [ - -75.845, - 45.328 - ], - [ - -75.83931578947369, - 45.32926315789474 - ], - [ - -75.839, - 45.33 - ], - [ - -75.83234782608695, - 45.33147826086957 - ], - [ - -75.832, - 45.332 - ], - [ - -75.82970588235294, - 45.332764705882354 - ], - [ - -75.829, - 45.334 - ], - [ - -75.82, - 45.336 - ], - [ - -75.811, - 45.334 - ], - [ - -75.807, - 45.327 - ], - [ - -75.811, - 45.321 - ], - [ - -75.814, - 45.32 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.802, - 45.278 - ], - [ - -75.793, - 45.276 - ], - [ - -75.79220000000001, - 45.2746 - ], - [ - -75.792, - 45.275 - ], - [ - -75.782, - 45.278 - ], - [ - -75.773, - 45.275 - ], - [ - -75.77, - 45.269 - ], - [ - -75.773, - 45.262 - ], - [ - -75.782, - 45.26 - ], - [ - -75.792, - 45.262 - ], - [ - -75.79265217391304, - 45.26352173913044 - ], - [ - -75.793, - 45.263 - ], - [ - -75.802, - 45.26 - ], - [ - -75.811, - 45.263 - ], - [ - -75.815, - 45.269 - ], - [ - -75.811, - 45.276 - ], - [ - -75.802, - 45.278 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.613, - 45.442 - ], - [ - -75.604, - 45.44 - ], - [ - -75.6, - 45.433 - ], - [ - -75.604, - 45.427 - ], - [ - -75.613, - 45.424 - ], - [ - -75.622, - 45.427 - ], - [ - -75.625, - 45.433 - ], - [ - -75.622, - 45.44 - ], - [ - -75.613, - 45.442 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.951, - 45.379 - ], - [ - -75.942, - 45.376 - ], - [ - -75.938, - 45.37 - ], - [ - -75.942, - 45.363 - ], - [ - -75.951, - 45.361 - ], - [ - -75.96, - 45.363 - ], - [ - -75.964, - 45.37 - ], - [ - -75.96, - 45.376 - ], - [ - -75.951, - 45.379 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.777, - 45.333 - ], - [ - -75.768, - 45.33 - ], - [ - -75.765, - 45.324 - ], - [ - -75.768, - 45.317 - ], - [ - -75.777, - 45.315 - ], - [ - -75.787, - 45.317 - ], - [ - -75.79, - 45.324 - ], - [ - -75.787, - 45.33 - ], - [ - -75.777, - 45.333 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.738, - 45.284 - ], - [ - -75.729, - 45.281 - ], - [ - -75.725, - 45.275 - ], - [ - -75.729, - 45.268 - ], - [ - -75.738, - 45.266 - ], - [ - -75.73917391304347, - 45.266260869565215 - ], - [ - -75.741, - 45.262 - ], - [ - -75.75, - 45.26 - ], - [ - -75.759, - 45.262 - ], - [ - -75.763, - 45.269 - ], - [ - -75.759, - 45.275 - ], - [ - -75.75, - 45.278 - ], - [ - -75.74918181818182, - 45.277727272727276 - ], - [ - -75.747, - 45.281 - ], - [ - -75.738, - 45.284 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.838, - 45.29 - ], - [ - -75.829, - 45.288 - ], - [ - -75.825, - 45.281 - ], - [ - -75.829, - 45.275 - ], - [ - -75.838, - 45.272 - ], - [ - -75.847, - 45.275 - ], - [ - -75.851, - 45.281 - ], - [ - -75.847, - 45.288 - ], - [ - -75.838, - 45.29 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.344, - 45.349 - ], - [ - -75.335, - 45.347 - ], - [ - -75.331, - 45.34 - ], - [ - -75.335, - 45.334 - ], - [ - -75.333, - 45.331 - ], - [ - -75.337, - 45.324 - ], - [ - -75.346, - 45.322 - ], - [ - -75.3466, - 45.32213333333333 - ], - [ - -75.347, - 45.322 - ], - [ - -75.34899999999996, - 45.322666666666656 - ], - [ - -75.355, - 45.324 - ], - [ - -75.3554705882353, - 45.32482352941177 - ], - [ - -75.356, - 45.325 - ], - [ - -75.359, - 45.331 - ], - [ - -75.356, - 45.338 - ], - [ - -75.35570967741936, - 45.33806451612903 - ], - [ - -75.357, - 45.34 - ], - [ - -75.353, - 45.347 - ], - [ - -75.344, - 45.349 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.713, - 45.249 - ], - [ - -75.704, - 45.247 - ], - [ - -75.7, - 45.24 - ], - [ - -75.704, - 45.234 - ], - [ - -75.713, - 45.231 - ], - [ - -75.722, - 45.234 - ], - [ - -75.725, - 45.24 - ], - [ - -75.722, - 45.247 - ], - [ - -75.713, - 45.249 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.698, - 45.587 - ], - [ - -76.689, - 45.584 - ], - [ - -76.685, - 45.578 - ], - [ - -76.689, - 45.571 - ], - [ - -76.698, - 45.569 - ], - [ - -76.707, - 45.571 - ], - [ - -76.711, - 45.578 - ], - [ - -76.707, - 45.584 - ], - [ - -76.698, - 45.587 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -74.881, - 45.567 - ], - [ - -74.87983870967741, - 45.56674193548387 - ], - [ - -74.879, - 45.568 - ], - [ - -74.87, - 45.571 - ], - [ - -74.861, - 45.568 - ], - [ - -74.857, - 45.562 - ], - [ - -74.861, - 45.556 - ], - [ - -74.87, - 45.553 - ], - [ - -74.87109090909091, - 45.553363636363635 - ], - [ - -74.872, - 45.552 - ], - [ - -74.881, - 45.549 - ], - [ - -74.89, - 45.552 - ], - [ - -74.894, - 45.558 - ], - [ - -74.89, - 45.565 - ], - [ - -74.881, - 45.567 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -74.904, - 45.561 - ], - [ - -74.895, - 45.558 - ], - [ - -74.891, - 45.552 - ], - [ - -74.895, - 45.545 - ], - [ - -74.90178947368422, - 45.543491228070174 - ], - [ - -74.902, - 45.543 - ], - [ - -74.912, - 45.541 - ], - [ - -74.921, - 45.543 - ], - [ - -74.924, - 45.55 - ], - [ - -74.921, - 45.556 - ], - [ - -74.912, - 45.559 - ], - [ - -74.91094736842106, - 45.558684210526316 - ], - [ - -74.904, - 45.561 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.18857142857144, - 45.24214285714286 - ], - [ - -76.188, - 45.243 - ], - [ - -76.179, - 45.246 - ], - [ - -76.17, - 45.243 - ], - [ - -76.167, - 45.237 - ], - [ - -76.17, - 45.23 - ], - [ - -76.17605454545455, - 45.228654545454546 - ], - [ - -76.177, - 45.227 - ], - [ - -76.18422535211268, - 45.225394366197186 - ], - [ - -76.184, - 45.225 - ], - [ - -76.188, - 45.219 - ], - [ - -76.19435294117646, - 45.216882352941184 - ], - [ - -76.196, - 45.214 - ], - [ - -76.205, - 45.212 - ], - [ - -76.214, - 45.214 - ], - [ - -76.217, - 45.221 - ], - [ - -76.214, - 45.227 - ], - [ - -76.20764705882353, - 45.22911764705882 - ], - [ - -76.206, - 45.232 - ], - [ - -76.19791304347825, - 45.23379710144928 - ], - [ - -76.198, - 45.234 - ], - [ - -76.195, - 45.24 - ], - [ - -76.18857142857144, - 45.24214285714286 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.23, - 45.112 - ], - [ - -75.221, - 45.109 - ], - [ - -75.2205625, - 45.108125 - ], - [ - -75.22, - 45.108 - ], - [ - -75.216, - 45.101 - ], - [ - -75.22, - 45.095 - ], - [ - -75.229, - 45.092 - ], - [ - -75.238, - 45.095 - ], - [ - -75.242, - 45.101 - ], - [ - -75.24184615384615, - 45.10126923076923 - ], - [ - -75.243, - 45.103 - ], - [ - -75.239, - 45.109 - ], - [ - -75.23, - 45.112 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.969, - 45.392 - ], - [ - -75.96, - 45.389 - ], - [ - -75.957, - 45.383 - ], - [ - -75.96, - 45.377 - ], - [ - -75.969, - 45.374 - ], - [ - -75.979, - 45.377 - ], - [ - -75.982, - 45.383 - ], - [ - -75.979, - 45.389 - ], - [ - -75.969, - 45.392 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.077, - 45.155 - ], - [ - -75.068, - 45.153 - ], - [ - -75.065, - 45.146 - ], - [ - -75.068, - 45.14 - ], - [ - -75.077, - 45.137 - ], - [ - -75.086, - 45.14 - ], - [ - -75.09, - 45.146 - ], - [ - -75.086, - 45.153 - ], - [ - -75.077, - 45.155 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.938, - 44.844 - ], - [ - -75.929, - 44.841 - ], - [ - -75.925, - 44.835 - ], - [ - -75.929, - 44.828 - ], - [ - -75.938, - 44.826 - ], - [ - -75.947, - 44.828 - ], - [ - -75.95, - 44.835 - ], - [ - -75.947, - 44.841 - ], - [ - -75.938, - 44.844 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.252, - 45.339 - ], - [ - -75.243, - 45.336 - ], - [ - -75.239, - 45.33 - ], - [ - -75.24108450704226, - 45.326352112676055 - ], - [ - -75.235, - 45.325 - ], - [ - -75.231, - 45.318 - ], - [ - -75.235, - 45.312 - ], - [ - -75.244, - 45.309 - ], - [ - -75.253, - 45.312 - ], - [ - -75.257, - 45.318 - ], - [ - -75.25491549295775, - 45.32164788732394 - ], - [ - -75.261, - 45.323 - ], - [ - -75.265, - 45.33 - ], - [ - -75.261, - 45.336 - ], - [ - -75.252, - 45.339 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -74.887, - 45.347 - ], - [ - -74.884, - 45.34 - ], - [ - -74.887, - 45.334 - ], - [ - -74.896, - 45.331 - ], - [ - -74.905, - 45.334 - ], - [ - -74.909, - 45.34 - ], - [ - -74.90852000000001, - 45.34084 - ], - [ - -74.909, - 45.341 - ], - [ - -74.913, - 45.347 - ], - [ - -74.909, - 45.353 - ], - [ - -74.9, - 45.356 - ], - [ - -74.891, - 45.353 - ], - [ - -74.887, - 45.347 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.679, - 44.975 - ], - [ - -75.67, - 44.972 - ], - [ - -75.666, - 44.966 - ], - [ - -75.67, - 44.959 - ], - [ - -75.679, - 44.957 - ], - [ - -75.688, - 44.959 - ], - [ - -75.691, - 44.966 - ], - [ - -75.688, - 44.972 - ], - [ - -75.679, - 44.975 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.141, - 44.858 - ], - [ - -76.132, - 44.856 - ], - [ - -76.129, - 44.849 - ], - [ - -76.132, - 44.843 - ], - [ - -76.141, - 44.84 - ], - [ - -76.15, - 44.843 - ], - [ - -76.154, - 44.849 - ], - [ - -76.15, - 44.856 - ], - [ - -76.141, - 44.858 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.249, - 45.568 - ], - [ - -75.24, - 45.565 - ], - [ - -75.236, - 45.559 - ], - [ - -75.24, - 45.553 - ], - [ - -75.249, - 45.55 - ], - [ - -75.258, - 45.553 - ], - [ - -75.262, - 45.559 - ], - [ - -75.258, - 45.565 - ], - [ - -75.249, - 45.568 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.344, - 45.451 - ], - [ - -75.335, - 45.448 - ], - [ - -75.332, - 45.442 - ], - [ - -75.335, - 45.435 - ], - [ - -75.344, - 45.433 - ], - [ - -75.353, - 45.435 - ], - [ - -75.357, - 45.442 - ], - [ - -75.353, - 45.448 - ], - [ - -75.344, - 45.451 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.423, - 45.43 - ], - [ - -75.414, - 45.428 - ], - [ - -75.41, - 45.421 - ], - [ - -75.414, - 45.415 - ], - [ - -75.423, - 45.412 - ], - [ - -75.432, - 45.415 - ], - [ - -75.436, - 45.421 - ], - [ - -75.432, - 45.428 - ], - [ - -75.423, - 45.43 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.291, - 45.343 - ], - [ - -76.282, - 45.34 - ], - [ - -76.278, - 45.334 - ], - [ - -76.27828571428572, - 45.3335 - ], - [ - -76.278, - 45.333 - ], - [ - -76.282, - 45.327 - ], - [ - -76.291, - 45.324 - ], - [ - -76.3, - 45.327 - ], - [ - -76.303, - 45.333 - ], - [ - -76.3027857142857, - 45.3335 - ], - [ - -76.303, - 45.334 - ], - [ - -76.3, - 45.34 - ], - [ - -76.291, - 45.343 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.491, - 45.468 - ], - [ - -75.482, - 45.466 - ], - [ - -75.478, - 45.459 - ], - [ - -75.482, - 45.453 - ], - [ - -75.491, - 45.45 - ], - [ - -75.5, - 45.453 - ], - [ - -75.504, - 45.459 - ], - [ - -75.5, - 45.466 - ], - [ - -75.491, - 45.468 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.074, - 45.495 - ], - [ - -76.065, - 45.493 - ], - [ - -76.061, - 45.486 - ], - [ - -76.065, - 45.48 - ], - [ - -76.074, - 45.477 - ], - [ - -76.083, - 45.48 - ], - [ - -76.086, - 45.486 - ], - [ - -76.083, - 45.493 - ], - [ - -76.074, - 45.495 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.458, - 44.995 - ], - [ - -75.449, - 44.992 - ], - [ - -75.445, - 44.986 - ], - [ - -75.449, - 44.98 - ], - [ - -75.458, - 44.977 - ], - [ - -75.467, - 44.98 - ], - [ - -75.471, - 44.986 - ], - [ - -75.467, - 44.992 - ], - [ - -75.458, - 44.995 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.377, - 45.097 - ], - [ - -75.368, - 45.095 - ], - [ - -75.365, - 45.088 - ], - [ - -75.368, - 45.082 - ], - [ - -75.377, - 45.079 - ], - [ - -75.386, - 45.082 - ], - [ - -75.39, - 45.088 - ], - [ - -75.386, - 45.095 - ], - [ - -75.377, - 45.097 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.461, - 45.169 - ], - [ - -75.452, - 45.166 - ], - [ - -75.448, - 45.16 - ], - [ - -75.452, - 45.153 - ], - [ - -75.461, - 45.151 - ], - [ - -75.47, - 45.153 - ], - [ - -75.474, - 45.16 - ], - [ - -75.47, - 45.166 - ], - [ - -75.461, - 45.169 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.836, - 45.361 - ], - [ - -75.826, - 45.359 - ], - [ - -75.823, - 45.352 - ], - [ - -75.826, - 45.346 - ], - [ - -75.836, - 45.343 - ], - [ - -75.845, - 45.346 - ], - [ - -75.848, - 45.352 - ], - [ - -75.845, - 45.359 - ], - [ - -75.836, - 45.361 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.455, - 45.378 - ], - [ - -75.446, - 45.375 - ], - [ - -75.443, - 45.369 - ], - [ - -75.446, - 45.363 - ], - [ - -75.455, - 45.36 - ], - [ - -75.464, - 45.363 - ], - [ - -75.468, - 45.369 - ], - [ - -75.464, - 45.375 - ], - [ - -75.455, - 45.378 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.245, - 45.419 - ], - [ - -75.236, - 45.417 - ], - [ - -75.232, - 45.41 - ], - [ - -75.236, - 45.404 - ], - [ - -75.245, - 45.401 - ], - [ - -75.254, - 45.404 - ], - [ - -75.258, - 45.41 - ], - [ - -75.254, - 45.417 - ], - [ - -75.245, - 45.419 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.249, - 45.069 - ], - [ - -76.24, - 45.067 - ], - [ - -76.236, - 45.06 - ], - [ - -76.24, - 45.054 - ], - [ - -76.249, - 45.051 - ], - [ - -76.258, - 45.054 - ], - [ - -76.262, - 45.06 - ], - [ - -76.258, - 45.067 - ], - [ - -76.249, - 45.069 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.571, - 45.29 - ], - [ - -75.562, - 45.288 - ], - [ - -75.558, - 45.281 - ], - [ - -75.562, - 45.275 - ], - [ - -75.571, - 45.272 - ], - [ - -75.58, - 45.275 - ], - [ - -75.584, - 45.281 - ], - [ - -75.58, - 45.288 - ], - [ - -75.571, - 45.29 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.60073913043477, - 45.13839130434783 - ], - [ - -75.601, - 45.138 - ], - [ - -75.61, - 45.135 - ], - [ - -75.619, - 45.138 - ], - [ - -75.622, - 45.144 - ], - [ - -75.619, - 45.151 - ], - [ - -75.6161875, - 45.151625 - ], - [ - -75.616, - 45.152 - ], - [ - -75.607, - 45.155 - ], - [ - -75.598, - 45.152 - ], - [ - -75.594, - 45.146 - ], - [ - -75.598, - 45.139 - ], - [ - -75.60073913043477, - 45.13839130434783 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -74.994, - 45.503 - ], - [ - -74.985, - 45.501 - ], - [ - -74.981, - 45.494 - ], - [ - -74.985, - 45.488 - ], - [ - -74.994, - 45.485 - ], - [ - -75.003, - 45.488 - ], - [ - -75.007, - 45.494 - ], - [ - -75.003, - 45.501 - ], - [ - -74.994, - 45.503 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.48481249999999, - 45.605624999999996 - ], - [ - -76.482, - 45.605 - ], - [ - -76.48176470588236, - 45.604588235294116 - ], - [ - -76.477, - 45.603 - ], - [ - -76.473, - 45.597 - ], - [ - -76.477, - 45.59 - ], - [ - -76.486, - 45.588 - ], - [ - -76.4908, - 45.58906666666667 - ], - [ - -76.491, - 45.589 - ], - [ - -76.49200000000003, - 45.58933333333334 - ], - [ - -76.495, - 45.59 - ], - [ - -76.49523529411765, - 45.590411764705884 - ], - [ - -76.5, - 45.592 - ], - [ - -76.50085714285714, - 45.59328571428571 - ], - [ - -76.503, - 45.594 - ], - [ - -76.507, - 45.6 - ], - [ - -76.503, - 45.606 - ], - [ - -76.494, - 45.609 - ], - [ - -76.485, - 45.606 - ], - [ - -76.48481249999999, - 45.605624999999996 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.075, - 45.472 - ], - [ - -76.066, - 45.469 - ], - [ - -76.062, - 45.463 - ], - [ - -76.066, - 45.456 - ], - [ - -76.075, - 45.454 - ], - [ - -76.084, - 45.456 - ], - [ - -76.087, - 45.463 - ], - [ - -76.084, - 45.469 - ], - [ - -76.075, - 45.472 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.357, - 45.02 - ], - [ - -76.348, - 45.017 - ], - [ - -76.344, - 45.011 - ], - [ - -76.348, - 45.004 - ], - [ - -76.357, - 45.002 - ], - [ - -76.366, - 45.004 - ], - [ - -76.369, - 45.011 - ], - [ - -76.366, - 45.017 - ], - [ - -76.357, - 45.02 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.836, - 44.924 - ], - [ - -75.827, - 44.921 - ], - [ - -75.824, - 44.915 - ], - [ - -75.827, - 44.908 - ], - [ - -75.836, - 44.906 - ], - [ - -75.845, - 44.908 - ], - [ - -75.849, - 44.915 - ], - [ - -75.845, - 44.921 - ], - [ - -75.836, - 44.924 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.79633333333334, - 45.4135 - ], - [ - -75.796, - 45.413 - ], - [ - -75.8, - 45.406 - ], - [ - -75.809, - 45.404 - ], - [ - -75.818, - 45.406 - ], - [ - -75.822, - 45.413 - ], - [ - -75.82166666666667, - 45.4135 - ], - [ - -75.822, - 45.414 - ], - [ - -75.818, - 45.421 - ], - [ - -75.817, - 45.423 - ], - [ - -75.807, - 45.426 - ], - [ - -75.798, - 45.423 - ], - [ - -75.795, - 45.417 - ], - [ - -75.79626666666667, - 45.41446666666666 - ], - [ - -75.796, - 45.414 - ], - [ - -75.79633333333334, - 45.4135 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.839, - 45.42 - ], - [ - -75.83, - 45.417 - ], - [ - -75.826, - 45.411 - ], - [ - -75.83, - 45.405 - ], - [ - -75.821, - 45.402 - ], - [ - -75.817, - 45.396 - ], - [ - -75.821, - 45.39 - ], - [ - -75.83, - 45.387 - ], - [ - -75.8305, - 45.38716666666667 - ], - [ - -75.834, - 45.386 - ], - [ - -75.843, - 45.389 - ], - [ - -75.84590909090909, - 45.39336363636364 - ], - [ - -75.853, - 45.391 - ], - [ - -75.862, - 45.394 - ], - [ - -75.866, - 45.4 - ], - [ - -75.86498591549295, - 45.40177464788732 - ], - [ - -75.866, - 45.402 - ], - [ - -75.87, - 45.409 - ], - [ - -75.866, - 45.415 - ], - [ - -75.857, - 45.418 - ], - [ - -75.84885714285714, - 45.415285714285716 - ], - [ - -75.848, - 45.417 - ], - [ - -75.839, - 45.42 - ] - ], - [ - [ - -75.84060000000001, - 45.40253333333333 - ], - [ - -75.84164705882353, - 45.40288235294118 - ], - [ - -75.84135211267606, - 45.4023661971831 - ], - [ - -75.84060000000001, - 45.40253333333333 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.72398181818181, - 45.45321818181819 - ], - [ - -75.723, - 45.453 - ], - [ - -75.7225, - 45.452125 - ], - [ - -75.722, - 45.453 - ], - [ - -75.713, - 45.455 - ], - [ - -75.704, - 45.453 - ], - [ - -75.7, - 45.446 - ], - [ - -75.704, - 45.44 - ], - [ - -75.71190909090909, - 45.437363636363635 - ], - [ - -75.709, - 45.433 - ], - [ - -75.713, - 45.426 - ], - [ - -75.71534782608695, - 45.42547826086957 - ], - [ - -75.717, - 45.423 - ], - [ - -75.726, - 45.42 - ], - [ - -75.735, - 45.423 - ], - [ - -75.739, - 45.429 - ], - [ - -75.73538709677419, - 45.43441935483872 - ], - [ - -75.738, - 45.435 - ], - [ - -75.74040000000001, - 45.4392 - ], - [ - -75.744, - 45.438 - ], - [ - -75.753, - 45.441 - ], - [ - -75.7567142857143, - 45.44657142857143 - ], - [ - -75.761, - 45.448 - ], - [ - -75.765, - 45.454 - ], - [ - -75.761, - 45.461 - ], - [ - -75.75965000000001, - 45.461299999999994 - ], - [ - -75.76, - 45.462 - ], - [ - -75.757, - 45.469 - ], - [ - -75.748, - 45.471 - ], - [ - -75.7475, - 45.47088888888889 - ], - [ - -75.747, - 45.471 - ], - [ - -75.737, - 45.469 - ], - [ - -75.73633333333332, - 45.467444444444446 - ], - [ - -75.732, - 45.466 - ], - [ - -75.728, - 45.46 - ], - [ - -75.72935714285714, - 45.45762499999999 - ], - [ - -75.729, - 45.457 - ], - [ - -75.72964516129032, - 45.45603225806452 - ], - [ - -75.725, - 45.455 - ], - [ - -75.72398181818181, - 45.45321818181819 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.7251690140845, - 45.468295774647885 - ], - [ - -75.725, - 45.468 - ], - [ - -75.729, - 45.462 - ], - [ - -75.738, - 45.459 - ], - [ - -75.747, - 45.462 - ], - [ - -75.751, - 45.468 - ], - [ - -75.75038461538462, - 45.469076923076926 - ], - [ - -75.751, - 45.47 - ], - [ - -75.751, - 45.470000000000006 - ], - [ - -75.753, - 45.473 - ], - [ - -75.749, - 45.48 - ], - [ - -75.74, - 45.482 - ], - [ - -75.731, - 45.485 - ], - [ - -75.722, - 45.482 - ], - [ - -75.718, - 45.476 - ], - [ - -75.722, - 45.469 - ], - [ - -75.7251690140845, - 45.468295774647885 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.188, - 45.401 - ], - [ - -76.179, - 45.398 - ], - [ - -76.176, - 45.392 - ], - [ - -76.179, - 45.385 - ], - [ - -76.188, - 45.383 - ], - [ - -76.198, - 45.385 - ], - [ - -76.201, - 45.392 - ], - [ - -76.198, - 45.398 - ], - [ - -76.188, - 45.401 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.36, - 44.949 - ], - [ - -75.351, - 44.946 - ], - [ - -75.347, - 44.94 - ], - [ - -75.351, - 44.933 - ], - [ - -75.36, - 44.931 - ], - [ - -75.369, - 44.933 - ], - [ - -75.372, - 44.94 - ], - [ - -75.369, - 44.946 - ], - [ - -75.36, - 44.949 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.454, - 45.48 - ], - [ - -75.445, - 45.477 - ], - [ - -75.441, - 45.471 - ], - [ - -75.445, - 45.465 - ], - [ - -75.454, - 45.462 - ], - [ - -75.463, - 45.465 - ], - [ - -75.467, - 45.471 - ], - [ - -75.463, - 45.477 - ], - [ - -75.454, - 45.48 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.808, - 45.395 - ], - [ - -75.8075, - 45.39483333333334 - ], - [ - -75.807, - 45.395 - ], - [ - -75.798, - 45.392 - ], - [ - -75.795, - 45.386 - ], - [ - -75.798, - 45.38 - ], - [ - -75.807, - 45.377 - ], - [ - -75.8075, - 45.37716666666667 - ], - [ - -75.808, - 45.377 - ], - [ - -75.817, - 45.38 - ], - [ - -75.821, - 45.386 - ], - [ - -75.817, - 45.392 - ], - [ - -75.808, - 45.395 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.71718181818181, - 45.67527272727273 - ], - [ - -75.717, - 45.675 - ], - [ - -75.721, - 45.668 - ], - [ - -75.73, - 45.666 - ], - [ - -75.739, - 45.668 - ], - [ - -75.743, - 45.675 - ], - [ - -75.739, - 45.681 - ], - [ - -75.73681818181818, - 45.68172727272727 - ], - [ - -75.737, - 45.682 - ], - [ - -75.733, - 45.689 - ], - [ - -75.724, - 45.691 - ], - [ - -75.715, - 45.689 - ], - [ - -75.711, - 45.682 - ], - [ - -75.715, - 45.676 - ], - [ - -75.71718181818181, - 45.67527272727273 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.783, - 45.58 - ], - [ - -75.774, - 45.577 - ], - [ - -75.77, - 45.571 - ], - [ - -75.774, - 45.564 - ], - [ - -75.783, - 45.562 - ], - [ - -75.792, - 45.564 - ], - [ - -75.795, - 45.571 - ], - [ - -75.792, - 45.577 - ], - [ - -75.783, - 45.58 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -74.989, - 45.55 - ], - [ - -74.98, - 45.547 - ], - [ - -74.977, - 45.541 - ], - [ - -74.98, - 45.535 - ], - [ - -74.98514285714285, - 45.53328571428571 - ], - [ - -74.988, - 45.529 - ], - [ - -74.997, - 45.526 - ], - [ - -74.9975, - 45.52616666666667 - ], - [ - -74.998, - 45.526 - ], - [ - -75.007, - 45.529 - ], - [ - -75.011, - 45.535 - ], - [ - -75.007, - 45.541 - ], - [ - -75.0064705882353, - 45.54117647058823 - ], - [ - -75.006, - 45.542 - ], - [ - -75.00052173913043, - 45.543217391304346 - ], - [ - -74.998, - 45.547 - ], - [ - -74.989, - 45.55 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.766, - 45.445 - ], - [ - -75.757, - 45.443 - ], - [ - -75.753, - 45.436 - ], - [ - -75.75323076923077, - 45.43565384615384 - ], - [ - -75.75, - 45.43 - ], - [ - -75.75028571428571, - 45.429571428571435 - ], - [ - -75.75028571428571, - 45.42957142857143 - ], - [ - -75.746, - 45.431 - ], - [ - -75.737, - 45.428 - ], - [ - -75.733, - 45.422 - ], - [ - -75.737, - 45.416 - ], - [ - -75.746, - 45.413 - ], - [ - -75.755, - 45.416 - ], - [ - -75.75718181818182, - 45.41927272727273 - ], - [ - -75.761, - 45.418 - ], - [ - -75.77, - 45.421 - ], - [ - -75.77199999999999, - 45.42399999999999 - ], - [ - -75.772, - 45.424 - ], - [ - -75.774, - 45.427 - ], - [ - -75.776, - 45.43 - ], - [ - -75.77553846153846, - 45.43080769230769 - ], - [ - -75.779, - 45.436 - ], - [ - -75.77863636363637, - 45.43663636363636 - ], - [ - -75.786, - 45.435 - ], - [ - -75.795, - 45.437 - ], - [ - -75.799, - 45.444 - ], - [ - -75.795, - 45.451 - ], - [ - -75.786, - 45.453 - ], - [ - -75.777, - 45.451 - ], - [ - -75.773, - 45.444 - ], - [ - -75.77336363636364, - 45.443363636363635 - ], - [ - -75.766, - 45.445 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.68857142857142, - 45.465142857142865 - ], - [ - -75.687, - 45.462 - ], - [ - -75.68724489795919, - 45.46142857142857 - ], - [ - -75.687, - 45.461 - ], - [ - -75.6882, - 45.4592 - ], - [ - -75.69, - 45.455 - ], - [ - -75.693, - 45.45433333333333 - ], - [ - -75.7, - 45.452 - ], - [ - -75.709, - 45.455 - ], - [ - -75.713, - 45.461 - ], - [ - -75.71192307692307, - 45.46288461538461 - ], - [ - -75.714, - 45.466 - ], - [ - -75.71281690140844, - 45.46807042253521 - ], - [ - -75.717, - 45.469 - ], - [ - -75.721, - 45.475 - ], - [ - -75.717, - 45.482 - ], - [ - -75.711375, - 45.48325 - ], - [ - -75.711, - 45.484 - ], - [ - -75.702, - 45.487 - ], - [ - -75.692, - 45.484 - ], - [ - -75.689, - 45.478 - ], - [ - -75.69173333333333, - 45.47253333333333 - ], - [ - -75.688, - 45.466 - ], - [ - -75.68857142857142, - 45.465142857142865 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.719, - 45.498 - ], - [ - -75.7148, - 45.4966 - ], - [ - -75.713, - 45.497 - ], - [ - -75.704, - 45.495 - ], - [ - -75.70101818181818, - 45.48978181818182 - ], - [ - -75.693, - 45.488 - ], - [ - -75.689, - 45.481 - ], - [ - -75.693, - 45.475 - ], - [ - -75.702, - 45.472 - ], - [ - -75.711, - 45.475 - ], - [ - -75.71385714285715, - 45.479285714285716 - ], - [ - -75.71719999999999, - 45.480399999999996 - ], - [ - -75.719, - 45.48 - ], - [ - -75.72375000000001, - 45.48105555555556 - ], - [ - -75.724, - 45.481 - ], - [ - -75.733, - 45.483 - ], - [ - -75.737, - 45.49 - ], - [ - -75.733, - 45.496 - ], - [ - -75.724, - 45.499 - ], - [ - -75.72, - 45.49766666666667 - ], - [ - -75.719, - 45.498 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.66587096774194, - 45.476193548387094 - ], - [ - -75.666, - 45.476 - ], - [ - -75.675, - 45.473 - ], - [ - -75.684, - 45.476 - ], - [ - -75.68709090909091, - 45.48063636363636 - ], - [ - -75.689, - 45.48 - ], - [ - -75.698, - 45.483 - ], - [ - -75.702, - 45.489 - ], - [ - -75.698, - 45.496 - ], - [ - -75.689, - 45.498 - ], - [ - -75.68586956521739, - 45.49730434782609 - ], - [ - -75.689, - 45.502 - ], - [ - -75.68807692307692, - 45.50361538461539 - ], - [ - -75.689, - 45.505 - ], - [ - -75.685, - 45.512 - ], - [ - -75.676, - 45.514 - ], - [ - -75.667, - 45.512 - ], - [ - -75.663, - 45.505 - ], - [ - -75.66392307692307, - 45.50361538461539 - ], - [ - -75.663, - 45.502 - ], - [ - -75.66557142857144, - 45.49814285714285 - ], - [ - -75.657, - 45.501 - ], - [ - -75.648, - 45.498 - ], - [ - -75.644, - 45.492 - ], - [ - -75.648, - 45.485 - ], - [ - -75.65258181818182, - 45.48398181818182 - ], - [ - -75.656, - 45.478 - ], - [ - -75.665, - 45.476 - ], - [ - -75.66587096774194, - 45.476193548387094 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.62969230769231, - 45.490461538461545 - ], - [ - -75.626, - 45.484 - ], - [ - -75.63, - 45.478 - ], - [ - -75.639, - 45.475 - ], - [ - -75.642, - 45.476 - ], - [ - -75.645, - 45.475 - ], - [ - -75.648, - 45.476 - ], - [ - -75.651, - 45.475 - ], - [ - -75.66, - 45.478 - ], - [ - -75.663, - 45.484 - ], - [ - -75.66, - 45.49 - ], - [ - -75.65345454545454, - 45.49218181818182 - ], - [ - -75.654, - 45.493 - ], - [ - -75.65, - 45.5 - ], - [ - -75.641, - 45.502 - ], - [ - -75.632, - 45.5 - ], - [ - -75.628, - 45.493 - ], - [ - -75.62969230769231, - 45.490461538461545 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.421, - 45.595 - ], - [ - -75.412, - 45.593 - ], - [ - -75.41058823529413, - 45.590529411764706 - ], - [ - -75.403, - 45.588 - ], - [ - -75.39917391304348, - 45.58226086956522 - ], - [ - -75.398, - 45.582 - ], - [ - -75.394, - 45.575 - ], - [ - -75.398, - 45.569 - ], - [ - -75.407, - 45.566 - ], - [ - -75.416, - 45.569 - ], - [ - -75.41982608695652, - 45.574739130434786 - ], - [ - -75.421, - 45.575 - ], - [ - -75.42241176470588, - 45.57747058823529 - ], - [ - -75.43, - 45.58 - ], - [ - -75.434, - 45.586 - ], - [ - -75.43, - 45.593 - ], - [ - -75.421, - 45.595 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.642, - 45.51 - ], - [ - -75.633, - 45.508 - ], - [ - -75.629, - 45.501 - ], - [ - -75.633, - 45.495 - ], - [ - -75.642, - 45.492 - ], - [ - -75.651, - 45.495 - ], - [ - -75.655, - 45.501 - ], - [ - -75.651, - 45.508 - ], - [ - -75.642, - 45.51 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.815, - 45.451 - ], - [ - -75.806, - 45.449 - ], - [ - -75.803, - 45.442 - ], - [ - -75.806, - 45.436 - ], - [ - -75.815, - 45.433 - ], - [ - -75.824, - 45.436 - ], - [ - -75.828, - 45.442 - ], - [ - -75.824, - 45.449 - ], - [ - -75.815, - 45.451 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.496, - 45.237 - ], - [ - -75.487, - 45.234 - ], - [ - -75.483, - 45.228 - ], - [ - -75.487, - 45.221 - ], - [ - -75.496, - 45.219 - ], - [ - -75.505, - 45.221 - ], - [ - -75.509, - 45.228 - ], - [ - -75.505, - 45.234 - ], - [ - -75.496, - 45.237 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.228, - 45.3 - ], - [ - -75.219, - 45.297 - ], - [ - -75.216, - 45.291 - ], - [ - -75.21624489795917, - 45.29042857142857 - ], - [ - -75.216, - 45.29 - ], - [ - -75.21719999999999, - 45.28820000000001 - ], - [ - -75.219, - 45.284 - ], - [ - -75.22200000000001, - 45.283333333333324 - ], - [ - -75.229, - 45.281 - ], - [ - -75.238, - 45.284 - ], - [ - -75.242, - 45.29 - ], - [ - -75.238, - 45.297 - ], - [ - -75.23499999999999, - 45.29766666666667 - ], - [ - -75.228, - 45.3 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.412, - 44.927 - ], - [ - -75.403, - 44.924 - ], - [ - -75.399, - 44.918 - ], - [ - -75.403, - 44.911 - ], - [ - -75.412, - 44.909 - ], - [ - -75.421, - 44.911 - ], - [ - -75.425, - 44.918 - ], - [ - -75.421, - 44.924 - ], - [ - -75.412, - 44.927 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.41600000000007, - 45.563666666666684 - ], - [ - -75.413, - 45.563 - ], - [ - -75.41276470588235, - 45.562588235294115 - ], - [ - -75.411, - 45.562 - ], - [ - -75.407, - 45.556 - ], - [ - -75.411, - 45.55 - ], - [ - -75.42, - 45.547 - ], - [ - -75.42016666666667, - 45.54705555555555 - ], - [ - -75.418, - 45.542 - ], - [ - -75.421, - 45.536 - ], - [ - -75.431, - 45.533 - ], - [ - -75.44, - 45.536 - ], - [ - -75.443, - 45.542 - ], - [ - -75.441, - 45.54666666666667 - ], - [ - -75.445, - 45.548 - ], - [ - -75.449, - 45.554 - ], - [ - -75.445, - 45.561 - ], - [ - -75.44094366197183, - 45.5619014084507 - ], - [ - -75.441, - 45.562 - ], - [ - -75.437, - 45.568 - ], - [ - -75.428, - 45.571 - ], - [ - -75.419, - 45.568 - ], - [ - -75.41614285714286, - 45.56371428571428 - ], - [ - -75.41600000000007, - 45.563666666666684 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.344, - 45.442 - ], - [ - -76.335, - 45.44 - ], - [ - -76.33405454545453, - 45.438345454545455 - ], - [ - -76.328, - 45.437 - ], - [ - -76.324, - 45.43 - ], - [ - -76.328, - 45.424 - ], - [ - -76.337, - 45.421 - ], - [ - -76.346, - 45.424 - ], - [ - -76.34657142857144, - 45.42485714285714 - ], - [ - -76.353, - 45.427 - ], - [ - -76.356, - 45.433 - ], - [ - -76.353, - 45.44 - ], - [ - -76.344, - 45.442 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.326, - 45.201 - ], - [ - -76.317, - 45.198 - ], - [ - -76.314, - 45.192 - ], - [ - -76.317, - 45.186 - ], - [ - -76.326, - 45.183 - ], - [ - -76.335, - 45.186 - ], - [ - -76.339, - 45.192 - ], - [ - -76.335, - 45.198 - ], - [ - -76.326, - 45.201 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.106, - 45.116 - ], - [ - -76.097, - 45.113 - ], - [ - -76.093, - 45.107 - ], - [ - -76.097, - 45.1 - ], - [ - -76.106, - 45.098 - ], - [ - -76.115, - 45.1 - ], - [ - -76.118, - 45.107 - ], - [ - -76.115, - 45.113 - ], - [ - -76.106, - 45.116 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.931, - 45.692 - ], - [ - -75.922, - 45.689 - ], - [ - -75.918, - 45.683 - ], - [ - -75.922, - 45.676 - ], - [ - -75.931, - 45.674 - ], - [ - -75.94, - 45.676 - ], - [ - -75.944, - 45.683 - ], - [ - -75.94, - 45.689 - ], - [ - -75.931, - 45.692 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.772, - 45.484 - ], - [ - -75.763, - 45.481 - ], - [ - -75.759, - 45.475 - ], - [ - -75.76294366197183, - 45.4680985915493 - ], - [ - -75.758, - 45.467 - ], - [ - -75.754, - 45.46 - ], - [ - -75.758, - 45.454 - ], - [ - -75.767, - 45.451 - ], - [ - -75.776, - 45.454 - ], - [ - -75.78, - 45.46 - ], - [ - -75.77605633802817, - 45.4669014084507 - ], - [ - -75.781, - 45.468 - ], - [ - -75.785, - 45.475 - ], - [ - -75.781, - 45.481 - ], - [ - -75.772, - 45.484 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.82860869565218, - 45.192086956521734 - ], - [ - -75.832, - 45.187 - ], - [ - -75.841, - 45.184 - ], - [ - -75.85, - 45.187 - ], - [ - -75.854, - 45.193 - ], - [ - -75.85, - 45.199 - ], - [ - -75.84142857142858, - 45.201857142857136 - ], - [ - -75.838, - 45.207 - ], - [ - -75.83371428571428, - 45.20842857142857 - ], - [ - -75.832, - 45.211 - ], - [ - -75.823, - 45.214 - ], - [ - -75.814, - 45.211 - ], - [ - -75.81, - 45.205 - ], - [ - -75.814, - 45.198 - ], - [ - -75.81873684210525, - 45.19694736842105 - ], - [ - -75.82, - 45.194 - ], - [ - -75.82860869565218, - 45.192086956521734 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.228, - 45.248 - ], - [ - -76.219, - 45.246 - ], - [ - -76.216, - 45.239 - ], - [ - -76.219, - 45.233 - ], - [ - -76.228, - 45.23 - ], - [ - -76.237, - 45.233 - ], - [ - -76.241, - 45.239 - ], - [ - -76.237, - 45.246 - ], - [ - -76.228, - 45.248 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.188, - 45.217 - ], - [ - -76.179, - 45.214 - ], - [ - -76.175, - 45.208 - ], - [ - -76.179, - 45.201 - ], - [ - -76.188, - 45.199 - ], - [ - -76.197, - 45.201 - ], - [ - -76.201, - 45.208 - ], - [ - -76.197, - 45.214 - ], - [ - -76.188, - 45.217 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.518, - 45.25 - ], - [ - -75.509, - 45.248 - ], - [ - -75.505, - 45.241 - ], - [ - -75.509, - 45.235 - ], - [ - -75.518, - 45.232 - ], - [ - -75.527, - 45.235 - ], - [ - -75.531, - 45.241 - ], - [ - -75.527, - 45.248 - ], - [ - -75.518, - 45.25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -74.902, - 45.385 - ], - [ - -74.893, - 45.382 - ], - [ - -74.89, - 45.376 - ], - [ - -74.893, - 45.369 - ], - [ - -74.902, - 45.367 - ], - [ - -74.911, - 45.369 - ], - [ - -74.915, - 45.376 - ], - [ - -74.911, - 45.382 - ], - [ - -74.902, - 45.385 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.73424489795917, - 45.48842857142857 - ], - [ - -75.734, - 45.488 - ], - [ - -75.73519999999999, - 45.4862 - ], - [ - -75.737, - 45.482 - ], - [ - -75.7395, - 45.4815 - ], - [ - -75.747, - 45.479 - ], - [ - -75.756, - 45.482 - ], - [ - -75.76, - 45.488 - ], - [ - -75.756, - 45.495 - ], - [ - -75.747, - 45.498 - ], - [ - -75.737, - 45.495 - ], - [ - -75.734, - 45.489 - ], - [ - -75.73424489795917, - 45.48842857142857 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.711, - 45.137 - ], - [ - -75.702, - 45.134 - ], - [ - -75.699, - 45.128 - ], - [ - -75.702, - 45.121 - ], - [ - -75.711, - 45.119 - ], - [ - -75.72, - 45.121 - ], - [ - -75.724, - 45.128 - ], - [ - -75.72, - 45.134 - ], - [ - -75.711, - 45.137 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.491, - 45.364 - ], - [ - -76.482, - 45.361 - ], - [ - -76.478, - 45.355 - ], - [ - -76.482, - 45.349 - ], - [ - -76.491, - 45.346 - ], - [ - -76.5, - 45.349 - ], - [ - -76.504, - 45.355 - ], - [ - -76.5, - 45.361 - ], - [ - -76.491, - 45.364 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.303, - 45.277 - ], - [ - -75.3015, - 45.276500000000006 - ], - [ - -75.294, - 45.279 - ], - [ - -75.285, - 45.276 - ], - [ - -75.281, - 45.27 - ], - [ - -75.285, - 45.263 - ], - [ - -75.294, - 45.261 - ], - [ - -75.303, - 45.259 - ], - [ - -75.312, - 45.261 - ], - [ - -75.316, - 45.268 - ], - [ - -75.312, - 45.274 - ], - [ - -75.303, - 45.277 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.245, - 44.984 - ], - [ - -75.236, - 44.982 - ], - [ - -75.232, - 44.975 - ], - [ - -75.236, - 44.969 - ], - [ - -75.245, - 44.966 - ], - [ - -75.254, - 44.969 - ], - [ - -75.257, - 44.975 - ], - [ - -75.254, - 44.982 - ], - [ - -75.245, - 44.984 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.283, - 45.417 - ], - [ - -76.273, - 45.415 - ], - [ - -76.27, - 45.408 - ], - [ - -76.273, - 45.402 - ], - [ - -76.283, - 45.399 - ], - [ - -76.292, - 45.402 - ], - [ - -76.295, - 45.408 - ], - [ - -76.292, - 45.415 - ], - [ - -76.283, - 45.417 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.059, - 45.048 - ], - [ - -76.05, - 45.045 - ], - [ - -76.047, - 45.039 - ], - [ - -76.05, - 45.033 - ], - [ - -76.059, - 45.03 - ], - [ - -76.068, - 45.033 - ], - [ - -76.072, - 45.039 - ], - [ - -76.068, - 45.045 - ], - [ - -76.059, - 45.048 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -74.956, - 45.553 - ], - [ - -74.946, - 45.55 - ], - [ - -74.943, - 45.544 - ], - [ - -74.946, - 45.537 - ], - [ - -74.956, - 45.535 - ], - [ - -74.965, - 45.537 - ], - [ - -74.968, - 45.544 - ], - [ - -74.965, - 45.55 - ], - [ - -74.956, - 45.553 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.12, - 45.576 - ], - [ - -75.111, - 45.574 - ], - [ - -75.108, - 45.567 - ], - [ - -75.111, - 45.561 - ], - [ - -75.12, - 45.558 - ], - [ - -75.129, - 45.561 - ], - [ - -75.133, - 45.567 - ], - [ - -75.129, - 45.574 - ], - [ - -75.12, - 45.576 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.51, - 45.448 - ], - [ - -76.501, - 45.445 - ], - [ - -76.497, - 45.439 - ], - [ - -76.501, - 45.432 - ], - [ - -76.51, - 45.43 - ], - [ - -76.519, - 45.432 - ], - [ - -76.523, - 45.439 - ], - [ - -76.519, - 45.445 - ], - [ - -76.51, - 45.448 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -74.931, - 45.443 - ], - [ - -74.922, - 45.44 - ], - [ - -74.918, - 45.434 - ], - [ - -74.922, - 45.428 - ], - [ - -74.931, - 45.425 - ], - [ - -74.94, - 45.428 - ], - [ - -74.944, - 45.434 - ], - [ - -74.94, - 45.44 - ], - [ - -74.931, - 45.443 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.014, - 45.626 - ], - [ - -75.005, - 45.624 - ], - [ - -75.001, - 45.617 - ], - [ - -75.005, - 45.611 - ], - [ - -75.014, - 45.608 - ], - [ - -75.01542105263158, - 45.60847368421052 - ], - [ - -75.017, - 45.608 - ], - [ - -75.026, - 45.611 - ], - [ - -75.029, - 45.617 - ], - [ - -75.026, - 45.624 - ], - [ - -75.017, - 45.626 - ], - [ - -75.01542105263158, - 45.625684210526316 - ], - [ - -75.014, - 45.626 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.2282857142857, - 45.597500000000004 - ], - [ - -75.228, - 45.597 - ], - [ - -75.232, - 45.591 - ], - [ - -75.241, - 45.588 - ], - [ - -75.25, - 45.591 - ], - [ - -75.254, - 45.597 - ], - [ - -75.2537142857143, - 45.597500000000004 - ], - [ - -75.254, - 45.598 - ], - [ - -75.25, - 45.604 - ], - [ - -75.241, - 45.607 - ], - [ - -75.232, - 45.604 - ], - [ - -75.228, - 45.598 - ], - [ - -75.2282857142857, - 45.597500000000004 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -74.948, - 45.659 - ], - [ - -74.939, - 45.657 - ], - [ - -74.935, - 45.65 - ], - [ - -74.939, - 45.644 - ], - [ - -74.948, - 45.641 - ], - [ - -74.957, - 45.644 - ], - [ - -74.96, - 45.65 - ], - [ - -74.957, - 45.657 - ], - [ - -74.948, - 45.659 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.637, - 45.208 - ], - [ - -75.628, - 45.205 - ], - [ - -75.625, - 45.199 - ], - [ - -75.628, - 45.192 - ], - [ - -75.637, - 45.19 - ], - [ - -75.646, - 45.192 - ], - [ - -75.65, - 45.199 - ], - [ - -75.646, - 45.205 - ], - [ - -75.637, - 45.208 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.43, - 45.263 - ], - [ - -75.421, - 45.261 - ], - [ - -75.417, - 45.254 - ], - [ - -75.421, - 45.248 - ], - [ - -75.43, - 45.245 - ], - [ - -75.439, - 45.248 - ], - [ - -75.443, - 45.254 - ], - [ - -75.439, - 45.261 - ], - [ - -75.43, - 45.263 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.525, - 45.351 - ], - [ - -75.516, - 45.349 - ], - [ - -75.512, - 45.342 - ], - [ - -75.516, - 45.336 - ], - [ - -75.525, - 45.333 - ], - [ - -75.534, - 45.336 - ], - [ - -75.538, - 45.342 - ], - [ - -75.534, - 45.349 - ], - [ - -75.525, - 45.351 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.12, - 45.615 - ], - [ - -75.111, - 45.612 - ], - [ - -75.107, - 45.606 - ], - [ - -75.111, - 45.599 - ], - [ - -75.12, - 45.597 - ], - [ - -75.129, - 45.599 - ], - [ - -75.133, - 45.606 - ], - [ - -75.129, - 45.612 - ], - [ - -75.12, - 45.615 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.497, - 45.539 - ], - [ - -75.487, - 45.537 - ], - [ - -75.484, - 45.53 - ], - [ - -75.487, - 45.524 - ], - [ - -75.497, - 45.521 - ], - [ - -75.506, - 45.524 - ], - [ - -75.509, - 45.53 - ], - [ - -75.506, - 45.537 - ], - [ - -75.497, - 45.539 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.571, - 45.507 - ], - [ - -75.562, - 45.505 - ], - [ - -75.558, - 45.498 - ], - [ - -75.562, - 45.492 - ], - [ - -75.571, - 45.489 - ], - [ - -75.58, - 45.492 - ], - [ - -75.584, - 45.498 - ], - [ - -75.58, - 45.505 - ], - [ - -75.571, - 45.507 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.6, - 45.497 - ], - [ - -75.591, - 45.495 - ], - [ - -75.587, - 45.488 - ], - [ - -75.591, - 45.482 - ], - [ - -75.59373913043478, - 45.481391304347824 - ], - [ - -75.594, - 45.481 - ], - [ - -75.603, - 45.478 - ], - [ - -75.612, - 45.481 - ], - [ - -75.616, - 45.487 - ], - [ - -75.612, - 45.493 - ], - [ - -75.61094117647059, - 45.49335294117647 - ], - [ - -75.61, - 45.495 - ], - [ - -75.601, - 45.497 - ], - [ - -75.6005, - 45.49688888888889 - ], - [ - -75.6, - 45.497 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.609, - 45.516 - ], - [ - -75.6, - 45.513 - ], - [ - -75.596, - 45.507 - ], - [ - -75.6, - 45.501 - ], - [ - -75.609, - 45.498 - ], - [ - -75.618, - 45.501 - ], - [ - -75.622, - 45.507 - ], - [ - -75.618, - 45.513 - ], - [ - -75.609, - 45.516 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.272, - 45.563 - ], - [ - -75.263, - 45.56 - ], - [ - -75.259, - 45.554 - ], - [ - -75.263, - 45.547 - ], - [ - -75.272, - 45.545 - ], - [ - -75.281, - 45.547 - ], - [ - -75.284, - 45.554 - ], - [ - -75.281, - 45.56 - ], - [ - -75.272, - 45.563 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.647, - 45.158 - ], - [ - -75.638, - 45.155 - ], - [ - -75.634, - 45.149 - ], - [ - -75.638, - 45.142 - ], - [ - -75.647, - 45.14 - ], - [ - -75.656, - 45.142 - ], - [ - -75.659, - 45.149 - ], - [ - -75.656, - 45.155 - ], - [ - -75.647, - 45.158 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.193, - 45.435 - ], - [ - -75.184, - 45.433 - ], - [ - -75.18, - 45.426 - ], - [ - -75.184, - 45.42 - ], - [ - -75.193, - 45.417 - ], - [ - -75.202, - 45.42 - ], - [ - -75.206, - 45.426 - ], - [ - -75.202, - 45.433 - ], - [ - -75.193, - 45.435 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.057, - 45.74 - ], - [ - -75.048, - 45.737 - ], - [ - -75.044, - 45.731 - ], - [ - -75.048, - 45.725 - ], - [ - -75.057, - 45.722 - ], - [ - -75.066, - 45.725 - ], - [ - -75.07, - 45.731 - ], - [ - -75.066, - 45.737 - ], - [ - -75.057, - 45.74 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.811, - 45.512 - ], - [ - -75.801, - 45.51 - ], - [ - -75.798, - 45.503 - ], - [ - -75.801, - 45.497 - ], - [ - -75.811, - 45.494 - ], - [ - -75.82, - 45.497 - ], - [ - -75.823, - 45.503 - ], - [ - -75.82, - 45.51 - ], - [ - -75.811, - 45.512 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.341, - 45.085 - ], - [ - -75.332, - 45.082 - ], - [ - -75.328, - 45.076 - ], - [ - -75.332, - 45.069 - ], - [ - -75.341, - 45.067 - ], - [ - -75.35, - 45.069 - ], - [ - -75.354, - 45.076 - ], - [ - -75.35, - 45.082 - ], - [ - -75.341, - 45.085 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.711, - 45.798 - ], - [ - -75.702, - 45.795 - ], - [ - -75.698, - 45.789 - ], - [ - -75.702, - 45.783 - ], - [ - -75.711, - 45.78 - ], - [ - -75.72, - 45.783 - ], - [ - -75.724, - 45.789 - ], - [ - -75.72, - 45.795 - ], - [ - -75.711, - 45.798 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.617, - 45.605 - ], - [ - -75.608, - 45.602 - ], - [ - -75.604, - 45.596 - ], - [ - -75.608, - 45.589 - ], - [ - -75.617, - 45.587 - ], - [ - -75.626, - 45.589 - ], - [ - -75.63, - 45.596 - ], - [ - -75.626, - 45.602 - ], - [ - -75.617, - 45.605 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.109, - 45.185 - ], - [ - -75.1, - 45.182 - ], - [ - -75.096, - 45.176 - ], - [ - -75.1, - 45.17 - ], - [ - -75.109, - 45.167 - ], - [ - -75.118, - 45.17 - ], - [ - -75.122, - 45.176 - ], - [ - -75.118, - 45.182 - ], - [ - -75.109, - 45.185 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.151, - 45.225 - ], - [ - -75.142, - 45.223 - ], - [ - -75.138, - 45.216 - ], - [ - -75.142, - 45.21 - ], - [ - -75.151, - 45.207 - ], - [ - -75.16, - 45.21 - ], - [ - -75.164, - 45.216 - ], - [ - -75.16, - 45.223 - ], - [ - -75.151, - 45.225 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.293, - 45.041 - ], - [ - -75.284, - 45.038 - ], - [ - -75.281, - 45.032 - ], - [ - -75.284, - 45.026 - ], - [ - -75.293, - 45.023 - ], - [ - -75.302, - 45.026 - ], - [ - -75.306, - 45.032 - ], - [ - -75.302, - 45.038 - ], - [ - -75.293, - 45.041 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.581, - 45.306 - ], - [ - -75.572, - 45.303 - ], - [ - -75.568, - 45.297 - ], - [ - -75.572, - 45.291 - ], - [ - -75.581, - 45.288 - ], - [ - -75.59, - 45.291 - ], - [ - -75.593, - 45.297 - ], - [ - -75.59, - 45.303 - ], - [ - -75.581, - 45.306 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.021, - 45.548 - ], - [ - -76.011, - 45.545 - ], - [ - -76.008, - 45.539 - ], - [ - -76.011, - 45.532 - ], - [ - -76.021, - 45.53 - ], - [ - -76.03, - 45.532 - ], - [ - -76.033, - 45.539 - ], - [ - -76.03, - 45.545 - ], - [ - -76.021, - 45.548 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.4, - 45.468 - ], - [ - -76.391, - 45.466 - ], - [ - -76.387, - 45.459 - ], - [ - -76.391, - 45.453 - ], - [ - -76.4, - 45.45 - ], - [ - -76.409, - 45.453 - ], - [ - -76.413, - 45.459 - ], - [ - -76.409, - 45.466 - ], - [ - -76.4, - 45.468 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.401, - 45.585 - ], - [ - -75.391, - 45.582 - ], - [ - -75.388, - 45.576 - ], - [ - -75.391, - 45.569 - ], - [ - -75.401, - 45.567 - ], - [ - -75.41, - 45.569 - ], - [ - -75.413, - 45.576 - ], - [ - -75.41, - 45.582 - ], - [ - -75.401, - 45.585 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.23, - 45.53 - ], - [ - -76.221, - 45.527 - ], - [ - -76.217, - 45.521 - ], - [ - -76.221, - 45.514 - ], - [ - -76.23, - 45.512 - ], - [ - -76.239, - 45.514 - ], - [ - -76.243, - 45.521 - ], - [ - -76.239, - 45.527 - ], - [ - -76.23, - 45.53 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-dissolve/test/out/polysByProperty.geojson b/packages/turf-dissolve/test/out/polysByProperty.geojson deleted file mode 100644 index e658973dea..0000000000 --- a/packages/turf-dissolve/test/out/polysByProperty.geojson +++ /dev/null @@ -1,173 +0,0 @@ -{ - "type": "FeatureCollection", - "propertyName": "combine", - "features": [ - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0.4450683930362929, - 0.10986321392741416 - ], - [ - 0, - 1 - ], - [ - 1, - 1 - ], - [ - 2, - 1 - ], - [ - 2, - 0 - ], - [ - 1.2362060546874962, - 0 - ], - [ - 1.2362060546874962, - -0.8901516807502449 - ], - [ - 0.23620605468749623, - -0.8901516807502449 - ], - [ - 0.23620605468749623, - 0.10986321392741416 - ], - [ - 0.4450683930362929, - 0.10986321392741416 - ] - ], - [ - [ - 1, - 0.10986321392741416 - ], - [ - 1, - 0.5 - ], - [ - 0.7659179283564485, - 0.10986321392741416 - ], - [ - 1, - 0.10986321392741416 - ] - ] - ] - }, - "properties": { - "stroke": "#555555", - "stroke-width": 2, - "stroke-opacity": 1, - "fill": "#ff0000", - "fill-opacity": 0.5, - "combine": "yes" - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 1.516113281250002, - 0 - ], - [ - 2, - 0 - ], - [ - 2, - -1 - ], - [ - 1.516113281250002, - -1 - ], - [ - 1.516113281250002, - -1.647722051796948 - ], - [ - 0.851440429687502, - -1.647722051796948 - ], - [ - 0.851440429687502, - 1.4500404973607692 - ], - [ - 1.516113281250002, - 1.4500404973607692 - ], - [ - 1.516113281250002, - 0 - ] - ] - ] - }, - "properties": { - "stroke": "#555555", - "stroke-width": 2, - "stroke-opacity": 1, - "fill": "#00ff00", - "fill-opacity": 0.5, - "combine": "no" - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#555555", - "stroke-width": 2, - "stroke-opacity": 1, - "fill": "#ffff00", - "fill-opacity": 0.5 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -0.252685546875, - 1.252341676699629 - ], - [ - -0.252685546875, - 1.653212936926045 - ], - [ - 0.28564453125, - 1.653212936926045 - ], - [ - 0.28564453125, - 1.252341676699629 - ], - [ - -0.252685546875, - 1.252341676699629 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-dissolve/test/out/polysWithoutProperty.geojson b/packages/turf-dissolve/test/out/polysWithoutProperty.geojson deleted file mode 100644 index 47b1af4b3b..0000000000 --- a/packages/turf-dissolve/test/out/polysWithoutProperty.geojson +++ /dev/null @@ -1,142 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0.4450683930362929, - 0.10986321392741416 - ], - [ - 0, - 1 - ], - [ - 0.851440429687502, - 1 - ], - [ - 0.851440429687502, - 1.4500404973607692 - ], - [ - 1.516113281250002, - 1.4500404973607692 - ], - [ - 1.516113281250002, - 1 - ], - [ - 2, - 1 - ], - [ - 2, - 0 - ], - [ - 2, - -1 - ], - [ - 1.516113281250002, - -1 - ], - [ - 1.516113281250002, - -1.647722051796948 - ], - [ - 0.851440429687502, - -1.647722051796948 - ], - [ - 0.851440429687502, - -0.8901516807502449 - ], - [ - 0.23620605468749623, - -0.8901516807502449 - ], - [ - 0.23620605468749623, - 0.10986321392741416 - ], - [ - 0.4450683930362929, - 0.10986321392741416 - ] - ], - [ - [ - 0.851440429687502, - 0.2524007161458367 - ], - [ - 0.7659179283564485, - 0.10986321392741416 - ], - [ - 0.851440429687502, - 0.10986321392741416 - ], - [ - 0.851440429687502, - 0.2524007161458367 - ] - ] - ] - }, - "properties": { - "stroke": "#555555", - "stroke-width": 2, - "stroke-opacity": 1, - "fill": "#ff0000", - "fill-opacity": 0.5, - "combine": "yes" - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#555555", - "stroke-width": 2, - "stroke-opacity": 1, - "fill": "#ffff00", - "fill-opacity": 0.5 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -0.252685546875, - 1.252341676699629 - ], - [ - -0.252685546875, - 1.653212936926045 - ], - [ - 0.28564453125, - 1.653212936926045 - ], - [ - 0.28564453125, - 1.252341676699629 - ], - [ - -0.252685546875, - 1.252341676699629 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-dissolve/test/out/simplified-issue.geojson b/packages/turf-dissolve/test/out/simplified-issue.geojson deleted file mode 100644 index 98bcd2628b..0000000000 --- a/packages/turf-dissolve/test/out/simplified-issue.geojson +++ /dev/null @@ -1,2228 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.68227272727272, - 45.33590909090909 - ], - [ - -75.681, - 45.334 - ], - [ - -75.685, - 45.327 - ], - [ - -75.694, - 45.325 - ], - [ - -75.698, - 45.32588888888889 - ], - [ - -75.702, - 45.325 - ], - [ - -75.711, - 45.327 - ], - [ - -75.71346153846154, - 45.331307692307696 - ], - [ - -75.715, - 45.329 - ], - [ - -75.724, - 45.326 - ], - [ - -75.733, - 45.329 - ], - [ - -75.736, - 45.335 - ], - [ - -75.735625, - 45.335875 - ], - [ - -75.739, - 45.337 - ], - [ - -75.742, - 45.343 - ], - [ - -75.74175000000001, - 45.343583333333335 - ], - [ - -75.743, - 45.344 - ], - [ - -75.746, - 45.35 - ], - [ - -75.743, - 45.357 - ], - [ - -75.734, - 45.359 - ], - [ - -75.725, - 45.357 - ], - [ - -75.721, - 45.35 - ], - [ - -75.717, - 45.343 - ], - [ - -75.71732258064516, - 45.342516129032255 - ], - [ - -75.715, - 45.342 - ], - [ - -75.71244, - 45.34648 - ], - [ - -75.714, - 45.347 - ], - [ - -75.717, - 45.353 - ], - [ - -75.714, - 45.36 - ], - [ - -75.708, - 45.361333333333334 - ], - [ - -75.711, - 45.362 - ], - [ - -75.71166666666667, - 45.36355555555556 - ], - [ - -75.713, - 45.364 - ], - [ - -75.717, - 45.37 - ], - [ - -75.713, - 45.377 - ], - [ - -75.704, - 45.379 - ], - [ - -75.695, - 45.377 - ], - [ - -75.69424137931034, - 45.375672413793104 - ], - [ - -75.692, - 45.375 - ], - [ - -75.689, - 45.369 - ], - [ - -75.692, - 45.362 - ], - [ - -75.69884210526315, - 45.36063157894737 - ], - [ - -75.696, - 45.36 - ], - [ - -75.692, - 45.353 - ], - [ - -75.69373913043478, - 45.35039130434782 - ], - [ - -75.691, - 45.351 - ], - [ - -75.682, - 45.349 - ], - [ - -75.678, - 45.342 - ], - [ - -75.682, - 45.336 - ], - [ - -75.68227272727272, - 45.33590909090909 - ] - ], - [ - [ - -75.715, - 45.342 - ], - [ - -75.71253846153846, - 45.33769230769231 - ], - [ - -75.71233333333333, - 45.337999999999994 - ], - [ - -75.715, - 45.342 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.618, - 45.398 - ], - [ - -75.627, - 45.395 - ], - [ - -75.631, - 45.389 - ], - [ - -75.627, - 45.383 - ], - [ - -75.618, - 45.38 - ], - [ - -75.609, - 45.383 - ], - [ - -75.606, - 45.389 - ], - [ - -75.609, - 45.395 - ], - [ - -75.618, - 45.398 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.63419999999999, - 45.43593333333334 - ], - [ - -75.63, - 45.435 - ], - [ - -75.62976470588235, - 45.43458823529412 - ], - [ - -75.62899999999996, - 45.43433333333333 - ], - [ - -75.623, - 45.433 - ], - [ - -75.62252941176472, - 45.43217647058824 - ], - [ - -75.622, - 45.432 - ], - [ - -75.61974193548387, - 45.428612903225805 - ], - [ - -75.618, - 45.429 - ], - [ - -75.609, - 45.427 - ], - [ - -75.605, - 45.42 - ], - [ - -75.609, - 45.414 - ], - [ - -75.61757142857144, - 45.411142857142856 - ], - [ - -75.621, - 45.406 - ], - [ - -75.63, - 45.403 - ], - [ - -75.634, - 45.404333333333334 - ], - [ - -75.641, - 45.402 - ], - [ - -75.65, - 45.405 - ], - [ - -75.654, - 45.411 - ], - [ - -75.65, - 45.417 - ], - [ - -75.64500000000001, - 45.41866666666667 - ], - [ - -75.646, - 45.419 - ], - [ - -75.64683870967743, - 45.420258064516126 - ], - [ - -75.648, - 45.42 - ], - [ - -75.657, - 45.422 - ], - [ - -75.661, - 45.429 - ], - [ - -75.66, - 45.4305 - ], - [ - -75.661, - 45.432 - ], - [ - -75.66081818181819, - 45.43227272727273 - ], - [ - -75.663, - 45.433 - ], - [ - -75.667, - 45.439 - ], - [ - -75.663, - 45.445 - ], - [ - -75.66183333333333, - 45.445388888888886 - ], - [ - -75.659, - 45.452 - ], - [ - -75.65, - 45.454 - ], - [ - -75.641, - 45.452 - ], - [ - -75.64084, - 45.451719999999995 - ], - [ - -75.64, - 45.452 - ], - [ - -75.6388, - 45.4516 - ], - [ - -75.638, - 45.453 - ], - [ - -75.629, - 45.455 - ], - [ - -75.62, - 45.453 - ], - [ - -75.616, - 45.446 - ], - [ - -75.62, - 45.44 - ], - [ - -75.629, - 45.437 - ], - [ - -75.63071428571429, - 45.437571428571424 - ], - [ - -75.631, - 45.437 - ], - [ - -75.63419999999999, - 45.43593333333334 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.763, - 45.382999999999996 - ], - [ - -75.763, - 45.383 - ], - [ - -75.75742857142856, - 45.38485714285715 - ], - [ - -75.75735483870967, - 45.38496774193548 - ], - [ - -75.762, - 45.386 - ], - [ - -75.766, - 45.393 - ], - [ - -75.762, - 45.399 - ], - [ - -75.75370588235293, - 45.40176470588236 - ], - [ - -75.753, - 45.403 - ], - [ - -75.75136363636365, - 45.403363636363636 - ], - [ - -75.751, - 45.404 - ], - [ - -75.7424909090909, - 45.40589090909091 - ], - [ - -75.739, - 45.412 - ], - [ - -75.73, - 45.414 - ], - [ - -75.721, - 45.412 - ], - [ - -75.717, - 45.405 - ], - [ - -75.71814285714285, - 45.403285714285715 - ], - [ - -75.717, - 45.401 - ], - [ - -75.71815384615385, - 45.3983076923077 - ], - [ - -75.718, - 45.398 - ], - [ - -75.721, - 45.391 - ], - [ - -75.72925000000001, - 45.38916666666667 - ], - [ - -75.724, - 45.388 - ], - [ - -75.721, - 45.381 - ], - [ - -75.724, - 45.375 - ], - [ - -75.733, - 45.372 - ], - [ - -75.73895744680851, - 45.37378723404255 - ], - [ - -75.7438695652174, - 45.37269565217391 - ], - [ - -75.745, - 45.371 - ], - [ - -75.74729411764706, - 45.37023529411765 - ], - [ - -75.748, - 45.369 - ], - [ - -75.757, - 45.367 - ], - [ - -75.76067605633803, - 45.367816901408446 - ], - [ - -75.764, - 45.362 - ], - [ - -75.773, - 45.36 - ], - [ - -75.782, - 45.362 - ], - [ - -75.786, - 45.369 - ], - [ - -75.782, - 45.375 - ], - [ - -75.773, - 45.378 - ], - [ - -75.76945454545454, - 45.37681818181818 - ], - [ - -75.766, - 45.382 - ], - [ - -75.763, - 45.382999999999996 - ] - ], - [ - [ - -75.73493548387097, - 45.390096774193545 - ], - [ - -75.735, - 45.39 - ], - [ - -75.73799999999999, - 45.38933333333334 - ], - [ - -75.74033333333334, - 45.388555555555556 - ], - [ - -75.74034375000001, - 45.38853125 - ], - [ - -75.73378947368423, - 45.389842105263156 - ], - [ - -75.73493548387097, - 45.390096774193545 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.588, - 45.458 - ], - [ - -75.597, - 45.456 - ], - [ - -75.601, - 45.449 - ], - [ - -75.597, - 45.443 - ], - [ - -75.588, - 45.44 - ], - [ - -75.579, - 45.443 - ], - [ - -75.575, - 45.449 - ], - [ - -75.579, - 45.456 - ], - [ - -75.588, - 45.458 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.65966666666667, - 45.347 - ], - [ - -75.657, - 45.343 - ], - [ - -75.661, - 45.337 - ], - [ - -75.67, - 45.334 - ], - [ - -75.679, - 45.337 - ], - [ - -75.683, - 45.343 - ], - [ - -75.68033333333334, - 45.347 - ], - [ - -75.683, - 45.351 - ], - [ - -75.679, - 45.357 - ], - [ - -75.67, - 45.36 - ], - [ - -75.661, - 45.357 - ], - [ - -75.659, - 45.354000000000006 - ], - [ - -75.655, - 45.36 - ], - [ - -75.646, - 45.363 - ], - [ - -75.6448, - 45.3626 - ], - [ - -75.643, - 45.363 - ], - [ - -75.64273913043479, - 45.36294202898551 - ], - [ - -75.641, - 45.367 - ], - [ - -75.631, - 45.369 - ], - [ - -75.622, - 45.367 - ], - [ - -75.619, - 45.36 - ], - [ - -75.62114285714286, - 45.355714285714285 - ], - [ - -75.616, - 45.354 - ], - [ - -75.612, - 45.348 - ], - [ - -75.616, - 45.342 - ], - [ - -75.625, - 45.339 - ], - [ - -75.634, - 45.342 - ], - [ - -75.63677419354839, - 45.34616129032258 - ], - [ - -75.642, - 45.345 - ], - [ - -75.6425, - 45.34511111111111 - ], - [ - -75.643, - 45.345 - ], - [ - -75.6448, - 45.3454 - ], - [ - -75.646, - 45.345 - ], - [ - -75.655, - 45.348 - ], - [ - -75.657, - 45.35099999999999 - ], - [ - -75.65966666666667, - 45.347 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.5945, - 45.456833333333336 - ], - [ - -75.594, - 45.457 - ], - [ - -75.585, - 45.454 - ], - [ - -75.581, - 45.448 - ], - [ - -75.585, - 45.441 - ], - [ - -75.59374647887324, - 45.439056338028166 - ], - [ - -75.592, - 45.436 - ], - [ - -75.596, - 45.43 - ], - [ - -75.60371428571428, - 45.42742857142857 - ], - [ - -75.604, - 45.427 - ], - [ - -75.613, - 45.424 - ], - [ - -75.622, - 45.427 - ], - [ - -75.625, - 45.433 - ], - [ - -75.622, - 45.44 - ], - [ - -75.61524999999999, - 45.4415 - ], - [ - -75.615, - 45.442 - ], - [ - -75.61433333333333, - 45.44222222222222 - ], - [ - -75.614, - 45.443 - ], - [ - -75.60799999999996, - 45.44433333333334 - ], - [ - -75.60624, - 45.444919999999996 - ], - [ - -75.608, - 45.448 - ], - [ - -75.604, - 45.454 - ], - [ - -75.595, - 45.457 - ], - [ - -75.5945, - 45.456833333333336 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.7552, - 45.3676 - ], - [ - -75.757, - 45.367 - ], - [ - -75.766, - 45.37 - ], - [ - -75.77, - 45.376 - ], - [ - -75.766, - 45.383 - ], - [ - -75.76321818181819, - 45.383618181818186 - ], - [ - -75.763, - 45.384 - ], - [ - -75.754, - 45.386 - ], - [ - -75.745, - 45.384 - ], - [ - -75.74429411764706, - 45.38276470588235 - ], - [ - -75.739, - 45.381 - ], - [ - -75.735, - 45.375 - ], - [ - -75.739, - 45.368 - ], - [ - -75.748, - 45.366 - ], - [ - -75.7552, - 45.3676 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.64, - 45.389 - ], - [ - -75.63181818181818, - 45.39172727272727 - ], - [ - -75.634, - 45.395 - ], - [ - -75.63342857142857, - 45.396 - ], - [ - -75.634, - 45.397 - ], - [ - -75.63, - 45.403 - ], - [ - -75.621, - 45.406 - ], - [ - -75.612, - 45.403 - ], - [ - -75.608, - 45.397 - ], - [ - -75.60906122448979, - 45.395142857142865 - ], - [ - -75.609, - 45.395 - ], - [ - -75.612, - 45.389 - ], - [ - -75.62018181818182, - 45.38627272727273 - ], - [ - -75.618, - 45.383 - ], - [ - -75.6190909090909, - 45.38136363636364 - ], - [ - -75.615, - 45.38 - ], - [ - -75.611, - 45.374 - ], - [ - -75.615, - 45.368 - ], - [ - -75.624, - 45.365 - ], - [ - -75.633, - 45.368 - ], - [ - -75.6359090909091, - 45.37236363636364 - ], - [ - -75.64, - 45.371 - ], - [ - -75.649, - 45.374 - ], - [ - -75.652, - 45.38 - ], - [ - -75.649, - 45.387 - ], - [ - -75.64, - 45.389 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.67790909090908, - 45.43563636363636 - ], - [ - -75.675, - 45.44 - ], - [ - -75.666, - 45.443 - ], - [ - -75.657, - 45.44 - ], - [ - -75.653, - 45.434 - ], - [ - -75.657, - 45.428 - ], - [ - -75.666, - 45.425 - ], - [ - -75.673625, - 45.42754166666666 - ], - [ - -75.676, - 45.422 - ], - [ - -75.685, - 45.42 - ], - [ - -75.68516363636364, - 45.42003636363636 - ], - [ - -75.684, - 45.418 - ], - [ - -75.688, - 45.412 - ], - [ - -75.69357142857143, - 45.41014285714286 - ], - [ - -75.697, - 45.405 - ], - [ - -75.706, - 45.402 - ], - [ - -75.715, - 45.405 - ], - [ - -75.719, - 45.411 - ], - [ - -75.715, - 45.417 - ], - [ - -75.70952941176469, - 45.41882352941177 - ], - [ - -75.706, - 45.425 - ], - [ - -75.697, - 45.427 - ], - [ - -75.69683636363636, - 45.42696363636363 - ], - [ - -75.698, - 45.429 - ], - [ - -75.694, - 45.435 - ], - [ - -75.685, - 45.438 - ], - [ - -75.67790909090908, - 45.43563636363636 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.65925352112676, - 45.440056338028164 - ], - [ - -75.659, - 45.44 - ], - [ - -75.656, - 45.433 - ], - [ - -75.659, - 45.427 - ], - [ - -75.668, - 45.424 - ], - [ - -75.66900000000001, - 45.42433333333333 - ], - [ - -75.67, - 45.424 - ], - [ - -75.6722, - 45.424733333333336 - ], - [ - -75.68, - 45.423 - ], - [ - -75.689, - 45.425 - ], - [ - -75.692, - 45.432 - ], - [ - -75.689, - 45.438 - ], - [ - -75.68857142857142, - 45.43814285714286 - ], - [ - -75.689, - 45.439 - ], - [ - -75.686, - 45.446 - ], - [ - -75.68091304347827, - 45.44713043478261 - ], - [ - -75.679, - 45.45 - ], - [ - -75.67, - 45.452 - ], - [ - -75.661, - 45.45 - ], - [ - -75.657, - 45.444 - ], - [ - -75.65925352112676, - 45.440056338028164 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.59527272727273, - 45.410090909090904 - ], - [ - -75.596, - 45.409 - ], - [ - -75.60252941176469, - 45.406823529411774 - ], - [ - -75.603, - 45.406 - ], - [ - -75.60495652173914, - 45.4055652173913 - ], - [ - -75.608, - 45.401 - ], - [ - -75.617, - 45.398 - ], - [ - -75.619, - 45.398666666666664 - ], - [ - -75.627, - 45.396 - ], - [ - -75.636, - 45.399 - ], - [ - -75.64, - 45.405 - ], - [ - -75.636, - 45.412 - ], - [ - -75.627, - 45.414 - ], - [ - -75.6246, - 45.413466666666665 - ], - [ - -75.6236, - 45.4138 - ], - [ - -75.62193333333333, - 45.41713333333332 - ], - [ - -75.623, - 45.419 - ], - [ - -75.619, - 45.425 - ], - [ - -75.61, - 45.427 - ], - [ - -75.60520000000001, - 45.42593333333333 - ], - [ - -75.605, - 45.426 - ], - [ - -75.596, - 45.428 - ], - [ - -75.5954, - 45.42786666666667 - ], - [ - -75.595, - 45.428 - ], - [ - -75.593, - 45.42733333333333 - ], - [ - -75.587, - 45.426 - ], - [ - -75.58666666666667, - 45.42522222222222 - ], - [ - -75.586, - 45.425 - ], - [ - -75.582, - 45.419 - ], - [ - -75.586, - 45.413 - ], - [ - -75.595, - 45.41 - ], - [ - -75.59527272727273, - 45.410090909090904 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.72330769230769, - 45.35453846153846 - ], - [ - -75.723, - 45.354 - ], - [ - -75.727, - 45.348 - ], - [ - -75.736, - 45.345 - ], - [ - -75.745, - 45.348 - ], - [ - -75.749, - 45.354 - ], - [ - -75.74823076923077, - 45.35534615384615 - ], - [ - -75.752, - 45.361 - ], - [ - -75.748, - 45.368 - ], - [ - -75.74358181818181, - 45.36898181818182 - ], - [ - -75.743, - 45.37 - ], - [ - -75.734, - 45.372 - ], - [ - -75.725, - 45.37 - ], - [ - -75.721, - 45.363 - ], - [ - -75.723, - 45.36 - ], - [ - -75.72466666666666, - 45.357499999999995 - ], - [ - -75.723, - 45.355 - ], - [ - -75.72330769230769, - 45.35453846153846 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.79265217391304, - 45.37452173913044 - ], - [ - -75.791, - 45.377 - ], - [ - -75.782, - 45.38 - ], - [ - -75.773, - 45.377 - ], - [ - -75.769, - 45.371 - ], - [ - -75.773, - 45.364 - ], - [ - -75.77532258064517, - 45.36348387096774 - ], - [ - -75.775, - 45.363 - ], - [ - -75.779, - 45.356 - ], - [ - -75.788, - 45.354 - ], - [ - -75.797, - 45.356 - ], - [ - -75.801, - 45.363 - ], - [ - -75.79866666666668, - 45.366499999999995 - ], - [ - -75.799, - 45.367 - ], - [ - -75.795, - 45.374 - ], - [ - -75.79265217391304, - 45.37452173913044 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.77558064516128, - 45.33812903225807 - ], - [ - -75.777, - 45.336 - ], - [ - -75.77871428571429, - 45.33542857142857 - ], - [ - -75.779, - 45.335 - ], - [ - -75.788, - 45.332 - ], - [ - -75.797, - 45.335 - ], - [ - -75.801, - 45.341 - ], - [ - -75.79899999999999, - 45.3445 - ], - [ - -75.80038028169014, - 45.34691549295775 - ], - [ - -75.809, - 45.345 - ], - [ - -75.818, - 45.347 - ], - [ - -75.822, - 45.354 - ], - [ - -75.818, - 45.36 - ], - [ - -75.809, - 45.363 - ], - [ - -75.8, - 45.36 - ], - [ - -75.79612903225807, - 45.354193548387094 - ], - [ - -75.788, - 45.356 - ], - [ - -75.78020000000001, - 45.35426666666667 - ], - [ - -75.775, - 45.356 - ], - [ - -75.766, - 45.353 - ], - [ - -75.762, - 45.347 - ], - [ - -75.766, - 45.34 - ], - [ - -75.775, - 45.338 - ], - [ - -75.77558064516128, - 45.33812903225807 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.62, - 45.373 - ], - [ - -75.629, - 45.371 - ], - [ - -75.633, - 45.364 - ], - [ - -75.629, - 45.358 - ], - [ - -75.62, - 45.355 - ], - [ - -75.611, - 45.358 - ], - [ - -75.607, - 45.364 - ], - [ - -75.611, - 45.371 - ], - [ - -75.62, - 45.373 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.699, - 45.419333333333334 - ], - [ - -75.694, - 45.421 - ], - [ - -75.685, - 45.418 - ], - [ - -75.68385714285714, - 45.416285714285706 - ], - [ - -75.683, - 45.416 - ], - [ - -75.68100000000004, - 45.41200000000006 - ], - [ - -75.681, - 45.412 - ], - [ - -75.681, - 45.41199999999999 - ], - [ - -75.68, - 45.41 - ], - [ - -75.683, - 45.403 - ], - [ - -75.68938181818181, - 45.40158181818182 - ], - [ - -75.692, - 45.397 - ], - [ - -75.69674545454545, - 45.395945454545455 - ], - [ - -75.699, - 45.392 - ], - [ - -75.708, - 45.39 - ], - [ - -75.717, - 45.392 - ], - [ - -75.721, - 45.399 - ], - [ - -75.717, - 45.405 - ], - [ - -75.7159090909091, - 45.40536363636364 - ], - [ - -75.717, - 45.407 - ], - [ - -75.713, - 45.414 - ], - [ - -75.70605263157894, - 45.41554385964912 - ], - [ - -75.705, - 45.418 - ], - [ - -75.699, - 45.419333333333334 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.76398591549295, - 45.33577464788733 - ], - [ - -75.765, - 45.336 - ], - [ - -75.769, - 45.343 - ], - [ - -75.765, - 45.349 - ], - [ - -75.756, - 45.352 - ], - [ - -75.747, - 45.349 - ], - [ - -75.744, - 45.343 - ], - [ - -75.74469565217392, - 45.3413768115942 - ], - [ - -75.743, - 45.341 - ], - [ - -75.739, - 45.334 - ], - [ - -75.743, - 45.328 - ], - [ - -75.752, - 45.325 - ], - [ - -75.761, - 45.328 - ], - [ - -75.765, - 45.334 - ], - [ - -75.76398591549295, - 45.33577464788733 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.631, - 45.432 - ], - [ - -75.64, - 45.43 - ], - [ - -75.644, - 45.423 - ], - [ - -75.64, - 45.417 - ], - [ - -75.631, - 45.414 - ], - [ - -75.622, - 45.417 - ], - [ - -75.618, - 45.423 - ], - [ - -75.622, - 45.43 - ], - [ - -75.631, - 45.432 - ] - ] - ] - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.707, - 45.327 - ], - [ - -75.711, - 45.321 - ], - [ - -75.72, - 45.318 - ], - [ - -75.729, - 45.321 - ], - [ - -75.733, - 45.327 - ], - [ - -75.73261538461539, - 45.327576923076926 - ], - [ - -75.734, - 45.33 - ], - [ - -75.73066666666666, - 45.33500000000001 - ], - [ - -75.732, - 45.337 - ], - [ - -75.728, - 45.344 - ], - [ - -75.719, - 45.346 - ], - [ - -75.71, - 45.344 - ], - [ - -75.706, - 45.337 - ], - [ - -75.70933333333333, - 45.332 - ], - [ - -75.708, - 45.33 - ], - [ - -75.70846153846153, - 45.32919230769231 - ], - [ - -75.707, - 45.327 - ] - ] - ] - }, - "properties": {} - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -75.58990909090909, - 45.38163636363637 - ], - [ - -75.588, - 45.381 - ], - [ - -75.584, - 45.375 - ], - [ - -75.588, - 45.368 - ], - [ - -75.597, - 45.366 - ], - [ - -75.606, - 45.368 - ], - [ - -75.61, - 45.375 - ], - [ - -75.60909090909091, - 45.376363636363635 - ], - [ - -75.611, - 45.377 - ], - [ - -75.615, - 45.383 - ], - [ - -75.611, - 45.389 - ], - [ - -75.602, - 45.392 - ], - [ - -75.593, - 45.389 - ], - [ - -75.589, - 45.383 - ], - [ - -75.58990909090909, - 45.38163636363637 - ] - ] - ] - }, - "properties": {} - } - ] -} diff --git a/packages/turf-distance-weight/.gitignore b/packages/turf-distance-weight/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-distance-weight/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-distance-weight/LICENSE b/packages/turf-distance-weight/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-distance-weight/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-distance-weight/README.md b/packages/turf-distance-weight/README.md deleted file mode 100644 index 0a0972be8e..0000000000 --- a/packages/turf-distance-weight/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# @turf/distance-weight - - - -## pNormDistance - -calcualte the Minkowski p-norm distance between two features. - -**Parameters** - -- `feature1` point feature -- `feature2` point feature -- `p` p-norm 1=<p<=infinity 1: Manhattan distance 2: Euclidean distance - -## distanceWeight - -**Parameters** - -- `fc` **[FeatureCollection](https://tools.ietf.org/html/rfc7946#section-3.3)<any>** FeatureCollection. -- `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** option object. - - `options.threshold` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** If the distance between neighbor and - target features is greater than threshold, the weight of that neighbor is 0. (optional, default `10000`) - - `options.p` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Minkowski p-norm distance parameter. - 1: Manhattan distance. 2: Euclidean distance. 1=<p<=infinity. (optional, default `2`) - - `options.binary` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** If true, weight=1 if d <= threshold otherwise weight=0. - If false, weight=Math.pow(d, alpha). (optional, default `false`) - - `options.alpha` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** distance decay parameter. - A big value means the weight decay quickly as distance increases. (optional, default `-1`) - - `options.standardization` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** row standardization. (optional, default `false`) - -**Examples** - -```javascript -var bbox = [-65, 40, -63, 42]; -var dataset = turf.randomPoint(100, { bbox: bbox }); -var result = turf.distanceWeight(dataset); -``` - -Returns **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)>>** distance weight matrix. - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/distance-weight -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-distance-weight/index.d.ts b/packages/turf-distance-weight/index.d.ts deleted file mode 100644 index 78c2673fb0..0000000000 --- a/packages/turf-distance-weight/index.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Feature, FeatureCollection, Point } from "@turf/helpers"; -/** - * calcualte the Minkowski p-norm distance between two features. - * @param feature1 point feature - * @param feature2 point feature - * @param p p-norm 1=, feature2: Feature, p?: number): number; -/** - * - * - * @name distanceWeight - * @param {FeatureCollection} fc FeatureCollection. - * @param {Object} [options] option object. - * @param {number} [options.threshold=10000] If the distance between neighbor and - * target features is greater than threshold, the weight of that neighbor is 0. - * @param {number} [options.p=2] Minkowski p-norm distance parameter. - * 1: Manhattan distance. 2: Euclidean distance. 1=>} distance weight matrix. - * @example - * - * var bbox = [-65, 40, -63, 42]; - * var dataset = turf.randomPoint(100, { bbox: bbox }); - * var result = turf.distanceWeight(dataset); - */ -export default function distanceWeight(fc: FeatureCollection, options?: { - threshold?: number; - p?: number; - binary?: boolean; - alpha?: number; - standardization?: boolean; -}): number[][]; diff --git a/packages/turf-distance-weight/index.ts b/packages/turf-distance-weight/index.ts deleted file mode 100644 index b094525ad6..0000000000 --- a/packages/turf-distance-weight/index.ts +++ /dev/null @@ -1,118 +0,0 @@ -import centroid from "@turf/centroid"; -import { Feature, FeatureCollection, Point } from "@turf/helpers"; -import { getCoord } from "@turf/invariant"; -import { featureEach } from "@turf/meta"; - -/** - * calcualte the Minkowski p-norm distance between two features. - * @param feature1 point feature - * @param feature2 point feature - * @param p p-norm 1=, feature2: Feature, p: number = 2): number { - const coordinate1 = getCoord(feature1); - const coordinate2 = getCoord(feature2); - const xDiff = coordinate1[0] - coordinate2[0]; - const yDiff = coordinate1[1] - coordinate2[1]; - if (p === 1) { - return Math.abs(xDiff) + Math.abs(yDiff); - } - return Math.pow((Math.pow(xDiff, p) + Math.pow(yDiff, p)), 1 / p); -} - -/** - * - * - * @name distanceWeight - * @param {FeatureCollection} fc FeatureCollection. - * @param {Object} [options] option object. - * @param {number} [options.threshold=10000] If the distance between neighbor and - * target features is greater than threshold, the weight of that neighbor is 0. - * @param {number} [options.p=2] Minkowski p-norm distance parameter. - * 1: Manhattan distance. 2: Euclidean distance. 1=>} distance weight matrix. - * @example - * - * var bbox = [-65, 40, -63, 42]; - * var dataset = turf.randomPoint(100, { bbox: bbox }); - * var result = turf.distanceWeight(dataset); - */ -export default function distanceWeight(fc: FeatureCollection, options?: { - threshold?: number; - p?: number; - binary?: boolean; - alpha?: number; - standardization?: boolean; -}): number[][] { - - options = options || {}; - const threshold = options.threshold || 10000; - const p = options.p || 2; - const binary = options.binary || false; - const alpha = options.alpha || -1; - const rowTransform = options.standardization || false; - - const features: Array> = []; - featureEach(fc, (feature) => { - features.push(centroid(feature)); - }); - - // computing the distance between the features - const weights: number[][] = []; - for (let i = 0; i < features.length; i++) { - weights[i] = []; - } - - for (let i = 0; i < features.length; i++) { - for (let j = i; j < features.length; j++) { - if (i === j) { - weights[i][j] = 0; - } - const dis = pNormDistance(features[i], features[j], p); - weights[i][j] = dis; - weights[j][i] = dis; - } - } - - // binary or distance decay - for (let i = 0; i < features.length; i++) { - for (let j = 0; j < features.length; j++) { - const dis: number = weights[i][j]; - if (dis === 0) { - continue; - } - if (binary) { - if (dis <= threshold) { - weights[i][j] = 1.0; - } else { - weights[i][j] = 0.0; - } - } else { - if (dis <= threshold) { - weights[i][j] = Math.pow(dis, alpha); - } else { - weights[i][j] = 0.0; - } - } - } - } - - if (rowTransform) { - for (let i = 0; i < features.length; i++) { - const rowSum = weights[i].reduce((sum: number, currentVal: number) => { - return sum + currentVal; - }, 0); - for (let j = 0; j < features.length; j++) { - weights[i][j] = weights[i][j] / rowSum; - } - } - } - - return weights; - -} diff --git a/packages/turf-distance-weight/package.json b/packages/turf-distance-weight/package.json deleted file mode 100644 index 4f77520caa..0000000000 --- a/packages/turf-distance-weight/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@turf/distance-weight", - "version": "6.0.1", - "description": "turf distance-weight module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "distance-weight" - ], - "author": "Turf Authors", - "contributors": [ - "Haoming Zhuang <@zhuang-hao-ming>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "write-json-file": "*", - "load-json-file": "*", - "tape": "*", - "typescript": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/centroid": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-distance-weight/test.js b/packages/turf-distance-weight/test.js deleted file mode 100644 index 04f9367e29..0000000000 --- a/packages/turf-distance-weight/test.js +++ /dev/null @@ -1,97 +0,0 @@ -const { point } = require('@turf/helpers'); - -const test = require('tape'); -const glob = require('glob'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const distanceWeight = require('.').default; -const { pNormDistance } = require('.'); - -test('pNormDistance function', t => { - - t.equal(pNormDistance(point([2, 0]), point([0, 0]), 2), 2, '2-norm is ok'); - t.equal(pNormDistance(point([1, 1]), point([0, 0]), 1), 2, '1-norm is ok'); - t.end(); - -}); - -test('turf-distance-weight', t => { - - const columbusPath = path.join(__dirname, 'test', 'in', 'point.json'); - const columbusJson = load.sync(columbusPath); - - let result = distanceWeight(columbusJson, { - threshold: 1, - binary: false, - p: 1, - alpha: 1, - standardization: false - }); - t.equal(result[0][1], 0.8320121090670778, 'base arguments'); - - // test threshold - result = distanceWeight(columbusJson, { - threshold: 2, - binary: false, - p: 1, - alpha: 1 - }); - t.equal(result[0][1], 0.8320121090670778, 'change threshold'); - - // test binary - result = distanceWeight(columbusJson, { - threshold: 1, - binary: true, - p: 1, - alpha: 1 - }); - t.equal(result[0][1], 1, 'change binary'); - - // test p - result = distanceWeight(columbusJson, { - threshold: 1, - binary: false, - p: 2, - alpha: 1 - }); - t.equal(result[0][1], 0.5987182558007202, 'change p'); - - // test alpha - result = distanceWeight(columbusJson, { - threshold: 1, - binary: false, - p: 1, - alpha: -1 - }); - t.equal(result[0][1], 1.201905584188293, 'change alpha'); - - result = distanceWeight(columbusJson, { - threshold: 1, - binary: false, - p: 1, - alpha: 1, - standardization: true - }); - t.equal(result[0][1], 0.5311565480348293, 'standardization 1'); - - result = distanceWeight(columbusJson, { - threshold: 1, - binary: true, - p: 1, - alpha: 1, - standardization: true - }); - t.equal(result[0][1], 0.5, 'standardization 2'); - - - - // test default - result = distanceWeight(columbusJson); - t.equal(result[0][1], 1.6702346893742355, 'default arguments'); - - - t.end(); - - -}); diff --git a/packages/turf-distance-weight/tsconfig.json b/packages/turf-distance-weight/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-distance-weight/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-distance-weight/tslint.json b/packages/turf-distance-weight/tslint.json deleted file mode 100644 index 9dd5998b9c..0000000000 --- a/packages/turf-distance-weight/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {"interface-name": false}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-distance/.gitignore b/packages/turf-distance/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-distance/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-distance/LICENSE b/packages/turf-distance/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-distance/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-distance/README.md b/packages/turf-distance/README.md deleted file mode 100644 index 9757b686fa..0000000000 --- a/packages/turf-distance/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# @turf/distance - - - -## distance - -Calculates the distance between two [points][1] in degrees, radians, miles, or kilometers. -This uses the [Haversine formula][2] to account for global curvature. - -**Parameters** - -- `from` **[Coord][3]** origin point -- `to` **[Coord][3]** destination point -- `options` **[Object][4]** Optional parameters (optional, default `{}`) - - `options.units` **[string][5]** can be degrees, radians, miles, or kilometers (optional, default `'kilometers'`) - -**Examples** - -```javascript -var from = turf.point([-75.343, 39.984]); -var to = turf.point([-75.534, 39.123]); -var options = {units: 'miles'}; - -var distance = turf.distance(from, to, options); - -//addToMap -var addToMap = [from, to]; -from.properties.distance = distance; -to.properties.distance = distance; -``` - -Returns **[number][6]** distance between the two points - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: http://en.wikipedia.org/wiki/Haversine_formula - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/distance -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-distance/index.ts b/packages/turf-distance/index.ts deleted file mode 100644 index 2f4b84bf82..0000000000 --- a/packages/turf-distance/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { getCoord } from '@turf/invariant'; -import { - radiansToLength, isObject, degreesToRadians, - Coord, Units -} from '@turf/helpers'; - -//http://en.wikipedia.org/wiki/Haversine_formula -//http://www.movable-type.co.uk/scripts/latlong.html - -/** - * Calculates the distance between two {@link Point|points} in degrees, radians, miles, or kilometers. - * This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature. - * - * @name distance - * @param {Coord} from origin point - * @param {Coord} to destination point - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers - * @returns {number} distance between the two points - * @example - * var from = turf.point([-75.343, 39.984]); - * var to = turf.point([-75.534, 39.123]); - * var options = {units: 'miles'}; - * - * var distance = turf.distance(from, to, options); - * - * //addToMap - * var addToMap = [from, to]; - * from.properties.distance = distance; - * to.properties.distance = distance; - */ -function distance(from: Coord, to: Coord, options: { - units?: Units, -} = {}) { - var coordinates1 = getCoord(from); - var coordinates2 = getCoord(to); - var dLat = degreesToRadians((coordinates2[1] - coordinates1[1])); - var dLon = degreesToRadians((coordinates2[0] - coordinates1[0])); - var lat1 = degreesToRadians(coordinates1[1]); - var lat2 = degreesToRadians(coordinates2[1]); - - var a = Math.pow(Math.sin(dLat / 2), 2) + - Math.pow(Math.sin(dLon / 2), 2) * Math.cos(lat1) * Math.cos(lat2); - - return radiansToLength(2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)), options.units); -} - -export default distance; diff --git a/packages/turf-distance/package.json b/packages/turf-distance/package.json deleted file mode 100644 index b0783af247..0000000000 --- a/packages/turf-distance/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "@turf/distance", - "version": "6.0.1", - "description": "turf distance module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "distance", - "miles", - "km" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-distance/test.js b/packages/turf-distance/test.js deleted file mode 100644 index 62e12b0e4f..0000000000 --- a/packages/turf-distance/test.js +++ /dev/null @@ -1,50 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const test = require('tape'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { point } = require('@turf/helpers'); -const distance = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('distance', t => { - fixtures.forEach(fixture => { - const name = fixture.name; - const geojson = fixture.geojson; - const pt1 = geojson.features[0]; - const pt2 = geojson.features[1]; - const distances = { - miles: distance(pt1, pt2, {units: 'miles'}), - nauticalmiles: distance(pt1, pt2, {units: 'nauticalmiles'}), - kilometers: distance(pt1, pt2, {units: 'kilometers'}), - radians: distance(pt1, pt2, {units: 'radians'}), - degrees: distance(pt1, pt2, {units: 'degrees'}) - }; - if (process.env.REGEN) write.sync(directories.out + name + '.json', distances); - t.deepEqual(distances, load.sync(directories.out + name + '.json'), name); - }); - t.end(); -}); - -// https://github.com/Turfjs/turf/issues/758 -test('distance -- Issue #758', t => { - t.equal(Math.round(distance(point([-180, -90]), point([180, -90]))), 0, 'should be 0'); - t.end(); -}); - -test('distance -- throws', t => { - t.throws(() => distance(point([0, 0]), point([10, 10]), {units: 'foo'}), /units is invalid/); - t.end(); -}); diff --git a/packages/turf-ellipse/LICENSE b/packages/turf-ellipse/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-ellipse/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-ellipse/README.md b/packages/turf-ellipse/README.md deleted file mode 100644 index fb34a0c079..0000000000 --- a/packages/turf-ellipse/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# @turf/ellipse - - - -## ellipse - -Takes a [Point][1] and calculates the ellipse polygon given two semi-axes expressed in variable units and steps for precision. - -**Parameters** - -- `center` **[Coord][2]** center point -- `xSemiAxis` **[number][3]** semi (major) axis of the ellipse along the x-axis -- `ySemiAxis` **[number][3]** semi (minor) axis of the ellipse along the y-axis -- `options` **[Object][4]** Optional parameters (optional, default `{}`) - - `options.angle` **[number][3]** angle of rotation (along the vertical axis), from North in decimal degrees, negative clockwise (optional, default `0`) - - `options.pivot` **[Coord][2]** point around which the rotation will be performed (optional, default `'origin'`) - - `options.steps` **[number][3]** number of steps (optional, default `64`) - - `options.units` **[string][5]** unit of measurement for axes (optional, default `'kilometers'`) - - `options.properties` **[Object][4]** properties (optional, default `{}`) - -**Examples** - -```javascript -var center = [-75, 40]; -var xSemiAxis = 5; -var ySemiAxis = 2; -var ellipse = turf.ellipse(center, xSemiAxis, ySemiAxis); - -//addToMap -var addToMap = [turf.point(center), ellipse] -``` - -Returns **[Feature][6]<[Polygon][7]>** ellipse polygon - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[6]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/ellipse -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-ellipse/index.js b/packages/turf-ellipse/index.js deleted file mode 100644 index 26bb714f09..0000000000 --- a/packages/turf-ellipse/index.js +++ /dev/null @@ -1,92 +0,0 @@ -import { degreesToRadians, polygon, isObject, isNumber } from '@turf/helpers'; -import rhumbDestination from '@turf/rhumb-destination'; -import transformRotate from '@turf/transform-rotate'; -import { getCoord } from '@turf/invariant'; - -/** - * Takes a {@link Point} and calculates the ellipse polygon given two semi-axes expressed in variable units and steps for precision. - * - * @param {Coord} center center point - * @param {number} xSemiAxis semi (major) axis of the ellipse along the x-axis - * @param {number} ySemiAxis semi (minor) axis of the ellipse along the y-axis - * @param {Object} [options={}] Optional parameters - * @param {number} [options.angle=0] angle of rotation (along the vertical axis), from North in decimal degrees, negative clockwise - * @param {Coord} [options.pivot='origin'] point around which the rotation will be performed - * @param {number} [options.steps=64] number of steps - * @param {string} [options.units='kilometers'] unit of measurement for axes - * @param {Object} [options.properties={}] properties - * @returns {Feature} ellipse polygon - * @example - * var center = [-75, 40]; - * var xSemiAxis = 5; - * var ySemiAxis = 2; - * var ellipse = turf.ellipse(center, xSemiAxis, ySemiAxis); - * - * //addToMap - * var addToMap = [turf.point(center), ellipse] - */ -function ellipse(center, xSemiAxis, ySemiAxis, options) { - // Optional params - options = options || {}; - var steps = options.steps || 64; - var units = options.units || 'kilometers'; - var angle = options.angle || 0; - var pivot = options.pivot || center; - var properties = options.properties || center.properties || {}; - - // validation - if (!center) throw new Error('center is required'); - if (!xSemiAxis) throw new Error('xSemiAxis is required'); - if (!ySemiAxis) throw new Error('ySemiAxis is required'); - if (!isObject(options)) throw new Error('options must be an object'); - if (!isNumber(steps)) throw new Error('steps must be a number'); - if (!isNumber(angle)) throw new Error('angle must be a number'); - - var centerCoords = getCoord(center); - if (units === 'degrees') { - var angleRad = degreesToRadians(angle); - } else { - xSemiAxis = rhumbDestination(center, xSemiAxis, 90, {units: units}); - ySemiAxis = rhumbDestination(center, ySemiAxis, 0, {units: units}); - xSemiAxis = getCoord(xSemiAxis)[0] - centerCoords[0]; - ySemiAxis = getCoord(ySemiAxis)[1] - centerCoords[1]; - } - - var coordinates = []; - for (var i = 0; i < steps; i += 1) { - var stepAngle = i * -360 / steps; - var x = ((xSemiAxis * ySemiAxis) / Math.sqrt(Math.pow(ySemiAxis, 2) + (Math.pow(xSemiAxis, 2) * Math.pow(getTanDeg(stepAngle), 2)))); - var y = ((xSemiAxis * ySemiAxis) / Math.sqrt(Math.pow(xSemiAxis, 2) + (Math.pow(ySemiAxis, 2) / Math.pow(getTanDeg(stepAngle), 2)))); - - if (stepAngle < -90 && stepAngle >= -270) x = -x; - if (stepAngle < -180 && stepAngle >= -360) y = -y; - if (units === 'degrees') { - var newx = x * Math.cos(angleRad) + y * Math.sin(angleRad); - var newy = y * Math.cos(angleRad) - x * Math.sin(angleRad); - x = newx; - y = newy; - } - - coordinates.push([x + centerCoords[0], y + centerCoords[1]]); - } - coordinates.push(coordinates[0]); - if (units === 'degrees') { - return polygon([coordinates], properties); - } else { - return transformRotate(polygon([coordinates], properties), angle, { pivot: pivot }); - } -} - -/** - * Get Tan Degrees - * - * @private - * @param {number} deg Degrees - * @returns {number} Tan Degrees - */ -function getTanDeg(deg) { - var rad = deg * Math.PI / 180; - return Math.tan(rad); -} - -export default ellipse; diff --git a/packages/turf-ellipse/package.json b/packages/turf-ellipse/package.json deleted file mode 100644 index 97735faace..0000000000 --- a/packages/turf-ellipse/package.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "@turf/ellipse", - "version": "5.1.5", - "description": "turf ellipse module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "ellipse" - ], - "author": "Turf Authors", - "contributors": [ - "Moacir P. de Sá Pereira <@muziejus>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@mapbox/geojsonhint": "*", - "@std/esm": "*", - "@turf/bbox-polygon": "6.x", - "@turf/circle": "6.x", - "@turf/destination": "6.x", - "@turf/truncate": "6.x", - "benchmark": "*", - "glob": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/rhumb-destination": "6.x", - "@turf/transform-rotate": "^5.1.5" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-ellipse/test.js b/packages/turf-ellipse/test.js deleted file mode 100644 index 7c3827dcb4..0000000000 --- a/packages/turf-ellipse/test.js +++ /dev/null @@ -1,97 +0,0 @@ -import test from 'tape'; -import glob from 'glob'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import circle from '@turf/circle'; -import truncate from '@turf/truncate'; -import geojsonhint from '@mapbox/geojsonhint'; -import bboxPolygon from '@turf/bbox-polygon'; -import rhumbDestination from '@turf/rhumb-destination'; -// import destination from '@turf/destination'; -import { featureCollection } from '@turf/helpers'; -import ellipse from '.'; - -test('turf-ellipse', t => { - glob.sync(path.join(__dirname, 'test', 'in', '*.json')).forEach(filepath => { - // Define params - const {name} = path.parse(filepath); - const geojson = load.sync(filepath); - const center = geojson.geometry.coordinates; - let {xSemiAxis, ySemiAxis, steps, angle, units} = geojson.properties; - angle = angle || 0; - const options = {steps, angle, units}; - const maxAxis = Math.max(xSemiAxis, ySemiAxis); - - // Styled results - const maxDestination0 = rhumbDestination(center, maxAxis, angle, {units}); - const maxDestination90 = rhumbDestination(center, maxAxis, angle + 90, {units}); - const maxDestination180 = rhumbDestination(center, maxAxis, angle + 180, {units}); - const maxDestination270 = rhumbDestination(center, maxAxis, angle + 270, {units}); - - const xDestination0 = rhumbDestination(center, xSemiAxis, angle, {units}); - const xDestination90 = rhumbDestination(center, xSemiAxis, angle + 90, {units}); - const xDestination180 = rhumbDestination(center, xSemiAxis, angle + 180, {units}); - const xDestination270 = rhumbDestination(center, xSemiAxis, angle + 270, {units}); - - const yDestination0 = rhumbDestination(center, ySemiAxis, angle, {units}); - const yDestination90 = rhumbDestination(center, ySemiAxis, angle + 90, {units}); - const yDestination180 = rhumbDestination(center, ySemiAxis, angle + 180, {units}); - const yDestination270 = rhumbDestination(center, ySemiAxis, angle + 270, {units}); - - const bboxX = colorize(bboxPolygon([ - xDestination270.geometry.coordinates[0], - yDestination180.geometry.coordinates[1], - xDestination90.geometry.coordinates[0], - yDestination0.geometry.coordinates[1], - ]), '#FFF'); - const bboxY = colorize(bboxPolygon([ - yDestination270.geometry.coordinates[0], - xDestination180.geometry.coordinates[1], - yDestination90.geometry.coordinates[0], - xDestination0.geometry.coordinates[1], - ]), '#666'); - const bboxMax = colorize(bboxPolygon([ - maxDestination270.geometry.coordinates[0], - maxDestination180.geometry.coordinates[1], - maxDestination90.geometry.coordinates[0], - maxDestination0.geometry.coordinates[1], - ]), '#000'); - - const results = featureCollection([ - bboxX, - bboxY, - bboxMax, - geojson, - truncate(colorize(circle(center, maxAxis, options), '#F00')), - truncate(colorize(ellipse(center, xSemiAxis, ySemiAxis, options), '#00F')), - truncate(colorize(ellipse(center, xSemiAxis, ySemiAxis, {steps, angle: angle + 90, units}), '#0F0')), - ]); - - // Save to file - const out = filepath.replace(path.join('test', 'in'), path.join('test', 'out')); - if (process.env.REGEN) write.sync(out, results); - t.deepEqual(results, load.sync(out), name); - }); - t.end(); -}); - -test('turf-ellipse -- with coordinates', t => { - t.assert(ellipse([-100, 75], 5, 1)); - t.end(); -}); - -test('turf-ellipse -- validate geojson', t => { - const E = ellipse([0, 0], 10, 20); - geojsonhint.hint(E).forEach(hint => t.fail(hint.message)); - t.end(); -}); - -function colorize(feature, color) { - color = color || '#F00'; - feature.properties['stroke-width'] = 6; - feature.properties.stroke = color; - feature.properties.fill = color; - feature.properties['fill-opacity'] = 0; - return feature; -} diff --git a/packages/turf-envelope/LICENSE b/packages/turf-envelope/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-envelope/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-envelope/README.md b/packages/turf-envelope/README.md deleted file mode 100644 index dc770fc08f..0000000000 --- a/packages/turf-envelope/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# @turf/envelope - - - -## envelope - -Takes any number of features and returns a rectangular [Polygon][1] that encompasses all vertices. - -**Parameters** - -- `geojson` **[GeoJSON][2]** input features - -**Examples** - -```javascript -var features = turf.featureCollection([ - turf.point([-75.343, 39.984], {"name": "Location A"}), - turf.point([-75.833, 39.284], {"name": "Location B"}), - turf.point([-75.534, 39.123], {"name": "Location C"}) -]); - -var enveloped = turf.envelope(features); - -//addToMap -var addToMap = [features, enveloped]; -``` - -Returns **[Feature][3]<[Polygon][4]>** a rectangular Polygon feature that encompasses all vertices - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[2]: https://tools.ietf.org/html/rfc7946#section-3 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/envelope -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-envelope/index.d.ts b/packages/turf-envelope/index.d.ts deleted file mode 100644 index 7d8a4f6014..0000000000 --- a/packages/turf-envelope/index.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Feature, AllGeoJSON, Polygon } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#envelope - */ -export default function envelope( - features: AllGeoJSON -): Feature; diff --git a/packages/turf-envelope/index.js b/packages/turf-envelope/index.js deleted file mode 100644 index adbb99bd38..0000000000 --- a/packages/turf-envelope/index.js +++ /dev/null @@ -1,26 +0,0 @@ -import bbox from '@turf/bbox'; -import bboxPolygon from '@turf/bbox-polygon'; - -/** - * Takes any number of features and returns a rectangular {@link Polygon} that encompasses all vertices. - * - * @name envelope - * @param {GeoJSON} geojson input features - * @returns {Feature} a rectangular Polygon feature that encompasses all vertices - * @example - * var features = turf.featureCollection([ - * turf.point([-75.343, 39.984], {"name": "Location A"}), - * turf.point([-75.833, 39.284], {"name": "Location B"}), - * turf.point([-75.534, 39.123], {"name": "Location C"}) - * ]); - * - * var enveloped = turf.envelope(features); - * - * //addToMap - * var addToMap = [features, enveloped]; - */ -function envelope(geojson) { - return bboxPolygon(bbox(geojson)); -} - -export default envelope; diff --git a/packages/turf-envelope/package.json b/packages/turf-envelope/package.json deleted file mode 100644 index 327ee11214..0000000000 --- a/packages/turf-envelope/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@turf/envelope", - "version": "5.1.5", - "description": "turf envelope module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "envelope", - "polygon", - "extent" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/bbox-polygon": "6.x", - "@turf/helpers": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-explode/LICENSE b/packages/turf-explode/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-explode/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-explode/README.md b/packages/turf-explode/README.md deleted file mode 100644 index cce76ed7f3..0000000000 --- a/packages/turf-explode/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# @turf/explode - - - -## explode - -Takes a feature or set of features and returns all positions as [points][1]. - -**Parameters** - -- `geojson` **[GeoJSON][2]** input features - -**Examples** - -```javascript -var polygon = turf.polygon([[[-81, 41], [-88, 36], [-84, 31], [-80, 33], [-77, 39], [-81, 41]]]); - -var explode = turf.explode(polygon); - -//addToMap -var addToMap = [polygon, explode] -``` - -- Throws **[Error][3]** if it encounters an unknown geometry type - -Returns **[FeatureCollection][4]<point>** points representing the exploded input features - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error - -[4]: https://tools.ietf.org/html/rfc7946#section-3.3 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/explode -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-explode/index.js b/packages/turf-explode/index.js deleted file mode 100644 index 30e26ea82f..0000000000 --- a/packages/turf-explode/index.js +++ /dev/null @@ -1,35 +0,0 @@ -import { coordEach, featureEach } from '@turf/meta'; -import { point, featureCollection } from '@turf/helpers'; - -/** - * Takes a feature or set of features and returns all positions as {@link Point|points}. - * - * @name explode - * @param {GeoJSON} geojson input features - * @returns {FeatureCollection} points representing the exploded input features - * @throws {Error} if it encounters an unknown geometry type - * @example - * var polygon = turf.polygon([[[-81, 41], [-88, 36], [-84, 31], [-80, 33], [-77, 39], [-81, 41]]]); - * - * var explode = turf.explode(polygon); - * - * //addToMap - * var addToMap = [polygon, explode] - */ -function explode(geojson) { - var points = []; - if (geojson.type === 'FeatureCollection') { - featureEach(geojson, function (feature) { - coordEach(feature, function (coord) { - points.push(point(coord, feature.properties)); - }); - }); - } else { - coordEach(geojson, function (coord) { - points.push(point(coord, geojson.properties)); - }); - } - return featureCollection(points); -} - -export default explode; diff --git a/packages/turf-explode/package.json b/packages/turf-explode/package.json deleted file mode 100644 index 490befdbf0..0000000000 --- a/packages/turf-explode/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@turf/explode", - "version": "5.1.5", - "description": "turf explode module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "geospatial", - "coordinates" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "geojson-fixtures": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-flatten/LICENSE b/packages/turf-flatten/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-flatten/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-flatten/README.md b/packages/turf-flatten/README.md deleted file mode 100644 index 09a60aae58..0000000000 --- a/packages/turf-flatten/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# @turf/flatten - - - -## flatten - -Flattens any [GeoJSON][1] to a [FeatureCollection][2] inspired by [geojson-flatten][3]. - -**Parameters** - -- `geojson` **[GeoJSON][4]** any valid GeoJSON Object - -**Examples** - -```javascript -var multiGeometry = turf.multiPolygon([ - [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]], - [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], - [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]] -]); - -var flatten = turf.flatten(multiGeometry); - -//addToMap -var addToMap = [flatten] -``` - -Returns **[FeatureCollection][5]<any>** all Multi-Geometries are flattened into single Features - -[1]: https://tools.ietf.org/html/rfc7946#section-3 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[3]: https://github.com/tmcw/geojson-flatten - -[4]: https://tools.ietf.org/html/rfc7946#section-3 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.3 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/flatten -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-flatten/index.d.ts b/packages/turf-flatten/index.d.ts deleted file mode 100644 index fdf1977c4b..0000000000 --- a/packages/turf-flatten/index.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { - Point, - MultiPoint, - LineString, - MultiLineString, - Polygon, - MultiPolygon, - Feature, - FeatureCollection, - AllGeoJSON -} from '@turf/helpers' - -/** - * http://turfjs.org/docs/#flatten - */ -declare function flatten(geojson: Feature | FeatureCollection | T): FeatureCollection; -declare function flatten(geojson: Feature | FeatureCollection | T): FeatureCollection; -declare function flatten(geojson: Feature | FeatureCollection | T): FeatureCollection; -declare function flatten(geojson: AllGeoJSON): FeatureCollection; - -export default flatten; diff --git a/packages/turf-flatten/index.js b/packages/turf-flatten/index.js deleted file mode 100644 index 3f3ecdf692..0000000000 --- a/packages/turf-flatten/index.js +++ /dev/null @@ -1,32 +0,0 @@ -import { flattenEach } from '@turf/meta'; -import { featureCollection } from '@turf/helpers'; - -/** - * Flattens any {@link GeoJSON} to a {@link FeatureCollection} inspired by [geojson-flatten](https://github.com/tmcw/geojson-flatten). - * - * @name flatten - * @param {GeoJSON} geojson any valid GeoJSON Object - * @returns {FeatureCollection} all Multi-Geometries are flattened into single Features - * @example - * var multiGeometry = turf.multiPolygon([ - * [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]], - * [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], - * [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]] - * ]); - * - * var flatten = turf.flatten(multiGeometry); - * - * //addToMap - * var addToMap = [flatten] - */ -function flatten(geojson) { - if (!geojson) throw new Error('geojson is required'); - - var results = []; - flattenEach(geojson, function (feature) { - results.push(feature); - }); - return featureCollection(results); -} - -export default flatten; diff --git a/packages/turf-flatten/package.json b/packages/turf-flatten/package.json deleted file mode 100644 index 835527fb86..0000000000 --- a/packages/turf-flatten/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "@turf/flatten", - "version": "5.1.5", - "description": "turf flatten module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "geography", - "gis", - "featurecollection" - ], - "author": "Turf Authors", - "contributors": [ - "Tom MacWright <@tmcw>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-flatten/types.ts b/packages/turf-flatten/types.ts deleted file mode 100644 index c0b260344c..0000000000 --- a/packages/turf-flatten/types.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { - multiPoint, - multiLineString, - geometryCollection, - // Typescript types - FeatureCollection, - Point, - LineString -} from '@turf/helpers' -import flatten from './' - -const multiPt = multiPoint([[0, 0], [10, 10]]) -const multiLine = multiLineString([[[20, 20], [30, 30]], [[0, 0], [10, 10]]]) - -let points: FeatureCollection = flatten(multiPt); -let lines: FeatureCollection = flatten(multiLine); -points = flatten(multiPt.geometry); -lines = flatten(multiLine.geometry); - -flatten(geometryCollection([multiPt.geometry, multiLine.geometry])); diff --git a/packages/turf-flip/LICENSE b/packages/turf-flip/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-flip/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-flip/README.md b/packages/turf-flip/README.md deleted file mode 100644 index 33475addf2..0000000000 --- a/packages/turf-flip/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# @turf/flip - - - -## flip - -Takes input features and flips all of their coordinates from `[x, y]` to `[y, x]`. - -**Parameters** - -- `geojson` **[GeoJSON][1]** input features -- `options` **[Object][2]** Optional parameters (optional, default `{}`) - - `options.mutate` **[boolean][3]** allows GeoJSON input to be mutated (significant performance increase if true) (optional, default `false`) - -**Examples** - -```javascript -var serbia = turf.point([20.566406, 43.421008]); - -var saudiArabia = turf.flip(serbia); - -//addToMap -var addToMap = [serbia, saudiArabia]; -``` - -Returns **[GeoJSON][1]** a feature or set of features of the same type as `input` with flipped coordinates - -[1]: https://tools.ietf.org/html/rfc7946#section-3 - -[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/flip -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-flip/index.js b/packages/turf-flip/index.js deleted file mode 100644 index 5c75fc4962..0000000000 --- a/packages/turf-flip/index.js +++ /dev/null @@ -1,42 +0,0 @@ -import { coordEach } from '@turf/meta'; -import { isObject } from '@turf/helpers'; -import clone from '@turf/clone'; - -/** - * Takes input features and flips all of their coordinates from `[x, y]` to `[y, x]`. - * - * @name flip - * @param {GeoJSON} geojson input features - * @param {Object} [options={}] Optional parameters - * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) - * @returns {GeoJSON} a feature or set of features of the same type as `input` with flipped coordinates - * @example - * var serbia = turf.point([20.566406, 43.421008]); - * - * var saudiArabia = turf.flip(serbia); - * - * //addToMap - * var addToMap = [serbia, saudiArabia]; - */ -function flip(geojson, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var mutate = options.mutate; - - if (!geojson) throw new Error('geojson is required'); - // ensure that we don't modify features in-place and changes to the - // output do not change the previous feature, including changes to nested - // properties. - if (mutate === false || mutate === undefined) geojson = clone(geojson); - - coordEach(geojson, function (coord) { - var x = coord[0]; - var y = coord[1]; - coord[0] = y; - coord[1] = x; - }); - return geojson; -} - -export default flip; diff --git a/packages/turf-flip/package.json b/packages/turf-flip/package.json deleted file mode 100644 index b0714bf152..0000000000 --- a/packages/turf-flip/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@turf/flip", - "version": "5.1.5", - "description": "turf flip module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "coordinate", - "flip" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/clone": "6.x", - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-flip/test.js b/packages/turf-flip/test.js deleted file mode 100644 index e16bd6c5a2..0000000000 --- a/packages/turf-flip/test.js +++ /dev/null @@ -1,42 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import { point } from '@turf/helpers'; -import flip from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-flip', t => { - fixtures.forEach(fixture => { - const name = fixture.name; - const filename = fixture.filename; - const geojson = fixture.geojson; - const results = flip(geojson); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEqual(load.sync(directories.out + filename), results, name); - }); - t.end(); -}); - -test('turf-flip - handle input mutation', t => { - const geojson = point([120, 40]); - flip(geojson); - t.deepEqual(geojson, point([120, 40]), 'does not mutate input'); - flip(geojson, {mutate: true}); - t.deepEqual(geojson, point([40, 120]), 'does mutate input'); - t.end(); -}); diff --git a/packages/turf-flip/types.ts b/packages/turf-flip/types.ts deleted file mode 100644 index 28c260f22a..0000000000 --- a/packages/turf-flip/types.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {featureCollection, point, lineString, geometryCollection} from '@turf/helpers' -import flip from './' - -const pt = point([120.1234567, 40.1234567]) -const ptGeom = pt.geometry -const line = lineString([[20,80], [50, 40]]) -const lineGeom = line.geometry -const points = featureCollection([pt]) -const lines = featureCollection([line]) -const geomCollection = geometryCollection([ptGeom, lineGeom]) - -flip(pt) -flip(ptGeom) -flip(line) -flip(lineGeom) -flip(lines) -flip(points) -flip(geomCollection, {mutate: true}) - diff --git a/packages/turf-great-circle/LICENSE b/packages/turf-great-circle/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-great-circle/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-great-circle/README.md b/packages/turf-great-circle/README.md deleted file mode 100644 index befb79d8bd..0000000000 --- a/packages/turf-great-circle/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# @turf/great-circle - - - -## greatCircle - -Calculate great circles routes as [LineString][1] - -**Parameters** - -- `start` **[Coord][2]** source point feature -- `end` **[Coord][2]** destination point feature -- `options` **[Object][3]** Optional parameters (optional, default `{}`) - - `options.properties` **[Object][3]** line feature properties (optional, default `{}`) - - `options.npoints` **[number][4]** number of points (optional, default `100`) - - `options.offset` **[number][4]** offset controls the likelyhood that lines will - be split which cross the dateline. The higher the number the more likely. (optional, default `10`) - -**Examples** - -```javascript -var start = turf.point([-122, 48]); -var end = turf.point([-77, 39]); - -var greatCircle = turf.greatCircle(start, end, {'name': 'Seattle to DC'}); - -//addToMap -var addToMap = [start, end, greatCircle] -``` - -Returns **[Feature][5]<[LineString][6]>** great circle line feature - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[5]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/great-circle -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-great-circle/bench.js b/packages/turf-great-circle/bench.js deleted file mode 100644 index 1a3eb03061..0000000000 --- a/packages/turf-great-circle/bench.js +++ /dev/null @@ -1,14 +0,0 @@ -import Benchmark from 'benchmark'; -import { point } from '@turf/helpers'; -import greatCircle from './'; - -const point1 = point([-75, 45]); -const point2 = point([30, 45]); - -const suite = new Benchmark.Suite('turf-great-circle'); - -suite - .add('greatCircle', () => { greatCircle(point1, point2); }) - .on('cycle', e => console.log(String(e.target))) - .on('complete', () => {}) - .run(); diff --git a/packages/turf-great-circle/index.d.ts b/packages/turf-great-circle/index.d.ts deleted file mode 100644 index 40ef7457eb..0000000000 --- a/packages/turf-great-circle/index.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { LineString, Feature, Coord, Properties } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#greatcircle - */ -export default function greatCircle( - start: Coord, - end: Coord, - options?: { - properties?: Properties, - npoints?: number, - offset?: number - } -): Feature; diff --git a/packages/turf-great-circle/index.js b/packages/turf-great-circle/index.js deleted file mode 100644 index a181381202..0000000000 --- a/packages/turf-great-circle/index.js +++ /dev/null @@ -1,48 +0,0 @@ -import { getCoord } from '@turf/invariant'; -import { GreatCircle } from './lib/arc'; - -/** - * Calculate great circles routes as {@link LineString} - * - * @name greatCircle - * @param {Coord} start source point feature - * @param {Coord} end destination point feature - * @param {Object} [options={}] Optional parameters - * @param {Object} [options.properties={}] line feature properties - * @param {number} [options.npoints=100] number of points - * @param {number} [options.offset=10] offset controls the likelyhood that lines will - * be split which cross the dateline. The higher the number the more likely. - * @returns {Feature} great circle line feature - * @example - * var start = turf.point([-122, 48]); - * var end = turf.point([-77, 39]); - * - * var greatCircle = turf.greatCircle(start, end, {'name': 'Seattle to DC'}); - * - * //addToMap - * var addToMap = [start, end, greatCircle] - */ -function greatCircle(start, end, options) { - // Optional parameters - options = options || {}; - if (typeof options !== 'object') throw new Error('options is invalid'); - var properties = options.properties; - var npoints = options.npoints; - var offset = options.offset; - - start = getCoord(start); - end = getCoord(end); - properties = properties || {}; - npoints = npoints || 100; - offset = offset || 10; - - var generator = new GreatCircle({x: start[0], y: start[1]}, {x: end[0], y: end[1]}, properties); - - /* eslint-disable */ - var line = generator.Arc(npoints, {offset: offset}); - /* eslint-enable */ - - return line.json(); -} - -export default greatCircle; diff --git a/packages/turf-great-circle/package.json b/packages/turf-great-circle/package.json deleted file mode 100644 index 9d02028001..0000000000 --- a/packages/turf-great-circle/package.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "@turf/great-circle", - "version": "5.1.5", - "description": "turf great-circle module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "lib", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "arc", - "line", - "great", - "circle" - ], - "author": "Turf Authors", - "contributors": [ - "Dane Springmeyer <@springmeyer>", - "Stepan Kuzmin <@stepankuzmin>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/truncate": "6.x", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-great-circle/test.js b/packages/turf-great-circle/test.js deleted file mode 100644 index ff45b0b23d..0000000000 --- a/packages/turf-great-circle/test.js +++ /dev/null @@ -1,37 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import truncate from '@turf/truncate'; -import { featureCollection } from '@turf/helpers'; -import greatCircle from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -let fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(path.join(directories.in, filename)) - }; -}); - -test('turf-great-circle', t => { - fixtures.forEach(fixture => { - const name = fixture.name; - const filename = fixture.filename; - const geojson = fixture.geojson; - const start = geojson.features[0]; - const end = geojson.features[1]; - const line = truncate(greatCircle(start, end)); - const results = featureCollection([line, start, end]); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEquals(results, load.sync(directories.out + filename), name); - }); - t.end(); -}); diff --git a/packages/turf-great-circle/types.ts b/packages/turf-great-circle/types.ts deleted file mode 100644 index f1fc62d3e6..0000000000 --- a/packages/turf-great-circle/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { point } from '@turf/helpers' -import greatCircle from './' - -const pt1 = point([0, 0]) -const pt2 = point([60, 0]) -greatCircle(pt1, pt2) -greatCircle(pt1.geometry, pt2.geometry) -greatCircle(pt1.geometry.coordinates, pt2.geometry.coordinates) -greatCircle(pt1, pt2, {properties: {'name': 'Seattle to DC'}}) -greatCircle(pt1, pt2, {npoints: 10}) -greatCircle(pt1, pt2, {offset: 100, npoints: 10}) - diff --git a/packages/turf-helpers/.gitignore b/packages/turf-helpers/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-helpers/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-helpers/LICENSE b/packages/turf-helpers/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-helpers/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-helpers/README.md b/packages/turf-helpers/README.md deleted file mode 100644 index 75ee559dcf..0000000000 --- a/packages/turf-helpers/README.md +++ /dev/null @@ -1,579 +0,0 @@ -# @turf/helpers - - - -## earthRadius - -Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth. - -## factors - -Unit of measurement factors using a spherical (non-ellipsoid) earth radius. - -## unitsFactors - -Units of measurement factors based on 1 meter. - -## areaFactors - -Area of measurement factors based on 1 square meter. - -## feature - -Wraps a GeoJSON [Geometry][1] in a GeoJSON [Feature][2]. - -**Parameters** - -- `geometry` **[Geometry][3]** input geometry -- `properties` **[Object][4]** an Object of key-value pairs to add as properties (optional, default `{}`) -- `options` **[Object][4]** Optional Parameters (optional, default `{}`) - - `options.bbox` **[Array][5]<[number][6]>?** Bounding Box Array [west, south, east, north] associated with the Feature - - `options.id` **([string][7] \| [number][6])?** Identifier associated with the Feature - -**Examples** - -```javascript -var geometry = { - "type": "Point", - "coordinates": [110, 50] -}; - -var feature = turf.feature(geometry); - -//=feature -``` - -Returns **[Feature][8]** a GeoJSON Feature - -## geometry - -Creates a GeoJSON [Geometry][1] from a Geometry string type & coordinates. -For GeometryCollection type use `helpers.geometryCollection` - -**Parameters** - -- `type` **[string][7]** Geometry Type -- `coordinates` **[Array][5]<[number][6]>** Coordinates -- `options` **[Object][4]** Optional Parameters (optional, default `{}`) - - `options.bbox` **[Array][5]<[number][6]>?** Bounding Box Array [west, south, east, north] associated with the Geometry - -**Examples** - -```javascript -var type = 'Point'; -var coordinates = [110, 50]; - -var geometry = turf.geometry(type, coordinates); - -//=geometry -``` - -Returns **[Geometry][3]** a GeoJSON Geometry - -## point - -Creates a [Point][9] [Feature][2] from a Position. - -**Parameters** - -- `coordinates` **[Array][5]<[number][6]>** longitude, latitude position (each in decimal degrees) -- `properties` **[Object][4]** an Object of key-value pairs to add as properties (optional, default `{}`) -- `options` **[Object][4]** Optional Parameters (optional, default `{}`) - - `options.bbox` **[Array][5]<[number][6]>?** Bounding Box Array [west, south, east, north] associated with the Feature - - `options.id` **([string][7] \| [number][6])?** Identifier associated with the Feature - -**Examples** - -```javascript -var point = turf.point([-75.343, 39.984]); - -//=point -``` - -Returns **[Feature][8]<[Point][10]>** a Point feature - -## points - -Creates a [Point][9] [FeatureCollection][11] from an Array of Point coordinates. - -**Parameters** - -- `coordinates` **[Array][5]<[Array][5]<[number][6]>>** an array of Points -- `properties` **[Object][4]** Translate these properties to each Feature (optional, default `{}`) -- `options` **[Object][4]** Optional Parameters (optional, default `{}`) - - `options.bbox` **[Array][5]<[number][6]>?** Bounding Box Array [west, south, east, north] associated with the FeatureCollection - - `options.id` **([string][7] \| [number][6])?** Identifier associated with the FeatureCollection - -**Examples** - -```javascript -var points = turf.points([ - [-75, 39], - [-80, 45], - [-78, 50] -]); - -//=points -``` - -Returns **[FeatureCollection][12]<[Point][10]>** Point Feature - -## polygon - -Creates a [Polygon][13] [Feature][2] from an Array of LinearRings. - -**Parameters** - -- `coordinates` **[Array][5]<[Array][5]<[Array][5]<[number][6]>>>** an array of LinearRings -- `properties` **[Object][4]** an Object of key-value pairs to add as properties (optional, default `{}`) -- `options` **[Object][4]** Optional Parameters (optional, default `{}`) - - `options.bbox` **[Array][5]<[number][6]>?** Bounding Box Array [west, south, east, north] associated with the Feature - - `options.id` **([string][7] \| [number][6])?** Identifier associated with the Feature - -**Examples** - -```javascript -var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' }); - -//=polygon -``` - -Returns **[Feature][8]<[Polygon][14]>** Polygon Feature - -## polygons - -Creates a [Polygon][13] [FeatureCollection][11] from an Array of Polygon coordinates. - -**Parameters** - -- `coordinates` **[Array][5]<[Array][5]<[Array][5]<[Array][5]<[number][6]>>>>** an array of Polygon coordinates -- `properties` **[Object][4]** an Object of key-value pairs to add as properties (optional, default `{}`) -- `options` **[Object][4]** Optional Parameters (optional, default `{}`) - - `options.bbox` **[Array][5]<[number][6]>?** Bounding Box Array [west, south, east, north] associated with the Feature - - `options.id` **([string][7] \| [number][6])?** Identifier associated with the FeatureCollection - -**Examples** - -```javascript -var polygons = turf.polygons([ - [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], - [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]], -]); - -//=polygons -``` - -Returns **[FeatureCollection][12]<[Polygon][14]>** Polygon FeatureCollection - -## lineString - -Creates a [LineString][15] [Feature][2] from an Array of Positions. - -**Parameters** - -- `coordinates` **[Array][5]<[Array][5]<[number][6]>>** an array of Positions -- `properties` **[Object][4]** an Object of key-value pairs to add as properties (optional, default `{}`) -- `options` **[Object][4]** Optional Parameters (optional, default `{}`) - - `options.bbox` **[Array][5]<[number][6]>?** Bounding Box Array [west, south, east, north] associated with the Feature - - `options.id` **([string][7] \| [number][6])?** Identifier associated with the Feature - -**Examples** - -```javascript -var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'}); -var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'}); - -//=linestring1 -//=linestring2 -``` - -Returns **[Feature][8]<[LineString][16]>** LineString Feature - -## lineStrings - -Creates a [LineString][15] [FeatureCollection][11] from an Array of LineString coordinates. - -**Parameters** - -- `coordinates` **[Array][5]<[Array][5]<[number][6]>>** an array of LinearRings -- `properties` **[Object][4]** an Object of key-value pairs to add as properties (optional, default `{}`) -- `options` **[Object][4]** Optional Parameters (optional, default `{}`) - - `options.bbox` **[Array][5]<[number][6]>?** Bounding Box Array [west, south, east, north] associated with the FeatureCollection - - `options.id` **([string][7] \| [number][6])?** Identifier associated with the FeatureCollection - -**Examples** - -```javascript -var linestrings = turf.lineStrings([ - [[-24, 63], [-23, 60], [-25, 65], [-20, 69]], - [[-14, 43], [-13, 40], [-15, 45], [-10, 49]] -]); - -//=linestrings -``` - -Returns **[FeatureCollection][12]<[LineString][16]>** LineString FeatureCollection - -## featureCollection - -Takes one or more [Features][2] and creates a [FeatureCollection][11]. - -**Parameters** - -- `features` **[Array][5]<[Feature][8]>** input features -- `options` **[Object][4]** Optional Parameters (optional, default `{}`) - - `options.bbox` **[Array][5]<[number][6]>?** Bounding Box Array [west, south, east, north] associated with the Feature - - `options.id` **([string][7] \| [number][6])?** Identifier associated with the Feature - -**Examples** - -```javascript -var locationA = turf.point([-75.343, 39.984], {name: 'Location A'}); -var locationB = turf.point([-75.833, 39.284], {name: 'Location B'}); -var locationC = turf.point([-75.534, 39.123], {name: 'Location C'}); - -var collection = turf.featureCollection([ - locationA, - locationB, - locationC -]); - -//=collection -``` - -Returns **[FeatureCollection][12]** FeatureCollection of Features - -## multiLineString - -Creates a [Feature<MultiLineString>][17] based on a -coordinate array. Properties can be added optionally. - -**Parameters** - -- `coordinates` **[Array][5]<[Array][5]<[Array][5]<[number][6]>>>** an array of LineStrings -- `properties` **[Object][4]** an Object of key-value pairs to add as properties (optional, default `{}`) -- `options` **[Object][4]** Optional Parameters (optional, default `{}`) - - `options.bbox` **[Array][5]<[number][6]>?** Bounding Box Array [west, south, east, north] associated with the Feature - - `options.id` **([string][7] \| [number][6])?** Identifier associated with the Feature - -**Examples** - -```javascript -var multiLine = turf.multiLineString([[[0,0],[10,10]]]); - -//=multiLine -``` - -- Throws **[Error][18]** if no coordinates are passed - -Returns **[Feature][8]<[MultiLineString][19]>** a MultiLineString feature - -## multiPoint - -Creates a [Feature<MultiPoint>][20] based on a -coordinate array. Properties can be added optionally. - -**Parameters** - -- `coordinates` **[Array][5]<[Array][5]<[number][6]>>** an array of Positions -- `properties` **[Object][4]** an Object of key-value pairs to add as properties (optional, default `{}`) -- `options` **[Object][4]** Optional Parameters (optional, default `{}`) - - `options.bbox` **[Array][5]<[number][6]>?** Bounding Box Array [west, south, east, north] associated with the Feature - - `options.id` **([string][7] \| [number][6])?** Identifier associated with the Feature - -**Examples** - -```javascript -var multiPt = turf.multiPoint([[0,0],[10,10]]); - -//=multiPt -``` - -- Throws **[Error][18]** if no coordinates are passed - -Returns **[Feature][8]<[MultiPoint][21]>** a MultiPoint feature - -## multiPolygon - -Creates a [Feature<MultiPolygon>][22] based on a -coordinate array. Properties can be added optionally. - -**Parameters** - -- `coordinates` **[Array][5]<[Array][5]<[Array][5]<[Array][5]<[number][6]>>>>** an array of Polygons -- `properties` **[Object][4]** an Object of key-value pairs to add as properties (optional, default `{}`) -- `options` **[Object][4]** Optional Parameters (optional, default `{}`) - - `options.bbox` **[Array][5]<[number][6]>?** Bounding Box Array [west, south, east, north] associated with the Feature - - `options.id` **([string][7] \| [number][6])?** Identifier associated with the Feature - -**Examples** - -```javascript -var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]); - -//=multiPoly -``` - -- Throws **[Error][18]** if no coordinates are passed - -Returns **[Feature][8]<[MultiPolygon][23]>** a multipolygon feature - -## geometryCollection - -Creates a [Feature<GeometryCollection>][24] based on a -coordinate array. Properties can be added optionally. - -**Parameters** - -- `geometries` **[Array][5]<[Geometry][3]>** an array of GeoJSON Geometries -- `properties` **[Object][4]** an Object of key-value pairs to add as properties (optional, default `{}`) -- `options` **[Object][4]** Optional Parameters (optional, default `{}`) - - `options.bbox` **[Array][5]<[number][6]>?** Bounding Box Array [west, south, east, north] associated with the Feature - - `options.id` **([string][7] \| [number][6])?** Identifier associated with the Feature - -**Examples** - -```javascript -var pt = { - "type": "Point", - "coordinates": [100, 0] - }; -var line = { - "type": "LineString", - "coordinates": [ [101, 0], [102, 1] ] - }; -var collection = turf.geometryCollection([pt, line]); - -//=collection -``` - -Returns **[Feature][8]<[GeometryCollection][25]>** a GeoJSON GeometryCollection Feature - -## round - -Round number to precision - -**Parameters** - -- `num` **[number][6]** Number -- `precision` **[number][6]** Precision (optional, default `0`) - -**Examples** - -```javascript -turf.round(120.4321) -//=120 - -turf.round(120.4321, 2) -//=120.43 -``` - -Returns **[number][6]** rounded number - -## radiansToLength - -Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit. -Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet - -**Parameters** - -- `radians` **[number][6]** in radians across the sphere -- `units` **[string][7]** can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers. (optional, default `'kilometers'`) - -Returns **[number][6]** distance - -## lengthToRadians - -Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians -Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet - -**Parameters** - -- `distance` **[number][6]** in real units -- `units` **[string][7]** can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers. (optional, default `'kilometers'`) - -Returns **[number][6]** radians - -## lengthToDegrees - -Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees -Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet - -**Parameters** - -- `distance` **[number][6]** in real units -- `units` **[string][7]** can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers. (optional, default `'kilometers'`) - -Returns **[number][6]** degrees - -## bearingToAzimuth - -Converts any bearing angle from the north line direction (positive clockwise) -and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line - -**Parameters** - -- `bearing` **[number][6]** angle, between -180 and +180 degrees - -Returns **[number][6]** angle between 0 and 360 degrees - -## radiansToDegrees - -Converts an angle in radians to degrees - -**Parameters** - -- `radians` **[number][6]** angle in radians - -Returns **[number][6]** degrees between 0 and 360 degrees - -## degreesToRadians - -Converts an angle in degrees to radians - -**Parameters** - -- `degrees` **[number][6]** angle between 0 and 360 degrees - -Returns **[number][6]** angle in radians - -## convertLength - -Converts a length to the requested unit. -Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet - -**Parameters** - -- `length` **[number][6]** to be converted -- `originalUnit` **[string][7]** of the length -- `finalUnit` **[string][7]** returned unit (optional, default `'kilometers'`) - -Returns **[number][6]** the converted length - -## convertArea - -Converts a area to the requested unit. -Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches - -**Parameters** - -- `area` **[number][6]** to be converted -- `originalUnit` **[string][7]** of the distance (optional, default `'meters'`) -- `finalUnit` **[string][7]** returned unit (optional, default `'kilometers'`) - -Returns **[number][6]** the converted distance - -## isNumber - -isNumber - -**Parameters** - -- `num` **any** Number to validate - -**Examples** - -```javascript -turf.isNumber(123) -//=true -turf.isNumber('foo') -//=false -``` - -Returns **[boolean][26]** true/false - -## isObject - -isObject - -**Parameters** - -- `input` **any** variable to validate - -**Examples** - -```javascript -turf.isObject({elevation: 10}) -//=true -turf.isObject('foo') -//=false -``` - -Returns **[boolean][26]** true/false - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[8]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[9]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[10]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[11]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[12]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[13]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[14]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[15]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[16]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[17]: Feature - -[18]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error - -[19]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[20]: Feature - -[21]: https://tools.ietf.org/html/rfc7946#section-3.1.3 - -[22]: Feature - -[23]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[24]: Feature - -[25]: https://tools.ietf.org/html/rfc7946#section-3.1.8 - -[26]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/helpers -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-helpers/index.d.ts b/packages/turf-helpers/index.d.ts deleted file mode 100644 index e764a0c9a4..0000000000 --- a/packages/turf-helpers/index.d.ts +++ /dev/null @@ -1,489 +0,0 @@ -import { BBox, CollectionTypes, Feature, FeatureCollection, GeoJSONObject, Geometries, Geometry, GeometryCollection, GeometryObject, GeometryTypes, Id, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, Position, Properties, Types } from "./lib/geojson"; -export { Id, Properties, BBox, Position, Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryObject, GeoJSONObject, GeometryCollection, Geometry, GeometryTypes, Types, CollectionTypes, Geometries, Feature, FeatureCollection }; -export declare type Coord = Feature | Point | Position; -export declare type Units = "meters" | "millimeters" | "centimeters" | "kilometers" | "acres" | "miles" | "nauticalmiles" | "inches" | "yards" | "feet" | "radians" | "degrees"; -export declare type Grid = "point" | "square" | "hex" | "triangle"; -export declare type Corners = "sw" | "se" | "nw" | "ne" | "center" | "centroid"; -export declare type Lines = LineString | MultiLineString | Polygon | MultiPolygon; -export declare type AllGeoJSON = Feature | FeatureCollection | Geometry | GeometryCollection; -/** - * @module helpers - */ -/** - * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth. - * - * @memberof helpers - * @type {number} - */ -export declare let earthRadius: number; -/** - * Unit of measurement factors using a spherical (non-ellipsoid) earth radius. - * - * @memberof helpers - * @type {Object} - */ -export declare let factors: { - [key: string]: number; -}; -/** - * Units of measurement factors based on 1 meter. - * - * @memberof helpers - * @type {Object} - */ -export declare let unitsFactors: { - [key: string]: number; -}; -/** - * Area of measurement factors based on 1 square meter. - * - * @memberof helpers - * @type {Object} - */ -export declare let areaFactors: any; -/** - * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}. - * - * @name feature - * @param {Geometry} geometry input geometry - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} a GeoJSON Feature - * @example - * var geometry = { - * "type": "Point", - * "coordinates": [110, 50] - * }; - * - * var feature = turf.feature(geometry); - * - * //=feature - */ -export declare function feature(geom: G, properties?: P, options?: { - bbox?: BBox; - id?: Id; -}): Feature; -/** - * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates. - * For GeometryCollection type use `helpers.geometryCollection` - * - * @name geometry - * @param {string} type Geometry Type - * @param {Array} coordinates Coordinates - * @param {Object} [options={}] Optional Parameters - * @returns {Geometry} a GeoJSON Geometry - * @example - * var type = "Point"; - * var coordinates = [110, 50]; - * var geometry = turf.geometry(type, coordinates); - * // => geometry - */ -export declare function geometry(type: "Point" | "LineString" | "Polygon" | "MultiPoint" | "MultiLineString" | "MultiPolygon", coordinates: any[], options?: {}): Point | LineString | Polygon | MultiPoint | MultiLineString | MultiPolygon; -/** - * Creates a {@link Point} {@link Feature} from a Position. - * - * @name point - * @param {Array} coordinates longitude, latitude position (each in decimal degrees) - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} a Point feature - * @example - * var point = turf.point([-75.343, 39.984]); - * - * //=point - */ -export declare function point

(coordinates: Position, properties?: P, options?: { - bbox?: BBox; - id?: Id; -}): Feature; -/** - * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates. - * - * @name points - * @param {Array>} coordinates an array of Points - * @param {Object} [properties={}] Translate these properties to each Feature - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] - * associated with the FeatureCollection - * @param {string|number} [options.id] Identifier associated with the FeatureCollection - * @returns {FeatureCollection} Point Feature - * @example - * var points = turf.points([ - * [-75, 39], - * [-80, 45], - * [-78, 50] - * ]); - * - * //=points - */ -export declare function points

(coordinates: Position[], properties?: P, options?: { - bbox?: BBox; - id?: Id; -}): FeatureCollection; -/** - * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings. - * - * @name polygon - * @param {Array>>} coordinates an array of LinearRings - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} Polygon Feature - * @example - * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' }); - * - * //=polygon - */ -export declare function polygon

(coordinates: Position[][], properties?: P, options?: { - bbox?: BBox; - id?: Id; -}): Feature; -/** - * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates. - * - * @name polygons - * @param {Array>>>} coordinates an array of Polygon coordinates - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the FeatureCollection - * @returns {FeatureCollection} Polygon FeatureCollection - * @example - * var polygons = turf.polygons([ - * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], - * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]], - * ]); - * - * //=polygons - */ -export declare function polygons

(coordinates: Position[][][], properties?: P, options?: { - bbox?: BBox; - id?: Id; -}): FeatureCollection; -/** - * Creates a {@link LineString} {@link Feature} from an Array of Positions. - * - * @name lineString - * @param {Array>} coordinates an array of Positions - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} LineString Feature - * @example - * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'}); - * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'}); - * - * //=linestring1 - * //=linestring2 - */ -export declare function lineString

(coordinates: Position[], properties?: P, options?: { - bbox?: BBox; - id?: Id; -}): Feature; -/** - * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates. - * - * @name lineStrings - * @param {Array>>} coordinates an array of LinearRings - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] - * associated with the FeatureCollection - * @param {string|number} [options.id] Identifier associated with the FeatureCollection - * @returns {FeatureCollection} LineString FeatureCollection - * @example - * var linestrings = turf.lineStrings([ - * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]], - * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]] - * ]); - * - * //=linestrings - */ -export declare function lineStrings

(coordinates: Position[][], properties?: P, options?: { - bbox?: BBox; - id?: Id; -}): FeatureCollection; -/** - * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}. - * - * @name featureCollection - * @param {Feature[]} features input features - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {FeatureCollection} FeatureCollection of Features - * @example - * var locationA = turf.point([-75.343, 39.984], {name: 'Location A'}); - * var locationB = turf.point([-75.833, 39.284], {name: 'Location B'}); - * var locationC = turf.point([-75.534, 39.123], {name: 'Location C'}); - * - * var collection = turf.featureCollection([ - * locationA, - * locationB, - * locationC - * ]); - * - * //=collection - */ -export declare function featureCollection(features: Array>, options?: { - bbox?: BBox; - id?: Id; -}): FeatureCollection; -/** - * Creates a {@link Feature} based on a - * coordinate array. Properties can be added optionally. - * - * @name multiLineString - * @param {Array>>} coordinates an array of LineStrings - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} a MultiLineString feature - * @throws {Error} if no coordinates are passed - * @example - * var multiLine = turf.multiLineString([[[0,0],[10,10]]]); - * - * //=multiLine - */ -export declare function multiLineString

(coordinates: Position[][], properties?: P, options?: { - bbox?: BBox; - id?: Id; -}): Feature; -/** - * Creates a {@link Feature} based on a - * coordinate array. Properties can be added optionally. - * - * @name multiPoint - * @param {Array>} coordinates an array of Positions - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} a MultiPoint feature - * @throws {Error} if no coordinates are passed - * @example - * var multiPt = turf.multiPoint([[0,0],[10,10]]); - * - * //=multiPt - */ -export declare function multiPoint

(coordinates: Position[], properties?: P, options?: { - bbox?: BBox; - id?: Id; -}): Feature; -/** - * Creates a {@link Feature} based on a - * coordinate array. Properties can be added optionally. - * - * @name multiPolygon - * @param {Array>>>} coordinates an array of Polygons - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} a multipolygon feature - * @throws {Error} if no coordinates are passed - * @example - * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]); - * - * //=multiPoly - * - */ -export declare function multiPolygon

(coordinates: Position[][][], properties?: P, options?: { - bbox?: BBox; - id?: Id; -}): Feature; -/** - * Creates a {@link Feature} based on a - * coordinate array. Properties can be added optionally. - * - * @name geometryCollection - * @param {Array} geometries an array of GeoJSON Geometries - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} a GeoJSON GeometryCollection Feature - * @example - * var pt = turf.geometry("Point", [100, 0]); - * var line = turf.geometry("LineString", [[101, 0], [102, 1]]); - * var collection = turf.geometryCollection([pt, line]); - * - * // => collection - */ -export declare function geometryCollection

(geometries: Array, properties?: P, options?: { - bbox?: BBox; - id?: Id; -}): Feature; -/** - * Round number to precision - * - * @param {number} num Number - * @param {number} [precision=0] Precision - * @returns {number} rounded number - * @example - * turf.round(120.4321) - * //=120 - * - * turf.round(120.4321, 2) - * //=120.43 - */ -export declare function round(num: number, precision?: number): number; -/** - * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit. - * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet - * - * @name radiansToLength - * @param {number} radians in radians across the sphere - * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers inches, yards, metres, - * meters, kilometres, kilometers. - * @returns {number} distance - */ -export declare function radiansToLength(radians: number, units?: Units): number; -/** - * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians - * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet - * - * @name lengthToRadians - * @param {number} distance in real units - * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers inches, yards, metres, - * meters, kilometres, kilometers. - * @returns {number} radians - */ -export declare function lengthToRadians(distance: number, units?: Units): number; -/** - * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees - * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet - * - * @name lengthToDegrees - * @param {number} distance in real units - * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers inches, yards, metres, - * meters, kilometres, kilometers. - * @returns {number} degrees - */ -export declare function lengthToDegrees(distance: number, units?: Units): number; -/** - * Converts any bearing angle from the north line direction (positive clockwise) - * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line - * - * @name bearingToAzimuth - * @param {number} bearing angle, between -180 and +180 degrees - * @returns {number} angle between 0 and 360 degrees - */ -export declare function bearingToAzimuth(bearing: number): number; -/** - * Converts an angle in radians to degrees - * - * @name radiansToDegrees - * @param {number} radians angle in radians - * @returns {number} degrees between 0 and 360 degrees - */ -export declare function radiansToDegrees(radians: number): number; -/** - * Converts an angle in degrees to radians - * - * @name degreesToRadians - * @param {number} degrees angle between 0 and 360 degrees - * @returns {number} angle in radians - */ -export declare function degreesToRadians(degrees: number): number; -/** - * Converts a length to the requested unit. - * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet - * - * @param {number} length to be converted - * @param {Units} [originalUnit="kilometers"] of the length - * @param {Units} [finalUnit="kilometers"] returned unit - * @returns {number} the converted length - */ -export declare function convertLength(length: number, originalUnit?: Units, finalUnit?: Units): number; -/** - * Converts a area to the requested unit. - * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches - * @param {number} area to be converted - * @param {Units} [originalUnit="meters"] of the distance - * @param {Units} [finalUnit="kilometers"] returned unit - * @returns {number} the converted distance - */ -export declare function convertArea(area: number, originalUnit?: Units, finalUnit?: Units): number; -/** - * isNumber - * - * @param {*} num Number to validate - * @returns {boolean} true/false - * @example - * turf.isNumber(123) - * //=true - * turf.isNumber('foo') - * //=false - */ -export declare function isNumber(num: any): boolean; -/** - * isObject - * - * @param {*} input variable to validate - * @returns {boolean} true/false - * @example - * turf.isObject({elevation: 10}) - * //=true - * turf.isObject('foo') - * //=false - */ -export declare function isObject(input: any): boolean; -/** - * Validate BBox - * - * @private - * @param {Array} bbox BBox to validate - * @returns {void} - * @throws Error if BBox is not valid - * @example - * validateBBox([-180, -40, 110, 50]) - * //=OK - * validateBBox([-180, -40]) - * //=Error - * validateBBox('Foo') - * //=Error - * validateBBox(5) - * //=Error - * validateBBox(null) - * //=Error - * validateBBox(undefined) - * //=Error - */ -export declare function validateBBox(bbox: any): void; -/** - * Validate Id - * - * @private - * @param {string|number} id Id to validate - * @returns {void} - * @throws Error if Id is not valid - * @example - * validateId([-180, -40, 110, 50]) - * //=Error - * validateId([-180, -40]) - * //=Error - * validateId('Foo') - * //=OK - * validateId(5) - * //=OK - * validateId(null) - * //=Error - * validateId(undefined) - * //=Error - */ -export declare function validateId(id: any): void; -export declare function radians2degrees(): void; -export declare function degrees2radians(): void; -export declare function distanceToDegrees(): void; -export declare function distanceToRadians(): void; -export declare function radiansToDistance(): void; -export declare function bearingToAngle(): void; -export declare function convertDistance(): void; diff --git a/packages/turf-helpers/index.ts b/packages/turf-helpers/index.ts deleted file mode 100644 index 9420e1a958..0000000000 --- a/packages/turf-helpers/index.ts +++ /dev/null @@ -1,762 +0,0 @@ -import { - BBox, CollectionTypes, Feature, FeatureCollection, - GeoJSONObject, Geometries, Geometry, GeometryCollection, GeometryObject, GeometryTypes, - Id, LineString, MultiLineString, MultiPoint, - MultiPolygon, Point, Polygon, Position, - Properties, Types, -} from "./lib/geojson"; -export { - Id, Properties, BBox, Position, - Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, - GeometryObject, GeoJSONObject, GeometryCollection, Geometry, - GeometryTypes, Types, CollectionTypes, Geometries, - Feature, FeatureCollection, -}; - -// TurfJS Combined Types -export type Coord = Feature | Point | Position; - -// TurfJS String Types -export type Units = "meters" | "millimeters" | "centimeters" | - "kilometers" | "acres" | "miles" | "nauticalmiles" | - "inches" | "yards" | "feet" | "radians" | "degrees"; -export type Grid = "point" | "square" | "hex" | "triangle"; -export type Corners = "sw" | "se" | "nw" | "ne" | "center" | "centroid"; - -export type Lines = LineString | MultiLineString | Polygon | MultiPolygon; -export type AllGeoJSON = Feature | FeatureCollection | Geometry | GeometryCollection; - -/** - * @module helpers - */ - -/** - * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth. - * - * @memberof helpers - * @type {number} - */ -export let earthRadius = 6371008.8; - -/** - * Unit of measurement factors using a spherical (non-ellipsoid) earth radius. - * - * @memberof helpers - * @type {Object} - */ -export let factors: {[key: string]: number} = { - centimeters: earthRadius * 100, - centimetres: earthRadius * 100, - degrees: earthRadius / 111325, - feet: earthRadius * 3.28084, - inches: earthRadius * 39.370, - kilometers: earthRadius / 1000, - kilometres: earthRadius / 1000, - meters: earthRadius, - metres: earthRadius, - miles: earthRadius / 1609.344, - millimeters: earthRadius * 1000, - millimetres: earthRadius * 1000, - nauticalmiles: earthRadius / 1852, - radians: 1, - yards: earthRadius / 1.0936, -}; - -/** - * Units of measurement factors based on 1 meter. - * - * @memberof helpers - * @type {Object} - */ -export let unitsFactors: {[key: string]: number} = { - centimeters: 100, - centimetres: 100, - degrees: 1 / 111325, - feet: 3.28084, - inches: 39.370, - kilometers: 1 / 1000, - kilometres: 1 / 1000, - meters: 1, - metres: 1, - miles: 1 / 1609.344, - millimeters: 1000, - millimetres: 1000, - nauticalmiles: 1 / 1852, - radians: 1 / earthRadius, - yards: 1 / 1.0936, -}; - -/** - * Area of measurement factors based on 1 square meter. - * - * @memberof helpers - * @type {Object} - */ -export let areaFactors: any = { - acres: 0.000247105, - centimeters: 10000, - centimetres: 10000, - feet: 10.763910417, - inches: 1550.003100006, - kilometers: 0.000001, - kilometres: 0.000001, - meters: 1, - metres: 1, - miles: 3.86e-7, - millimeters: 1000000, - millimetres: 1000000, - yards: 1.195990046, -}; - -/** - * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}. - * - * @name feature - * @param {Geometry} geometry input geometry - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} a GeoJSON Feature - * @example - * var geometry = { - * "type": "Point", - * "coordinates": [110, 50] - * }; - * - * var feature = turf.feature(geometry); - * - * //=feature - */ -export function feature( - geom: G, - properties?: P, - options: {bbox?: BBox, id?: Id} = {}, -): Feature { - const feat: any = {type: "Feature"}; - if (options.id === 0 || options.id) { feat.id = options.id; } - if (options.bbox) { feat.bbox = options.bbox; } - feat.properties = properties || {}; - feat.geometry = geom; - return feat; -} - -/** - * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates. - * For GeometryCollection type use `helpers.geometryCollection` - * - * @name geometry - * @param {string} type Geometry Type - * @param {Array} coordinates Coordinates - * @param {Object} [options={}] Optional Parameters - * @returns {Geometry} a GeoJSON Geometry - * @example - * var type = "Point"; - * var coordinates = [110, 50]; - * var geometry = turf.geometry(type, coordinates); - * // => geometry - */ -export function geometry( - type: "Point" | "LineString" | "Polygon" | "MultiPoint" | "MultiLineString" | "MultiPolygon", - coordinates: any[], - options: {} = {}, -) { - switch (type) { - case "Point": return point(coordinates).geometry; - case "LineString": return lineString(coordinates).geometry; - case "Polygon": return polygon(coordinates).geometry; - case "MultiPoint": return multiPoint(coordinates).geometry; - case "MultiLineString": return multiLineString(coordinates).geometry; - case "MultiPolygon": return multiPolygon(coordinates).geometry; - default: throw new Error(type + " is invalid"); - } -} - -/** - * Creates a {@link Point} {@link Feature} from a Position. - * - * @name point - * @param {Array} coordinates longitude, latitude position (each in decimal degrees) - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} a Point feature - * @example - * var point = turf.point([-75.343, 39.984]); - * - * //=point - */ -export function point

( - coordinates: Position, - properties?: P, - options: {bbox?: BBox, id?: Id} = {}, -): Feature { - const geom: Point = { - type: "Point", - coordinates, - }; - return feature(geom, properties, options); -} - -/** - * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates. - * - * @name points - * @param {Array>} coordinates an array of Points - * @param {Object} [properties={}] Translate these properties to each Feature - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] - * associated with the FeatureCollection - * @param {string|number} [options.id] Identifier associated with the FeatureCollection - * @returns {FeatureCollection} Point Feature - * @example - * var points = turf.points([ - * [-75, 39], - * [-80, 45], - * [-78, 50] - * ]); - * - * //=points - */ -export function points

( - coordinates: Position[], - properties?: P, - options: {bbox?: BBox, id?: Id} = {}, -): FeatureCollection { - return featureCollection(coordinates.map((coords) => { - return point(coords, properties); - }), options); -} - -/** - * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings. - * - * @name polygon - * @param {Array>>} coordinates an array of LinearRings - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} Polygon Feature - * @example - * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' }); - * - * //=polygon - */ -export function polygon

( - coordinates: Position[][], - properties?: P, - options: {bbox?: BBox, id?: Id} = {}, -): Feature { - for (const ring of coordinates) { - if (ring.length < 4) { - throw new Error("Each LinearRing of a Polygon must have 4 or more Positions."); - } - for (let j = 0; j < ring[ring.length - 1].length; j++) { - // Check if first point of Polygon contains two numbers - if (ring[ring.length - 1][j] !== ring[0][j]) { - throw new Error("First and last Position are not equivalent."); - } - } - } - const geom: Polygon = { - type: "Polygon", - coordinates, - }; - return feature(geom, properties, options); -} - -/** - * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates. - * - * @name polygons - * @param {Array>>>} coordinates an array of Polygon coordinates - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the FeatureCollection - * @returns {FeatureCollection} Polygon FeatureCollection - * @example - * var polygons = turf.polygons([ - * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], - * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]], - * ]); - * - * //=polygons - */ -export function polygons

( - coordinates: Position[][][], - properties?: P, - options: {bbox?: BBox, id?: Id} = {}, -): FeatureCollection { - return featureCollection(coordinates.map((coords) => { - return polygon(coords, properties); - }), options); -} - -/** - * Creates a {@link LineString} {@link Feature} from an Array of Positions. - * - * @name lineString - * @param {Array>} coordinates an array of Positions - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} LineString Feature - * @example - * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'}); - * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'}); - * - * //=linestring1 - * //=linestring2 - */ -export function lineString

( - coordinates: Position[], - properties?: P, - options: {bbox?: BBox, id?: Id} = {}, -): Feature { - if (coordinates.length < 2) { throw new Error("coordinates must be an array of two or more positions"); } - const geom: LineString = { - type: "LineString", - coordinates, - }; - return feature(geom, properties, options); -} - -/** - * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates. - * - * @name lineStrings - * @param {Array>>} coordinates an array of LinearRings - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] - * associated with the FeatureCollection - * @param {string|number} [options.id] Identifier associated with the FeatureCollection - * @returns {FeatureCollection} LineString FeatureCollection - * @example - * var linestrings = turf.lineStrings([ - * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]], - * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]] - * ]); - * - * //=linestrings - */ -export function lineStrings

( - coordinates: Position[][], - properties?: P, - options: {bbox?: BBox, id?: Id} = {}, -): FeatureCollection { - return featureCollection(coordinates.map((coords) => { - return lineString(coords, properties); - }), options); -} - -/** - * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}. - * - * @name featureCollection - * @param {Feature[]} features input features - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {FeatureCollection} FeatureCollection of Features - * @example - * var locationA = turf.point([-75.343, 39.984], {name: 'Location A'}); - * var locationB = turf.point([-75.833, 39.284], {name: 'Location B'}); - * var locationC = turf.point([-75.534, 39.123], {name: 'Location C'}); - * - * var collection = turf.featureCollection([ - * locationA, - * locationB, - * locationC - * ]); - * - * //=collection - */ -export function featureCollection( - features: Array>, - options: {bbox?: BBox, id?: Id} = {}, -): FeatureCollection { - const fc: any = {type: "FeatureCollection"}; - if (options.id) { fc.id = options.id; } - if (options.bbox) { fc.bbox = options.bbox; } - fc.features = features; - return fc; -} - -/** - * Creates a {@link Feature} based on a - * coordinate array. Properties can be added optionally. - * - * @name multiLineString - * @param {Array>>} coordinates an array of LineStrings - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} a MultiLineString feature - * @throws {Error} if no coordinates are passed - * @example - * var multiLine = turf.multiLineString([[[0,0],[10,10]]]); - * - * //=multiLine - */ -export function multiLineString

( - coordinates: Position[][], - properties?: P, - options: {bbox?: BBox, id?: Id} = {}, -): Feature { - const geom: MultiLineString = { - type: "MultiLineString", - coordinates, - }; - return feature(geom, properties, options); -} - -/** - * Creates a {@link Feature} based on a - * coordinate array. Properties can be added optionally. - * - * @name multiPoint - * @param {Array>} coordinates an array of Positions - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} a MultiPoint feature - * @throws {Error} if no coordinates are passed - * @example - * var multiPt = turf.multiPoint([[0,0],[10,10]]); - * - * //=multiPt - */ -export function multiPoint

( - coordinates: Position[], - properties?: P, - options: {bbox?: BBox, id?: Id} = {}, -): Feature { - const geom: MultiPoint = { - type: "MultiPoint", - coordinates, - }; - return feature(geom, properties, options); -} - -/** - * Creates a {@link Feature} based on a - * coordinate array. Properties can be added optionally. - * - * @name multiPolygon - * @param {Array>>>} coordinates an array of Polygons - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} a multipolygon feature - * @throws {Error} if no coordinates are passed - * @example - * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]); - * - * //=multiPoly - * - */ -export function multiPolygon

( - coordinates: Position[][][], - properties?: P, - options: {bbox?: BBox, id?: Id} = {}, -): Feature { - const geom: MultiPolygon = { - type: "MultiPolygon", - coordinates, - }; - return feature(geom, properties, options); -} - -/** - * Creates a {@link Feature} based on a - * coordinate array. Properties can be added optionally. - * - * @name geometryCollection - * @param {Array} geometries an array of GeoJSON Geometries - * @param {Object} [properties={}] an Object of key-value pairs to add as properties - * @param {Object} [options={}] Optional Parameters - * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature - * @param {string|number} [options.id] Identifier associated with the Feature - * @returns {Feature} a GeoJSON GeometryCollection Feature - * @example - * var pt = turf.geometry("Point", [100, 0]); - * var line = turf.geometry("LineString", [[101, 0], [102, 1]]); - * var collection = turf.geometryCollection([pt, line]); - * - * // => collection - */ -export function geometryCollection

( - geometries: Array, - properties?: P, - options: {bbox?: BBox, id?: Id} = {}, -): Feature { - const geom: GeometryCollection = { - type: "GeometryCollection", - geometries, - }; - return feature(geom, properties, options); -} - -/** - * Round number to precision - * - * @param {number} num Number - * @param {number} [precision=0] Precision - * @returns {number} rounded number - * @example - * turf.round(120.4321) - * //=120 - * - * turf.round(120.4321, 2) - * //=120.43 - */ -export function round(num: number, precision = 0): number { - if (precision && !(precision >= 0)) { throw new Error("precision must be a positive number"); } - const multiplier = Math.pow(10, precision || 0); - return Math.round(num * multiplier) / multiplier; -} - -/** - * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit. - * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet - * - * @name radiansToLength - * @param {number} radians in radians across the sphere - * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers inches, yards, metres, - * meters, kilometres, kilometers. - * @returns {number} distance - */ -export function radiansToLength(radians: number, units: Units = "kilometers"): number { - const factor = factors[units]; - if (!factor) { throw new Error(units + " units is invalid"); } - return radians * factor; -} - -/** - * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians - * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet - * - * @name lengthToRadians - * @param {number} distance in real units - * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers inches, yards, metres, - * meters, kilometres, kilometers. - * @returns {number} radians - */ -export function lengthToRadians(distance: number, units: Units = "kilometers"): number { - const factor = factors[units]; - if (!factor) { throw new Error(units + " units is invalid"); } - return distance / factor; -} - -/** - * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees - * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet - * - * @name lengthToDegrees - * @param {number} distance in real units - * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers inches, yards, metres, - * meters, kilometres, kilometers. - * @returns {number} degrees - */ -export function lengthToDegrees(distance: number, units?: Units): number { - return radiansToDegrees(lengthToRadians(distance, units)); -} - -/** - * Converts any bearing angle from the north line direction (positive clockwise) - * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line - * - * @name bearingToAzimuth - * @param {number} bearing angle, between -180 and +180 degrees - * @returns {number} angle between 0 and 360 degrees - */ -export function bearingToAzimuth(bearing: number): number { - let angle = bearing % 360; - if (angle < 0) { angle += 360; } - return angle; -} - -/** - * Converts an angle in radians to degrees - * - * @name radiansToDegrees - * @param {number} radians angle in radians - * @returns {number} degrees between 0 and 360 degrees - */ -export function radiansToDegrees(radians: number): number { - const degrees = radians % (2 * Math.PI); - return degrees * 180 / Math.PI; -} - -/** - * Converts an angle in degrees to radians - * - * @name degreesToRadians - * @param {number} degrees angle between 0 and 360 degrees - * @returns {number} angle in radians - */ -export function degreesToRadians(degrees: number): number { - const radians = degrees % 360; - return radians * Math.PI / 180; -} - -/** - * Converts a length to the requested unit. - * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet - * - * @param {number} length to be converted - * @param {Units} [originalUnit="kilometers"] of the length - * @param {Units} [finalUnit="kilometers"] returned unit - * @returns {number} the converted length - */ -export function convertLength( - length: number, - originalUnit: Units = "kilometers", - finalUnit: Units = "kilometers", -): number { - if (!(length >= 0)) { throw new Error("length must be a positive number"); } - return radiansToLength(lengthToRadians(length, originalUnit), finalUnit); -} - -/** - * Converts a area to the requested unit. - * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches - * @param {number} area to be converted - * @param {Units} [originalUnit="meters"] of the distance - * @param {Units} [finalUnit="kilometers"] returned unit - * @returns {number} the converted distance - */ -export function convertArea(area: number, originalUnit: Units = "meters", finalUnit: Units = "kilometers"): number { - if (!(area >= 0)) { throw new Error("area must be a positive number"); } - - const startFactor = areaFactors[originalUnit]; - if (!startFactor) { throw new Error("invalid original units"); } - - const finalFactor = areaFactors[finalUnit]; - if (!finalFactor) { throw new Error("invalid final units"); } - - return (area / startFactor) * finalFactor; -} - -/** - * isNumber - * - * @param {*} num Number to validate - * @returns {boolean} true/false - * @example - * turf.isNumber(123) - * //=true - * turf.isNumber('foo') - * //=false - */ -export function isNumber(num: any): boolean { - return !isNaN(num) && num !== null && !Array.isArray(num); -} - -/** - * isObject - * - * @param {*} input variable to validate - * @returns {boolean} true/false - * @example - * turf.isObject({elevation: 10}) - * //=true - * turf.isObject('foo') - * //=false - */ -export function isObject(input: any): boolean { - return (!!input) && (input.constructor === Object); -} - -/** - * Validate BBox - * - * @private - * @param {Array} bbox BBox to validate - * @returns {void} - * @throws Error if BBox is not valid - * @example - * validateBBox([-180, -40, 110, 50]) - * //=OK - * validateBBox([-180, -40]) - * //=Error - * validateBBox('Foo') - * //=Error - * validateBBox(5) - * //=Error - * validateBBox(null) - * //=Error - * validateBBox(undefined) - * //=Error - */ -export function validateBBox(bbox: any): void { - if (!bbox) { throw new Error("bbox is required"); } - if (!Array.isArray(bbox)) { throw new Error("bbox must be an Array"); } - if (bbox.length !== 4 && bbox.length !== 6) { throw new Error("bbox must be an Array of 4 or 6 numbers"); } - bbox.forEach((num) => { - if (!isNumber(num)) { throw new Error("bbox must only contain numbers"); } - }); -} - -/** - * Validate Id - * - * @private - * @param {string|number} id Id to validate - * @returns {void} - * @throws Error if Id is not valid - * @example - * validateId([-180, -40, 110, 50]) - * //=Error - * validateId([-180, -40]) - * //=Error - * validateId('Foo') - * //=OK - * validateId(5) - * //=OK - * validateId(null) - * //=Error - * validateId(undefined) - * //=Error - */ -export function validateId(id: any): void { - if (!id) { throw new Error("id is required"); } - if (["string", "number"].indexOf(typeof id) === -1) { throw new Error("id must be a number or a string"); } -} - -// Deprecated methods -export function radians2degrees(): void { - throw new Error("method has been renamed to `radiansToDegrees`"); -} - -export function degrees2radians(): void { - throw new Error("method has been renamed to `degreesToRadians`"); -} - -export function distanceToDegrees(): void { - throw new Error("method has been renamed to `lengthToDegrees`"); -} - -export function distanceToRadians(): void { - throw new Error("method has been renamed to `lengthToRadians`"); -} - -export function radiansToDistance(): void { - throw new Error("method has been renamed to `radiansToLength`"); -} - -export function bearingToAngle(): void { - throw new Error("method has been renamed to `bearingToAzimuth`"); -} - -export function convertDistance(): void { - throw new Error("method has been renamed to `convertLength`"); -} diff --git a/packages/turf-helpers/lib/geojson.d.ts b/packages/turf-helpers/lib/geojson.d.ts deleted file mode 100644 index 1a59101d84..0000000000 --- a/packages/turf-helpers/lib/geojson.d.ts +++ /dev/null @@ -1,240 +0,0 @@ -// Type definitions for geojson 7946.0 -// Project: https://geojson.org/ -// Definitions by: Jacob Bruun -// Arne Schubert -// Jeff Jacobson -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.3 - -// Note: as of the RFC 7946 version of GeoJSON, Coordinate Reference Systems -// are no longer supported. (See https://tools.ietf.org/html/rfc7946#appendix-B)} - -// export as namespace GeoJSON; - -/** - * GeometryTypes - * - * https://tools.ietf.org/html/rfc7946#section-1.4 - * The valid values for the "type" property of GeoJSON geometry objects. - */ -export type GeometryTypes = "Point" | - "LineString" | - "Polygon" | - "MultiPoint" | - "MultiLineString" | - "MultiPolygon" | - "GeometryCollection"; - -export type CollectionTypes = "FeatureCollection" | "GeometryCollection"; - -/** - * Types - * - * https://tools.ietf.org/html/rfc7946#section-1.4 - * The value values for the "type" property of GeoJSON Objects. - */ -export type Types = "Feature" | GeometryTypes | CollectionTypes; - -/** - * Bounding box - * - * https://tools.ietf.org/html/rfc7946#section-5 - * A GeoJSON object MAY have a member named "bbox" to include information on the coordinate range for its Geometries, Features, or FeatureCollections. - * The value of the bbox member MUST be an array of length 2*n where n is the number of dimensions represented in the contained geometries, - * with all axes of the most southwesterly point followed by all axes of the more northeasterly point. - * The axes order of a bbox follows the axes order of geometries. - */ -export type BBox2d = [number, number, number, number]; -export type BBox3d = [number, number, number, number, number, number]; -export type BBox = BBox2d | BBox3d; - -/** - * Id - * - * https://tools.ietf.org/html/rfc7946#section-3.2 - * If a Feature has a commonly used identifier, that identifier SHOULD be included as a member of - * the Feature object with the name "id", and the value of this member is either a JSON string or number. - */ -export type Id = string | number; - -/** - * Position - * - * https://tools.ietf.org/html/rfc7946#section-3.1.1 - * Array should contain between two and three elements. - * The previous GeoJSON specification allowed more elements (e.g., which could be used to represent M values), - * but the current specification only allows X, Y, and (optionally) Z to be defined. - */ -export type Position = number[]; // [number, number] | [number, number, number]; - -/** - * Properties - * - * https://tools.ietf.org/html/rfc7946#section-3.2 - * A Feature object has a member with the name "properties". - * The value of the properties member is an object (any JSON object or a JSON null value). - */ -export type Properties = { [name: string]: any; } | null; - -/** - * Geometries - */ -export type Geometries = Point | - LineString | - Polygon | - MultiPoint | - MultiLineString | - MultiPolygon; - -/** - * GeoJSON Object - * - * https://tools.ietf.org/html/rfc7946#section-3 - * The GeoJSON specification also allows [foreign members](https://tools.ietf.org/html/rfc7946#section-6.1) - * Developers should use "&" type in TypeScript or extend the interface to add these foreign members. - */ -export interface GeoJSONObject { - // Don't include foreign members directly into this type def. - // in order to preserve type safety. - // [key: string]: any; - /** - * Specifies the type of GeoJSON object. - */ - type: string; - /** - * Bounding box of the coordinate range of the object's Geometries, Features, or Feature Collections. - * https://tools.ietf.org/html/rfc7946#section-5 - */ - bbox?: BBox; -} - -/** - * Geometry Object - * - * https://tools.ietf.org/html/rfc7946#section-3 - */ -export interface GeometryObject extends GeoJSONObject { - type: GeometryTypes; -} - -/** - * Geometry - * - * https://tools.ietf.org/html/rfc7946#section-3 - */ -export interface Geometry extends GeoJSONObject { - coordinates: Position | - Position[] | - Position[][] | - Position[][][]; -} - -/** - * Point Geometry Object - * - * https://tools.ietf.org/html/rfc7946#section-3.1.2 - */ -export interface Point extends GeometryObject { - type: "Point"; - coordinates: Position; -} - -/** - * MultiPoint Geometry Object - * - * https://tools.ietf.org/html/rfc7946#section-3.1.3 - */ -export interface MultiPoint extends GeometryObject { - type: "MultiPoint"; - coordinates: Position[]; -} - -/** - * LineString Geometry Object - * - * https://tools.ietf.org/html/rfc7946#section-3.1.4 - */ -export interface LineString extends GeometryObject { - type: "LineString"; - coordinates: Position[]; -} - -/** - * MultiLineString Geometry Object - * - * https://tools.ietf.org/html/rfc7946#section-3.1.5 - */ -export interface MultiLineString extends GeometryObject { - type: "MultiLineString"; - coordinates: Position[][]; -} - -/** - * Polygon Geometry Object - * - * https://tools.ietf.org/html/rfc7946#section-3.1.6 - */ -export interface Polygon extends GeometryObject { - type: "Polygon"; - coordinates: Position[][]; -} - -/** - * MultiPolygon Geometry Object - * - * https://tools.ietf.org/html/rfc7946#section-3.1.7 - */ -export interface MultiPolygon extends GeometryObject { - type: "MultiPolygon"; - coordinates: Position[][][]; -} - -/** - * GeometryCollection - * - * https://tools.ietf.org/html/rfc7946#section-3.1.8 - * - * A GeoJSON object with type "GeometryCollection" is a Geometry object. - * A GeometryCollection has a member with the name "geometries". - * The value of "geometries" is an array. Each element of this array is a GeoJSON Geometry object. - * It is possible for this array to be empty. - */ -export interface GeometryCollection extends GeometryObject { - type: "GeometryCollection"; - geometries: Array; -} - -/** - * Feature - * - * https://tools.ietf.org/html/rfc7946#section-3.2 - * A Feature object represents a spatially bounded thing. - * Every Feature object is a GeoJSON object no matter where it occurs in a GeoJSON text. - */ -export interface Feature extends GeoJSONObject { - type: "Feature"; - geometry: G; - /** - * A value that uniquely identifies this feature in a - * https://tools.ietf.org/html/rfc7946#section-3.2. - */ - id?: Id; - /** - * Properties associated with this feature. - */ - properties: P; -} - -/** - * Feature Collection - * - * https://tools.ietf.org/html/rfc7946#section-3.3 - * A GeoJSON object with the type "FeatureCollection" is a FeatureCollection object. - * A FeatureCollection object has a member with the name "features". - * The value of "features" is a JSON array. Each element of the array is a Feature object as defined above. - * It is possible for this array to be empty. - */ -export interface FeatureCollection extends GeoJSONObject { - type: "FeatureCollection"; - features: Array>; -} diff --git a/packages/turf-helpers/package.json b/packages/turf-helpers/package.json deleted file mode 100644 index b86ca54cad..0000000000 --- a/packages/turf-helpers/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "@turf/helpers", - "version": "6.1.3", - "description": "turf helpers module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "lib" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "geo", - "point", - "turf", - "geojson" - ], - "author": "Turf Authors", - "contributors": [ - "Tom MacWright <@tmcw>", - "Stefano Borghi <@stebogit>", - "Denis Carriere <@DenisCarriere>", - "William Nordmann <@wnordmann>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "tape": "*", - "typescript": "*", - "tslint": "*", - "@types/tape": "*" - } -} diff --git a/packages/turf-helpers/test.js b/packages/turf-helpers/test.js deleted file mode 100644 index 728699e8a4..0000000000 --- a/packages/turf-helpers/test.js +++ /dev/null @@ -1,509 +0,0 @@ -const test = require('tape'); -const { - point, polygon, lineString, - feature, featureCollection, geometryCollection, - multiLineString, multiPoint, multiPolygon, - radiansToLength, lengthToRadians, lengthToDegrees, radiansToDegrees, degreesToRadians, - bearingToAzimuth, convertLength, convertArea, - round, isObject, isNumber, earthRadius -} = require('./'); -const turf = require('./'); - -test('point', t => { - const ptArray = point([5, 10], {name: 'test point'}); - - t.ok(ptArray); - t.equal(ptArray.geometry.coordinates[0], 5); - t.equal(ptArray.geometry.coordinates[1], 10); - t.equal(ptArray.properties.name, 'test point'); - - // t.throws(() => { - // point('hey', 'invalid'); - // }, 'numbers required'); - - const noProps = point([0, 0]); - t.deepEqual(noProps.properties, {}, 'no props becomes {}'); - - t.end(); -}); - -test('polygon', t => { - const poly = polygon([[[5, 10], [20, 40], [40, 0], [5, 10]]], {name: 'test polygon'}); - t.ok(poly); - t.equal(poly.geometry.coordinates[0][0][0], 5); - t.equal(poly.geometry.coordinates[0][1][0], 20); - t.equal(poly.geometry.coordinates[0][2][0], 40); - t.equal(poly.properties.name, 'test polygon'); - t.equal(poly.geometry.type, 'Polygon'); - t.throws(() => { - t.equal(polygon([[[20.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]]).message); - }, /First and last Position are not equivalent/, 'invalid ring - not wrapped'); - t.throws(() => { - t.equal(polygon([[[20.0, 0.0], [101.0, 0.0]]]).message); - }, /Each LinearRing of a Polygon must have 4 or more Positions/, 'invalid ring - too few positions'); - const noProperties = polygon([[[5, 10], [20, 40], [40, 0], [5, 10]]]); - t.deepEqual(noProperties.properties, {}); - t.end(); -}); - -test('lineString', t => { - const line = lineString([[5, 10], [20, 40]], {name: 'test line'}); - t.ok(line, 'creates a linestring'); - t.equal(line.geometry.coordinates[0][0], 5); - t.equal(line.geometry.coordinates[1][0], 20); - t.equal(line.properties.name, 'test line'); - t.deepEqual(lineString([[5, 10], [20, 40]]).properties, {}, 'no properties case'); - - t.throws(() => lineString(), 'error on no coordinates'); - t.throws(() => lineString([[5, 10]]), 'coordinates must be an array of two or more positions'); - t.throws(() => lineString([['xyz', 10]]), 'coordinates must contain numbers'); - t.throws(() => lineString([[5, 'xyz']]), 'coordinates must contain numbers'); - t.end(); -}); - -test('featureCollection', t => { - const p1 = point([0, 0], {name: 'first point'}); - const p2 = point([0, 10]); - const p3 = point([10, 10]); - const p4 = point([10, 0]); - const fc = featureCollection([p1, p2, p3, p4]); - t.ok(fc); - t.equal(fc.features.length, 4); - t.equal(fc.features[0].properties.name, 'first point'); - t.equal(fc.type, 'FeatureCollection'); - t.equal(fc.features[1].geometry.type, 'Point'); - t.equal(fc.features[1].geometry.coordinates[0], 0); - t.equal(fc.features[1].geometry.coordinates[1], 10); - // t.throws(() => featureCollection(fc), /features must be an Array/); - // t.throws(() => featureCollection(p1), /features must be an Array/); - t.end(); -}); - -test('multilinestring', t => { - t.deepEqual(multiLineString([[[0, 0], [10, 10]], [[5, 0], [15, 8]]]), { - type: 'Feature', - properties: {}, - geometry: { - type: 'MultiLineString', - coordinates: [[[0, 0], [10, 10]], [[5, 0], [15, 8]]] - } - }, 'takes coordinates'); - - t.deepEqual(multiLineString([[[0, 0], [10, 10]], [[5, 0], [15, 8]]], {test: 23}), { - type: 'Feature', - properties: { - test: 23 - }, - geometry: { - type: 'MultiLineString', - coordinates: [[[0, 0], [10, 10]], [[5, 0], [15, 8]]] - } - }, 'takes properties'); - - - // t.throws(() => { - // multiLineString(); - // }, 'throws error with no coordinates'); - - t.end(); -}); - - -test('multiPoint', t => { - t.deepEqual(multiPoint([[0, 0], [10, 10]]), { - type: 'Feature', - properties: {}, - geometry: { - type: 'MultiPoint', - coordinates: [ - [0, 0], - [10, 10] - ] - } - }, 'takes coordinates'); - - t.deepEqual(multiPoint([[0, 0], [10, 10]], {test: 23}), { - type: 'Feature', - properties: { - test: 23 - }, - geometry: { - type: 'MultiPoint', - coordinates: [ - [0, 0], - [10, 10] - ] - } - }, 'takes properties'); - - - // t.throws(() => { - // multiPoint(); - // }, 'throws error with no coordinates'); - - t.end(); -}); - -test('feature', t => { - const pt = { - type: 'Point', - coordinates: [ - 67.5, - 32.84267363195431 - ] - }; - const line = { - type: 'LineString', - coordinates: [ - [ - 82.96875, - 58.99531118795094 - ], - [ - 72.7734375, - 55.57834467218206 - ], - [ - 84.0234375, - 55.57834467218206 - ] - ] - }; - const polygon = { - type: 'Polygon', - coordinates: [ - [ - [ - 85.78125, - -3.513421045640032 - ], - [ - 85.78125, - 13.581920900545844 - ], - [ - 92.46093749999999, - 13.581920900545844 - ], - [ - 92.46093749999999, - -3.513421045640032 - ], - [ - 85.78125, - -3.513421045640032 - ] - ] - ] - }; - t.end(); -}); - -test('multipolygon', t =>{ - t.deepEqual(multiPolygon([[[[94, 57], [78, 49], [94, 43], [94, 57]]], [[[93, 19], [63, 7], [79, 0], [93, 19]]]]), { - type: 'Feature', - properties: {}, - geometry: { - type: 'MultiPolygon', - coordinates: [[[[94, 57], [78, 49], [94, 43], [94, 57]]], [[[93, 19], [63, 7], [79, 0], [93, 19]]]] - } - }, 'takes coordinates'); - - t.deepEqual(multiPolygon([[[[94, 57], [78, 49], [94, 43], [94, 57]]], [[[93, 19], [63, 7], [79, 0], [93, 19]]]], {test: 23}), { - type: 'Feature', - properties: { - test: 23 - }, - geometry: { - type: 'MultiPolygon', - coordinates: [[[[94, 57], [78, 49], [94, 43], [94, 57]]], [[[93, 19], [63, 7], [79, 0], [93, 19]]]] - } - }, 'takes properties'); - - - // t.throws(() => { - // multiPolygon(); - // }, 'throws error with no coordinates'); - - t.end(); -}); - -test('geometrycollection', t => { - const pt = { - type: 'Point', - coordinates: [100, 0] - }; - const line = { - type: 'LineString', - coordinates: [[101, 0], [102, 1]] - }; - const gc = geometryCollection([pt, line]); - - t.deepEqual(gc, { - type: 'Feature', - properties: {}, - geometry: { - type: 'GeometryCollection', - geometries: [ - { - type: 'Point', - coordinates: [100, 0] - }, - { - type: 'LineString', - coordinates: [[101, 0], [102, 1]] - } - ] - } - }, 'creates a GeometryCollection'); - - const gcWithProps = geometryCollection([pt, line], {a: 23}); - t.deepEqual(gcWithProps, { - type: 'Feature', - properties: {a: 23}, - geometry: { - type: 'GeometryCollection', - geometries: [ - { - type: 'Point', - coordinates: [100, 0] - }, - { - type: 'LineString', - coordinates: [[101, 0], [102, 1]] - } - ] - } - }, 'creates a GeometryCollection with properties'); - - t.end(); -}); - -test('radiansToLength', t => { - t.equal(radiansToLength(1, 'radians'), 1); - t.equal(radiansToLength(1, 'kilometers'), earthRadius / 1000); - t.equal(radiansToLength(1, 'miles'), earthRadius / 1609.344); - // t.throws(() => radiansToLength(1, 'foo'), 'invalid units'); - t.end(); -}); - -test('lengthToRadians', t => { - t.equal(lengthToRadians(1, 'radians'), 1); - t.equal(lengthToRadians(earthRadius / 1000, 'kilometers'), 1); - t.equal(lengthToRadians(earthRadius / 1609.344, 'miles'), 1); - // t.throws(() => lengthToRadians(1, 'foo'), 'invalid units'); - t.end(); -}); - -test('lengthToDegrees', t => { - t.equal(lengthToDegrees(1, 'radians'), 57.29577951308232); - t.equal(lengthToDegrees(100, 'kilometers'), 0.899320363724538); - t.equal(lengthToDegrees(10, 'miles'), 0.1447315831437903); - // t.throws(() => lengthToRadians(1, 'foo'), 'invalid units'); - t.end(); -}); - -test('radiansToDegrees', t => { - t.equal(round(radiansToDegrees(Math.PI / 3), 6), 60, 'radiance conversion PI/3'); - t.equal(radiansToDegrees(3.5 * Math.PI), 270, 'radiance conversion 3.5PI'); - t.equal(radiansToDegrees(-Math.PI), -180, 'radiance conversion -PI'); - t.end(); -}); - -test('radiansToDegrees', t => { - t.equal(degreesToRadians(60), Math.PI / 3, 'degrees conversion 60'); - t.equal(degreesToRadians(270), 1.5 * Math.PI, 'degrees conversion 270'); - t.equal(degreesToRadians(-180), -Math.PI, 'degrees conversion -180'); - t.end(); -}); - -test('bearingToAzimuth', t => { - t.equal(bearingToAzimuth(40), 40); - t.equal(bearingToAzimuth(-105), 255); - t.equal(bearingToAzimuth(410), 50); - t.equal(bearingToAzimuth(-200), 160); - t.equal(bearingToAzimuth(-395), 325); - t.end(); -}); - -test('round', t => { - t.equal(round(125.123), 125); - t.equal(round(123.123, 1), 123.1); - t.equal(round(123.5), 124); - t.throws(() => round(34.5, 'precision'), 'invalid precision'); - t.throws(() => round(34.5, -5), 'invalid precision'); - t.end(); -}); - -test('convertLength', t => { - t.equal(convertLength(1000, 'meters'), 1); - t.equal(convertLength(1, 'kilometers', 'miles'), 0.621371192237334); - t.equal(convertLength(1, 'miles', 'kilometers'), 1.609344); - t.equal(convertLength(1, 'nauticalmiles'), 1.852); - t.equal(convertLength(1, 'meters', 'centimeters'), 100.00000000000001); - // t.throws(() => convertLength(1, 'foo'), 'invalid units'); - t.end(); -}); - -test('convertArea', t => { - t.equal(convertArea(1000), 0.001); - t.equal(convertArea(1, 'kilometres', 'miles'), 0.386); - t.equal(convertArea(1, 'miles', 'kilometers'), 2.5906735751295336); - t.equal(convertArea(1, 'meters', 'centimetres'), 10000); - t.equal(convertArea(100, 'metres', 'acres'), 0.0247105); - t.equal(convertArea(100, undefined, 'yards'), 119.59900459999999); - t.equal(convertArea(100, 'metres', 'feet'), 1076.3910417); - t.equal(convertArea(100000, 'feet', undefined), 0.009290303999749462); - // t.throws(() => convertLength(1, 'foo'), 'invalid original units'); - // t.throws(() => convertLength(1, 'meters', 'foo'), 'invalid final units'); - - t.end(); -}); - -// https://github.com/Turfjs/turf/issues/853 -// https://github.com/Turfjs/turf/pull/866#discussion_r129873661 -test('null geometries', t => { - t.equal(feature(null).geometry, null, 'feature'); - t.equal(featureCollection([feature(null)]).features[0].geometry, null, 'featureCollection'); - t.equal(geometryCollection([feature(null).geometry]).geometry.geometries[0], null, 'geometryCollection'); - t.equal(geometryCollection([]).geometry.geometries.length, 0, 'geometryCollection -- empty'); - t.end(); -}); - -test('turf-helpers -- Handle Id & BBox properties', t => { - const id = 12345; - const bbox = [10, 30, 10, 30]; - const pt = point([10, 30], {}, {bbox, id}); - const ptId0 = point([10, 30], {}, {bbox, id: 0}); - const fc = featureCollection([pt], {bbox, id}); - t.equal(pt.id, id, 'feature id'); - t.equal(ptId0.id, 0, 'feature id = 0'); // issue #1180 - t.equal(pt.bbox, bbox, 'feature bbox'); - t.equal(fc.id, id, 'featureCollection id'); - t.equal(fc.bbox, bbox, 'featureCollection bbox'); - // t.throws(() => point([10, 30], {}, {bbox: [0], id}), 'throws invalid bbox'); - // t.throws(() => point([10, 30], {}, {bbox, id: {invalid: 'id'}}), 'throws invalid id'); - // t.throws(() => featureCollection([pt], {bbox: [0], id}), 'throws invalid bbox'); - // t.throws(() => featureCollection([pt], {bbox: [0], id: {invalid: 'id'}}), 'throws invalid id'); - t.end(); -}); - -test('turf-helpers -- isNumber', t => { - // t.throws(() => point(['foo', 'bar']), /coordinates must contain numbers/, 'coordinates must contain numbers'); - // t.throws(() => lineString([['foo', 'bar'], ['hello', 'world']]), /coordinates must contain numbers/, 'coordinates must contain numbers'); - // t.throws(() => polygon([[['foo', 'bar'], ['hello', 'world'], ['world', 'hello'], ['foo', 'bar']]]), /coordinates must contain numbers/, 'coordinates must contain numbers'); - - // true - t.true(isNumber(123)); - t.true(isNumber(1.23)); - t.true(isNumber(-1.23)); - t.true(isNumber(-123)); - t.true(isNumber('123')); - t.true(isNumber(+'123')); - t.true(isNumber('1e10000')); - t.true(isNumber(1e10000)); - t.true(isNumber(Infinity)); - t.true(isNumber(-Infinity)); - - // false - t.false(isNumber(+'ciao')); - t.false(isNumber('foo')); - t.false(isNumber('10px')); - t.false(isNumber(NaN)); - t.false(isNumber(undefined)); - t.false(isNumber(null)); - t.false(isNumber({a: 1})); - t.false(isNumber({})); - t.false(isNumber([1, 2, 3])); - t.false(isNumber([])); - t.false(isNumber(isNumber)); - t.end(); -}); - -test('turf-helpers -- isObject', t => { - // true - t.true(isObject({a: 1})); - t.true(isObject({})); - t.true(point([0, 1])); - - // false - t.false(isObject(123)); - t.false(isObject(Infinity)); - t.false(isObject(-123)); - t.false(isObject('foo')); - t.false(isObject(NaN)); - t.false(isObject(undefined)); - t.false(isObject(null)); - t.false(isObject([1, 2, 3])); - t.false(isObject([])); - t.false(isObject(isNumber)); - t.end(); -}); - -test('turf-helpers -- points', t => { - const points = turf.points([ - [-75, 39], - [-80, 45], - [-78, 50] - ], {foo: 'bar'}, {id: 'hello'}); - - t.equal(points.features.length, 3); - t.equal(points.id, 'hello'); - t.equal(points.features[0].properties.foo, 'bar'); - t.end(); -}); - -test('turf-helpers -- lineStrings', t => { - var linestrings = turf.lineStrings([ - [[-24, 63], [-23, 60], [-25, 65], [-20, 69]], - [[-14, 43], [-13, 40], [-15, 45], [-10, 49]] - ], {foo: 'bar'}, {id: 'hello'}); - - t.equal(linestrings.features.length, 2); - t.equal(linestrings.id, 'hello'); - t.equal(linestrings.features[0].properties.foo, 'bar'); - t.end(); -}); - -test('turf-helpers -- polygons', t => { - var polygons = turf.polygons([ - [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], - [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]], - ], {foo: 'bar'}, {id: 'hello'}); - - t.equal(polygons.features.length, 2); - t.equal(polygons.id, 'hello'); - t.equal(polygons.features[0].properties.foo, 'bar'); - t.end(); -}); - -test('turf-helpers -- Issue #1284 - Prevent mutating Properties', t => { - // https://github.com/Turfjs/turf/issues/1284 - const coord = [110, 45]; - const properties = {foo: 'bar'} - - // Create initial Feature - const pt = feature(coord, properties); - t.deepEqual(pt.properties, {foo: 'bar'}) - t.deepEqual(properties, {foo: 'bar'}) - - // Mutate Original Properties - properties.foo = 'barbar'; - - // Initial Point's Properties ~should~ be mutated - // https://github.com/Turfjs/turf/commit/39c6c9ec29986cc540960b3e2680e9e0a65168a1#r28018260 - t.deepEqual(pt.properties, {foo: 'barbar'}) - t.deepEqual(properties, {foo: 'barbar'}) - - // Include this test case if initial point should ~not~ have it's properties mutated - t.skip(pt.properties, {foo: 'bar'}) - - // Create Mutated Point - const ptMutate = feature(coord, properties); - t.deepEqual(ptMutate.properties, {foo: 'barbar'}) - t.deepEqual(properties, {foo: 'barbar'}) - - // New Features should contain empty properties {} - t.deepEqual(feature(coord).properties, {}); - t.end(); -}); diff --git a/packages/turf-helpers/tsconfig.json b/packages/turf-helpers/tsconfig.json deleted file mode 100644 index b3d69bef60..0000000000 --- a/packages/turf-helpers/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - }, - "files": [ - "index.ts" - ] -} \ No newline at end of file diff --git a/packages/turf-helpers/tslint.json b/packages/turf-helpers/tslint.json deleted file mode 100644 index 10574fa516..0000000000 --- a/packages/turf-helpers/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {"object-literal-sort-keys": false}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-helpers/types.ts b/packages/turf-helpers/types.ts deleted file mode 100644 index 8249de993f..0000000000 --- a/packages/turf-helpers/types.ts +++ /dev/null @@ -1,164 +0,0 @@ -import * as helpers from "./"; -import { - BBox, - bearingToAzimuth, - convertArea, - convertLength, - degreesToRadians, - earthRadius, - feature, - featureCollection, - Geometries, - geometry, - geometryCollection, - GeometryCollection, - isNumber, - isObject, - lengthToDegrees, - lengthToRadians, - lineString, - LineString, - multiLineString, - MultiLineString, - multiPoint, - MultiPoint, - multiPolygon, - // Typescript types - MultiPolygon, - point, - Point, - Polygon, - polygon, - radiansToDegrees, - radiansToLength, - round, -} from "./"; - -// Fixtures -const bbox: BBox = [-180, -90, 180, 90]; -const properties = {foo: "bar"}; -const pt = point([0, 1]); -const line = lineString([[0, 1], [2, 3]]); -const poly = polygon([[[0, 1], [0, 0], [2, 3], [0, 1]]]); -const feat = feature({coordinates: [1, 0], type: "point"}); -const multiPt = multiPoint([[0, 1], [2, 3], [0, 1]]); -const multiLine = multiLineString([[[0, 1], [2, 3], [0, 1]]]); -const multiPoly = multiPolygon([[[[0, 1], [0, 0], [2, 3], [0, 1]]]]); - -// radiansToLength & lengthToRadians -radiansToLength(5); -lengthToRadians(10); -lengthToDegrees(45); - -// default import & import * as -point([0, 1]); -lineString([[0, 1], [2, 3]]); -polygon([[[0, 1], [0, 0], [2, 3], [0, 1]]]); -feature({coordinates: [1, 0], type: "point"}); -multiPoint([[0, 1], [2, 3], [0, 1]]); -multiLineString([[[0, 1], [2, 3], [0, 1]]]); -multiPolygon([[[[0, 1], [0, 0], [2, 3], [0, 1]]]]); - -// Mixed collection is defiend as FeatureCollection -const mixed = featureCollection([pt, poly]); -mixed.features.push(pt); -mixed.features.push(line); -mixed.features.push(poly); - -// Blank collection is defined as FeatureCollection -const blank = featureCollection([]); -blank.features.push(pt); -blank.features.push(line); -blank.features.push(poly); - -// Collection with only Points -const points = featureCollection([]); -points.features.push(pt); -// points.features.push(line) -// Argument of type 'Feature' is not assignable to parameter of type 'Feature'. - -// Collection with only LineStrings -const lines = featureCollection([line]); -lines.features.push(line); -// lines.features.push(pt) -// Argument of type 'Feature' is not assignable to parameter of type 'Feature'. - -// Collection with only Polygons -const polygons = featureCollection([]); -polygons.features.push(poly); - -// bbox & id -point(pt.geometry.coordinates, properties, {bbox, id: 1}); -lineString(line.geometry.coordinates, properties, {bbox, id: 1}); -polygon(poly.geometry.coordinates, properties, {bbox, id: 1}); -multiPoint(multiPt.geometry.coordinates, properties, {bbox, id: 1}); -multiLineString(multiLine.geometry.coordinates, properties, {bbox, id: 1}); -multiPolygon(multiPoly.geometry.coordinates, properties, {bbox, id: 1}); -geometryCollection([pt.geometry], properties, {bbox, id: 1}); - -// properties -point(pt.geometry.coordinates, {foo: "bar"}); -point(pt.geometry.coordinates, {1: 2}); -point(pt.geometry.coordinates, {1: {foo: "bar"}}); - -// isNumber -- true -isNumber(123); -isNumber(1.23); -isNumber(-1.23); -isNumber(-123); -isNumber("123"); -isNumber(+"123"); -isNumber("1e10000"); -isNumber(1e10000); -isNumber(Infinity); -isNumber(-Infinity); - -// isNumber -- false -isNumber(+"ciao"); -isNumber("foo"); -isNumber("10px"); -isNumber(NaN); -isNumber(undefined); -isNumber(null); -isNumber({a: 1}); -isNumber({}); -isNumber([1, 2, 3]); -isNumber([]); -isNumber(isNumber); - -// isObject -- true -isObject({a: 1}); -isObject({}); -isObject(point([0, 1])); - -// isObject -- false -isObject(123); -isObject(Infinity); -isObject(-123); -isObject("foo"); -isObject(NaN); -isObject(undefined); -isObject(null); -isObject([1, 2, 3]); -isObject([]); -isObject(isNumber); - -// Geometry -const ptGeom = geometry("Point", pt.geometry.coordinates); -const lineGeom = geometry("LineString", line.geometry.coordinates); -const polyGeom = geometry("Polygon", poly.geometry.coordinates); -const multiPtGeom = geometry("MultiPoint", multiPt.geometry.coordinates); -const multiLineGeom = geometry("MultiLineString", multiLine.geometry.coordinates); -const multiPolyGeom = geometry("MultiPolygon", multiPoly.geometry.coordinates); - -// Custom Properties -const customPt = point([10, 50], {foo: "bar"}); - -// Handle GeometryCollection & Feature.GeometryCollection -const geomCollection = geometryCollection([pt.geometry, line.geometry]); -const p1 = geomCollection.geometry.geometries[0]; -const l1 = geomCollection.geometry.geometries[0]; - -const mixedGeomCollection = featureCollection([pt, geomCollection]); -const fc = featureCollection([pt, line]); -const featureGeomCollection = feature(geomCollection.geometry); diff --git a/packages/turf-hex-grid/.gitignore b/packages/turf-hex-grid/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-hex-grid/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-hex-grid/LICENSE b/packages/turf-hex-grid/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-hex-grid/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-hex-grid/README.md b/packages/turf-hex-grid/README.md deleted file mode 100644 index 7de54bb58f..0000000000 --- a/packages/turf-hex-grid/README.md +++ /dev/null @@ -1,82 +0,0 @@ -# @turf/hex-grid - - - -## hexGrid - -Takes a bounding box and the diameter of the cell and returns a [FeatureCollection][1] of flat-topped -hexagons or triangles ([Polygon][2] features) aligned in an "odd-q" vertical grid as -described in [Hexagonal Grids][3]. - -**Parameters** - -- `bbox` **[BBox][4]** extent in [minX, minY, maxX, maxY] order -- `cellSide` **[number][5]** length of the side of the the hexagons or triangles, in units. It will also coincide with the - radius of the circumcircle of the hexagons. -- `options` **[Object][6]** Optional parameters (optional, default `{}`) - - `options.units` **[string][7]** used in calculating cell size, can be degrees, radians, miles, or kilometers (optional, default `'kilometers'`) - - `options.properties` **[Object][6]** passed to each hexagon or triangle of the grid (optional, default `{}`) - - `options.mask` **[Feature][8]<[Polygon][9]>?** if passed a Polygon or MultiPolygon, the grid Points will be created only inside it - - `options.triangles` **[boolean][10]** whether to return as triangles instead of hexagons (optional, default `false`) - -**Examples** - -```javascript -var bbox = [-96,31,-84,40]; -var cellSide = 50; -var options = {units: 'miles'}; - -var hexgrid = turf.hexGrid(bbox, cellSide, options); - -//addToMap -var addToMap = [hexgrid]; -``` - -Returns **[FeatureCollection][11]<[Polygon][9]>** a hexagonal grid - -[1]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[3]: http://www.redblobgames.com/grids/hexagons/ - -[4]: https://tools.ietf.org/html/rfc7946#section-5 - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[8]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[9]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - -[11]: https://tools.ietf.org/html/rfc7946#section-3.3 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/hex-grid -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-hex-grid/index.ts b/packages/turf-hex-grid/index.ts deleted file mode 100644 index 563b19a501..0000000000 --- a/packages/turf-hex-grid/index.ts +++ /dev/null @@ -1,193 +0,0 @@ -import distance from '@turf/distance'; -import intersect from '@turf/intersect'; -import { getType } from '@turf/invariant'; -import { - polygon, featureCollection, isObject, isNumber, - Feature, FeatureCollection, Units, Properties, Polygon, MultiPolygon, BBox -} from '@turf/helpers'; - -/** - * Takes a bounding box and the diameter of the cell and returns a {@link FeatureCollection} of flat-topped - * hexagons or triangles ({@link Polygon} features) aligned in an "odd-q" vertical grid as - * described in [Hexagonal Grids](http://www.redblobgames.com/grids/hexagons/). - * - * @name hexGrid - * @param {BBox} bbox extent in [minX, minY, maxX, maxY] order - * @param {number} cellSide length of the side of the the hexagons or triangles, in units. It will also coincide with the - * radius of the circumcircle of the hexagons. - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] used in calculating cell size, can be degrees, radians, miles, or kilometers - * @param {Object} [options.properties={}] passed to each hexagon or triangle of the grid - * @param {Feature} [options.mask] if passed a Polygon or MultiPolygon, the grid Points will be created only inside it - * @param {boolean} [options.triangles=false] whether to return as triangles instead of hexagons - * @returns {FeatureCollection} a hexagonal grid - * @example - * var bbox = [-96,31,-84,40]; - * var cellSide = 50; - * var options = {units: 'miles'}; - * - * var hexgrid = turf.hexGrid(bbox, cellSide, options); - * - * //addToMap - * var addToMap = [hexgrid]; - */ -function hexGrid

(bbox: BBox, cellSide: number, options: { - units?: Units, - triangles?: boolean, - properties?: P, - mask?: Feature | Polygon; -} = {}): FeatureCollection { - // Issue => https://github.com/Turfjs/turf/issues/1284 - const clonedProperties = JSON.stringify(options.properties || {}) - - const [west, south, east, north] = bbox; - const centerY = (south + north) / 2; - const centerX = (west + east) / 2; - - // https://github.com/Turfjs/turf/issues/758 - const xFraction = cellSide * 2 / (distance([west, centerY], [east, centerY], options)); - const cellWidth = xFraction * (east - west); - const yFraction = cellSide * 2 / (distance([centerX, south], [centerX, north], options)); - const cellHeight = yFraction * (north - south); - const radius = cellWidth / 2; - - const hex_width = radius * 2; - const hex_height = Math.sqrt(3) / 2 * cellHeight; - - const box_width = east - west; - const box_height = north - south; - - const x_interval = 3 / 4 * hex_width; - const y_interval = hex_height; - - // adjust box_width so all hexagons will be inside the bbox - const x_span = (box_width - hex_width) / (hex_width - radius / 2); - const x_count = Math.floor(x_span); - - const x_adjust = ((x_count * x_interval - radius / 2) - box_width) / 2 - radius / 2 + x_interval / 2; - - // adjust box_height so all hexagons will be inside the bbox - const y_count = Math.floor((box_height - hex_height) / hex_height); - - let y_adjust = (box_height - y_count * hex_height) / 2; - - const hasOffsetY = y_count * hex_height - box_height > hex_height / 2; - if (hasOffsetY) { - y_adjust -= hex_height / 4; - } - - // Precompute cosines and sines of angles used in hexagon creation for performance gain - const cosines = []; - const sines = []; - for (let i = 0; i < 6; i++) { - const angle = 2 * Math.PI / 6 * i; - cosines.push(Math.cos(angle)); - sines.push(Math.sin(angle)); - } - - const results = []; - for (let x = 0; x <= x_count; x++) { - for (let y = 0; y <= y_count; y++) { - - const isOdd = x % 2 === 1; - if (y === 0 && isOdd) continue; - if (y === 0 && hasOffsetY) continue; - - const center_x = x * x_interval + west - x_adjust; - let center_y = y * y_interval + south + y_adjust; - - if (isOdd) { - center_y -= hex_height / 2; - } - - if (options.triangles === true) { - hexTriangles( - [center_x, center_y], - cellWidth / 2, - cellHeight / 2, - JSON.parse(clonedProperties), - cosines, - sines).forEach(function (triangle) { - if (options.mask) { - if (intersect(options.mask, triangle)) results.push(triangle); - } else { - results.push(triangle); - } - }); - } else { - const hex = hexagon( - [center_x, center_y], - cellWidth / 2, - cellHeight / 2, - JSON.parse(clonedProperties), - cosines, - sines - ); - if (options.mask) { - if (intersect(options.mask, hex)) results.push(hex); - } else { - results.push(hex); - } - } - } - } - - return featureCollection(results); -} - -/** - * Creates hexagon - * - * @private - * @param {Array} center of the hexagon - * @param {number} rx half hexagon width - * @param {number} ry half hexagon height - * @param {Object} properties passed to each hexagon - * @param {Array} cosines precomputed - * @param {Array} sines precomputed - * @returns {Feature} hexagon - */ -function hexagon(center, rx, ry, properties, cosines, sines) { - const vertices = []; - for (let i = 0; i < 6; i++) { - const x = center[0] + rx * cosines[i]; - const y = center[1] + ry * sines[i]; - vertices.push([x, y]); - } - //first and last vertex must be the same - vertices.push(vertices[0].slice()); - return polygon([vertices], properties); -} - -/** - * Creates triangles composing an hexagon - * - * @private - * @param {Array} center of the hexagon - * @param {number} rx half triangle width - * @param {number} ry half triangle height - * @param {Object} properties passed to each triangle - * @param {Array} cosines precomputed - * @param {Array} sines precomputed - * @returns {Array>} triangles - */ -function hexTriangles(center, rx, ry, properties, cosines, sines) { - const triangles = []; - for (let i = 0; i < 6; i++) { - const vertices = []; - vertices.push(center); - vertices.push([ - center[0] + rx * cosines[i], - center[1] + ry * sines[i] - ]); - vertices.push([ - center[0] + rx * cosines[(i + 1) % 6], - center[1] + ry * sines[(i + 1) % 6] - ]); - vertices.push(center); - triangles.push(polygon([vertices], properties)); - } - return triangles; -} - -export default hexGrid; diff --git a/packages/turf-hex-grid/package.json b/packages/turf-hex-grid/package.json deleted file mode 100644 index fbf9cc6c92..0000000000 --- a/packages/turf-hex-grid/package.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "@turf/hex-grid", - "version": "6.0.2", - "description": "turf hex-grid module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "grid", - "hexgrid", - "hexbin", - "points", - "geojson" - ], - "author": "Turf Authors", - "contributors": [ - "James Seppi <@jseppi>", - "Morgan Herlocker <@morganherlocker>", - "Tom MacWright <@tmcw>", - "Jan Vaillant <@jvail>", - "Lyzi Diamond <@lyzidiamond>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/bbox-polygon": "*", - "@turf/truncate": "*", - "benchmark": "*", - "load-json-file": "*", - "tape": "*", - "write-json-file": "*", - "typescript": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/distance": "6.x", - "@turf/helpers": "6.x", - "@turf/intersect": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-hex-grid/test.js b/packages/turf-hex-grid/test.js deleted file mode 100644 index 02da71b6f1..0000000000 --- a/packages/turf-hex-grid/test.js +++ /dev/null @@ -1,103 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const truncate = require('@turf/truncate').default; -const bboxPoly = require('@turf/bbox-polygon').default; -const hexGrid = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - json: load.sync(directories.in + filename) - }; -}); - -test('hex-grid', t => { - fixtures.forEach(({name, json, filename}) => { - const {bbox, cellSide} = json; - const options = json; - - const result = truncate(hexGrid(bbox, cellSide, options)); - const poly = bboxPoly(bbox); - t.assert(poly.bbox); - poly.properties = { - stroke: '#F00', - 'stroke-width': 6, - 'fill-opacity': 0 - }; - result.features.push(poly); - if (options.mask) { - options.mask.properties = { - "stroke": "#00F", - "stroke-width": 6, - "fill-opacity": 0 - }; - result.features.push(options.mask); - } - - if (process.env.REGEN) write.sync(directories.out + name + '.geojson', result); - t.deepEqual(result, load.sync(directories.out + name + '.geojson'), name); - }); - t.end(); -}); - - -test('grid tiles count', t => { - const bbox1 = require(directories.in + 'bbox1.json').bbox; - t.equal(hexGrid(bbox1, 50, {units: 'miles'}).features.length, 52); - t.equal(hexGrid(bbox1, 50, {units: 'miles', triangles: true}).features.length, 312); - - t.end(); -}); - -test('Property mutation', t => { - const bbox1 = require(directories.in + 'bbox1.json').bbox; - const grid = hexGrid(bbox1, 50, {units: 'miles', properties: {foo: 'bar'}}) - t.equal(grid.features[0].properties.foo, 'bar'); - t.equal(grid.features[1].properties.foo, 'bar'); - - grid.features[0].properties.foo = 'baz' - t.equal(grid.features[0].properties.foo, 'baz'); - t.equal(grid.features[1].properties.foo, 'bar'); - t.end(); -}); - - -test('longitude (13141439571036224) - issue #758', t => { - const bbox = [-179, -90, 179, 90]; - const grid = hexGrid(bbox, 250, {units: 'kilometers'}); - - const coords = []; - grid.features.forEach(feature => feature.geometry.coordinates[0].forEach(coord => coords.push(coord))); - - for (const coord of coords) { - const lng = coord[0]; - const lat = coord[1]; - if (lng > 1000 || lng < -1000) { - t.fail(`longitude is +- 1000 [${lng},${lat}]`); - break; - } - } - t.end(); -}); - -test('hex-grid -- throw', t => { - const bbox = [0, 0, 1, 1]; - // Types handled by Typescript - // t.throws(() => hexGrid(null, 0), /bbox is required/, 'missing bbox'); - // t.throws(() => hexGrid('string', 0), /bbox must be array/, 'invalid bbox'); - // t.throws(() => hexGrid([0, 2], 1), /bbox must contain 4 numbers/, 'invalid bbox'); - // t.throws(() => hexGrid(bbox, null), /cellSide is required/, 'missing cellSide'); - // t.throws(() => hexGrid(bbox, 'string'), /cellSide is invalid/, 'invalid cellSide'); - // t.throws(() => hexGrid(bbox, 1, 'string'), /options is invalid/, 'invalid options'); - t.end(); -}); - diff --git a/packages/turf-hex-grid/types.ts b/packages/turf-hex-grid/types.ts deleted file mode 100644 index 6e5d7521d4..0000000000 --- a/packages/turf-hex-grid/types.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {BBox} from '@turf/helpers' -import hexGrid from './' - -const bbox: BBox = [ - -96.6357421875, - 31.12819929911196, - -84.9462890625, - 40.58058466412764 -] - -hexGrid(bbox, 50) -hexGrid(bbox, 50, {units: 'miles'}) -hexGrid(bbox, 50, {units: 'miles', triangles: true}) - -// Access Custom Properties -const foo = hexGrid(bbox, 50, {units: 'miles', triangles: true, properties: {foo: 'bar'}}) -foo.features[0].properties.foo -// foo.features[0].properties.bar // => [ts] Property 'bar' does not exist on type '{ foo: string; }'. - diff --git a/packages/turf-interpolate/LICENSE b/packages/turf-interpolate/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-interpolate/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-interpolate/README.md b/packages/turf-interpolate/README.md deleted file mode 100644 index a1035f65be..0000000000 --- a/packages/turf-interpolate/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# @turf/interpolate - - - -## interpolate - -Takes a set of points and estimates their 'property' values on a grid using the [Inverse Distance Weighting (IDW) method][1]. - -**Parameters** - -- `points` **[FeatureCollection][2]<[Point][3]>** with known value -- `cellSize` **[number][4]** the distance across each grid point -- `options` **[Object][5]** Optional parameters (optional, default `{}`) - - `options.gridType` **[string][6]** defines the output format based on a Grid Type (options: 'square' | 'point' | 'hex' | 'triangle') (optional, default `'square'`) - - `options.property` **[string][6]** the property name in `points` from which z-values will be pulled, zValue fallbacks to 3rd coordinate if no property exists. (optional, default `'elevation'`) - - `options.units` **[string][6]** used in calculating cellSize, can be degrees, radians, miles, or kilometers (optional, default `'kilometers'`) - - `options.weight` **[number][4]** exponent regulating the distance-decay weighting (optional, default `1`) - -**Examples** - -```javascript -var points = turf.randomPoint(30, {bbox: [50, 30, 70, 50]}); - -// add a random property to each point -turf.featureEach(points, function(point) { - point.properties.solRad = Math.random() * 50; -}); -var options = {gridType: 'points', property: 'solRad', units: 'miles'}; -var grid = turf.interpolate(points, 100, options); - -//addToMap -var addToMap = [grid]; -``` - -Returns **[FeatureCollection][2]<([Point][3] \| [Polygon][7])>** grid of points or polygons with interpolated 'property' - -[1]: https://en.wikipedia.org/wiki/Inverse_distance_weighting - -[2]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/interpolate -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-interpolate/index.d.ts b/packages/turf-interpolate/index.d.ts deleted file mode 100644 index dc947647af..0000000000 --- a/packages/turf-interpolate/index.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Point, Polygon, Units, FeatureCollection, Grid } from '@turf/helpers'; - -/** - * http://turfjs.org/docs/#interpolate - */ -export default function interpolate( - points: FeatureCollection, - cellSize: number, - options?: { - gridType?: 'point', - property?: string, - units?: Units, - weight?: number - } -): FeatureCollection; -export default function interpolate( - points: FeatureCollection, - cellSize: number, - options?: { - gridType?: Grid, - property?: string, - units?: Units, - weight?: number - } -): FeatureCollection; diff --git a/packages/turf-interpolate/index.js b/packages/turf-interpolate/index.js deleted file mode 100644 index 6c3cd737cd..0000000000 --- a/packages/turf-interpolate/index.js +++ /dev/null @@ -1,105 +0,0 @@ -import bbox from '@turf/bbox'; -import hexGrid from '@turf/hex-grid'; -import pointGrid from '@turf/point-grid'; -import distance from '@turf/distance'; -import centroid from '@turf/centroid'; -import squareGrid from '@turf/square-grid'; -import triangleGrid from '@turf/triangle-grid'; -import clone from '@turf/clone'; -import { featureCollection } from '@turf/helpers'; -import { featureEach } from '@turf/meta'; -import { collectionOf } from '@turf/invariant'; - -/** - * Takes a set of points and estimates their 'property' values on a grid using the [Inverse Distance Weighting (IDW) method](https://en.wikipedia.org/wiki/Inverse_distance_weighting). - * - * @name interpolate - * @param {FeatureCollection} points with known value - * @param {number} cellSize the distance across each grid point - * @param {Object} [options={}] Optional parameters - * @param {string} [options.gridType='square'] defines the output format based on a Grid Type (options: 'square' | 'point' | 'hex' | 'triangle') - * @param {string} [options.property='elevation'] the property name in `points` from which z-values will be pulled, zValue fallbacks to 3rd coordinate if no property exists. - * @param {string} [options.units='kilometers'] used in calculating cellSize, can be degrees, radians, miles, or kilometers - * @param {number} [options.weight=1] exponent regulating the distance-decay weighting - * @returns {FeatureCollection} grid of points or polygons with interpolated 'property' - * @example - * var points = turf.randomPoint(30, {bbox: [50, 30, 70, 50]}); - * - * // add a random property to each point - * turf.featureEach(points, function(point) { - * point.properties.solRad = Math.random() * 50; - * }); - * var options = {gridType: 'points', property: 'solRad', units: 'miles'}; - * var grid = turf.interpolate(points, 100, options); - * - * //addToMap - * var addToMap = [grid]; - */ -function interpolate(points, cellSize, options) { - // Optional parameters - options = options || {}; - if (typeof options !== 'object') throw new Error('options is invalid'); - var gridType = options.gridType; - var property = options.property; - var weight = options.weight; - - // validation - if (!points) throw new Error('points is required'); - collectionOf(points, 'Point', 'input must contain Points'); - if (!cellSize) throw new Error('cellSize is required'); - if (weight !== undefined && typeof weight !== 'number') throw new Error('weight must be a number'); - - // default values - property = property || 'elevation'; - gridType = gridType || 'square'; - weight = weight || 1; - - var box = bbox(points); - var grid; - switch (gridType) { - case 'point': - case 'points': - grid = pointGrid(box, cellSize, options); - break; - case 'square': - case 'squares': - grid = squareGrid(box, cellSize, options); - break; - case 'hex': - case 'hexes': - grid = hexGrid(box, cellSize, options); - break; - case 'triangle': - case 'triangles': - grid = triangleGrid(box, cellSize, options); - break; - default: - throw new Error('invalid gridType'); - } - var results = []; - featureEach(grid, function (gridFeature) { - var zw = 0; - var sw = 0; - // calculate the distance from each input point to the grid points - featureEach(points, function (point) { - var gridPoint = (gridType === 'point') ? gridFeature : centroid(gridFeature); - var d = distance(gridPoint, point, options); - var zValue; - // property has priority for zValue, fallbacks to 3rd coordinate from geometry - if (property !== undefined) zValue = point.properties[property]; - if (zValue === undefined) zValue = point.geometry.coordinates[2]; - if (zValue === undefined) throw new Error('zValue is missing'); - if (d === 0) zw = zValue; - var w = 1.0 / Math.pow(d, weight); - sw += w; - zw += w * zValue; - }); - // write interpolated value for each grid point - var newFeature = clone(gridFeature); - newFeature.properties[property] = zw / sw; - results.push(newFeature); - }); - return featureCollection(results); -} - -export default interpolate; diff --git a/packages/turf-interpolate/package.json b/packages/turf-interpolate/package.json deleted file mode 100644 index a71ccbc48b..0000000000 --- a/packages/turf-interpolate/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "@turf/interpolate", - "version": "5.1.5", - "description": "turf interpolate module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "idw", - "interpolate" - ], - "author": "Turf Authors", - "contributors": [ - "Stefano Borghi <@stebogit>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/truncate": "6.x", - "benchmark": "*", - "chromatism": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/centroid": "6.x", - "@turf/clone": "6.x", - "@turf/distance": "6.x", - "@turf/helpers": "6.x", - "@turf/hex-grid": "^5.1.5", - "@turf/invariant": "6.x", - "@turf/meta": "6.x", - "@turf/point-grid": "6.x", - "@turf/square-grid": "^5.1.5", - "@turf/triangle-grid": "^5.1.5" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-interpolate/test.js b/packages/turf-interpolate/test.js deleted file mode 100644 index e65f581c2a..0000000000 --- a/packages/turf-interpolate/test.js +++ /dev/null @@ -1,105 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import truncate from '@turf/truncate'; -import { brightness } from 'chromatism'; -import { round, featureCollection, point } from '@turf/helpers'; -import { featureEach, propEach } from '@turf/meta'; -import interpolate from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -var fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); -// fixtures = fixtures.filter(fixture => fixture.name === 'points-random') - -test('turf-interpolate', t => { - for (const {filename, name, geojson} of fixtures) { - const options = geojson.properties; - const cellSize = options.cellSize; - const property = options.property || 'elevation'; - - // Truncate coordinates & elevation (property) to 6 precision - let result = truncate(interpolate(geojson, cellSize, options)); - propEach(result, (properties, featureIndex) => { - properties[property] = round(properties[property]); - }); - result = colorize(result, property, name); - - if (process.env.REGEN) write.sync(directories.out + filename, result); - t.deepEquals(result, load.sync(directories.out + filename), name); - } - t.end(); -}); - -test('turf-interpolate -- throws errors', t => { - const cellSize = 1; - const property = 'elevation'; - const weight = 0.5; - const units = 'miles'; - const gridType = 'point'; - const points = featureCollection([ - point([1, 2], {elevation: 200}), - point([2, 1], {elevation: 300}), - point([1.5, 1.5], {elevation: 400}) - ]); - - t.assert(interpolate(points, cellSize, {gridType: gridType, units: units, weight: weight}).features.length); - t.throws(() => interpolate(points, undefined), /cellSize is required/, 'cellSize is required'); - t.throws(() => interpolate(undefined, cellSize), /points is required/, 'points is required'); - t.throws(() => interpolate(points, cellSize, {gridType: 'foo'}), /invalid gridType/, 'invalid gridType'); - t.throws(() => interpolate(points, cellSize, {units: 'foo'}), 'invalid units'); - t.throws(() => interpolate(points, cellSize, {weight: 'foo'}), /weight must be a number/, 'weight must be a number'); - t.throws(() => interpolate(points, cellSize, {property: 'foo'}), /zValue is missing/, 'zValue is missing'); - t.end(); -}); - -test('turf-interpolate -- zValue from 3rd coordinate', t => { - const cellSize = 1; - const points = featureCollection([ - point([1, 2, 200]), - point([2, 1, 300]), - point([1.5, 1.5, 400]) - ]); - t.assert(interpolate(points, cellSize).features.length, 'zValue from 3rd coordinate'); - t.end(); -}); - -// style result -function colorize(grid, property, name) { - property = property || 'elevation'; - let max = -Infinity; - let min = Infinity; - propEach(grid, properties => { - const value = properties[property]; - if (value > max) max = value; - if (value < min) min = value; - }); - const delta = (max - min); - if (delta === 0) throw new Error(name + ' delta is invalid'); - - featureEach(grid, feature => { - const value = feature.properties[property]; - const percent = round((value - min - delta / 2) / delta * 100); - // darker corresponds to higher values - const color = brightness(-percent, '#0086FF').hex; - if (feature.geometry.type === 'Point') feature.properties['marker-color'] = color; - else { - feature.properties['stroke'] = color; - feature.properties['fill'] = color; - feature.properties['fill-opacity'] = 0.85; - } - }); - - return grid; -} diff --git a/packages/turf-interpolate/types.ts b/packages/turf-interpolate/types.ts deleted file mode 100644 index 897893f116..0000000000 --- a/packages/turf-interpolate/types.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { point, featureCollection } from '@turf/helpers'; -import interpolate from './'; - -const cellSize = 1; -const property = 'pressure'; -const gridType = 'square'; -const weight = 0.5; -const units = 'miles'; -const points = featureCollection([ - point([1, 2]), - point([12, 13]), - point([23, 22]), -]); - -const grid = interpolate(points, cellSize, {gridType, property, units, weight}); -grid.features[0].properties.pressure; - -// Optional properties -interpolate(points, cellSize, {gridType, property, units}); -interpolate(points, cellSize, {gridType, property}); -interpolate(points, cellSize, {gridType}); -interpolate(points, cellSize, {gridType: 'point'}); diff --git a/packages/turf-intersect/.gitignore b/packages/turf-intersect/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-intersect/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-intersect/LICENSE b/packages/turf-intersect/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-intersect/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-intersect/README.md b/packages/turf-intersect/README.md deleted file mode 100644 index 97caf6d0ed..0000000000 --- a/packages/turf-intersect/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# @turf/intersect - - - -## intersect - -Takes two [polygon][1] or [multi-polygon][2] geometries and finds their polygonal intersection. If they don't intersect, returns null. - -**Parameters** - -- `poly1` **[Feature][3]<([Polygon][4] \| [MultiPolygon][5])>** the first polygon or multipolygon -- `poly2` **[Feature][3]<([Polygon][4] \| [MultiPolygon][5])>** the second polygon or multipolygon -- `options` **[Object][6]** Optional Parameters (optional, default `{}`) - - `options.properties` **[Object][6]** Translate GeoJSON Properties to Feature (optional, default `{}`) - -**Examples** - -```javascript -var poly1 = turf.polygon([[ - [-122.801742, 45.48565], - [-122.801742, 45.60491], - [-122.584762, 45.60491], - [-122.584762, 45.48565], - [-122.801742, 45.48565] -]]); - -var poly2 = turf.polygon([[ - [-122.520217, 45.535693], - [-122.64038, 45.553967], - [-122.720031, 45.526554], - [-122.669906, 45.507309], - [-122.723464, 45.446643], - [-122.532577, 45.408574], - [-122.487258, 45.477466], - [-122.520217, 45.535693] -]]); - -var intersection = turf.intersect(poly1, poly2); - -//addToMap -var addToMap = [poly1, poly2, intersection]; -``` - -Returns **([Feature][3] | null)** returns a feature representing the area they share (either a [Polygon][1] or [MultiPolygon][2]). If they do not share any area, returns `null`. - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/intersect -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-intersect/bench.js b/packages/turf-intersect/bench.js deleted file mode 100644 index 00c4381939..0000000000 --- a/packages/turf-intersect/bench.js +++ /dev/null @@ -1,21 +0,0 @@ -const path = require('path'); -const load = require('load-json-file'); -const Benchmark = require('benchmark'); -const intersect = require('./').default; - -// Fixtures -const armenia = load.sync(path.join(__dirname, 'test', 'in', 'armenia.geojson')); -const simple = load.sync(path.join(__dirname, 'test', 'in', 'Intersect1.geojson')); - -/** - * Benchmark Results - * - * turf-intersect#simple x 81,192 ops/sec ±1.94% (90 runs sampled) - * turf-intersect#armenia x 45,824 ops/sec ±2.42% (88 runs sampled) - */ -new Benchmark.Suite('turf-intersect') - .add('turf-intersect#simple', () => intersect(simple.features[0], simple.features[1])) - .add('turf-intersect#armenia', () => intersect(armenia.features[0], armenia.features[1])) - .on('cycle', e => console.log(String(e.target))) - .on('complete', () => {}) - .run(); diff --git a/packages/turf-intersect/index.d.ts b/packages/turf-intersect/index.d.ts deleted file mode 100644 index 6c4788ef3f..0000000000 --- a/packages/turf-intersect/index.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Feature, MultiPolygon, Polygon, Properties } from "@turf/helpers"; -/** - * Takes two {@link Polygon|polygon} or {@link MultiPolygon|multi-polygon} geometries and - * finds their polygonal intersection. If they don't intersect, returns null. - * - * @name intersect - * @param {Feature} poly1 the first polygon or multipolygon - * @param {Feature} poly2 the second polygon or multipolygon - * @param {Object} [options={}] Optional Parameters - * @param {Object} [options.properties={}] Translate GeoJSON Properties to Feature - * @returns {Feature|null} returns a feature representing the area they share (either a {@link Polygon} or - * {@link MultiPolygon}). If they do not share any area, returns `null`. - * @example - * var poly1 = turf.polygon([[ - * [-122.801742, 45.48565], - * [-122.801742, 45.60491], - * [-122.584762, 45.60491], - * [-122.584762, 45.48565], - * [-122.801742, 45.48565] - * ]]); - * - * var poly2 = turf.polygon([[ - * [-122.520217, 45.535693], - * [-122.64038, 45.553967], - * [-122.720031, 45.526554], - * [-122.669906, 45.507309], - * [-122.723464, 45.446643], - * [-122.532577, 45.408574], - * [-122.487258, 45.477466], - * [-122.520217, 45.535693] - * ]]); - * - * var intersection = turf.intersect(poly1, poly2); - * - * //addToMap - * var addToMap = [poly1, poly2, intersection]; - */ -export default function intersect

(poly1: Feature | Polygon | MultiPolygon, poly2: Feature | Polygon | MultiPolygon, options?: { - properties?: P; -}): Feature | null; diff --git a/packages/turf-intersect/index.ts b/packages/turf-intersect/index.ts deleted file mode 100644 index 0857b0d38e..0000000000 --- a/packages/turf-intersect/index.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { Feature, multiPolygon, MultiPolygon, polygon, Polygon, Properties } from "@turf/helpers"; -import { getGeom } from "@turf/invariant"; -import * as martinez from "martinez-polygon-clipping"; - -/** - * Takes two {@link Polygon|polygon} or {@link MultiPolygon|multi-polygon} geometries and - * finds their polygonal intersection. If they don't intersect, returns null. - * - * @name intersect - * @param {Feature} poly1 the first polygon or multipolygon - * @param {Feature} poly2 the second polygon or multipolygon - * @param {Object} [options={}] Optional Parameters - * @param {Object} [options.properties={}] Translate GeoJSON Properties to Feature - * @returns {Feature|null} returns a feature representing the area they share (either a {@link Polygon} or - * {@link MultiPolygon}). If they do not share any area, returns `null`. - * @example - * var poly1 = turf.polygon([[ - * [-122.801742, 45.48565], - * [-122.801742, 45.60491], - * [-122.584762, 45.60491], - * [-122.584762, 45.48565], - * [-122.801742, 45.48565] - * ]]); - * - * var poly2 = turf.polygon([[ - * [-122.520217, 45.535693], - * [-122.64038, 45.553967], - * [-122.720031, 45.526554], - * [-122.669906, 45.507309], - * [-122.723464, 45.446643], - * [-122.532577, 45.408574], - * [-122.487258, 45.477466], - * [-122.520217, 45.535693] - * ]]); - * - * var intersection = turf.intersect(poly1, poly2); - * - * //addToMap - * var addToMap = [poly1, poly2, intersection]; - */ -export default function intersect

( - poly1: Feature | Polygon | MultiPolygon, - poly2: Feature | Polygon | MultiPolygon, - options: { - properties?: P, - } = {}, -): Feature | null { - const geom1 = getGeom(poly1); - const geom2 = getGeom(poly2); - - if (geom1.type === "Polygon" && geom2.type === "Polygon") { - const intersection: any = martinez.intersection(geom1.coordinates, geom2.coordinates); - - if (intersection === null || intersection.length === 0) { return null; } - if (intersection.length === 1) { - const start = intersection[0][0][0]; - const end = intersection[0][0][intersection[0][0].length - 1]; - if (start[0] === end[0] && start[1] === end[1]) { return polygon(intersection[0], options.properties); } - return null; - } - return multiPolygon(intersection, options.properties); - - } else if (geom1.type === "MultiPolygon") { - let resultCoords: any[] = []; - - // iterate through the polygon and run intersect with each part, adding to the resultCoords. - for (const coords of geom1.coordinates) { - const subGeom = getGeom(polygon(coords)); - const subIntersection = intersect(subGeom, geom2); - - if (subIntersection) { - const subIntGeom = getGeom(subIntersection); - - if (subIntGeom.type === "Polygon") { resultCoords.push(subIntGeom.coordinates); - } else if (subIntGeom.type === "MultiPolygon") { resultCoords = resultCoords.concat(subIntGeom.coordinates); - } else { throw new Error("intersection is invalid"); } - } - } - - // Make a polygon with the result - if (resultCoords.length === 0) { return null; } - if (resultCoords.length === 1) { return polygon(resultCoords[0], options.properties); - } else { return multiPolygon(resultCoords, options.properties); } - - } else if (geom2.type === "MultiPolygon") { - // geom1 is a polygon and geom2 a multiPolygon, - // put the multiPolygon first and fallback to the previous case. - return intersect(geom2, geom1); - - } else { - // handle invalid geometry types - throw new Error("poly1 and poly2 must be either polygons or multiPolygons"); - } -} diff --git a/packages/turf-intersect/package.json b/packages/turf-intersect/package.json deleted file mode 100644 index 383d9aaf2c..0000000000 --- a/packages/turf-intersect/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "@turf/intersect", - "version": "6.1.2", - "description": "turf intersect module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis", - "intersect" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "glob": "*", - "load-json-file": "*", - "tape": "*", - "write-json-file": "*", - "typescript": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "martinez-polygon-clipping": "^0.4.3" - } -} diff --git a/packages/turf-intersect/test.js b/packages/turf-intersect/test.js deleted file mode 100644 index 1b8a623fe5..0000000000 --- a/packages/turf-intersect/test.js +++ /dev/null @@ -1,38 +0,0 @@ -const path = require('path'); -const glob = require('glob'); -const test = require('tape'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { featureCollection } = require('@turf/helpers'); -const intersect = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -test('turf-intersect', t => { - glob.sync(directories.in + '*.geojson').forEach(filepath => { - const { name, base } = path.parse(filepath); - const [polygon1, polygon2] = load.sync(filepath).features; - - if (name.includes('skip')) return t.skip(name); - - // Red Polygon1 - polygon1.properties = Object.assign(polygon1.properties || {}, {'fill-opacity': 0.5, fill: '#F00'}); - // Blue Polygon2 - polygon2.properties = Object.assign(polygon2.properties || {}, {'fill-opacity': 0.5, fill: '#00F'}); - - const results = featureCollection([polygon1, polygon2]); - const result = intersect(polygon1, polygon2); - if (result) { - // Green Polygon - result.properties = {'fill-opacity': 1, fill: '#0F0'}; - results.features.push(result); - } - - if (process.env.REGEN) write.sync(directories.out + base, results); - t.deepEqual(results, load.sync(directories.out + base), name); - }); - t.end(); -}); diff --git a/packages/turf-intersect/test/out/Intersect1.geojson b/packages/turf-intersect/test/out/Intersect1.geojson deleted file mode 100644 index 33ddbd476a..0000000000 --- a/packages/turf-intersect/test/out/Intersect1.geojson +++ /dev/null @@ -1,139 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#F00" - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -79.88571166992188, - 32.887659962078956 - ], - [ - -80.09788513183594, - 32.927436533285565 - ], - [ - -80.15350341796875, - 32.82825010814964 - ], - [ - -80.00312805175781, - 32.69428812316933 - ], - [ - -79.89395141601562, - 32.75551989829049 - ], - [ - -79.88571166992188, - 32.887659962078956 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#00F" - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -79.92141723632812, - 32.953944317478246 - ], - [ - -79.97428894042969, - 32.83690450361482 - ], - [ - -79.97360229492188, - 32.76071688548088 - ], - [ - -79.93034362792969, - 32.76475877693074 - ], - [ - -79.93789672851562, - 32.74108223150125 - ], - [ - -79.80537414550781, - 32.7231762754146 - ], - [ - -79.81773376464844, - 32.923402043498875 - ], - [ - -79.92141723632812, - 32.953944317478246 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -79.97428894042969, - 32.83690450361482 - ], - [ - -79.97360229492188, - 32.76071688548088 - ], - [ - -79.93034362792969, - 32.76475877693074 - ], - [ - -79.93789672851562, - 32.74108223150125 - ], - [ - -79.92322780260464, - 32.73910022106017 - ], - [ - -79.89395141601562, - 32.75551989829049 - ], - [ - -79.88571166992188, - 32.887659962078956 - ], - [ - -79.94623496447946, - 32.89900638172028 - ], - [ - -79.97428894042969, - 32.83690450361482 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-intersect/test/out/issue-412.geojson b/packages/turf-intersect/test/out/issue-412.geojson deleted file mode 100644 index 8184ba91ac..0000000000 --- a/packages/turf-intersect/test/out/issue-412.geojson +++ /dev/null @@ -1,65 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 11.076136797048882, - 9.856269774244707 - ], - [ - 11.262359619140625, - 9.85386305739084 - ], - [ - 11.083831787109375, - 9.85386305739084 - ], - [ - 11.076136797048882, - 9.856269774244707 - ] - ] - ] - }, - "properties": { - "fill-opacity": 0.5, - "fill": "#F00" - } - }, - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 11.62078857421875, - 10.306812602471467 - ], - [ - 11.162109375, - 9.848450887107404 - ], - [ - 11.072845458984375, - 9.85656910923582 - ], - [ - 11.62078857421875, - 10.306812602471467 - ] - ] - ] - }, - "properties": { - "fill-opacity": 0.5, - "fill": "#00F" - } - } - ] -} diff --git a/packages/turf-intersect/tsconfig.json b/packages/turf-intersect/tsconfig.json deleted file mode 100644 index 91cffcbf55..0000000000 --- a/packages/turf-intersect/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - }, - "files": [ - "index.ts" - ] -} \ No newline at end of file diff --git a/packages/turf-intersect/tslint.json b/packages/turf-intersect/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-intersect/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-intersect/types.ts b/packages/turf-intersect/types.ts deleted file mode 100644 index ea7b9d6432..0000000000 --- a/packages/turf-intersect/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { polygon } from '@turf/helpers' -import intersect from './' - -const poly1 = polygon([[[0, 0], [1, 1], [3, 0], [0, 0]]]) -const poly2 = polygon([[[10, 10], [21, 21], [0, 4], [10, 10]]]) - -const match = intersect(poly1, poly2) - -if (match === null) console.log('foo') - -const foo = intersect(poly1, poly2) || 'bar' \ No newline at end of file diff --git a/packages/turf-invariant/.gitignore b/packages/turf-invariant/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-invariant/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-invariant/LICENSE b/packages/turf-invariant/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-invariant/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-invariant/README.md b/packages/turf-invariant/README.md deleted file mode 100644 index c82293072c..0000000000 --- a/packages/turf-invariant/README.md +++ /dev/null @@ -1,202 +0,0 @@ -# @turf/invariant - - - -## getCoord - -Unwrap a coordinate from a Point Feature, Geometry or a single coordinate. - -**Parameters** - -- `coord` **([Array][1]<[number][2]> | [Geometry][3]<[Point][4]> | [Feature][5]<[Point][4]>)** GeoJSON Point or an Array of numbers - -**Examples** - -```javascript -var pt = turf.point([10, 10]); - -var coord = turf.getCoord(pt); -//= [10, 10] -``` - -Returns **[Array][1]<[number][2]>** coordinates - -## getCoords - -Unwrap coordinates from a Feature, Geometry Object or an Array - -**Parameters** - -- `coords` **([Array][1]<any> | [Geometry][3] \| [Feature][5])** Feature, Geometry Object or an Array - -**Examples** - -```javascript -var poly = turf.polygon([[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]]); - -var coords = turf.getCoords(poly); -//= [[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]] -``` - -Returns **[Array][1]<any>** coordinates - -## containsNumber - -Checks if coordinates contains a number - -**Parameters** - -- `coordinates` **[Array][1]<any>** GeoJSON Coordinates - -Returns **[boolean][6]** true if Array contains a number - -## geojsonType - -Enforce expectations about types of GeoJSON objects for Turf. - -**Parameters** - -- `value` **[GeoJSON][7]** any GeoJSON object -- `type` **[string][8]** expected GeoJSON type -- `name` **[string][8]** name of calling function - - -- Throws **[Error][9]** if value is not the expected type. - -## featureOf - -Enforce expectations about types of [Feature][10] inputs for Turf. -Internally this uses [geojsonType][11] to judge geometry types. - -**Parameters** - -- `feature` **[Feature][5]** a feature with an expected geometry type -- `type` **[string][8]** expected GeoJSON type -- `name` **[string][8]** name of calling function - - -- Throws **[Error][9]** error if value is not the expected type. - -## collectionOf - -Enforce expectations about types of [FeatureCollection][12] inputs for Turf. -Internally this uses [geojsonType][11] to judge geometry types. - -**Parameters** - -- `featureCollection` **[FeatureCollection][13]** a FeatureCollection for which features will be judged -- `type` **[string][8]** expected GeoJSON type -- `name` **[string][8]** name of calling function - - -- Throws **[Error][9]** if value is not the expected type. - -## getGeom - -Get Geometry from Feature or Geometry Object - -**Parameters** - -- `geojson` **([Feature][5] \| [Geometry][3])** GeoJSON Feature or Geometry Object - -**Examples** - -```javascript -var point = { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Point", - "coordinates": [110, 40] - } -} -var geom = turf.getGeom(point) -//={"type": "Point", "coordinates": [110, 40]} -``` - -- Throws **[Error][9]** if geojson is not a Feature or Geometry Object - -Returns **([Geometry][3] | null)** GeoJSON Geometry Object - -## getGeomType - -Get Geometry Type from Feature or Geometry Object - -- Throws **[Error][9]** **DEPRECATED** in v5.0.0 in favor of getType - -## getType - -Get GeoJSON object's type, Geometry type is prioritize. - -**Parameters** - -- `geojson` **[GeoJSON][7]** GeoJSON object -- `name` **[string][8]** name of the variable to display in error message (optional, default `"geojson"`) - -**Examples** - -```javascript -var point = { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Point", - "coordinates": [110, 40] - } -} -var geom = turf.getType(point) -//="Point" -``` - -Returns **[string][8]** GeoJSON type - -[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array - -[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - -[7]: https://tools.ietf.org/html/rfc7946#section-3 - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error - -[10]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[11]: #geojsontype - -[12]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[13]: https://tools.ietf.org/html/rfc7946#section-3.3 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/invariant -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-invariant/bench.js b/packages/turf-invariant/bench.js deleted file mode 100644 index 834a124ad9..0000000000 --- a/packages/turf-invariant/bench.js +++ /dev/null @@ -1,32 +0,0 @@ -const Benchmark = require('benchmark'); -const helpers = require('@turf/helpers'); -const invariant = require('./'); - -const pt = helpers.point([-75, 40]); -const line = helpers.lineString([[-75, 40], [-70, 50]]); -const poly = helpers.polygon([[[-75, 40], [-80, 50], [-70, 50], [-75, 40]]]); -const fc = helpers.points([ - [-75, 40], - [20, 50] -]); - -const suite = new Benchmark.Suite('turf-invariant'); - -/** - * Benchmark Results - * - * getCoord -- pt x 60,659,161 ops/sec ±1.34% (89 runs sampled) - * getCoords -- line x 63,252,327 ops/sec ±1.19% (81 runs sampled) - * getCoords -- poly x 62,053,169 ops/sec ±1.49% (85 runs sampled) - * collectionOf -- fc x 24,204,462 ops/sec ±2.00% (81 runs sampled) - * getType -- pt x 59,544,117 ops/sec ±1.14% (87 runs sampled) - */ -suite - .add('getCoord -- pt', () => invariant.getCoord(pt)) - .add('getCoords -- line', () => invariant.getCoords(line)) - .add('getCoords -- poly', () => invariant.getCoords(poly)) - .add('collectionOf -- fc', () => invariant.collectionOf(fc, 'Point', 'bench')) - .add('getType -- pt', () => invariant.getType(pt)) - .on('cycle', e => console.log(String(e.target))) - .on('complete', () => {}) - .run(); diff --git a/packages/turf-invariant/index.ts b/packages/turf-invariant/index.ts deleted file mode 100644 index d82e4a729e..0000000000 --- a/packages/turf-invariant/index.ts +++ /dev/null @@ -1,194 +0,0 @@ -import { - Feature, FeatureCollection, Geometries, Geometry, GeometryCollection, GeometryObject, isNumber, Point, -} from "@turf/helpers"; - -/** - * Unwrap a coordinate from a Point Feature, Geometry or a single coordinate. - * - * @name getCoord - * @param {Array|Geometry|Feature} coord GeoJSON Point or an Array of numbers - * @returns {Array} coordinates - * @example - * var pt = turf.point([10, 10]); - * - * var coord = turf.getCoord(pt); - * //= [10, 10] - */ -export function getCoord(coord: Feature | Point | number[]): number[] { - if (!coord) { throw new Error("coord is required"); } - - if (!Array.isArray(coord)) { - if (coord.type === "Feature" && coord.geometry !== null && coord.geometry.type === "Point") { - return coord.geometry.coordinates; - } - if (coord.type === "Point") { - return coord.coordinates; - } - } - if (Array.isArray(coord) && coord.length >= 2 && !Array.isArray(coord[0]) && !Array.isArray(coord[1])) { - return coord; - } - - throw new Error("coord must be GeoJSON Point or an Array of numbers"); -} - -/** - * Unwrap coordinates from a Feature, Geometry Object or an Array - * - * @name getCoords - * @param {Array|Geometry|Feature} coords Feature, Geometry Object or an Array - * @returns {Array} coordinates - * @example - * var poly = turf.polygon([[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]]); - * - * var coords = turf.getCoords(poly); - * //= [[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]] - */ -export function getCoords(coords: any[] | Feature | G): any[] { - if (Array.isArray(coords)) { return coords; } - - // Feature - if (coords.type === "Feature") { - if (coords.geometry !== null) { return coords.geometry.coordinates; } - } else { - // Geometry - if (coords.coordinates) { return coords.coordinates; } - } - - throw new Error("coords must be GeoJSON Feature, Geometry Object or an Array"); -} - -/** - * Checks if coordinates contains a number - * - * @name containsNumber - * @param {Array} coordinates GeoJSON Coordinates - * @returns {boolean} true if Array contains a number - */ -export function containsNumber(coordinates: any[]): boolean { - if (coordinates.length > 1 && isNumber(coordinates[0]) && isNumber(coordinates[1])) { - return true; - } - - if (Array.isArray(coordinates[0]) && coordinates[0].length) { - return containsNumber(coordinates[0]); - } - throw new Error("coordinates must only contain numbers"); -} - -/** - * Enforce expectations about types of GeoJSON objects for Turf. - * - * @name geojsonType - * @param {GeoJSON} value any GeoJSON object - * @param {string} type expected GeoJSON type - * @param {string} name name of calling function - * @throws {Error} if value is not the expected type. - */ -export function geojsonType(value: any, type: string, name: string): void { - if (!type || !name) { throw new Error("type and name required"); } - - if (!value || value.type !== type) { - throw new Error("Invalid input to " + name + ": must be a " + type + ", given " + value.type); - } -} - -/** - * Enforce expectations about types of {@link Feature} inputs for Turf. - * Internally this uses {@link geojsonType} to judge geometry types. - * - * @name featureOf - * @param {Feature} feature a feature with an expected geometry type - * @param {string} type expected GeoJSON type - * @param {string} name name of calling function - * @throws {Error} error if value is not the expected type. - */ -export function featureOf(feature: Feature, type: string, name: string): void { - if (!feature) { throw new Error("No feature passed"); } - if (!name) { throw new Error(".featureOf() requires a name"); } - if (!feature || feature.type !== "Feature" || !feature.geometry) { - throw new Error("Invalid input to " + name + ", Feature with geometry required"); - } - if (!feature.geometry || feature.geometry.type !== type) { - throw new Error("Invalid input to " + name + ": must be a " + type + ", given " + feature.geometry.type); - } -} - -/** - * Enforce expectations about types of {@link FeatureCollection} inputs for Turf. - * Internally this uses {@link geojsonType} to judge geometry types. - * - * @name collectionOf - * @param {FeatureCollection} featureCollection a FeatureCollection for which features will be judged - * @param {string} type expected GeoJSON type - * @param {string} name name of calling function - * @throws {Error} if value is not the expected type. - */ -export function collectionOf(featureCollection: FeatureCollection, type: string, name: string) { - if (!featureCollection) { throw new Error("No featureCollection passed"); } - if (!name) { throw new Error(".collectionOf() requires a name"); } - if (!featureCollection || featureCollection.type !== "FeatureCollection") { - throw new Error("Invalid input to " + name + ", FeatureCollection required"); - } - for (const feature of featureCollection.features) { - if (!feature || feature.type !== "Feature" || !feature.geometry) { - throw new Error("Invalid input to " + name + ", Feature with geometry required"); - } - if (!feature.geometry || feature.geometry.type !== type) { - throw new Error("Invalid input to " + name + ": must be a " + type + ", given " + feature.geometry.type); - } - } -} - -/** - * Get Geometry from Feature or Geometry Object - * - * @param {Feature|Geometry} geojson GeoJSON Feature or Geometry Object - * @returns {Geometry|null} GeoJSON Geometry Object - * @throws {Error} if geojson is not a Feature or Geometry Object - * @example - * var point = { - * "type": "Feature", - * "properties": {}, - * "geometry": { - * "type": "Point", - * "coordinates": [110, 40] - * } - * } - * var geom = turf.getGeom(point) - * //={"type": "Point", "coordinates": [110, 40]} - */ -export function getGeom( - geojson: Feature | G, -): G { - if (geojson.type === "Feature") { return geojson.geometry; } - return geojson; -} - -/** - * Get GeoJSON object's type, Geometry type is prioritize. - * - * @param {GeoJSON} geojson GeoJSON object - * @param {string} [name="geojson"] name of the variable to display in error message - * @returns {string} GeoJSON type - * @example - * var point = { - * "type": "Feature", - * "properties": {}, - * "geometry": { - * "type": "Point", - * "coordinates": [110, 40] - * } - * } - * var geom = turf.getType(point) - * //="Point" - */ -export function getType( - geojson: Feature | FeatureCollection | Geometries | GeometryCollection, - name?: string, -): string { - if (geojson.type === "FeatureCollection") { return "FeatureCollection"; } - if (geojson.type === "GeometryCollection") { return "GeometryCollection"; } - if (geojson.type === "Feature" && geojson.geometry !== null) { return geojson.geometry.type; } - return geojson.type; -} diff --git a/packages/turf-invariant/package.json b/packages/turf-invariant/package.json deleted file mode 100644 index cb860e5c11..0000000000 --- a/packages/turf-invariant/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "@turf/invariant", - "version": "6.1.2", - "description": "turf invariant module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "invariant", - "expectations" - ], - "author": "Turf Authors", - "contributors": [ - "Tom MacWright <@tmcw>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "typescript": "*", - "tslint": "*", - "tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x" - } -} diff --git a/packages/turf-invariant/test.js b/packages/turf-invariant/test.js deleted file mode 100644 index 31ce7ff0b2..0000000000 --- a/packages/turf-invariant/test.js +++ /dev/null @@ -1,231 +0,0 @@ -const test = require('tape'); -const { - point, lineString, polygon, - feature, featureCollection, geometryCollection, - multiLineString, lineStrings -} = require('@turf/helpers'); -const invariant = require('.'); - -test('invariant -- containsNumber', t => { - t.equals(invariant.containsNumber([1, 1]), true); - t.equals(invariant.containsNumber([[1, 1], [1, 1]]), true); - t.equals(invariant.containsNumber([[[1, 1], [1, 1]], [1, 1]]), true); - - //# Ensure recursive call handles Max callstack exceeded - t.throws(() => { - invariant.containsNumber(['foo', 1]); - }, /coordinates must only contain numbers/, 'Must only contain numbers'); - t.end(); -}); - -test('invariant -- geojsonType', t => { - t.throws(() => { - invariant.geojsonType(); - }, /type and name required/, '.geojsonType() name requirement'); - - t.throws(() => { - invariant.geojsonType({}, undefined, 'myfn'); - }, /type and name required/, 'invalid types'); - - t.throws(() => { - invariant.geojsonType({ - type: 'Point', - coordinates: [0, 0] - }, 'Polygon', 'myfn'); - }, /Invalid input to myfn: must be a Polygon, given Point/, 'invalid geometry type'); - - t.doesNotThrow(() => { - invariant.geojsonType({ - type: 'Point', - coordinates: [0, 0] - }, 'Point', 'myfn'); - }, 'valid geometry'); - - t.end(); -}); - -test('invariant -- featureOf', t => { - t.throws(() => { - invariant.featureOf({ - type: 'Feature', - geometry: { - type: 'Point', - coordinates: [0, 0] - }, - properties: {} - }, 'Polygon'); - }, /requires a name/, 'requires a name'); - - t.throws(() => { - invariant.featureOf({}, 'Polygon', 'foo'); - }, /Feature with geometry required/, 'requires a feature'); - - t.throws(() => { - invariant.featureOf({ - type: 'Feature', - geometry: { - type: 'Point', - coordinates: [0, 0] - }, - properties: {} - }, 'Polygon', 'myfn'); - }, /Invalid input to myfn: must be a Polygon, given Point/, 'invalid geometry type'); - - t.doesNotThrow(() => { - invariant.featureOf({ - type: 'Feature', - geometry: { - type: 'Point', - coordinates: [0, 0] - }, - properties: {} - }, 'Point', 'myfn'); - }, 'valid geometry type'); - - t.end(); -}); - -test('invariant -- collectionOf', t => { - t.throws(() => { - invariant.collectionOf({ - type: 'FeatureCollection', - features: [ - { - type: 'Feature', - geometry: { - type: 'Point', - coordinates: [0, 0] - }, - properties: {} - } - ] - }, 'Polygon', 'myfn'); - }, /Invalid input to myfn: must be a Polygon, given Point/, 'invalid geometry type'); - - t.throws(() => { - invariant.collectionOf({}, 'Polygon'); - }, /requires a name/, 'requires a name'); - - t.throws(() => { - invariant.collectionOf({}, 'Polygon', 'foo'); - }, /FeatureCollection required/, 'requires a featurecollection'); - - t.doesNotThrow(() => { - invariant.collectionOf({ - type: 'FeatureCollection', - features: [ - { - type: 'Feature', - geometry: { - type: 'Point', - coordinates: [0, 0] - }, - properties: {} - } - ] - }, 'Point', 'myfn'); - }, 'valid geometry type'); - - t.end(); -}); - -test('invariant -- getCoord', t => { - t.throws(() => invariant.getCoord(lineString([[1, 2], [3, 4]]))); - t.throws(() => invariant.getCoord(polygon([[[-75, 40], [-80, 50], [-70, 50], [-75, 40]]]))); - - t.deepEqual(invariant.getCoord({ - type: 'Point', - coordinates: [1, 2] - }), [1, 2]); - - t.deepEqual(invariant.getCoord(point([1, 2])), [1, 2]); - t.end(); -}); - -test('invariant -- getCoord', t => { - t.throws(() => invariant.getCoord({ - type: 'LineString', - coordinates: [[1, 2], [3, 4]] - })); - - t.throws(() => invariant.getCoord(false), 'false should throw Error'); - t.throws(() => invariant.getCoord(null), 'null should throw Error'); - t.throws(() => invariant.getCoord(lineString([[1, 2], [3, 4]])), 'LineString is not a Point'); - t.throws(() => invariant.getCoord([10]), 'Single number Array should throw Error'); - // t.throws(() => invariant.getCoord(['A', 'B']), 'Array of String should throw Error'); - // t.throws(() => invariant.getCoord([1, 'foo']), 'Mixed Array should throw Error'); - - t.deepEqual(invariant.getCoord({ - type: 'Point', - coordinates: [1, 2] - }), [1, 2]); - - t.deepEqual(invariant.getCoord(point([1, 2])), [1, 2]); - t.deepEqual(invariant.getCoord([1, 2]), [1, 2]); - t.end(); -}); - -test('invariant -- getCoords', t => { - t.throws(() => invariant.getCoords({ - type: 'LineString', - coordinates: null - })); - - t.throws(() => invariant.getCoords(false)); - t.throws(() => invariant.getCoords(null)); - t.throws(() => containsNumber(invariant.getCoords(['A', 'B', 'C']))); - t.throws(() => containsNumber(invariant.getCoords([1, 'foo', 'bar']))); - - t.deepEqual(invariant.getCoords({ - type: 'LineString', - coordinates: [[1, 2], [3, 4]] - }), [[1, 2], [3, 4]]); - - t.deepEqual(invariant.getCoords(point([1, 2])), [1, 2]); - t.deepEqual(invariant.getCoords(lineString([[1, 2], [3, 4]])), [[1, 2], [3, 4]]); - t.deepEqual(invariant.getCoords([1, 2]), [1, 2]); - t.end(); -}); - -test('invariant -- getGeom', t => { - const pt = point([1, 1]); - const line = lineString([[0, 1], [1, 1]]); - const collection = featureCollection([pt, line]); - const geomCollection = geometryCollection([pt.geometry, line.geometry]); - - t.deepEqual(invariant.getGeom(pt), pt.geometry, 'Point'); - t.deepEqual(invariant.getGeom(line.geometry), line.geometry, 'LineString'); - t.deepEqual(invariant.getGeom(geomCollection), geomCollection.geometry, 'GeometryCollection'); - t.deepEqual(invariant.getGeom(geomCollection.geometry), geomCollection.geometry, 'GeometryCollection'); - // t.throws(() => invariant.getGeom(collection), 'featureCollection not valid'); - t.end(); -}); - -test('invariant -- getType', t => { - const pt = point([1, 1]); - const line = lineString([[0, 1], [1, 1]]); - const collection = featureCollection([pt, line]); - const geomCollection = geometryCollection([pt.geometry, line.geometry]); - - t.deepEqual(invariant.getType(pt), 'Point'); - t.deepEqual(invariant.getType(line.geometry), 'LineString'); - t.deepEqual(invariant.getType(geomCollection), 'GeometryCollection'); - t.deepEqual(invariant.getType(collection), 'FeatureCollection'); - // t.throws(() => invariant.getType(null), /geojson is required/, 'geojson is required'); - t.end(); -}); - -// https://github.com/Turfjs/turf/issues/853 -test('null geometries', t => { - const nullFeature = { - type: 'Feature', - properties: {}, - geometry: null - }; - // t.throws(() => invariant.getGeom(null), /geojson is required/, 'getGeom => geojson is required'); - t.throws(() => invariant.getCoords(nullFeature), /coords must be GeoJSON Feature, Geometry Object or an Array/, 'getCoords => coords must be GeoJSON Feature, Geometry Object or an Array'); - t.throws(() => invariant.getCoord(nullFeature), /coord must be GeoJSON Point or an Array of numbers/, 'getCoord => coord must be GeoJSON Point or an Array of numbers'); - - // t.equal(invariant.getGeom(nullFeature), null, 'getGeom => null'); - t.end(); -}); diff --git a/packages/turf-invariant/tsconfig.json b/packages/turf-invariant/tsconfig.json deleted file mode 100644 index 91cffcbf55..0000000000 --- a/packages/turf-invariant/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - }, - "files": [ - "index.ts" - ] -} \ No newline at end of file diff --git a/packages/turf-invariant/tslint.json b/packages/turf-invariant/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-invariant/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-invariant/types.ts b/packages/turf-invariant/types.ts deleted file mode 100644 index f7d1e6c561..0000000000 --- a/packages/turf-invariant/types.ts +++ /dev/null @@ -1,59 +0,0 @@ -import * as helpers from "@turf/helpers"; -import { - Geometry, - GeometryCollection, - GeometryTypes, - LineString, - Point, - Polygon, - Position, - Types, -} from "@turf/helpers"; -import * as invariant from "./"; - -/** - * Fixtures - */ -const pt = helpers.point([0, 0]); -const line = helpers.lineString([[0, 0], [1, 1]]); -const poly = helpers.polygon([[[0, 0], [1, 1], [2, 2], [0, 0]]]); -const gc = helpers.geometryCollection([pt.geometry, line.geometry, poly.geometry]); -const fc = helpers.featureCollection([pt, line, poly]); - -/** - * invariant.getGeom - */ -// invariant.getGeom(fc); // Argument of type 'FeatureCollection' is not assignable to parameter of type -const gcGeom: GeometryCollection = invariant.getGeom(gc); -const pointGeom: Point = invariant.getGeom(pt); -const lineGeom: LineString = invariant.getGeom(line); -const polyGeom: Polygon = invariant.getGeom(poly); - -/** - * invariant.getType - */ -const type = invariant.getType(pt); - -/** - * getCoord - */ -invariant.getCoord(pt); -invariant.getCoord(pt.geometry); -invariant.getCoord(pt.geometry.coordinates); -let coordZ = [10, 30, 2000]; -coordZ = invariant.getCoord(coordZ); - -/** - * getCoords - */ -invariant.getCoords(pt.geometry)[0].toFixed(); -invariant.getCoords(pt.geometry.coordinates)[0].toFixed(); -invariant.getCoords(pt)[0].toFixed(); -invariant.getCoords(line.geometry)[0][0].toFixed(); -invariant.getCoords(line.geometry.coordinates)[0][0].toFixed(); -invariant.getCoords(line)[0][0].toFixed(); -invariant.getCoords(poly)[0][0][0].toFixed(); -invariant.getCoords(poly.geometry)[0][0][0].toFixed(); -invariant.getCoords(poly.geometry.coordinates)[0][0][0].toFixed(); -const lineCoords: Position[] = [[10, 30], [40, 40]]; -invariant.getCoords(lineCoords)[0][0].toFixed(); diff --git a/packages/turf-isobands/LICENSE b/packages/turf-isobands/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-isobands/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-isobands/README.md b/packages/turf-isobands/README.md deleted file mode 100644 index dee89d9d55..0000000000 --- a/packages/turf-isobands/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# @turf/isobands - - - -## isobands - -Takes a square or rectangular grid [FeatureCollection][1] of [Point][2] features with z-values and an array of -value breaks and generates filled contour isobands. - -**Parameters** - -- `pointGrid` **[FeatureCollection][3]<[Point][4]>** input points - must be square or rectangular -- `breaks` **[Array][5]<[number][6]>** where to draw contours -- `options` **[Object][7]** options on output (optional, default `{}`) - - `options.zProperty` **[string][8]** the property name in `points` from which z-values will be pulled (optional, default `'elevation'`) - - `options.commonProperties` **[Object][7]** GeoJSON properties passed to ALL isobands (optional, default `{}`) - - `options.breaksProperties` **[Array][5]<[Object][7]>** GeoJSON properties passed, in order, to the correspondent isoband (order defined by breaks) (optional, default `[]`) - -Returns **[FeatureCollection][3]<[MultiPolygon][9]>** a FeatureCollection of [MultiPolygon][10] features representing isobands - -[1]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[9]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[10]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/isobands -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-isobands/index.d.ts b/packages/turf-isobands/index.d.ts deleted file mode 100644 index 43649f52da..0000000000 --- a/packages/turf-isobands/index.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Point, MultiPolygon, FeatureCollection, Feature, Properties } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#isobands - */ -export default function isobands( - points: FeatureCollection, - breaks: number[], - options?: { - zProperty?: string; - commonProperties?: Properties; - breaksProperties?: Properties[]; - } -): FeatureCollection; diff --git a/packages/turf-isobands/index.js b/packages/turf-isobands/index.js deleted file mode 100644 index 24a790c5fc..0000000000 --- a/packages/turf-isobands/index.js +++ /dev/null @@ -1,249 +0,0 @@ -import bbox from '@turf/bbox'; -import area from '@turf/area'; -import booleanPointInPolygon from '@turf/boolean-point-in-polygon'; -import explode from '@turf/explode'; -import { collectionOf } from '@turf/invariant'; -import { polygon, multiPolygon, featureCollection, isObject } from '@turf/helpers'; -import objectAssign from 'object-assign'; -import gridToMatrix from './lib/grid-to-matrix'; -import isoBands from './lib/marchingsquares-isobands'; - -/** - * Takes a square or rectangular grid {@link FeatureCollection} of {@link Point} features with z-values and an array of - * value breaks and generates filled contour isobands. - * - * @name isobands - * @param {FeatureCollection} pointGrid input points - must be square or rectangular - * @param {Array} breaks where to draw contours - * @param {Object} [options={}] options on output - * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled - * @param {Object} [options.commonProperties={}] GeoJSON properties passed to ALL isobands - * @param {Array} [options.breaksProperties=[]] GeoJSON properties passed, in order, to the correspondent isoband (order defined by breaks) - * @returns {FeatureCollection} a FeatureCollection of {@link MultiPolygon} features representing isobands - */ -function isobands(pointGrid, breaks, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var zProperty = options.zProperty || 'elevation'; - var commonProperties = options.commonProperties || {}; - var breaksProperties = options.breaksProperties || []; - - // Validation - collectionOf(pointGrid, 'Point', 'Input must contain Points'); - if (!breaks) throw new Error('breaks is required'); - if (!Array.isArray(breaks)) throw new Error('breaks is not an Array'); - if (!isObject(commonProperties)) throw new Error('commonProperties is not an Object'); - if (!Array.isArray(breaksProperties)) throw new Error('breaksProperties is not an Array'); - - // Isoband methods - var matrix = gridToMatrix(pointGrid, {zProperty: zProperty, flip: true}); - var contours = createContourLines(matrix, breaks, zProperty); - contours = rescaleContours(contours, matrix, pointGrid); - - var multipolygons = contours.map(function (contour, index) { - if (breaksProperties[index] && !isObject(breaksProperties[index])) { - throw new Error('Each mappedProperty is required to be an Object'); - } - // collect all properties - var contourProperties = objectAssign( - {}, - commonProperties, - breaksProperties[index] - ); - contourProperties[zProperty] = contour[zProperty]; - var multiP = multiPolygon(contour.groupedRings, contourProperties); - return multiP; - }); - - return featureCollection(multipolygons); -} - -/** - * Creates the contours lines (featuresCollection of polygon features) from the 2D data grid - * - * Marchingsquares process the grid data as a 3D representation of a function on a 2D plane, therefore it - * assumes the points (x-y coordinates) are one 'unit' distance. The result of the IsoBands function needs to be - * rescaled, with turfjs, to the original area and proportions on the map - * - * @private - * @param {Array>} matrix Grid Data - * @param {Array} breaks Breaks - * @param {string} [property='elevation'] Property - * @returns {Array} contours - */ -function createContourLines(matrix, breaks, property) { - - var contours = []; - for (var i = 1; i < breaks.length; i++) { - var lowerBand = +breaks[i - 1]; // make sure the breaks value is a number - var upperBand = +breaks[i]; - - var isobandsCoords = isoBands(matrix, lowerBand, upperBand - lowerBand); - // as per GeoJson rules for creating a Polygon, make sure the first element - // in the array of LinearRings represents the exterior ring (i.e. biggest area), - // and any subsequent elements represent interior rings (i.e. smaller area); - // this avoids rendering issues of the MultiPolygons on the map - var nestedRings = orderByArea(isobandsCoords); - var groupedRings = groupNestedRings(nestedRings); - var obj = {}; - obj['groupedRings'] = groupedRings; - obj[property] = lowerBand + '-' + upperBand; - contours.push(obj); - } - return contours; -} - -/** - * Transform isobands of 2D grid to polygons for the map - * - * @private - * @param {Array} contours Contours - * @param {Array>} matrix Grid Data - * @param {Object} points Points by Latitude - * @returns {Array} contours - */ -function rescaleContours(contours, matrix, points) { - - // get dimensions (on the map) of the original grid - var gridBbox = bbox(points); // [ minX, minY, maxX, maxY ] - var originalWidth = gridBbox[2] - gridBbox[0]; - var originalHeigth = gridBbox[3] - gridBbox[1]; - - // get origin, which is the first point of the last row on the rectangular data on the map - var x0 = gridBbox[0]; - var y0 = gridBbox[1]; - // get number of cells per side - var matrixWidth = matrix[0].length - 1; - var matrixHeight = matrix.length - 1; - // calculate the scaling factor between matrix and rectangular grid on the map - var scaleX = originalWidth / matrixWidth; - var scaleY = originalHeigth / matrixHeight; - - var resize = function (point) { - point[0] = point[0] * scaleX + x0; - point[1] = point[1] * scaleY + y0; - }; - - // resize and shift each point/line of the isobands - contours.forEach(function (contour) { - contour.groupedRings.forEach(function (lineRingSet) { - lineRingSet.forEach(function (lineRing) { - lineRing.forEach(resize); - }); - }); - }); - return contours; -} - - -/* utility functions */ - - -/** - * Returns an array of coordinates (of LinearRings) in descending order by area - * - * @private - * @param {Array} ringsCoords array of closed LineString - * @returns {Array} array of the input LineString ordered by area - */ -function orderByArea(ringsCoords) { - var ringsWithArea = []; - var areas = []; - ringsCoords.forEach(function (coords) { - // var poly = polygon([points]); - var ringArea = area(polygon([coords])); - // create an array of areas value - areas.push(ringArea); - // associate each lineRing with its area - ringsWithArea.push({ring: coords, area: ringArea}); - }); - areas.sort(function (a, b) { // bigger --> smaller - return b - a; - }); - // create a new array of linearRings coordinates ordered by their area - var orderedByArea = []; - areas.forEach(function (area) { - for (var lr = 0; lr < ringsWithArea.length; lr++) { - if (ringsWithArea[lr].area === area) { - orderedByArea.push(ringsWithArea[lr].ring); - ringsWithArea.splice(lr, 1); - break; - } - } - }); - return orderedByArea; -} - -/** - * Returns an array of arrays of coordinates, each representing - * a set of (coordinates of) nested LinearRings, - * i.e. the first ring contains all the others - * - * @private - * @param {Array} orderedLinearRings array of coordinates (of LinearRings) in descending order by area - * @returns {Array} Array of coordinates of nested LinearRings - */ -function groupNestedRings(orderedLinearRings) { - // create a list of the (coordinates of) LinearRings - var lrList = orderedLinearRings.map(function (lr) { - return {lrCoordinates: lr, grouped: false}; - }); - var groupedLinearRingsCoords = []; - while (!allGrouped(lrList)) { - for (var i = 0; i < lrList.length; i++) { - if (!lrList[i].grouped) { - // create new group starting with the larger not already grouped ring - var group = []; - group.push(lrList[i].lrCoordinates); - lrList[i].grouped = true; - var outerMostPoly = polygon([lrList[i].lrCoordinates]); - // group all the rings contained by the outermost ring - for (var j = i + 1; j < lrList.length; j++) { - if (!lrList[j].grouped) { - var lrPoly = polygon([lrList[j].lrCoordinates]); - if (isInside(lrPoly, outerMostPoly)) { - group.push(lrList[j].lrCoordinates); - lrList[j].grouped = true; - } - } - } - // insert the new group - groupedLinearRingsCoords.push(group); - } - } - } - return groupedLinearRingsCoords; -} - -/** - * @private - * @param {Polygon} testPolygon polygon of interest - * @param {Polygon} targetPolygon polygon you want to compare with - * @returns {boolean} true if test-Polygon is inside target-Polygon - */ -function isInside(testPolygon, targetPolygon) { - var points = explode(testPolygon); - for (var i = 0; i < points.features.length; i++) { - if (!booleanPointInPolygon(points.features[i], targetPolygon)) { - return false; - } - } - return true; -} - -/** - * @private - * @param {Array} list list of objects which might contain the 'group' attribute - * @returns {boolean} true if all the objects in the list are marked as grouped - */ -function allGrouped(list) { - for (var i = 0; i < list.length; i++) { - if (list[i].grouped === false) { - return false; - } - } - return true; -} - -export default isobands; diff --git a/packages/turf-isobands/lib/grid-to-matrix.js b/packages/turf-isobands/lib/grid-to-matrix.js deleted file mode 100644 index 375a08ed7a..0000000000 --- a/packages/turf-isobands/lib/grid-to-matrix.js +++ /dev/null @@ -1,104 +0,0 @@ -import { getCoords, collectionOf } from '@turf/invariant'; -import { featureEach } from '@turf/meta'; -import { isObject } from '@turf/helpers'; - -/** - * Takes a {@link Point} grid and returns a correspondent matrix {Array>} - * of the 'property' values - * - * @name gridToMatrix - * @param {FeatureCollection} grid of points - * @param {Object} [options={}] Optional parameters - * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled - * @param {boolean} [options.flip=false] returns the matrix upside-down - * @param {boolean} [options.flags=false] flags, adding a `matrixPosition` array field ([row, column]) to its properties, - * the grid points with coordinates on the matrix - * @returns {Array>} matrix of property values - * @example - * var extent = [-70.823364, -33.553984, -70.473175, -33.302986]; - * var cellSize = 3; - * var grid = turf.pointGrid(extent, cellSize); - * // add a random property to each point between 0 and 60 - * for (var i = 0; i < grid.features.length; i++) { - * grid.features[i].properties.elevation = (Math.random() * 60); - * } - * gridToMatrix(grid); - * //= [ - * [ 1, 13, 10, 9, 10, 13, 18], - * [34, 8, 5, 4, 5, 8, 13], - * [10, 5, 2, 1, 2, 5, 4], - * [ 0, 4, 56, 19, 1, 4, 9], - * [10, 5, 2, 1, 2, 5, 10], - * [57, 8, 5, 4, 5, 0, 57], - * [ 3, 13, 10, 9, 5, 13, 18], - * [18, 13, 10, 9, 78, 13, 18] - * ] - */ -export default function gridToMatrix(grid, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var zProperty = options.zProperty || 'elevation'; - var flip = options.flip; - var flags = options.flags; - - // validation - collectionOf(grid, 'Point', 'input must contain Points'); - - var pointsMatrix = sortPointsByLatLng(grid, flip); - - var matrix = []; - // create property matrix from sorted points - // looping order matters here - for (var r = 0; r < pointsMatrix.length; r++) { - var pointRow = pointsMatrix[r]; - var row = []; - for (var c = 0; c < pointRow.length; c++) { - var point = pointRow[c]; - // Check if zProperty exist - if (point.properties[zProperty]) row.push(point.properties[zProperty]); - else row.push(0); - // add flags - if (flags === true) point.properties.matrixPosition = [r, c]; - } - matrix.push(row); - } - - return matrix; -} - -/** - * Sorts points by latitude and longitude, creating a 2-dimensional array of points - * - * @private - * @param {FeatureCollection} points GeoJSON Point features - * @param {boolean} [flip=false] returns the matrix upside-down - * @returns {Array>} points ordered by latitude and longitude - */ -function sortPointsByLatLng(points, flip) { - var pointsByLatitude = {}; - - // divide points by rows with the same latitude - featureEach(points, function (point) { - var lat = getCoords(point)[1]; - if (!pointsByLatitude[lat]) pointsByLatitude[lat] = []; - pointsByLatitude[lat].push(point); - }); - - // sort points (with the same latitude) by longitude - var orderedRowsByLatitude = Object.keys(pointsByLatitude).map(function (lat) { - var row = pointsByLatitude[lat]; - var rowOrderedByLongitude = row.sort(function (a, b) { - return getCoords(a)[0] - getCoords(b)[0]; - }); - return rowOrderedByLongitude; - }); - - // sort rows (of points with the same latitude) by latitude - var pointMatrix = orderedRowsByLatitude.sort(function (a, b) { - if (flip) return getCoords(a[0])[1] - getCoords(b[0])[1]; - else return getCoords(b[0])[1] - getCoords(a[0])[1]; - }); - - return pointMatrix; -} diff --git a/packages/turf-isobands/lib/matrix-to-grid.js b/packages/turf-isobands/lib/matrix-to-grid.js deleted file mode 100644 index e8b67bf26d..0000000000 --- a/packages/turf-isobands/lib/matrix-to-grid.js +++ /dev/null @@ -1,78 +0,0 @@ -import { isObject, featureCollection, point } from '@turf/helpers'; -import rhumbDestination from '@turf/rhumb-destination'; - -/** - * Takes a {@link Point} grid and returns a correspondent matrix {Array>} - * of the 'property' values - * - * @name matrixToGrid - * @param {Array>} matrix of numbers - * @param {Point|Array} origin position of the first bottom-left (South-West) point of the grid - * @param {number} cellSize the distance across each cell - * @param {Object} [options={}] optional parameters - * @param {string} [options.zProperty='elevation'] the grid points property name associated with the matrix value - * @param {Object} [options.properties={}] GeoJSON properties passed to all the points - * @param {string} [options.units='kilometers'] used in calculating cellSize, can be miles, or kilometers - * @returns {FeatureCollection} grid of points - * - * @example - * var matrixToGrid = require('matrix-to-grid'); - * var matrix = [ - * [ 1, 13, 20, 9, 10, 13, 18], - * [34, 8, 0, 4, 5, 8, 13], - * [10, 5, 2, 1, 2, 5, 24], - * [ 0, 4, 56, 19, 0, 4, 9], - * [10, 5, 2, 12, 2, 5, 10], - * [57, 8, 5, 4, 5, 0, 57], - * [ 3, 13, 0, 9, 5, 13, 35], - * [18, 13, 10, 9, 78, 13, 18] - * ]; - * var origin = [-70.823364, -33.553984] - * matrixToGrid(matrix, origin, 10); - * //= pointGrid - */ -export default function matrixToGrid(matrix, origin, cellSize, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var zProperty = options.zProperty || 'elevation'; - var properties = options.properties; - var units = options.units; - - // validation - if (!matrix || !Array.isArray(matrix)) throw new Error('matrix is required'); - if (!origin) throw new Error('origin is required'); - if (Array.isArray(origin)) { - origin = point(origin); // Convert coordinates array to point - } - // all matrix array have to be of the same size - var matrixCols = matrix[0].length; - var matrixRows = matrix.length; - for (var row = 1; row < matrixRows; row++) { - if (matrix[row].length !== matrixCols) throw new Error('matrix requires all rows of equal size'); - } - - var points = []; - for (var r = 0; r < matrixRows; r++) { - // create first point in the row - var first = rhumbDestination(origin, cellSize * r, 0, { units: units }); - first.properties[zProperty] = matrix[matrixRows - 1 - r][0]; - for (var prop in properties) { - first.properties[prop] = properties[prop]; - } - points.push(first); - for (var c = 1; c < matrixCols; c++) { - // create the other points in the same row - var pt = rhumbDestination(first, cellSize * c, 90, { units: units }); - for (var prop2 in properties) { - pt.properties[prop2] = properties[prop2]; - } - // add matrix property - var val = matrix[matrixRows - 1 - r][c]; - pt.properties[zProperty] = val; - points.push(pt); - } - } - var grid = featureCollection(points); - return grid; -} diff --git a/packages/turf-isobands/package.json b/packages/turf-isobands/package.json deleted file mode 100644 index 739b3f0bcf..0000000000 --- a/packages/turf-isobands/package.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "name": "@turf/isobands", - "version": "5.1.5", - "description": "turf isobands module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "lib", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "contours", - "isobands", - "elevation", - "topography", - "filled" - ], - "author": "Turf Authors", - "contributors": [ - "Stefano Borghi <@stebogit>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/envelope": "^5.1.5", - "@turf/point-grid": "6.x", - "@turf/random": "6.x", - "@turf/rhumb-destination": "6.x", - "@turf/truncate": "6.x", - "benchmark": "*", - "chroma-js": "*", - "load-json-file": "*", - "matrix-to-grid": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/area": "6.x", - "@turf/bbox": "6.x", - "@turf/boolean-point-in-polygon": "6.x", - "@turf/explode": "^5.1.5", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x", - "object-assign": "*" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-isobands/test.js b/packages/turf-isobands/test.js deleted file mode 100644 index a365994e98..0000000000 --- a/packages/turf-isobands/test.js +++ /dev/null @@ -1,61 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import envelope from '@turf/envelope'; -import pointGrid from '@turf/point-grid'; -import truncate from '@turf/truncate'; -import { getCoords } from '@turf/invariant'; -import { lineString } from '@turf/helpers'; -import { featureEach } from '@turf/meta'; -import { randomPolygon } from '@turf/random'; -import matrixToGrid from './lib/matrix-to-grid'; -import isobands from './'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - json: load.sync(directories.in + filename) - }; -}); - -test('isobands', t => { - fixtures.forEach(({name, json, filename}) => { - const options = json.properties || json - const { breaks, matrix, origin, cellSize } = options; - - // allow GeoJSON featureCollection or matrix - let points = json.properties ? json : matrixToGrid(matrix, origin, cellSize, options); - - // Results - const results = truncate(isobands(points, breaks, options)); - - // Add red line around point data - results.features.push(lineString(getCoords(envelope(points))[0], { - stroke: '#F00', - 'stroke-width': 1 - })); - - if (process.env.REGEN) write.sync(directories.out + name + '.geojson', results); - t.deepEqual(results, load.sync(directories.out + name + '.geojson'), name); - }); - - t.end(); -}); - -test('isobands -- throws', t => { - const points = pointGrid([-70.823364, -33.553984, -70.473175, -33.302986], 5); - - t.throws(() => isobands(randomPolygon(), [1, 2, 3]), 'invalid points'); - t.throws(() => isobands(points, ''), 'invalid breaks'); - t.throws(() => isobands(points, [1, 2, 3], {zProperty: 'temp', breaksProperties: 'hello' }), 'invalid options'); - - t.end(); -}); \ No newline at end of file diff --git a/packages/turf-isolines/LICENSE b/packages/turf-isolines/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-isolines/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-isolines/README.md b/packages/turf-isolines/README.md deleted file mode 100644 index f19bdbb27b..0000000000 --- a/packages/turf-isolines/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# @turf/isolines - - - -## isolines - -Takes a grid [FeatureCollection][1] of [Point][2] features with z-values and an array of -value breaks and generates [isolines][3]. - -**Parameters** - -- `pointGrid` **[FeatureCollection][4]<[Point][5]>** input points -- `breaks` **[Array][6]<[number][7]>** values of `zProperty` where to draw isolines -- `options` **[Object][8]** Optional parameters (optional, default `{}`) - - `options.zProperty` **[string][9]** the property name in `points` from which z-values will be pulled (optional, default `'elevation'`) - - `options.commonProperties` **[Object][8]** GeoJSON properties passed to ALL isolines (optional, default `{}`) - - `options.breaksProperties` **[Array][6]<[Object][8]>** GeoJSON properties passed, in order, to the correspondent isoline; - the breaks array will define the order in which the isolines are created (optional, default `[]`) - -**Examples** - -```javascript -// create a grid of points with random z-values in their properties -var extent = [0, 30, 20, 50]; -var cellWidth = 100; -var pointGrid = turf.pointGrid(extent, cellWidth, {units: 'miles'}); - -for (var i = 0; i < pointGrid.features.length; i++) { - pointGrid.features[i].properties.temperature = Math.random() * 10; -} -var breaks = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - -var lines = turf.isolines(pointGrid, breaks, {zProperty: 'temperature'}); - -//addToMap -var addToMap = [lines]; -``` - -Returns **[FeatureCollection][4]<[MultiLineString][10]>** a FeatureCollection of [MultiLineString][11] features representing isolines - -[1]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[3]: http://en.wikipedia.org/wiki/Isoline - -[4]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[10]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[11]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/isolines -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-isolines/index.d.ts b/packages/turf-isolines/index.d.ts deleted file mode 100644 index be49818c6a..0000000000 --- a/packages/turf-isolines/index.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Point, MultiLineString, FeatureCollection, Properties } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#isolines - */ -export default function isolines( - points: FeatureCollection, - breaks: number[], - options?: { - zProperty?: string, - commonProperties?: Properties, - breaksProperties?: Properties[] - } -): FeatureCollection; diff --git a/packages/turf-isolines/index.js b/packages/turf-isolines/index.js deleted file mode 100644 index 9168e12478..0000000000 --- a/packages/turf-isolines/index.js +++ /dev/null @@ -1,134 +0,0 @@ -import bbox from '@turf/bbox'; -import { coordEach } from '@turf/meta'; -import { collectionOf } from '@turf/invariant'; -import { multiLineString, featureCollection, isObject } from '@turf/helpers'; -import objectAssign from 'object-assign'; -import isoContours from './lib/marchingsquares-isocontours'; -import gridToMatrix from './lib/grid-to-matrix'; - -/** - * Takes a grid {@link FeatureCollection} of {@link Point} features with z-values and an array of - * value breaks and generates [isolines](http://en.wikipedia.org/wiki/Isoline). - * - * @name isolines - * @param {FeatureCollection} pointGrid input points - * @param {Array} breaks values of `zProperty` where to draw isolines - * @param {Object} [options={}] Optional parameters - * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled - * @param {Object} [options.commonProperties={}] GeoJSON properties passed to ALL isolines - * @param {Array} [options.breaksProperties=[]] GeoJSON properties passed, in order, to the correspondent isoline; - * the breaks array will define the order in which the isolines are created - * @returns {FeatureCollection} a FeatureCollection of {@link MultiLineString} features representing isolines - * @example - * // create a grid of points with random z-values in their properties - * var extent = [0, 30, 20, 50]; - * var cellWidth = 100; - * var pointGrid = turf.pointGrid(extent, cellWidth, {units: 'miles'}); - * - * for (var i = 0; i < pointGrid.features.length; i++) { - * pointGrid.features[i].properties.temperature = Math.random() * 10; - * } - * var breaks = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - * - * var lines = turf.isolines(pointGrid, breaks, {zProperty: 'temperature'}); - * - * //addToMap - * var addToMap = [lines]; - */ -function isolines(pointGrid, breaks, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var zProperty = options.zProperty || 'elevation'; - var commonProperties = options.commonProperties || {}; - var breaksProperties = options.breaksProperties || []; - - // Input validation - collectionOf(pointGrid, 'Point', 'Input must contain Points'); - if (!breaks) throw new Error('breaks is required'); - if (!Array.isArray(breaks)) throw new Error('breaks must be an Array'); - if (!isObject(commonProperties)) throw new Error('commonProperties must be an Object'); - if (!Array.isArray(breaksProperties)) throw new Error('breaksProperties must be an Array'); - - // Isoline methods - var matrix = gridToMatrix(pointGrid, {zProperty: zProperty, flip: true}); - var createdIsoLines = createIsoLines(matrix, breaks, zProperty, commonProperties, breaksProperties); - var scaledIsolines = rescaleIsolines(createdIsoLines, matrix, pointGrid); - - return featureCollection(scaledIsolines); -} - -/** - * Creates the isolines lines (featuresCollection of MultiLineString features) from the 2D data grid - * - * Marchingsquares process the grid data as a 3D representation of a function on a 2D plane, therefore it - * assumes the points (x-y coordinates) are one 'unit' distance. The result of the isolines function needs to be - * rescaled, with turfjs, to the original area and proportions on the map - * - * @private - * @param {Array>} matrix Grid Data - * @param {Array} breaks Breaks - * @param {string} zProperty name of the z-values property - * @param {Object} [commonProperties={}] GeoJSON properties passed to ALL isolines - * @param {Object} [breaksProperties=[]] GeoJSON properties passed to the correspondent isoline - * @returns {Array} isolines - */ -function createIsoLines(matrix, breaks, zProperty, commonProperties, breaksProperties) { - var results = []; - for (var i = 1; i < breaks.length; i++) { - var threshold = +breaks[i]; // make sure it's a number - - var properties = objectAssign( - {}, - commonProperties, - breaksProperties[i] - ); - properties[zProperty] = threshold; - var isoline = multiLineString(isoContours(matrix, threshold), properties); - - results.push(isoline); - } - return results; -} - -/** - * Translates and scales isolines - * - * @private - * @param {Array} createdIsoLines to be rescaled - * @param {Array>} matrix Grid Data - * @param {Object} points Points by Latitude - * @returns {Array} isolines - */ -function rescaleIsolines(createdIsoLines, matrix, points) { - - // get dimensions (on the map) of the original grid - var gridBbox = bbox(points); // [ minX, minY, maxX, maxY ] - var originalWidth = gridBbox[2] - gridBbox[0]; - var originalHeigth = gridBbox[3] - gridBbox[1]; - - // get origin, which is the first point of the last row on the rectangular data on the map - var x0 = gridBbox[0]; - var y0 = gridBbox[1]; - - // get number of cells per side - var matrixWidth = matrix[0].length - 1; - var matrixHeight = matrix.length - 1; - - // calculate the scaling factor between matrix and rectangular grid on the map - var scaleX = originalWidth / matrixWidth; - var scaleY = originalHeigth / matrixHeight; - - var resize = function (point) { - point[0] = point[0] * scaleX + x0; - point[1] = point[1] * scaleY + y0; - }; - - // resize and shift each point/line of the createdIsoLines - createdIsoLines.forEach(function (isoline) { - coordEach(isoline, resize); - }); - return createdIsoLines; -} - -export default isolines; diff --git a/packages/turf-isolines/lib/grid-to-matrix.js b/packages/turf-isolines/lib/grid-to-matrix.js deleted file mode 100644 index 375a08ed7a..0000000000 --- a/packages/turf-isolines/lib/grid-to-matrix.js +++ /dev/null @@ -1,104 +0,0 @@ -import { getCoords, collectionOf } from '@turf/invariant'; -import { featureEach } from '@turf/meta'; -import { isObject } from '@turf/helpers'; - -/** - * Takes a {@link Point} grid and returns a correspondent matrix {Array>} - * of the 'property' values - * - * @name gridToMatrix - * @param {FeatureCollection} grid of points - * @param {Object} [options={}] Optional parameters - * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled - * @param {boolean} [options.flip=false] returns the matrix upside-down - * @param {boolean} [options.flags=false] flags, adding a `matrixPosition` array field ([row, column]) to its properties, - * the grid points with coordinates on the matrix - * @returns {Array>} matrix of property values - * @example - * var extent = [-70.823364, -33.553984, -70.473175, -33.302986]; - * var cellSize = 3; - * var grid = turf.pointGrid(extent, cellSize); - * // add a random property to each point between 0 and 60 - * for (var i = 0; i < grid.features.length; i++) { - * grid.features[i].properties.elevation = (Math.random() * 60); - * } - * gridToMatrix(grid); - * //= [ - * [ 1, 13, 10, 9, 10, 13, 18], - * [34, 8, 5, 4, 5, 8, 13], - * [10, 5, 2, 1, 2, 5, 4], - * [ 0, 4, 56, 19, 1, 4, 9], - * [10, 5, 2, 1, 2, 5, 10], - * [57, 8, 5, 4, 5, 0, 57], - * [ 3, 13, 10, 9, 5, 13, 18], - * [18, 13, 10, 9, 78, 13, 18] - * ] - */ -export default function gridToMatrix(grid, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var zProperty = options.zProperty || 'elevation'; - var flip = options.flip; - var flags = options.flags; - - // validation - collectionOf(grid, 'Point', 'input must contain Points'); - - var pointsMatrix = sortPointsByLatLng(grid, flip); - - var matrix = []; - // create property matrix from sorted points - // looping order matters here - for (var r = 0; r < pointsMatrix.length; r++) { - var pointRow = pointsMatrix[r]; - var row = []; - for (var c = 0; c < pointRow.length; c++) { - var point = pointRow[c]; - // Check if zProperty exist - if (point.properties[zProperty]) row.push(point.properties[zProperty]); - else row.push(0); - // add flags - if (flags === true) point.properties.matrixPosition = [r, c]; - } - matrix.push(row); - } - - return matrix; -} - -/** - * Sorts points by latitude and longitude, creating a 2-dimensional array of points - * - * @private - * @param {FeatureCollection} points GeoJSON Point features - * @param {boolean} [flip=false] returns the matrix upside-down - * @returns {Array>} points ordered by latitude and longitude - */ -function sortPointsByLatLng(points, flip) { - var pointsByLatitude = {}; - - // divide points by rows with the same latitude - featureEach(points, function (point) { - var lat = getCoords(point)[1]; - if (!pointsByLatitude[lat]) pointsByLatitude[lat] = []; - pointsByLatitude[lat].push(point); - }); - - // sort points (with the same latitude) by longitude - var orderedRowsByLatitude = Object.keys(pointsByLatitude).map(function (lat) { - var row = pointsByLatitude[lat]; - var rowOrderedByLongitude = row.sort(function (a, b) { - return getCoords(a)[0] - getCoords(b)[0]; - }); - return rowOrderedByLongitude; - }); - - // sort rows (of points with the same latitude) by latitude - var pointMatrix = orderedRowsByLatitude.sort(function (a, b) { - if (flip) return getCoords(a[0])[1] - getCoords(b[0])[1]; - else return getCoords(b[0])[1] - getCoords(a[0])[1]; - }); - - return pointMatrix; -} diff --git a/packages/turf-isolines/lib/matrix-to-grid.js b/packages/turf-isolines/lib/matrix-to-grid.js deleted file mode 100644 index e8b67bf26d..0000000000 --- a/packages/turf-isolines/lib/matrix-to-grid.js +++ /dev/null @@ -1,78 +0,0 @@ -import { isObject, featureCollection, point } from '@turf/helpers'; -import rhumbDestination from '@turf/rhumb-destination'; - -/** - * Takes a {@link Point} grid and returns a correspondent matrix {Array>} - * of the 'property' values - * - * @name matrixToGrid - * @param {Array>} matrix of numbers - * @param {Point|Array} origin position of the first bottom-left (South-West) point of the grid - * @param {number} cellSize the distance across each cell - * @param {Object} [options={}] optional parameters - * @param {string} [options.zProperty='elevation'] the grid points property name associated with the matrix value - * @param {Object} [options.properties={}] GeoJSON properties passed to all the points - * @param {string} [options.units='kilometers'] used in calculating cellSize, can be miles, or kilometers - * @returns {FeatureCollection} grid of points - * - * @example - * var matrixToGrid = require('matrix-to-grid'); - * var matrix = [ - * [ 1, 13, 20, 9, 10, 13, 18], - * [34, 8, 0, 4, 5, 8, 13], - * [10, 5, 2, 1, 2, 5, 24], - * [ 0, 4, 56, 19, 0, 4, 9], - * [10, 5, 2, 12, 2, 5, 10], - * [57, 8, 5, 4, 5, 0, 57], - * [ 3, 13, 0, 9, 5, 13, 35], - * [18, 13, 10, 9, 78, 13, 18] - * ]; - * var origin = [-70.823364, -33.553984] - * matrixToGrid(matrix, origin, 10); - * //= pointGrid - */ -export default function matrixToGrid(matrix, origin, cellSize, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var zProperty = options.zProperty || 'elevation'; - var properties = options.properties; - var units = options.units; - - // validation - if (!matrix || !Array.isArray(matrix)) throw new Error('matrix is required'); - if (!origin) throw new Error('origin is required'); - if (Array.isArray(origin)) { - origin = point(origin); // Convert coordinates array to point - } - // all matrix array have to be of the same size - var matrixCols = matrix[0].length; - var matrixRows = matrix.length; - for (var row = 1; row < matrixRows; row++) { - if (matrix[row].length !== matrixCols) throw new Error('matrix requires all rows of equal size'); - } - - var points = []; - for (var r = 0; r < matrixRows; r++) { - // create first point in the row - var first = rhumbDestination(origin, cellSize * r, 0, { units: units }); - first.properties[zProperty] = matrix[matrixRows - 1 - r][0]; - for (var prop in properties) { - first.properties[prop] = properties[prop]; - } - points.push(first); - for (var c = 1; c < matrixCols; c++) { - // create the other points in the same row - var pt = rhumbDestination(first, cellSize * c, 90, { units: units }); - for (var prop2 in properties) { - pt.properties[prop2] = properties[prop2]; - } - // add matrix property - var val = matrix[matrixRows - 1 - r][c]; - pt.properties[zProperty] = val; - points.push(pt); - } - } - var grid = featureCollection(points); - return grid; -} diff --git a/packages/turf-isolines/package.json b/packages/turf-isolines/package.json deleted file mode 100644 index 2abdabb0a4..0000000000 --- a/packages/turf-isolines/package.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "@turf/isolines", - "version": "5.1.5", - "description": "turf isolines module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "lib", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "isolines", - "contours", - "elevation", - "topography" - ], - "author": "Turf Authors", - "contributors": [ - "Stefano Borghi <@stebogit>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "0.21.x", - "@turf/envelope": "^5.1.5", - "@turf/point-grid": "6.x", - "@turf/random": "6.x", - "@turf/rhumb-destination": "6.x", - "@turf/truncate": "6.x", - "benchmark": "*", - "load-json-file": "*", - "matrix-to-grid": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x", - "object-assign": "*" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-isolines/test.js b/packages/turf-isolines/test.js deleted file mode 100644 index 12463c882f..0000000000 --- a/packages/turf-isolines/test.js +++ /dev/null @@ -1,79 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import envelope from '@turf/envelope'; -import truncate from '@turf/truncate'; -import pointGrid from '@turf/point-grid'; -import { getCoords } from '@turf/invariant'; -import { randomPolygon } from '@turf/random'; -import { lineString, polygon } from '@turf/helpers'; -import matrixToGrid from './lib/matrix-to-grid'; -import isolines from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - json: load.sync(directories.in + filename) - }; -}); - -test('isolines', t => { - fixtures.forEach(({name, json, filename}) => { - const options = json.properties || json; - const { breaks, matrix, cellSize, origin} = options; - - // allow GeoJSON featureCollection or matrix - let points = json.properties ? json : matrixToGrid(matrix, origin, cellSize, options); - - // Results - const results = truncate(isolines(points, breaks, options)); - - // Add red line around point data - results.features.push(lineString(getCoords(envelope(points))[0], { - stroke: '#F00', - 'stroke-width': 1 - })); - - if (process.env.REGEN) write.sync(directories.out + name + '.geojson', results); - t.deepEqual(results, load.sync(directories.out + name + '.geojson'), name); - }); - - t.end(); -}); - -test('isolines -- throws', t => { - const points = pointGrid([-70.823364, -33.553984, -70.473175, -33.302986], 5); - - t.throws(() => isolines(randomPolygon()), 'invalid points'); - t.throws(() => isolines(points), /breaks is required/); - t.throws(() => isolines(points, 'string'), /breaks must be an Array/); - t.throws(() => isolines(points, [1, 2, 3], {commonProperties: 'foo'}), /commonProperties must be an Object/); - t.throws(() => isolines(points, [1, 2, 3], {breaksProperties: 'foo'}), /breaksProperties must be an Array/); - - // Updated tests since Turf 5.0 - t.assert(isolines(points, [1, 2, 3], {zProperty: 5}), 'zProperty can be a string'); - t.end(); -}); - -test('isolines -- handling properties', t => { - const points = pointGrid([-70.823364, -33.553984, -70.473175, -33.302986], 5); - const commonProperties = {name: 'unknown', source: 'foobar'}; - const breaksProperties = [{name: 'break1'}, {name: 'break2'}, {name: 'break3'}]; - - const lines = isolines(points, [1, 2, 3], { - zProperty: 'z', - commonProperties: commonProperties, - breaksProperties: breaksProperties - }); - t.equal(lines.features[0].properties.name, 'break2'); - t.equal(lines.features[0].properties.source, 'foobar'); - t.end(); -}); diff --git a/packages/turf-isolines/types.ts b/packages/turf-isolines/types.ts deleted file mode 100644 index 4a807195ed..0000000000 --- a/packages/turf-isolines/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { randomPoint } from '@turf/random' -import isolines from './' - -const points = randomPoint(100, { - bbox: [0, 30, 20, 50] -}) -for (let i = 0; i < points.features.length; i++) { - points.features[i].properties.z = Math.random() * 10; -} -const breaks = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] -const lines = isolines(points, breaks, {zProperty: 'temperature'}) -const properties = {apply: 'all'} - -// Properties option -isolines(points, breaks, {zProperty: 'temperature', commonProperties: properties}) -isolines(points, breaks, {zProperty: 'temperature', commonProperties: properties, breaksProperties: [{name: 'break1'}, {name: 'break2'}]}) diff --git a/packages/turf-kinks/.gitignore b/packages/turf-kinks/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-kinks/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-kinks/LICENSE b/packages/turf-kinks/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-kinks/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-kinks/README.md b/packages/turf-kinks/README.md deleted file mode 100644 index 28b489837d..0000000000 --- a/packages/turf-kinks/README.md +++ /dev/null @@ -1,79 +0,0 @@ -# @turf/kinks - - - -## kinks - -Takes a [linestring][1], [multi-linestring][2], [multi-polygon][3], or [polygon][4] and returns [points][5] at all self-intersections. - -**Parameters** - -- `featureIn` **[Feature][6]<([LineString][7] \| [MultiLineString][8] \| [MultiPolygon][9] \| [Polygon][10])>** input feature - -**Examples** - -```javascript -var poly = turf.polygon([[ - [-12.034835, 8.901183], - [-12.060413, 8.899826], - [-12.03638, 8.873199], - [-12.059383, 8.871418], - [-12.034835, 8.901183] -]]); - -var kinks = turf.kinks(poly); - -//addToMap -var addToMap = [poly, kinks] -``` - -Returns **[FeatureCollection][11]<[Point][12]>** self-intersections - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[8]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[9]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[10]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[11]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[12]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/kinks -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-kinks/index.d.ts b/packages/turf-kinks/index.d.ts deleted file mode 100644 index f9dfe266f0..0000000000 --- a/packages/turf-kinks/index.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Feature, FeatureCollection, LineString, MultiLineString, MultiPolygon, Point, Polygon } from "@turf/helpers"; -/** - * Takes a {@link LineString|linestring}, {@link MultiLineString|multi-linestring}, - * {@link MultiPolygon|multi-polygon} or {@link Polygon|polygon} and - * returns {@link Point|points} at all self-intersections. - * - * @name kinks - * @param {Feature} featureIn input feature - * @returns {FeatureCollection} self-intersections - * @example - * var poly = turf.polygon([[ - * [-12.034835, 8.901183], - * [-12.060413, 8.899826], - * [-12.03638, 8.873199], - * [-12.059383, 8.871418], - * [-12.034835, 8.901183] - * ]]); - * - * var kinks = turf.kinks(poly); - * - * //addToMap - * var addToMap = [poly, kinks] - */ -export default function kinks(featureIn: Feature | T): FeatureCollection; diff --git a/packages/turf-kinks/index.ts b/packages/turf-kinks/index.ts deleted file mode 100644 index dfe1f8954e..0000000000 --- a/packages/turf-kinks/index.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { point } from "@turf/helpers"; -import { - Feature, - FeatureCollection, - LineString, - MultiLineString, - MultiPolygon, - Point, - Polygon, -} from "@turf/helpers"; - -/** - * Takes a {@link LineString|linestring}, {@link MultiLineString|multi-linestring}, - * {@link MultiPolygon|multi-polygon} or {@link Polygon|polygon} and - * returns {@link Point|points} at all self-intersections. - * - * @name kinks - * @param {Feature} featureIn input feature - * @returns {FeatureCollection} self-intersections - * @example - * var poly = turf.polygon([[ - * [-12.034835, 8.901183], - * [-12.060413, 8.899826], - * [-12.03638, 8.873199], - * [-12.059383, 8.871418], - * [-12.034835, 8.901183] - * ]]); - * - * var kinks = turf.kinks(poly); - * - * //addToMap - * var addToMap = [poly, kinks] - */ -export default function kinks( - featureIn: Feature | T, -): FeatureCollection { - let coordinates: any; - let feature: any; - const results: FeatureCollection = { - type: "FeatureCollection", - features: [], - }; - if (featureIn.type === "Feature") { - feature = featureIn.geometry; - } else { - feature = featureIn; - } - if (feature.type === "LineString") { - coordinates = [feature.coordinates]; - } else if (feature.type === "MultiLineString") { - coordinates = feature.coordinates; - } else if (feature.type === "MultiPolygon") { - coordinates = [].concat.apply([], feature.coordinates); - } else if (feature.type === "Polygon") { - coordinates = feature.coordinates; - } else { - throw new Error("Input must be a LineString, MultiLineString, " + - "Polygon, or MultiPolygon Feature or Geometry"); - } - coordinates.forEach((line1: any) => { - coordinates.forEach((line2: any) => { - for (let i = 0; i < line1.length - 1; i++) { - // start iteration at i, intersections for k < i have already - // been checked in previous outer loop iterations - for (let k = i; k < line2.length - 1; k++) { - if (line1 === line2) { - // segments are adjacent and always share a vertex, not a kink - if (Math.abs(i - k) === 1) { - continue; - } - // first and last segment in a closed lineString or ring always share a vertex, not a kink - if ( - // segments are first and last segment of lineString - i === 0 && - k === line1.length - 2 && - // lineString is closed - line1[i][0] === line1[line1.length - 1][0] && - line1[i][1] === line1[line1.length - 1][1] - ) { - continue; - } - } - - const intersection: any = lineIntersects(line1[i][0], line1[i][1], line1[i + 1][0], line1[i + 1][1], - line2[k][0], line2[k][1], line2[k + 1][0], line2[k + 1][1]); - if (intersection) { - results.features.push(point([intersection[0], intersection[1]])); - } - } - } - }); - }); - return results; -} - -// modified from http://jsfiddle.net/justin_c_rounds/Gd2S2/light/ -function lineIntersects( - line1StartX: any, - line1StartY: any, - line1EndX: any, - line1EndY: any, - line2StartX: any, - line2StartY: any, - line2EndX: any, - line2EndY: any) { - // if the lines intersect, the result contains the x and y of the - // intersection (treating the lines as infinite) and booleans for whether - // line segment 1 or line segment 2 contain the point - let denominator; - let a; - let b; - let numerator1; - let numerator2; - const result = { - x: null, - y: null, - onLine1: false, - onLine2: false, - }; - denominator = ((line2EndY - line2StartY) * (line1EndX - line1StartX)) - ((line2EndX - line2StartX) * (line1EndY - line1StartY)); - if (denominator === 0) { - if (result.x !== null && result.y !== null) { - return result; - } else { - return false; - } - } - a = line1StartY - line2StartY; - b = line1StartX - line2StartX; - numerator1 = ((line2EndX - line2StartX) * a) - ((line2EndY - line2StartY) * b); - numerator2 = ((line1EndX - line1StartX) * a) - ((line1EndY - line1StartY) * b); - a = numerator1 / denominator; - b = numerator2 / denominator; - - // if we cast these lines infinitely in both directions, they intersect here: - result.x = line1StartX + (a * (line1EndX - line1StartX)); - result.y = line1StartY + (a * (line1EndY - line1StartY)); - - // if line1 is a segment and line2 is infinite, they intersect if: - if (a >= 0 && a <= 1) { - result.onLine1 = true; - } - // if line2 is a segment and line1 is infinite, they intersect if: - if (b >= 0 && b <= 1) { - result.onLine2 = true; - } - // if line1 and line2 are segments, they intersect if both of the above are true - if (result.onLine1 && result.onLine2) { - return [result.x, result.y]; - } else { - return false; - } -} diff --git a/packages/turf-kinks/package.json b/packages/turf-kinks/package.json deleted file mode 100644 index 745b23135a..0000000000 --- a/packages/turf-kinks/package.json +++ /dev/null @@ -1,45 +0,0 @@ - -{ - "name": "@turf/kinks", - "version": "6.0.0", - "description": "turf kinks module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "kinks", - "self-intersection" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/meta": "*", - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/helpers": "6.x" - } -} diff --git a/packages/turf-kinks/test.js b/packages/turf-kinks/test.js deleted file mode 100644 index 4a61f0986d..0000000000 --- a/packages/turf-kinks/test.js +++ /dev/null @@ -1,31 +0,0 @@ -const test = require('tape'); -const fs = require('fs'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { featureEach } = require('@turf/meta'); -const kinks = require('.').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-kinks', t => { - for (const {name, filename, geojson} of fixtures) { - const results = kinks(geojson); - featureEach(geojson, feature => results.features.push(feature)); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEqual(results, load.sync(directories.out + filename), name); - } - t.end(); -}); diff --git a/packages/turf-kinks/tsconfig.json b/packages/turf-kinks/tsconfig.json deleted file mode 100644 index 91cffcbf55..0000000000 --- a/packages/turf-kinks/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - }, - "files": [ - "index.ts" - ] -} \ No newline at end of file diff --git a/packages/turf-kinks/tslint.json b/packages/turf-kinks/tslint.json deleted file mode 100644 index a54537158a..0000000000 --- a/packages/turf-kinks/tslint.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": { - "object-literal-sort-keys": false, - "max-line-length": false - }, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-kinks/types.ts b/packages/turf-kinks/types.ts deleted file mode 100644 index 67982052e6..0000000000 --- a/packages/turf-kinks/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {polygon} from '@turf/helpers' -import kinks from './' - -const hourglass = polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]); -kinks(hourglass) diff --git a/packages/turf-length/.gitignore b/packages/turf-length/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-length/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-length/LICENSE b/packages/turf-length/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-length/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-length/README.md b/packages/turf-length/README.md deleted file mode 100644 index f1f4bcd874..0000000000 --- a/packages/turf-length/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# @turf/length - - - -## length - -Takes a [GeoJSON][1] and measures its length in the specified units, [(Multi)Point][2]'s distance are ignored. - -**Parameters** - -- `geojson` **[Feature][3]<([LineString][4] \| [MultiLineString][5])>** GeoJSON to measure -- `options` **[Object][6]** Optional parameters (optional, default `{}`) - - `options.units` **[string][7]** can be degrees, radians, miles, or kilometers (optional, default `kilometers`) - -**Examples** - -```javascript -var line = turf.lineString([[115, -32], [131, -22], [143, -25], [150, -34]]); -var length = turf.length(line, {units: 'miles'}); - -//addToMap -var addToMap = [line]; -line.properties.distance = length; -``` - -Returns **[number][8]** length of GeoJSON - -[1]: https://tools.ietf.org/html/rfc7946#section-3 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/length -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-length/index.d.ts b/packages/turf-length/index.d.ts deleted file mode 100644 index 8dff74bfb9..0000000000 --- a/packages/turf-length/index.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Feature, FeatureCollection, GeometryCollection, Units } from "@turf/helpers"; -/** - * Takes a {@link GeoJSON} and measures its length in the specified units, {@link (Multi)Point}'s distance are ignored. - * - * @name length - * @param {Feature} geojson GeoJSON to measure - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units=kilometers] can be degrees, radians, miles, or kilometers - * @returns {number} length of GeoJSON - * @example - * var line = turf.lineString([[115, -32], [131, -22], [143, -25], [150, -34]]); - * var length = turf.length(line, {units: 'miles'}); - * - * //addToMap - * var addToMap = [line]; - * line.properties.distance = length; - */ -export default function length(geojson: Feature | FeatureCollection | GeometryCollection, options?: { - units?: Units; -}): number; diff --git a/packages/turf-length/index.ts b/packages/turf-length/index.ts deleted file mode 100644 index 17fda9dfdd..0000000000 --- a/packages/turf-length/index.ts +++ /dev/null @@ -1,29 +0,0 @@ -import distance from "@turf/distance"; -import { Feature, FeatureCollection, GeometryCollection, LineString, MultiLineString, Units } from "@turf/helpers"; -import { segmentReduce } from "@turf/meta"; - -/** - * Takes a {@link GeoJSON} and measures its length in the specified units, {@link (Multi)Point}'s distance are ignored. - * - * @name length - * @param {Feature} geojson GeoJSON to measure - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units=kilometers] can be degrees, radians, miles, or kilometers - * @returns {number} length of GeoJSON - * @example - * var line = turf.lineString([[115, -32], [131, -22], [143, -25], [150, -34]]); - * var length = turf.length(line, {units: 'miles'}); - * - * //addToMap - * var addToMap = [line]; - * line.properties.distance = length; - */ -export default function length(geojson: Feature | FeatureCollection | GeometryCollection, options: { - units?: Units, -} = {}): number { - // Calculate distance from 2-vertex line segments - return segmentReduce(geojson, (previousValue, segment) => { - const coords = segment!.geometry.coordinates; - return previousValue! + distance(coords[0], coords[1], options); - }, 0); -} diff --git a/packages/turf-length/package.json b/packages/turf-length/package.json deleted file mode 100644 index c16bb32fa3..0000000000 --- a/packages/turf-length/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@turf/length", - "version": "6.0.2", - "description": "turf length module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "linestring", - "length", - "distance", - "units", - "gis" - ], - "author": "Turf Authors", - "contributors": [ - "Denis Carriere <@DenisCarriere>", - "Tom MacWright <@tmcw>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/distance": "6.x", - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-length/tsconfig.json b/packages/turf-length/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-length/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-length/tslint.json b/packages/turf-length/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-length/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-line-arc/.gitignore b/packages/turf-line-arc/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-line-arc/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-line-arc/LICENSE b/packages/turf-line-arc/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-line-arc/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-line-arc/README.md b/packages/turf-line-arc/README.md deleted file mode 100644 index c393d82432..0000000000 --- a/packages/turf-line-arc/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# @turf/line-arc - - - -## lineArc - -Creates a circular arc, of a circle of the given radius and center point, between bearing1 and bearing2; -0 bearing is North of center point, positive clockwise. - -**Parameters** - -- `center` **[Coord][1]** center point -- `radius` **[number][2]** radius of the circle -- `bearing1` **[number][2]** angle, in decimal degrees, of the first radius of the arc -- `bearing2` **[number][2]** angle, in decimal degrees, of the second radius of the arc -- `options` **[Object][3]** Optional parameters (optional, default `{}`) - - `options.steps` **[number][2]** number of steps (optional, default `64`) - - `options.units` **[string][4]** miles, kilometers, degrees, or radians (optional, default `'kilometers'`) - -**Examples** - -```javascript -var center = turf.point([-75, 40]); -var radius = 5; -var bearing1 = 25; -var bearing2 = 47; - -var arc = turf.lineArc(center, radius, bearing1, bearing2); - -//addToMap -var addToMap = [center, arc] -``` - -Returns **[Feature][5]<[LineString][6]>** line arc - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[5]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/line-arc -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-line-arc/index.d.ts b/packages/turf-line-arc/index.d.ts deleted file mode 100644 index 043ce697e2..0000000000 --- a/packages/turf-line-arc/index.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Coord, Feature, LineString, Units } from "@turf/helpers"; -/** - * Creates a circular arc, of a circle of the given radius and center point, between bearing1 and bearing2; - * 0 bearing is North of center point, positive clockwise. - * - * @name lineArc - * @param {Coord} center center point - * @param {number} radius radius of the circle - * @param {number} bearing1 angle, in decimal degrees, of the first radius of the arc - * @param {number} bearing2 angle, in decimal degrees, of the second radius of the arc - * @param {Object} [options={}] Optional parameters - * @param {number} [options.steps=64] number of steps - * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians - * @returns {Feature} line arc - * @example - * var center = turf.point([-75, 40]); - * var radius = 5; - * var bearing1 = 25; - * var bearing2 = 47; - * - * var arc = turf.lineArc(center, radius, bearing1, bearing2); - * - * //addToMap - * var addToMap = [center, arc] - */ -export default function lineArc(center: Coord, radius: number, bearing1: number, bearing2: number, options?: { - steps?: number; - units?: Units; -}): Feature; diff --git a/packages/turf-line-arc/index.js b/packages/turf-line-arc/index.js deleted file mode 100644 index a0a020a9e3..0000000000 --- a/packages/turf-line-arc/index.js +++ /dev/null @@ -1,74 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -var circle_1 = __importDefault(require("@turf/circle")); -var destination_1 = __importDefault(require("@turf/destination")); -var helpers_1 = require("@turf/helpers"); -/** - * Creates a circular arc, of a circle of the given radius and center point, between bearing1 and bearing2; - * 0 bearing is North of center point, positive clockwise. - * - * @name lineArc - * @param {Coord} center center point - * @param {number} radius radius of the circle - * @param {number} bearing1 angle, in decimal degrees, of the first radius of the arc - * @param {number} bearing2 angle, in decimal degrees, of the second radius of the arc - * @param {Object} [options={}] Optional parameters - * @param {number} [options.steps=64] number of steps - * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians - * @returns {Feature} line arc - * @example - * var center = turf.point([-75, 40]); - * var radius = 5; - * var bearing1 = 25; - * var bearing2 = 47; - * - * var arc = turf.lineArc(center, radius, bearing1, bearing2); - * - * //addToMap - * var addToMap = [center, arc] - */ -function lineArc(center, radius, bearing1, bearing2, options) { - if (options === void 0) { options = {}; } - // default params - var steps = options.steps || 64; - var angle1 = convertAngleTo360(bearing1); - var angle2 = convertAngleTo360(bearing2); - var properties = (!Array.isArray(center) && center.type === "Feature") ? center.properties : {}; - // handle angle parameters - if (angle1 === angle2) { - return helpers_1.lineString(circle_1.default(center, radius, options).geometry.coordinates[0], properties); - } - var arcStartDegree = angle1; - var arcEndDegree = (angle1 < angle2) ? angle2 : angle2 + 360; - var alfa = arcStartDegree; - var coordinates = []; - var i = 0; - while (alfa < arcEndDegree) { - coordinates.push(destination_1.default(center, radius, alfa, options).geometry.coordinates); - i++; - alfa = arcStartDegree + i * 360 / steps; - } - if (alfa > arcEndDegree) { - coordinates.push(destination_1.default(center, radius, arcEndDegree, options).geometry.coordinates); - } - return helpers_1.lineString(coordinates, properties); -} -exports.default = lineArc; -/** - * Takes any angle in degrees - * and returns a valid angle between 0-360 degrees - * - * @private - * @param {number} alfa angle between -180-180 degrees - * @returns {number} angle between 0-360 degrees - */ -function convertAngleTo360(alfa) { - var beta = alfa % 360; - if (beta < 0) { - beta += 360; - } - return beta; -} diff --git a/packages/turf-line-arc/index.ts b/packages/turf-line-arc/index.ts deleted file mode 100644 index 683a70463a..0000000000 --- a/packages/turf-line-arc/index.ts +++ /dev/null @@ -1,76 +0,0 @@ -import circle from "@turf/circle"; -import destination from "@turf/destination"; -import { Coord, Feature, isObject, lineString, LineString, Units } from "@turf/helpers"; - -/** - * Creates a circular arc, of a circle of the given radius and center point, between bearing1 and bearing2; - * 0 bearing is North of center point, positive clockwise. - * - * @name lineArc - * @param {Coord} center center point - * @param {number} radius radius of the circle - * @param {number} bearing1 angle, in decimal degrees, of the first radius of the arc - * @param {number} bearing2 angle, in decimal degrees, of the second radius of the arc - * @param {Object} [options={}] Optional parameters - * @param {number} [options.steps=64] number of steps - * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians - * @returns {Feature} line arc - * @example - * var center = turf.point([-75, 40]); - * var radius = 5; - * var bearing1 = 25; - * var bearing2 = 47; - * - * var arc = turf.lineArc(center, radius, bearing1, bearing2); - * - * //addToMap - * var addToMap = [center, arc] - */ -export default function lineArc(center: Coord, radius: number, bearing1: number, bearing2: number, options: { - steps?: number, - units?: Units, -} = {}): Feature { - // default params - const steps = options.steps || 64; - - const angle1 = convertAngleTo360(bearing1); - const angle2 = convertAngleTo360(bearing2); - const properties = (!Array.isArray(center) && center.type === "Feature") ? center.properties : {}; - - // handle angle parameters - if (angle1 === angle2) { - return lineString(circle(center, radius, options).geometry.coordinates[0], properties); - } - const arcStartDegree = angle1; - const arcEndDegree = (angle1 < angle2) ? angle2 : angle2 + 360; - - let alfa = arcStartDegree; - const coordinates = []; - let i = 0; - - while (alfa < arcEndDegree) { - coordinates.push(destination(center, radius, alfa, options).geometry.coordinates); - i++; - alfa = arcStartDegree + i * 360 / steps; - } - if (alfa > arcEndDegree) { - coordinates.push(destination(center, radius, arcEndDegree, options).geometry.coordinates); - } - return lineString(coordinates, properties); -} - -/** - * Takes any angle in degrees - * and returns a valid angle between 0-360 degrees - * - * @private - * @param {number} alfa angle between -180-180 degrees - * @returns {number} angle between 0-360 degrees - */ -function convertAngleTo360(alfa: number) { - let beta = alfa % 360; - if (beta < 0) { - beta += 360; - } - return beta; -} diff --git a/packages/turf-line-arc/package.json b/packages/turf-line-arc/package.json deleted file mode 100644 index b9949743b1..0000000000 --- a/packages/turf-line-arc/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "@turf/line-arc", - "version": "6.0.0", - "description": "turf line-arc module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gif" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/truncate": "*", - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/circle": "6.x", - "@turf/destination": "6.x", - "@turf/helpers": "6.x" - } -} diff --git a/packages/turf-line-arc/test.js b/packages/turf-line-arc/test.js deleted file mode 100644 index 8d1015f474..0000000000 --- a/packages/turf-line-arc/test.js +++ /dev/null @@ -1,33 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const truncate = require('@turf/truncate').default; -const { featureCollection } = require('@turf/helpers'); -const lineArc = require('./index').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-line-arc', t => { - for (const {filename, name, geojson} of fixtures) { - const {radius, bearing1, bearing2, steps, units} = geojson.properties; - const arc = truncate(lineArc(geojson, radius, bearing1, bearing2, steps, units)); - const results = featureCollection([geojson, arc]); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEquals(results, load.sync(directories.out + filename), name); - } - t.end(); -}); diff --git a/packages/turf-line-arc/tsconfig.json b/packages/turf-line-arc/tsconfig.json deleted file mode 100644 index 91cffcbf55..0000000000 --- a/packages/turf-line-arc/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - }, - "files": [ - "index.ts" - ] -} \ No newline at end of file diff --git a/packages/turf-line-arc/tslint.json b/packages/turf-line-arc/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-line-arc/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-line-arc/types.ts b/packages/turf-line-arc/types.ts deleted file mode 100644 index 48e22b4ca7..0000000000 --- a/packages/turf-line-arc/types.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {point} from "@turf/helpers"; -import linearc from "./"; - -const center = point([-75.343, 39.984]); -const bearing1 = 10; -const bearing2 = -30; -const radius = 5; -const steps = 10; -const units = "miles"; - -linearc(center, radius, bearing1, bearing2); -linearc(center, radius, bearing1, bearing2, {steps}); -linearc(center, radius, bearing1, bearing2, {steps, units}); diff --git a/packages/turf-line-chunk/LICENSE b/packages/turf-line-chunk/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-line-chunk/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-line-chunk/README.md b/packages/turf-line-chunk/README.md deleted file mode 100644 index 5f1d751e5f..0000000000 --- a/packages/turf-line-chunk/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# @turf/line-chunk - - - -## lineChunk - -Divides a [LineString][1] into chunks of a specified length. -If the line is shorter than the segment length then the original line is returned. - -**Parameters** - -- `geojson` **([FeatureCollection][2] \| [Geometry][3] \| [Feature][4]<([LineString][5] \| [MultiLineString][6])>)** the lines to split -- `segmentLength` **[number][7]** how long to make each segment -- `options` **[Object][8]** Optional parameters (optional, default `{}`) - - `options.units` **[string][9]** units can be degrees, radians, miles, or kilometers (optional, default `'kilometers'`) - - `options.reverse` **[boolean][10]** reverses coordinates to start the first chunked segment at the end (optional, default `false`) - -**Examples** - -```javascript -var line = turf.lineString([[-95, 40], [-93, 45], [-85, 50]]); - -var chunk = turf.lineChunk(line, 15, {units: 'miles'}); - -//addToMap -var addToMap = [chunk]; -``` - -Returns **[FeatureCollection][2]<[LineString][5]>** collection of line segments - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/line-chunk -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-line-chunk/index.d.ts b/packages/turf-line-chunk/index.d.ts deleted file mode 100644 index e4a1fcb0d7..0000000000 --- a/packages/turf-line-chunk/index.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { - LineString, - MultiLineString, - GeometryCollection, - Units, - Feature, - FeatureCollection, -} from '@turf/helpers' - -/** - * http://turfjs.org/docs/#linechunk - */ -export default function lineChunk( - geojson: Feature | FeatureCollection | T | GeometryCollection| Feature, - segmentLength: number, - options?: { - units?: Units, - reverse?: boolean - } -): FeatureCollection; diff --git a/packages/turf-line-chunk/index.js b/packages/turf-line-chunk/index.js deleted file mode 100644 index d0d8448ca9..0000000000 --- a/packages/turf-line-chunk/index.js +++ /dev/null @@ -1,80 +0,0 @@ -import length from '@turf/length'; -import lineSliceAlong from '@turf/line-slice-along'; -import { flattenEach } from '@turf/meta'; -import { featureCollection, isObject } from '@turf/helpers'; - -/** - * Divides a {@link LineString} into chunks of a specified length. - * If the line is shorter than the segment length then the original line is returned. - * - * @name lineChunk - * @param {FeatureCollection|Geometry|Feature} geojson the lines to split - * @param {number} segmentLength how long to make each segment - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] units can be degrees, radians, miles, or kilometers - * @param {boolean} [options.reverse=false] reverses coordinates to start the first chunked segment at the end - * @returns {FeatureCollection} collection of line segments - * @example - * var line = turf.lineString([[-95, 40], [-93, 45], [-85, 50]]); - * - * var chunk = turf.lineChunk(line, 15, {units: 'miles'}); - * - * //addToMap - * var addToMap = [chunk]; - */ -function lineChunk(geojson, segmentLength, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var units = options.units; - var reverse = options.reverse; - - // Validation - if (!geojson) throw new Error('geojson is required'); - if (segmentLength <= 0) throw new Error('segmentLength must be greater than 0'); - - // Container - var results = []; - - // Flatten each feature to simple LineString - flattenEach(geojson, function (feature) { - // reverses coordinates to start the first chunked segment at the end - if (reverse) feature.geometry.coordinates = feature.geometry.coordinates.reverse(); - - sliceLineSegments(feature, segmentLength, units, function (segment) { - results.push(segment); - }); - }); - return featureCollection(results); -} - -/** - * Slice Line Segments - * - * @private - * @param {Feature} line GeoJSON LineString - * @param {number} segmentLength how long to make each segment - * @param {string}[units='kilometers'] units can be degrees, radians, miles, or kilometers - * @param {Function} callback iterate over sliced line segments - * @returns {void} - */ -function sliceLineSegments(line, segmentLength, units, callback) { - var lineLength = length(line, {units: units}); - - // If the line is shorter than the segment length then the orginal line is returned. - if (lineLength <= segmentLength) return callback(line); - - var numberOfSegments = lineLength / segmentLength; - - // If numberOfSegments is integer, no need to plus 1 - if (!Number.isInteger(numberOfSegments)) { - numberOfSegments = Math.floor(numberOfSegments) + 1; - } - - for (var i = 0; i < numberOfSegments; i++) { - var outline = lineSliceAlong(line, segmentLength * i, segmentLength * (i + 1), {units: units}); - callback(outline, i); - } -} - -export default lineChunk; diff --git a/packages/turf-line-chunk/package.json b/packages/turf-line-chunk/package.json deleted file mode 100644 index 9194ccae21..0000000000 --- a/packages/turf-line-chunk/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "@turf/line-chunk", - "version": "5.1.5", - "description": "turf line-chunk module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis", - "geojson", - "linestring", - "line segment" - ], - "author": "Turf Authors", - "contributors": [ - "Tim Channell <@tcql>", - "Rowan Winsemius <@rowanwins>", - "Denis Carriere <@DenisCarriere>", - "Daniel Pulido <@dpmcmlxxvi>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/truncate": "6.x", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/length": "6.x", - "@turf/line-slice-along": "^5.1.5", - "@turf/meta": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-line-chunk/test.js b/packages/turf-line-chunk/test.js deleted file mode 100644 index b0cb0210c3..0000000000 --- a/packages/turf-line-chunk/test.js +++ /dev/null @@ -1,89 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import truncate from '@turf/truncate'; -import { featureEach } from '@turf/meta'; -import { lineString, featureCollection } from '@turf/helpers'; -import lineChunk from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return {filename, geojson: load.sync(directories.in + filename)}; -}); - -test('turf-line-chunk: shorter', t => { - for (let {filename, geojson} of fixtures) { - const chunked = colorize(truncate(lineChunk(geojson, 5, {units: 'miles'}))); - filename = filename.replace('.geojson', '.shorter.geojson'); - if (process.env.REGEN) { write.sync(directories.out + filename, chunked); } - - const expected = load.sync(directories.out + filename); - t.deepEquals(chunked, expected, path.parse(filename).name); - } - t.end(); -}); - -test('turf-line-chunk: longer', t => { - for (let {filename, geojson} of fixtures) { - const chunked = colorize(truncate(lineChunk(geojson, 50, {units: 'miles'}))); - filename = filename.replace('.geojson', '.longer.geojson'); - if (process.env.REGEN) { write.sync(directories.out + filename, chunked); } - - const expected = load.sync(directories.out + filename); - t.deepEquals(chunked, expected, path.parse(filename).name); - } - t.end(); -}); - -test('turf-line-chunk: reverse', t => { - for (let {filename, geojson} of fixtures) { - const chunked = colorize(truncate(lineChunk(geojson, 5, {units: 'miles', reverse: true}))); - filename = filename.replace('.geojson', '.reverse.geojson'); - if (process.env.REGEN) write.sync(directories.out + filename, chunked); - - const expected = load.sync(directories.out + filename); - t.deepEquals(chunked, expected, path.parse(filename).name); - } - t.end(); -}); - -test('turf-line-chunk: Support Geometry Objects', t => { - const line = lineString([[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]); - t.assert(lineChunk(line.geometry, 10), 'support geometry objects'); - t.end(); -}); - -test('turf-line-chunk: Prevent input mutation', t => { - const line = lineString([[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]); - const before = JSON.parse(JSON.stringify(line)); - lineChunk(line, 10); - t.deepEqual(line, before, 'input should not mutate'); - t.end(); -}); - -/** - * Colorize FeatureCollection - * - * @param {FeatureCollection|Feature} geojson Feature or FeatureCollection - * @returns {FeatureCollection} colorized FeatureCollection - */ -function colorize(geojson) { - const results = []; - featureEach(geojson, (feature, index) => { - const r = (index % 2 === 0) ? 'F' : '0'; - const g = (index % 2 === 0) ? '0' : '0'; - const b = (index % 2 === 0) ? '0' : 'F'; - feature.properties = Object.assign({ - stroke: '#' + r + g + b, - 'stroke-width': 10 - }, feature.properties); - results.push(feature); - }); - return featureCollection(results); -} diff --git a/packages/turf-line-chunk/types.ts b/packages/turf-line-chunk/types.ts deleted file mode 100644 index 279c05905a..0000000000 --- a/packages/turf-line-chunk/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { lineString, geometryCollection, featureCollection } from '@turf/helpers' -import lineChunk from './' - -const line = lineString([[0, 0], [1, 1], [2, 2]]); -const collection = featureCollection([line]); -const geomCollection = geometryCollection([line.geometry]); - -lineChunk(line, 2) -lineChunk(line, 2, {units: 'kilometers'}) -lineChunk(line.geometry, 2) -lineChunk(collection, 2) -lineChunk(geomCollection, 2) diff --git a/packages/turf-line-intersect/.gitignore b/packages/turf-line-intersect/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-line-intersect/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-line-intersect/LICENSE b/packages/turf-line-intersect/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-line-intersect/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-line-intersect/README.md b/packages/turf-line-intersect/README.md deleted file mode 100644 index 79d70ad613..0000000000 --- a/packages/turf-line-intersect/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# @turf/line-intersect - - - -## lineIntersect - -Takes any LineString or Polygon GeoJSON and returns the intersecting point(s). - -**Parameters** - -- `line1` **([Geometry][1] \| [FeatureCollection][2] \| [Feature][3]<([LineString][4] \| [MultiLineString][5] \| [Polygon][6] \| [MultiPolygon][7])>)** any LineString or Polygon -- `line2` **([Geometry][1] \| [FeatureCollection][2] \| [Feature][3]<([LineString][4] \| [MultiLineString][5] \| [Polygon][6] \| [MultiPolygon][7])>)** any LineString or Polygon - -**Examples** - -```javascript -var line1 = turf.lineString([[126, -11], [129, -21]]); -var line2 = turf.lineString([[123, -18], [131, -14]]); -var intersects = turf.lineIntersect(line1, line2); - -//addToMap -var addToMap = [line1, line2, intersects] -``` - -Returns **[FeatureCollection][2]<[Point][8]>** point(s) that intersect both - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[8]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/line-intersect -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-line-intersect/index.d.ts b/packages/turf-line-intersect/index.d.ts deleted file mode 100644 index 488224b7e6..0000000000 --- a/packages/turf-line-intersect/index.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Feature, FeatureCollection, LineString, MultiLineString, MultiPolygon, Point, Polygon } from "@turf/helpers"; -/** - * Takes any LineString or Polygon GeoJSON and returns the intersecting point(s). - * - * @name lineIntersect - * @param {GeoJSON} line1 any LineString or Polygon - * @param {GeoJSON} line2 any LineString or Polygon - * @returns {FeatureCollection} point(s) that intersect both - * @example - * var line1 = turf.lineString([[126, -11], [129, -21]]); - * var line2 = turf.lineString([[123, -18], [131, -14]]); - * var intersects = turf.lineIntersect(line1, line2); - * - * //addToMap - * var addToMap = [line1, line2, intersects] - */ -declare function lineIntersect(line1: FeatureCollection | Feature | G1, line2: FeatureCollection | Feature | G2): FeatureCollection; -export default lineIntersect; diff --git a/packages/turf-line-intersect/index.ts b/packages/turf-line-intersect/index.ts deleted file mode 100644 index e1f7a01192..0000000000 --- a/packages/turf-line-intersect/index.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { - feature, Feature, featureCollection, - FeatureCollection, LineString, MultiLineString, MultiPolygon, point, Point, Polygon, -} from "@turf/helpers"; -import { getCoords, getGeom } from "@turf/invariant"; -import lineSegment from "@turf/line-segment"; -import { featureEach } from "@turf/meta"; -import rbush from "geojson-rbush"; - -/** - * Takes any LineString or Polygon GeoJSON and returns the intersecting point(s). - * - * @name lineIntersect - * @param {GeoJSON} line1 any LineString or Polygon - * @param {GeoJSON} line2 any LineString or Polygon - * @returns {FeatureCollection} point(s) that intersect both - * @example - * var line1 = turf.lineString([[126, -11], [129, -21]]); - * var line2 = turf.lineString([[123, -18], [131, -14]]); - * var intersects = turf.lineIntersect(line1, line2); - * - * //addToMap - * var addToMap = [line1, line2, intersects] - */ -function lineIntersect< - G1 extends LineString|MultiLineString|Polygon|MultiPolygon, - G2 extends LineString|MultiLineString|Polygon|MultiPolygon ->( - line1: FeatureCollection | Feature | G1, - line2: FeatureCollection | Feature | G2, -): FeatureCollection { - const unique: any = {}; - const results: any[] = []; - - // First, normalize geometries to features - // Then, handle simple 2-vertex segments - if (line1.type === "LineString") { line1 = feature(line1); } - if (line2.type === "LineString") { line2 = feature(line2); } - if (line1.type === "Feature" && - line2.type === "Feature" && - line1.geometry !== null && - line2.geometry !== null && - line1.geometry.type === "LineString" && - line2.geometry.type === "LineString" && - line1.geometry.coordinates.length === 2 && - line2.geometry.coordinates.length === 2) { - const intersect = intersects(line1, line2); - if (intersect) { results.push(intersect); } - return featureCollection(results); - } - - // Handles complex GeoJSON Geometries - const tree = rbush(); - tree.load(lineSegment(line2)); - featureEach(lineSegment(line1), (segment) => { - featureEach(tree.search(segment), (match) => { - const intersect = intersects(segment, match); - if (intersect) { - // prevent duplicate points https://github.com/Turfjs/turf/issues/688 - const key = getCoords(intersect).join(","); - if (!unique[key]) { - unique[key] = true; - results.push(intersect); - } - } - }); - }); - return featureCollection(results); -} - -/** - * Find a point that intersects LineStrings with two coordinates each - * - * @private - * @param {Feature} line1 GeoJSON LineString (Must only contain 2 coordinates) - * @param {Feature} line2 GeoJSON LineString (Must only contain 2 coordinates) - * @returns {Feature} intersecting GeoJSON Point - */ -function intersects(line1: Feature, line2: Feature) { - const coords1: any = getCoords(line1); - const coords2: any = getCoords(line2); - if (coords1.length !== 2) { - throw new Error(" line1 must only contain 2 coordinates"); - } - if (coords2.length !== 2) { - throw new Error(" line2 must only contain 2 coordinates"); - } - const x1 = coords1[0][0]; - const y1 = coords1[0][1]; - const x2 = coords1[1][0]; - const y2 = coords1[1][1]; - const x3 = coords2[0][0]; - const y3 = coords2[0][1]; - const x4 = coords2[1][0]; - const y4 = coords2[1][1]; - const denom = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1)); - const numeA = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3)); - const numeB = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3)); - - if (denom === 0) { - if (numeA === 0 && numeB === 0) { - return null; - } - return null; - } - - const uA = numeA / denom; - const uB = numeB / denom; - - if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) { - const x = x1 + (uA * (x2 - x1)); - const y = y1 + (uA * (y2 - y1)); - return point([x, y]); - } - return null; -} - -export default lineIntersect; diff --git a/packages/turf-line-intersect/package.json b/packages/turf-line-intersect/package.json deleted file mode 100644 index 6c9c3293b1..0000000000 --- a/packages/turf-line-intersect/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "@turf/line-intersect", - "version": "6.0.2", - "description": "turf line-intersect module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "gis", - "line", - "intersect" - ], - "author": "Turf Authors", - "contributors": [ - "Denis Carriere <@DenisCarriere>", - "Daniel Pulido <@dpmcmlxxvi>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/truncate": "*", - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/line-segment": "6.x", - "@turf/meta": "6.x", - "geojson-rbush": "3.x" - } -} diff --git a/packages/turf-line-intersect/test.js b/packages/turf-line-intersect/test.js deleted file mode 100644 index b171069845..0000000000 --- a/packages/turf-line-intersect/test.js +++ /dev/null @@ -1,73 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const truncate = require('@turf/truncate').default; -const { featureCollection, geometryCollection, lineString, polygon } = require('@turf/helpers'); -const lineIntersect = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-line-intersect', t => { - for (const {filename, name, geojson} of fixtures) { - const [line1, line2] = geojson.features; - const results = truncate(lineIntersect(line1, line2)); - results.features.push(line1); - results.features.push(line2); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEquals(results, load.sync(directories.out + filename), name); - } - t.end(); -}); - -test('turf-line-intersect - prevent input mutation', t => { - const line1 = lineString([[7, 50], [8, 50], [9, 50]]); - const line2 = lineString([[8, 49], [8, 50], [8, 51]]); - const before1 = JSON.parse(JSON.stringify(line1)); - const before2 = JSON.parse(JSON.stringify(line2)); - - lineIntersect(line1, line2); - t.deepEqual(line1, before1, 'line1 input should not be mutated'); - t.deepEqual(line2, before2, 'line2 input should not be mutated'); - t.end(); -}); - -test('turf-line-intersect - Geometry Objects', t => { - const line1 = lineString([[7, 50], [8, 50], [9, 50]]); - const line2 = lineString([[8, 49], [8, 50], [8, 51]]); - t.ok(lineIntersect(line1.geometry, line2.geometry).features.length, 'support Geometry Objects'); - t.ok(lineIntersect(featureCollection([line1]), featureCollection([line2])).features.length, 'support Feature Collection'); - t.ok(lineIntersect(geometryCollection([line1.geometry]), geometryCollection([line2.geometry])).features.length, 'support Geometry Collection'); - t.end(); -}); - -test('turf-line-intersect - same point #688', t => { - const line1 = lineString([[7, 50], [8, 50], [9, 50]]); - const line2 = lineString([[8, 49], [8, 50], [8, 51]]); - - const results = lineIntersect(line1, line2); - t.equal(results.features.length, 1, 'should return single point'); - t.end(); -}); - -test('turf-line-intersect - polygon support #586', t => { - const poly1 = polygon([[[7, 50], [8, 50], [9, 50], [7, 50]]]); - const poly2 = polygon([[[8, 49], [8, 50], [8, 51], [8, 49]]]); - - const results = lineIntersect(poly1, poly2); - t.equal(results.features.length, 1, 'should return single point'); - t.end(); -}); diff --git a/packages/turf-line-intersect/tsconfig.json b/packages/turf-line-intersect/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-line-intersect/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-line-intersect/tslint.json b/packages/turf-line-intersect/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-line-intersect/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-line-offset/LICENSE b/packages/turf-line-offset/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-line-offset/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-line-offset/README.md b/packages/turf-line-offset/README.md deleted file mode 100644 index 9752a9542e..0000000000 --- a/packages/turf-line-offset/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# @turf/line-offset - - - -## lineOffset - -Takes a [line][1] and returns a [line][1] at offset by the specified distance. - -**Parameters** - -- `geojson` **([Geometry][2] \| [Feature][3]<([LineString][4] \| [MultiLineString][5])>)** input GeoJSON -- `distance` **[number][6]** distance to offset the line (can be of negative value) -- `options` **[Object][7]** Optional parameters (optional, default `{}`) - - `options.units` **[string][8]** can be degrees, radians, miles, kilometers, inches, yards, meters (optional, default `'kilometers'`) - -**Examples** - -```javascript -var line = turf.lineString([[-83, 30], [-84, 36], [-78, 41]], { "stroke": "#F00" }); - -var offsetLine = turf.lineOffset(line, 2, {units: 'miles'}); - -//addToMap -var addToMap = [offsetLine, line] -offsetLine.properties.stroke = "#00F" -``` - -Returns **[Feature][3]<([LineString][4] \| [MultiLineString][5])>** Line offset from the input line - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/line-offset -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-line-offset/index.js b/packages/turf-line-offset/index.js deleted file mode 100644 index 0e2f1bb101..0000000000 --- a/packages/turf-line-offset/index.js +++ /dev/null @@ -1,115 +0,0 @@ -import { flattenEach } from '@turf/meta'; -import { getCoords, getType } from '@turf/invariant'; -import { isObject, lineString, multiLineString, lengthToDegrees } from '@turf/helpers'; -import intersection from './lib/intersection'; - -/** - * Takes a {@link LineString|line} and returns a {@link LineString|line} at offset by the specified distance. - * - * @name lineOffset - * @param {Geometry|Feature} geojson input GeoJSON - * @param {number} distance distance to offset the line (can be of negative value) - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] can be degrees, radians, miles, kilometers, inches, yards, meters - * @returns {Feature} Line offset from the input line - * @example - * var line = turf.lineString([[-83, 30], [-84, 36], [-78, 41]], { "stroke": "#F00" }); - * - * var offsetLine = turf.lineOffset(line, 2, {units: 'miles'}); - * - * //addToMap - * var addToMap = [offsetLine, line] - * offsetLine.properties.stroke = "#00F" - */ -function lineOffset(geojson, distance, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var units = options.units; - - // Valdiation - if (!geojson) throw new Error('geojson is required'); - if (distance === undefined || distance === null || isNaN(distance)) throw new Error('distance is required'); - - var type = getType(geojson); - var properties = geojson.properties; - - switch (type) { - case 'LineString': - return lineOffsetFeature(geojson, distance, units); - case 'MultiLineString': - var coords = []; - flattenEach(geojson, function (feature) { - coords.push(lineOffsetFeature(feature, distance, units).geometry.coordinates); - }); - return multiLineString(coords, properties); - default: - throw new Error('geometry ' + type + ' is not supported'); - } -} - -/** - * Line Offset - * - * @private - * @param {Geometry|Feature} line input line - * @param {number} distance distance to offset the line (can be of negative value) - * @param {string} [units=kilometers] units - * @returns {Feature} Line offset from the input line - */ -function lineOffsetFeature(line, distance, units) { - var segments = []; - var offsetDegrees = lengthToDegrees(distance, units); - var coords = getCoords(line); - var finalCoords = []; - coords.forEach(function (currentCoords, index) { - if (index !== coords.length - 1) { - var segment = processSegment(currentCoords, coords[index + 1], offsetDegrees); - segments.push(segment); - if (index > 0) { - var seg2Coords = segments[index - 1]; - var intersects = intersection(segment, seg2Coords); - - // Handling for line segments that aren't straight - if (intersects !== false) { - seg2Coords[1] = intersects; - segment[0] = intersects; - } - - finalCoords.push(seg2Coords[0]); - if (index === coords.length - 2) { - finalCoords.push(segment[0]); - finalCoords.push(segment[1]); - } - } - // Handling for lines that only have 1 segment - if (coords.length === 2) { - finalCoords.push(segment[0]); - finalCoords.push(segment[1]); - } - } - }); - return lineString(finalCoords, line.properties); -} - -/** - * Process Segment - * Inspiration taken from http://stackoverflow.com/questions/2825412/draw-a-parallel-line - * - * @private - * @param {Array} point1 Point coordinates - * @param {Array} point2 Point coordinates - * @param {number} offset Offset - * @returns {Array>} offset points - */ -function processSegment(point1, point2, offset) { - var L = Math.sqrt((point1[0] - point2[0]) * (point1[0] - point2[0]) + (point1[1] - point2[1]) * (point1[1] - point2[1])); - - var out1x = point1[0] + offset * (point2[1] - point1[1]) / L; - var out2x = point2[0] + offset * (point2[1] - point1[1]) / L; - var out1y = point1[1] + offset * (point1[0] - point2[0]) / L; - var out2y = point2[1] + offset * (point1[0] - point2[0]) / L; - return [[out1x, out1y], [out2x, out2y]]; -} - -export default lineOffset; diff --git a/packages/turf-line-offset/package.json b/packages/turf-line-offset/package.json deleted file mode 100644 index b5dc8b8a7d..0000000000 --- a/packages/turf-line-offset/package.json +++ /dev/null @@ -1,62 +0,0 @@ - -{ - "name": "@turf/line-offset", - "version": "5.1.5", - "description": "turf line-offset module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "lib", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "line", - "linestring", - "turf", - "offset" - ], - "author": "Turf Authors", - "contributors": [ - "David Wee <@rook2pawn>", - "Rowan Winsemius <@rowanwins>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/truncate": "6.x", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-line-offset/test.js b/packages/turf-line-offset/test.js deleted file mode 100644 index f8be9c7f6a..0000000000 --- a/packages/turf-line-offset/test.js +++ /dev/null @@ -1,62 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import truncate from '@turf/truncate'; -import { featureCollection, lineString } from '@turf/helpers'; -import lineOffset from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -let fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); -// fixtures = fixtures.filter(fixture => fixture.name === 'polygon'); - -test('turf-line-offset', t => { - fixtures.forEach(fixture => { - const name = fixture.name; - const geojson = fixture.geojson; - const properties = geojson.properties || {}; - const distance = properties.distance || 50; - const units = properties.units; - - const output = truncate(lineOffset(geojson, distance, {units: units}), {precision: 4}); - output.properties.stroke = '#00F'; - const results = featureCollection([output, geojson]); - - if (process.env.REGEN) write.sync(directories.out + name + '.geojson', results); - t.deepEqual(results, load.sync(directories.out + name + '.geojson'), name); - }) - t.end(); -}); - -test('turf-line-offset - Throws Errors', t => { - const line = lineString([[10, 10], [0, 0]]); - t.throws(() => lineOffset(), /geojson is required/); - t.throws(() => lineOffset(line, /offset is required/)); - t.end(); -}); - -test('turf-line-offset - Support Geometry Objects', t => { - const line = lineString([[10, 10], [0, 0]]); - t.ok(lineOffset(line.geometry, 10), 'Geometry Object'); - t.end(); -}); - -test('turf-line-offset - Prevent Input Mutation', t => { - const line = lineString([[10, 10], [0, 0]]); - const before = JSON.parse(JSON.stringify(line)); - lineOffset(line.geometry, 10); - - t.deepEqual(line, before, 'input does not mutate'); - t.end(); -}); diff --git a/packages/turf-line-offset/test/in/northern-line.geojson b/packages/turf-line-offset/test/in/northern-line.geojson deleted file mode 100644 index ecb97bfaa1..0000000000 --- a/packages/turf-line-offset/test/in/northern-line.geojson +++ /dev/null @@ -1,60 +0,0 @@ -{ - "type": "Feature", - "properties": { - "stroke": "#F00", - "stroke-width": 6 - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - -93.66943359374999, - 75.2782047773442 - ], - [ - -94.15283203125, - 75.52189820596192 - ], - [ - -94.68017578125, - 75.60133818586581 - ], - [ - -95.64697265625, - 75.55208098028335 - ], - [ - -95.8447265625, - 75.37837872661018 - ], - [ - -96.339111328125, - 75.10975495781904 - ], - [ - -96.251220703125, - 74.89940428652537 - ], - [ - -95.20751953125, - 74.73829331009176 - ], - [ - -94.50439453125, - 74.63965846462719 - ], - [ - -93.878173828125, - 74.65129477919845 - ], - [ - -93.526611328125, - 74.73250841433554 - ], - [ - -93.50463867187499, - 75.09845822124332 - ] - ] - } -} \ No newline at end of file diff --git a/packages/turf-line-offset/test/out/linestring-long.geojson b/packages/turf-line-offset/test/out/linestring-long.geojson deleted file mode 100644 index 3a549331c5..0000000000 --- a/packages/turf-line-offset/test/out/linestring-long.geojson +++ /dev/null @@ -1,349 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "stroke-width": 6 - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - -24.1578, - 40.8064 - ], - [ - -6.1517, - 44.9157 - ], - [ - 0.4809, - 49.1618 - ], - [ - 2.2548, - 44.538 - ], - [ - -6.871, - 39.3029 - ], - [ - -5.7552, - 35.9523 - ], - [ - 0.0593, - 36.8825 - ], - [ - 1.8862, - 39.0318 - ], - [ - 3.5255, - 40.1624 - ], - [ - 5.9603, - 40.7374 - ], - [ - 6.7827, - 39.574 - ], - [ - 4.2094, - 37.3013 - ], - [ - 3.2046, - 35.3546 - ], - [ - 4.6269, - 31.1193 - ], - [ - 8.8011, - 32.1296 - ], - [ - 11.1932, - 33.796 - ], - [ - 10.995, - 36.0684 - ], - [ - 10.8145, - 38.3694 - ], - [ - 10.4401, - 39.3915 - ], - [ - 9.9308, - 40.6937 - ], - [ - 9.7908, - 41.7463 - ], - [ - 11.6055, - 43.6263 - ], - [ - 13.3465, - 43.522 - ], - [ - 14.3543, - 42.5805 - ], - [ - 15.3654, - 37.6979 - ], - [ - 15.2056, - 36.2931 - ], - [ - 14.5417, - 34.8048 - ], - [ - 12.9304, - 32.111 - ], - [ - 10.9461, - 20.5763 - ], - [ - 16.2165, - 29.0144 - ], - [ - 17.3071, - 31.3665 - ], - [ - 17.6718, - 33.3664 - ], - [ - 17.8439, - 34.932 - ], - [ - 19.8263, - 40.7725 - ], - [ - 20.8491, - 40.7026 - ], - [ - 20.2835, - 38.8607 - ], - [ - 20.6465, - 36.1255 - ], - [ - 20.8199, - 33.998 - ], - [ - 20.8199, - 30.6852 - ], - [ - 26.1851, - 32.8681 - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "stroke-width": 6 - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - -24.2578125, - 41.244772343082076 - ], - [ - -6.328125, - 45.336701909968134 - ], - [ - 0.703125, - 49.83798245308484 - ], - [ - 2.8125, - 44.33956524809713 - ], - [ - -6.328125, - 39.095962936305476 - ], - [ - -5.44921875, - 36.4566360115962 - ], - [ - -0.17578125, - 37.3002752813443 - ], - [ - 1.58203125, - 39.36827914916014 - ], - [ - 3.33984375, - 40.58058466412761 - ], - [ - 6.15234375, - 41.244772343082076 - ], - [ - 7.3828125, - 39.50404070558415 - ], - [ - 4.5703125, - 37.020098201368114 - ], - [ - 3.69140625, - 35.31736632923788 - ], - [ - 4.921875, - 31.653381399664 - ], - [ - 8.61328125, - 32.54681317351514 - ], - [ - 10.72265625, - 34.016241889667015 - ], - [ - 10.546875, - 36.03133177633187 - ], - [ - 10.37109375, - 38.272688535980976 - ], - [ - 10.01953125, - 39.232253141714885 - ], - [ - 9.4921875, - 40.58058466412761 - ], - [ - 9.31640625, - 41.902277040963696 - ], - [ - 11.42578125, - 44.08758502824516 - ], - [ - 13.53515625, - 43.96119063892024 - ], - [ - 14.765625, - 42.8115217450979 - ], - [ - 15.8203125, - 37.71859032558816 - ], - [ - 15.644531250000002, - 36.1733569352216 - ], - [ - 14.94140625, - 34.59704151614417 - ], - [ - 13.359375, - 31.952162238024975 - ], - [ - 11.77734375, - 22.755920681486405 - ], - [ - 15.8203125, - 29.22889003019423 - ], - [ - 16.875, - 31.50362930577303 - ], - [ - 17.2265625, - 33.43144133557529 - ], - [ - 17.402343749999996, - 35.02999636902566 - ], - [ - 19.51171875, - 41.244772343082076 - ], - [ - 21.4453125, - 41.11246878918088 - ], - [ - 20.7421875, - 38.8225909761771 - ], - [ - 21.09375, - 36.1733569352216 - ], - [ - 21.26953125, - 34.016241889667015 - ], - [ - 21.26953125, - 31.353636941500987 - ], - [ - 26.015625, - 33.284619968887675 - ] - ] - } - } - ] -} diff --git a/packages/turf-line-offset/test/out/linestring-same-start-end.geojson b/packages/turf-line-offset/test/out/linestring-same-start-end.geojson deleted file mode 100644 index eb51750e0d..0000000000 --- a/packages/turf-line-offset/test/out/linestring-same-start-end.geojson +++ /dev/null @@ -1,77 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "stroke-width": 6 - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - 121.982, - -19.5652 - ], - [ - 122.0751, - -27.341 - ], - [ - 134.9976, - -27.6698 - ], - [ - 139.8838, - -23.0733 - ], - [ - 134.1192, - -13.8651 - ], - [ - 122.2488, - -19.149 - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "stroke-width": 6 - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - 122.431640625, - -19.559790136497398 - ], - [ - 122.51953124999999, - -26.902476886279807 - ], - [ - 134.82421875, - -27.215556209029675 - ], - [ - 139.306640625, - -22.998851594142913 - ], - [ - 133.9453125, - -14.434680215297268 - ], - [ - 122.431640625, - -19.559790136497398 - ] - ] - } - } - ] -} diff --git a/packages/turf-line-offset/test/out/multi-linestring.geojson b/packages/turf-line-offset/test/out/multi-linestring.geojson deleted file mode 100644 index 88895efb50..0000000000 --- a/packages/turf-line-offset/test/out/multi-linestring.geojson +++ /dev/null @@ -1,85 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "stroke-width": 6 - }, - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 9.682, - 10.318 - ], - [ - 1.682, - 2.318 - ], - [ - -0.318, - 0.318 - ] - ], - [ - [ - 25.318, - 5.318 - ], - [ - 20, - 10.6359 - ], - [ - 14.682, - 5.318 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "stroke-width": 6 - }, - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 10, - 10 - ], - [ - 2, - 2 - ], - [ - 0, - 0 - ] - ], - [ - [ - 25, - 5 - ], - [ - 20, - 10 - ], - [ - 15, - 5 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-line-offset/test/out/northern-line.geojson b/packages/turf-line-offset/test/out/northern-line.geojson deleted file mode 100644 index e19370bc53..0000000000 --- a/packages/turf-line-offset/test/out/northern-line.geojson +++ /dev/null @@ -1,125 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "stroke-width": 6 - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - -93.467, - 75.6797 - ], - [ - -94.0147, - 75.9558 - ], - [ - -94.6579, - 76.0527 - ], - [ - -95.8261, - 75.9932 - ], - [ - -96.1036, - 75.7494 - ], - [ - -96.9105, - 75.311 - ], - [ - -96.5689, - 74.4935 - ], - [ - -95.2731, - 74.2934 - ], - [ - -94.5316, - 74.1894 - ], - [ - -93.8228, - 74.2026 - ], - [ - -93.0979, - 74.37 - ], - [ - -93.0558, - 75.0715 - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "stroke-width": 6 - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - -93.66943359374999, - 75.2782047773442 - ], - [ - -94.15283203125, - 75.52189820596192 - ], - [ - -94.68017578125, - 75.60133818586581 - ], - [ - -95.64697265625, - 75.55208098028335 - ], - [ - -95.8447265625, - 75.37837872661018 - ], - [ - -96.339111328125, - 75.10975495781904 - ], - [ - -96.251220703125, - 74.89940428652537 - ], - [ - -95.20751953125, - 74.73829331009176 - ], - [ - -94.50439453125, - 74.63965846462719 - ], - [ - -93.878173828125, - 74.65129477919845 - ], - [ - -93.526611328125, - 74.73250841433554 - ], - [ - -93.50463867187499, - 75.09845822124332 - ] - ] - } - } - ] -} diff --git a/packages/turf-line-offset/types.ts b/packages/turf-line-offset/types.ts deleted file mode 100644 index 044ee87b79..0000000000 --- a/packages/turf-line-offset/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -import lineOffset from './' -import {lineString, multiLineString} from '@turf/helpers' - -const line = lineString([[0, 0], [10, 10]]) -const multiLine = multiLineString([[[0, 0], [10, 10]], [[5, 5], [15, 15]]]) - -lineOffset(line, 50) -lineOffset(line.geometry, 50) -lineOffset(multiLine, 50) -lineOffset(multiLine.geometry, 50) -lineOffset(line, 50, {units: 'miles'}) diff --git a/packages/turf-line-overlap/.gitignore b/packages/turf-line-overlap/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-line-overlap/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-line-overlap/LICENSE b/packages/turf-line-overlap/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-line-overlap/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-line-overlap/README.md b/packages/turf-line-overlap/README.md deleted file mode 100644 index 2996b17e64..0000000000 --- a/packages/turf-line-overlap/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# @turf/line-overlap - - - -## lineOverlap - -Takes any LineString or Polygon and returns the overlapping lines between both features. - -**Parameters** - -- `line1` **([Geometry][1] \| [Feature][2]<([LineString][3] \| [MultiLineString][4] \| [Polygon][5] \| [MultiPolygon][6])>)** any LineString or Polygon -- `line2` **([Geometry][1] \| [Feature][2]<([LineString][3] \| [MultiLineString][4] \| [Polygon][5] \| [MultiPolygon][6])>)** any LineString or Polygon -- `options` **[Object][7]** Optional parameters (optional, default `{}`) - - `options.tolerance` **[number][8]** Tolerance distance to match overlapping line segments (in kilometers) (optional, default `0`) - -**Examples** - -```javascript -var line1 = turf.lineString([[115, -35], [125, -30], [135, -30], [145, -35]]); -var line2 = turf.lineString([[115, -25], [125, -30], [135, -30], [145, -25]]); - -var overlapping = turf.lineOverlap(line1, line2); - -//addToMap -var addToMap = [line1, line2, overlapping] -``` - -Returns **[FeatureCollection][9]<[LineString][3]>** lines(s) that are overlapping between both features - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[9]: https://tools.ietf.org/html/rfc7946#section-3.3 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/line-overlap -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-line-overlap/index.ts b/packages/turf-line-overlap/index.ts deleted file mode 100644 index bd09be183f..0000000000 --- a/packages/turf-line-overlap/index.ts +++ /dev/null @@ -1,127 +0,0 @@ -import rbush from 'geojson-rbush'; -import lineSegment from '@turf/line-segment'; -import nearestPointOnLine from '@turf/nearest-point-on-line'; -import booleanPointOnLine from '@turf/boolean-point-on-line'; -import { getCoords } from '@turf/invariant'; -import { featureEach, segmentEach } from '@turf/meta'; -import { - featureCollection, isObject, - FeatureCollection, Feature, LineString, MultiLineString, Polygon, MultiPolygon, -} from '@turf/helpers'; -import * as equal from 'deep-equal'; - -/** - * Takes any LineString or Polygon and returns the overlapping lines between both features. - * - * @name lineOverlap - * @param {Geometry|Feature} line1 any LineString or Polygon - * @param {Geometry|Feature} line2 any LineString or Polygon - * @param {Object} [options={}] Optional parameters - * @param {number} [options.tolerance=0] Tolerance distance to match overlapping line segments (in kilometers) - * @returns {FeatureCollection} lines(s) that are overlapping between both features - * @example - * var line1 = turf.lineString([[115, -35], [125, -30], [135, -30], [145, -35]]); - * var line2 = turf.lineString([[115, -25], [125, -30], [135, -30], [145, -25]]); - * - * var overlapping = turf.lineOverlap(line1, line2); - * - * //addToMap - * var addToMap = [line1, line2, overlapping] - */ -function lineOverlap( - line1: Feature | G1, - line2: Feature | G2, - options: {tolerance?: number}={} -): FeatureCollection { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var tolerance = options.tolerance || 0; - - // Containers - var features = []; - - // Create Spatial Index - var tree = rbush(); - - // To-Do -- HACK way to support typescript - const line: any = lineSegment(line1); - tree.load(line); - var overlapSegment; - - // Line Intersection - - // Iterate over line segments - segmentEach(line2, function (segment) { - var doesOverlaps = false; - - // Iterate over each segments which falls within the same bounds - featureEach(tree.search(segment), function (match) { - if (doesOverlaps === false) { - var coordsSegment = getCoords(segment).sort(); - var coordsMatch: any = getCoords(match).sort(); - - // Segment overlaps feature - if (equal(coordsSegment, coordsMatch)) { - doesOverlaps = true; - // Overlaps already exists - only append last coordinate of segment - if (overlapSegment) overlapSegment = concatSegment(overlapSegment, segment); - else overlapSegment = segment; - // Match segments which don't share nodes (Issue #901) - } else if ( - (tolerance === 0) ? - booleanPointOnLine(coordsSegment[0], match) && booleanPointOnLine(coordsSegment[1], match) : - nearestPointOnLine(match, coordsSegment[0]).properties.dist <= tolerance && - nearestPointOnLine(match, coordsSegment[1]).properties.dist <= tolerance) { - doesOverlaps = true; - if (overlapSegment) overlapSegment = concatSegment(overlapSegment, segment); - else overlapSegment = segment; - } else if ( - (tolerance === 0) ? - booleanPointOnLine(coordsMatch[0], segment) && booleanPointOnLine(coordsMatch[1], segment) : - nearestPointOnLine(segment, coordsMatch[0]).properties.dist <= tolerance && - nearestPointOnLine(segment, coordsMatch[1]).properties.dist <= tolerance) { - // Do not define (doesOverlap = true) since more matches can occur within the same segment - // doesOverlaps = true; - if (overlapSegment) overlapSegment = concatSegment(overlapSegment, match); - else overlapSegment = match; - } - } - }); - - // Segment doesn't overlap - add overlaps to results & reset - if (doesOverlaps === false && overlapSegment) { - features.push(overlapSegment); - overlapSegment = undefined; - } - }); - // Add last segment if exists - if (overlapSegment) features.push(overlapSegment); - - return featureCollection(features); -} - - -/** - * Concat Segment - * - * @private - * @param {Feature} line LineString - * @param {Feature} segment 2-vertex LineString - * @returns {Feature} concat linestring - */ -function concatSegment(line, segment) { - var coords = getCoords(segment); - var lineCoords = getCoords(line); - var start = lineCoords[0]; - var end = lineCoords[lineCoords.length - 1]; - var geom = line.geometry.coordinates; - - if (equal(coords[0], start)) geom.unshift(coords[1]); - else if (equal(coords[0], end)) geom.push(coords[1]); - else if (equal(coords[1], start)) geom.unshift(coords[0]); - else if (equal(coords[1], end)) geom.push(coords[0]); - return line; -} - -export default lineOverlap; diff --git a/packages/turf-line-overlap/package.json b/packages/turf-line-overlap/package.json deleted file mode 100644 index 1be66aba49..0000000000 --- a/packages/turf-line-overlap/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "@turf/line-overlap", - "version": "6.0.2", - "description": "turf line-overlap module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "gis", - "line", - "overlap" - ], - "author": "Turf Authors", - "contributors": [ - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/boolean-point-on-line": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/line-segment": "6.x", - "@turf/meta": "6.x", - "@turf/nearest-point-on-line": "6.x", - "deep-equal": "1.x", - "geojson-rbush": "3.x" - } -} diff --git a/packages/turf-line-overlap/test.js b/packages/turf-line-overlap/test.js deleted file mode 100644 index 0de641757b..0000000000 --- a/packages/turf-line-overlap/test.js +++ /dev/null @@ -1,56 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { featureEach } = require('@turf/meta'); -const { featureCollection, lineString } = require('@turf/helpers'); -const lineOverlap = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -let fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); -// fixtures = fixtures.filter(({name}) => name.includes('#901')); - -test('turf-line-overlap', t => { - for (const {filename, name, geojson} of fixtures) { - const [source, target] = geojson.features; - const shared = colorize(lineOverlap(source, target, geojson.properties), '#0F0'); - const results = featureCollection(shared.features.concat([source, target])); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEquals(results, load.sync(directories.out + filename), name); - } - t.end(); -}); - -test('turf-line-overlap - Geometry Object', t => { - const line1 = lineString([[115, -35], [125, -30], [135, -30], [145, -35]]); - const line2 = lineString([[135, -30], [145, -35]]); - - t.true(lineOverlap(line1.geometry, line2.geometry).features.length > 0, 'support geometry object'); - t.end(); -}); - -function colorize(features, color = '#F00', width = 25) { - const results = []; - featureEach(features, feature => { - feature.properties = { - stroke: color, - fill: color, - 'stroke-width': width - }; - results.push(feature); - }); - if (features.type === 'Feature') return results[0]; - return featureCollection(results); -} diff --git a/packages/turf-line-overlap/types.ts b/packages/turf-line-overlap/types.ts deleted file mode 100644 index 3ff385f4ea..0000000000 --- a/packages/turf-line-overlap/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { lineString, multiLineString, polygon, multiPolygon } from '@turf/helpers' -import lineOverlap from './' - -const line = lineString([[0, 0], [10, 10]]); -const multiLine = multiLineString([[[0, 0], [10, 10]], [[30, 30], [50, 50]]]); -const poly = polygon([[[0, 0], [10, 10], [15, 15], [0, 0]]]); -const multiPoly = multiPolygon([ - [[[0, 0], [10, 10], [15, 15], [0, 0]]], - [[[5, 5], [30, 30], [45, 45], [5, 5]]] -]) - -lineOverlap(line, poly) -lineOverlap(line, line) -lineOverlap(multiPoly, line) -lineOverlap(multiPoly, multiLine) -lineOverlap(multiPoly, multiLine, {tolerance: 5}) diff --git a/packages/turf-line-segment/.gitignore b/packages/turf-line-segment/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-line-segment/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-line-segment/LICENSE b/packages/turf-line-segment/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-line-segment/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-line-segment/README.md b/packages/turf-line-segment/README.md deleted file mode 100644 index b867a0d933..0000000000 --- a/packages/turf-line-segment/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# @turf/line-segment - - - -## lineSegment - -Creates a [FeatureCollection][1] of 2-vertex [LineString][2] segments from a [(Multi)LineString][2] or [(Multi)Polygon][3]. - -**Parameters** - -- `geojson` **([Geometry][4] \| [FeatureCollection][5] \| [Feature][6]<([LineString][7] \| [MultiLineString][8] \| [MultiPolygon][9] \| [Polygon][10])>)** GeoJSON Polygon or LineString - -**Examples** - -```javascript -var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]); -var segments = turf.lineSegment(polygon); - -//addToMap -var addToMap = [polygon, segments] -``` - -Returns **[FeatureCollection][5]<[LineString][7]>** 2-vertex line segments - -[1]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[8]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[9]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[10]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/line-segment -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-line-segment/index.d.ts b/packages/turf-line-segment/index.d.ts deleted file mode 100644 index 78fff5e3ca..0000000000 --- a/packages/turf-line-segment/index.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Feature, FeatureCollection, LineString, MultiLineString, MultiPolygon, Polygon } from "@turf/helpers"; -/** - * Creates a {@link FeatureCollection} of 2-vertex {@link LineString} segments from a - * {@link LineString|(Multi)LineString} or {@link Polygon|(Multi)Polygon}. - * - * @name lineSegment - * @param {GeoJSON} geojson GeoJSON Polygon or LineString - * @returns {FeatureCollection} 2-vertex line segments - * @example - * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]); - * var segments = turf.lineSegment(polygon); - * - * //addToMap - * var addToMap = [polygon, segments] - */ -declare function lineSegment(geojson: Feature | FeatureCollection | G): FeatureCollection; -export default lineSegment; diff --git a/packages/turf-line-segment/index.ts b/packages/turf-line-segment/index.ts deleted file mode 100644 index 27de3e29e2..0000000000 --- a/packages/turf-line-segment/index.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { - BBox, Feature, - featureCollection, FeatureCollection, lineString, LineString, MultiLineString, MultiPolygon, Polygon, -} from "@turf/helpers"; -import { getCoords } from "@turf/invariant"; -import { flattenEach } from "@turf/meta"; - -/** - * Creates a {@link FeatureCollection} of 2-vertex {@link LineString} segments from a - * {@link LineString|(Multi)LineString} or {@link Polygon|(Multi)Polygon}. - * - * @name lineSegment - * @param {GeoJSON} geojson GeoJSON Polygon or LineString - * @returns {FeatureCollection} 2-vertex line segments - * @example - * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]); - * var segments = turf.lineSegment(polygon); - * - * //addToMap - * var addToMap = [polygon, segments] - */ -function lineSegment( - geojson: Feature | FeatureCollection | G, -): FeatureCollection { - if (!geojson) { throw new Error("geojson is required"); } - - const results: Array> = []; - flattenEach(geojson, (feature: Feature) => { - lineSegmentFeature(feature, results); - }); - return featureCollection(results); -} - -/** - * Line Segment - * - * @private - * @param {Feature} geojson Line or polygon feature - * @param {Array} results push to results - * @returns {void} - */ -function lineSegmentFeature(geojson: Feature, results: Array>) { - let coords: number[][][] = []; - const geometry = geojson.geometry; - if (geometry !== null) { - switch (geometry.type) { - case "Polygon": - coords = getCoords(geometry); - break; - case "LineString": - coords = [getCoords(geometry)]; - } - coords.forEach((coord) => { - const segments = createSegments(coord, geojson.properties); - segments.forEach((segment) => { - segment.id = results.length; - results.push(segment); - }); - }); - } -} - -/** - * Create Segments from LineString coordinates - * - * @private - * @param {Array>} coords LineString coordinates - * @param {*} properties GeoJSON properties - * @returns {Array>} line segments - */ -function createSegments(coords: number[][], properties: any) { - const segments: Array> = []; - coords.reduce((previousCoords, currentCoords) => { - const segment = lineString([previousCoords, currentCoords], properties); - segment.bbox = bbox(previousCoords, currentCoords); - segments.push(segment); - return currentCoords; - }); - return segments; -} - -/** - * Create BBox between two coordinates (faster than @turf/bbox) - * - * @private - * @param {Array} coords1 Point coordinate - * @param {Array} coords2 Point coordinate - * @returns {BBox} [west, south, east, north] - */ -function bbox(coords1: number[], coords2: number[]): BBox { - const x1 = coords1[0]; - const y1 = coords1[1]; - const x2 = coords2[0]; - const y2 = coords2[1]; - const west = (x1 < x2) ? x1 : x2; - const south = (y1 < y2) ? y1 : y2; - const east = (x1 > x2) ? x1 : x2; - const north = (y1 > y2) ? y1 : y2; - return [west, south, east, north]; -} - -export default lineSegment; diff --git a/packages/turf-line-segment/package.json b/packages/turf-line-segment/package.json deleted file mode 100644 index 3d62390590..0000000000 --- a/packages/turf-line-segment/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "@turf/line-segment", - "version": "6.0.2", - "description": "turf line-segment module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "line", - "segment" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-line-segment/test.js b/packages/turf-line-segment/test.js deleted file mode 100644 index 9f9d103204..0000000000 --- a/packages/turf-line-segment/test.js +++ /dev/null @@ -1,61 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { featureEach } = require('@turf/meta'); -const { featureCollection, lineString } = require('@turf/helpers'); -const lineSegment = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-line-segment', t => { - for (const {name, filename, geojson} of fixtures) { - const results = colorSegments(lineSegment(geojson)); - featureEach(geojson, feature => { - feature.properties = { - stroke: '#000', - 'stroke-width': 3 - }; - results.features.push(feature); - }); - - // Save output - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEqual(results, load.sync(directories.out + filename), name); - } - t.end(); -}); - -test('turf-line-segment - Geometry Object', t => { - const line = lineString([[115, -35], [125, -30], [135, -30], [145, -35]]); - t.true(lineSegment(line.geometry).features.length > 0, 'geometry object'); - t.end(); -}); - -// Preview 2-vertex LineStrings with colors -function colorSegments(segments) { - const results = featureCollection([]); - featureEach(segments, (feature, index) => { - const r = (index % 2 === 0) ? 'F' : '0'; - const g = (index % 2 === 0) ? '0' : '0'; - const b = (index % 2 === 0) ? '0' : 'F'; - feature.properties = Object.assign({ - stroke: '#' + r + g + b, - 'stroke-width': 10 - }, feature.properties); - results.features.push(feature); - }); - return results; -} diff --git a/packages/turf-line-segment/tsconfig.json b/packages/turf-line-segment/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-line-segment/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-line-segment/tslint.json b/packages/turf-line-segment/tslint.json deleted file mode 100644 index 9dd5998b9c..0000000000 --- a/packages/turf-line-segment/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {"interface-name": false}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-line-slice-along/LICENSE b/packages/turf-line-slice-along/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-line-slice-along/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-line-slice-along/README.md b/packages/turf-line-slice-along/README.md deleted file mode 100644 index c47cb20894..0000000000 --- a/packages/turf-line-slice-along/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# @turf/line-slice-along - - - -## lineSliceAlong - -Takes a [line][1], a specified distance along the line to a start [Point][2], -and a specified distance along the line to a stop point -and returns a subsection of the line in-between those points. - -This can be useful for extracting only the part of a route between two distances. - -**Parameters** - -- `line` **([Feature][3]<[LineString][4]> | [LineString][4])** input line -- `startDist` **[number][5]** distance along the line to starting point -- `stopDist` **[number][5]** distance along the line to ending point -- `options` **[Object][6]** Optional parameters (optional, default `{}`) - - `options.units` **[string][7]** can be degrees, radians, miles, or kilometers (optional, default `'kilometers'`) - -**Examples** - -```javascript -var line = turf.lineString([[7, 45], [9, 45], [14, 40], [14, 41]]); -var start = 12.5; -var stop = 25; -var sliced = turf.lineSliceAlong(line, start, stop, {units: 'miles'}); - -//addToMap -var addToMap = [line, start, stop, sliced] -``` - -Returns **[Feature][3]<[LineString][4]>** sliced line - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/line-slice-along -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-line-slice-along/index.d.ts b/packages/turf-line-slice-along/index.d.ts deleted file mode 100644 index 5235ee2308..0000000000 --- a/packages/turf-line-slice-along/index.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Units, LineString, Feature} from '@turf/helpers' - -/** - * http://turfjs.org/docs/ - */ -export default function lineSliceAlong( - line: Feature | LineString, - startDist: number, - stopDist: number, - options?: { - units?: Units - } -): Feature; diff --git a/packages/turf-line-slice-along/index.js b/packages/turf-line-slice-along/index.js deleted file mode 100644 index d0ab3cd1b0..0000000000 --- a/packages/turf-line-slice-along/index.js +++ /dev/null @@ -1,84 +0,0 @@ -import bearing from '@turf/bearing'; -import distance from '@turf/distance'; -import destination from '@turf/destination'; -import { lineString, isObject } from '@turf/helpers'; - -/** - * Takes a {@link LineString|line}, a specified distance along the line to a start {@link Point}, - * and a specified distance along the line to a stop point - * and returns a subsection of the line in-between those points. - * - * This can be useful for extracting only the part of a route between two distances. - * - * @name lineSliceAlong - * @param {Feature|LineString} line input line - * @param {number} startDist distance along the line to starting point - * @param {number} stopDist distance along the line to ending point - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers - * @returns {Feature} sliced line - * @example - * var line = turf.lineString([[7, 45], [9, 45], [14, 40], [14, 41]]); - * var start = 12.5; - * var stop = 25; - * var sliced = turf.lineSliceAlong(line, start, stop, {units: 'miles'}); - * - * //addToMap - * var addToMap = [line, start, stop, sliced] - */ -function lineSliceAlong(line, startDist, stopDist, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - - var coords; - var slice = []; - - // Validation - if (line.type === 'Feature') coords = line.geometry.coordinates; - else if (line.type === 'LineString') coords = line.coordinates; - else throw new Error('input must be a LineString Feature or Geometry'); - var origCoordsLength = coords.length - var travelled = 0; - var overshot, direction, interpolated; - for (var i = 0; i < coords.length; i++) { - if (startDist >= travelled && i === coords.length - 1) break; - else if (travelled > startDist && slice.length === 0) { - overshot = startDist - travelled; - if (!overshot) { - slice.push(coords[i]); - return lineString(slice); - } - direction = bearing(coords[i], coords[i - 1]) - 180; - interpolated = destination(coords[i], overshot, direction, options); - slice.push(interpolated.geometry.coordinates); - } - - if (travelled >= stopDist) { - overshot = stopDist - travelled; - if (!overshot) { - slice.push(coords[i]); - return lineString(slice); - } - direction = bearing(coords[i], coords[i - 1]) - 180; - interpolated = destination(coords[i], overshot, direction, options); - slice.push(interpolated.geometry.coordinates); - return lineString(slice); - } - - if (travelled >= startDist) { - slice.push(coords[i]); - } - - if (i === coords.length - 1) { - return lineString(slice); - } - - travelled += distance(coords[i], coords[i + 1], options); - } - - if (travelled < startDist && coords.length === origCoordsLength) throw new Error('Start position is beyond line'); - return lineString(coords[coords.length - 1]); -} - -export default lineSliceAlong; diff --git a/packages/turf-line-slice-along/package.json b/packages/turf-line-slice-along/package.json deleted file mode 100644 index 7a39dcfbc8..0000000000 --- a/packages/turf-line-slice-along/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@turf/line-slice-along", - "version": "5.1.5", - "description": "turf line-slice-along module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "along", - "line-slice" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/along": "*", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*" - }, - "dependencies": { - "@turf/bearing": "6.x", - "@turf/destination": "6.x", - "@turf/distance": "6.x", - "@turf/helpers": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-line-slice-along/test.js b/packages/turf-line-slice-along/test.js deleted file mode 100644 index 5c6a147894..0000000000 --- a/packages/turf-line-slice-along/test.js +++ /dev/null @@ -1,78 +0,0 @@ -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import along from '@turf/along'; -import lineSliceAlong from '.'; - -var line1 = load.sync(path.join(__dirname, 'test', 'fixtures', 'line1.geojson')); -var route1 = load.sync(path.join(__dirname, 'test', 'fixtures', 'route1.geojson')); -var route2 = load.sync(path.join(__dirname, 'test', 'fixtures', 'route2.geojson')); - -test('turf-line-slice -- line1', function (t) { - var start = 500; - var stop = 750; - var options = {units: 'miles'}; - - var start_point = along(line1, start, options); - var end_point = along(line1, stop, options); - var sliced = lineSliceAlong(line1, start, stop, options); - t.equal(sliced.type, 'Feature'); - t.equal(sliced.geometry.type, 'LineString'); - t.deepEqual(sliced.geometry.coordinates[0], start_point.geometry.coordinates); - t.deepEqual(sliced.geometry.coordinates[sliced.geometry.coordinates.length - 1], end_point.geometry.coordinates); - t.end(); -}); - -test('turf-line-slice -- line1 overshoot', function (t) { - var start = 500; - var stop = 1500; - var options = {units: 'miles'}; - - var start_point = along(line1, start, options); - var end_point = along(line1, stop, options); - var sliced = lineSliceAlong(line1, start, stop, options); - t.equal(sliced.type, 'Feature'); - t.equal(sliced.geometry.type, 'LineString'); - t.deepEqual(sliced.geometry.coordinates[0], start_point.geometry.coordinates); - t.deepEqual(sliced.geometry.coordinates[sliced.geometry.coordinates.length - 1], end_point.geometry.coordinates); - t.end(); -}); - -test('turf-line-slice-along -- route1', function (t) { - var start = 500; - var stop = 750; - var options = {units: 'miles'}; - - var start_point = along(route1, start, options); - var end_point = along(route1, stop, options); - var sliced = lineSliceAlong(route1, start, stop, options); - t.equal(sliced.type, 'Feature'); - t.equal(sliced.geometry.type, 'LineString'); - t.deepEqual(sliced.geometry.coordinates[0], start_point.geometry.coordinates); - t.deepEqual(sliced.geometry.coordinates[sliced.geometry.coordinates.length - 1], end_point.geometry.coordinates); - t.end(); -}); - -test('turf-line-slice-along -- route2', function (t) { - var start = 25; - var stop = 50; - var options = {units: 'miles'}; - - var start_point = along(route2, start, options); - var end_point = along(route2, stop, options); - var sliced = lineSliceAlong(route2, start, stop, options); - t.equal(sliced.type, 'Feature'); - t.equal(sliced.geometry.type, 'LineString'); - t.deepEqual(sliced.geometry.coordinates[0], start_point.geometry.coordinates); - t.deepEqual(sliced.geometry.coordinates[sliced.geometry.coordinates.length - 1], end_point.geometry.coordinates); - t.end(); -}); - -test('turf-line-slice -- start longer than line length', function (t) { - var start = 500000; - var stop = 800000; - var options = {units: 'miles'}; - - t.throws(() => lineSliceAlong(line1, start, stop, options), 'Start position is beyond line'); - t.end(); -}); diff --git a/packages/turf-line-slice/LICENSE b/packages/turf-line-slice/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-line-slice/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-line-slice/README.md b/packages/turf-line-slice/README.md deleted file mode 100644 index 390adb3229..0000000000 --- a/packages/turf-line-slice/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# @turf/line-slice - - - -## lineSlice - -Takes a [line][1], a start [Point][2], and a stop point -and returns a subsection of the line in-between those points. -The start & stop points don't need to fall exactly on the line. - -This can be useful for extracting only the part of a route between waypoints. - -**Parameters** - -- `startPt` **[Coord][3]** starting point -- `stopPt` **[Coord][3]** stopping point -- `line` **([Feature][4]<[LineString][5]> | [LineString][5])** line to slice - -**Examples** - -```javascript -var line = turf.lineString([ - [-77.031669, 38.878605], - [-77.029609, 38.881946], - [-77.020339, 38.884084], - [-77.025661, 38.885821], - [-77.021884, 38.889563], - [-77.019824, 38.892368] -]); -var start = turf.point([-77.029609, 38.881946]); -var stop = turf.point([-77.021884, 38.889563]); - -var sliced = turf.lineSlice(start, stop, line); - -//addToMap -var addToMap = [start, stop, line] -``` - -Returns **[Feature][4]<[LineString][5]>** sliced line - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/line-slice -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-line-slice/bench.js b/packages/turf-line-slice/bench.js deleted file mode 100644 index d9191053a3..0000000000 --- a/packages/turf-line-slice/bench.js +++ /dev/null @@ -1,34 +0,0 @@ -import fs from 'fs'; -import Benchmark from 'benchmark'; -import { point } from '@turf/helpers'; -import lineSlice from './'; - -var route1 = JSON.parse(fs.readFileSync(__dirname + '/test/in/route1.geojson')); -var route2 = JSON.parse(fs.readFileSync(__dirname + '/test/in/route2.geojson')); -var line1 = JSON.parse(fs.readFileSync(__dirname + '/test/in/line1.geojson')); - -var start1 = point([-97.79617309570312,22.254624939561698]); -var stop1 = point([-97.72750854492188,22.057641623615734]); -var start2 = point([-79.0850830078125,37.60117623656667]); -var stop2 = point([-77.7667236328125,38.65119833229951]); -var start3 = point([-112.60660171508789,45.96021963947196]); -var stop3 = point([-111.97265625,48.84302835299516]); - -var suite = new Benchmark.Suite('turf-line-slice'); -suite - .add('turf-line-slice#simple',function () { - lineSlice(start1, stop1, line1); - }) - .add('turf-line-slice#route1',function () { - lineSlice(start2, stop2, route1); - }) - .add('turf-line-slice#route2',function () { - lineSlice(start3, stop3, route2); - }) - .on('cycle', function (event) { - console.log(String(event.target)); - }) - .on('complete', function () { - - }) - .run(); diff --git a/packages/turf-line-slice/index.d.ts b/packages/turf-line-slice/index.d.ts deleted file mode 100644 index 0f0c7062e8..0000000000 --- a/packages/turf-line-slice/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Feature, LineString, Coord } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#lineslice - */ -export default function lineSlice( - startPt: Coord, - stopPt: Coord, - line: Feature | LineString -): Feature; diff --git a/packages/turf-line-slice/index.js b/packages/turf-line-slice/index.js deleted file mode 100644 index 0927de430b..0000000000 --- a/packages/turf-line-slice/index.js +++ /dev/null @@ -1,55 +0,0 @@ -import { getCoords, getType } from '@turf/invariant'; -import { lineString as linestring } from '@turf/helpers'; -import nearestPointOnLine from '@turf/nearest-point-on-line'; - -/** - * Takes a {@link LineString|line}, a start {@link Point}, and a stop point - * and returns a subsection of the line in-between those points. - * The start & stop points don't need to fall exactly on the line. - * - * This can be useful for extracting only the part of a route between waypoints. - * - * @name lineSlice - * @param {Coord} startPt starting point - * @param {Coord} stopPt stopping point - * @param {Feature|LineString} line line to slice - * @returns {Feature} sliced line - * @example - * var line = turf.lineString([ - * [-77.031669, 38.878605], - * [-77.029609, 38.881946], - * [-77.020339, 38.884084], - * [-77.025661, 38.885821], - * [-77.021884, 38.889563], - * [-77.019824, 38.892368] - * ]); - * var start = turf.point([-77.029609, 38.881946]); - * var stop = turf.point([-77.021884, 38.889563]); - * - * var sliced = turf.lineSlice(start, stop, line); - * - * //addToMap - * var addToMap = [start, stop, line] - */ -function lineSlice(startPt, stopPt, line) { - // Validation - var coords = getCoords(line); - if (getType(line) !== 'LineString') throw new Error('line must be a LineString'); - - var startVertex = nearestPointOnLine(line, startPt); - var stopVertex = nearestPointOnLine(line, stopPt); - var ends; - if (startVertex.properties.index <= stopVertex.properties.index) { - ends = [startVertex, stopVertex]; - } else { - ends = [stopVertex, startVertex]; - } - var clipCoords = [ends[0].geometry.coordinates]; - for (var i = ends[0].properties.index + 1; i < ends[1].properties.index + 1; i++) { - clipCoords.push(coords[i]); - } - clipCoords.push(ends[1].geometry.coordinates); - return linestring(clipCoords, line.properties); -} - -export default lineSlice; diff --git a/packages/turf-line-slice/package.json b/packages/turf-line-slice/package.json deleted file mode 100644 index 2d277a8924..0000000000 --- a/packages/turf-line-slice/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "@turf/line-slice", - "version": "5.1.5", - "description": "turf line-slice module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "linestring", - "geojson", - "linear", - "reference", - "line", - "distance" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/truncate": "6.x", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/nearest-point-on-line": "^5.1.5" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-line-slice/test.js b/packages/turf-line-slice/test.js deleted file mode 100644 index 0cfbe2f095..0000000000 --- a/packages/turf-line-slice/test.js +++ /dev/null @@ -1,36 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import truncate from '@turf/truncate'; -import { featureCollection } from '@turf/helpers'; -import lineSlice from './'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-line-slice', t => { - for (const {filename, geojson, name} of fixtures) { - const [linestring, start, stop] = geojson.features; - const sliced = truncate(lineSlice(start, stop, linestring)); - sliced.properties['stroke'] = '#f0f'; - sliced.properties['stroke-width'] = 6; - const results = featureCollection(geojson.features); - results.features.push(sliced); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEquals(results, load.sync(directories.out + filename), name); - } - t.end(); -}); diff --git a/packages/turf-line-split/LICENSE b/packages/turf-line-split/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-line-split/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-line-split/README.md b/packages/turf-line-split/README.md deleted file mode 100644 index 499f056da0..0000000000 --- a/packages/turf-line-split/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# @turf/line-split - - - -## lineSplit - -Split a LineString by another GeoJSON Feature. - -**Parameters** - -- `line` **[Feature][1]<[LineString][2]>** LineString Feature to split -- `splitter` **[Feature][1]<any>** Feature used to split line - -**Examples** - -```javascript -var line = turf.lineString([[120, -25], [145, -25]]); -var splitter = turf.lineString([[130, -15], [130, -35]]); - -var split = turf.lineSplit(line, splitter); - -//addToMap -var addToMap = [line, splitter] -``` - -Returns **[FeatureCollection][3]<[LineString][2]>** Split LineStrings - -[1]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.3 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/line-split -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-line-split/index.d.ts b/packages/turf-line-split/index.d.ts deleted file mode 100644 index e4263f9978..0000000000 --- a/packages/turf-line-split/index.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { - Feature, - FeatureCollection, - Point, - MultiPoint, - LineString, - MultiLineString, - Polygon, - MultiPolygon, -} from '@turf/helpers'; - -export type Splitter = Feature - -/** - * http://turfjs.org/docs/#linesplit - */ -export default function lineSplit( - line: Feature | T, - splitter: Splitter -): FeatureCollection; diff --git a/packages/turf-line-split/index.js b/packages/turf-line-split/index.js deleted file mode 100644 index dafa1750c1..0000000000 --- a/packages/turf-line-split/index.js +++ /dev/null @@ -1,204 +0,0 @@ -import rbush from 'geojson-rbush'; -import square from '@turf/square'; -import bbox from '@turf/bbox'; -import truncate from '@turf/truncate'; -import lineSegment from '@turf/line-segment'; -import lineIntersect from '@turf/line-intersect'; -import nearestPointOnLine from '@turf/nearest-point-on-line'; -import { getCoords, getCoord, getType } from '@turf/invariant'; -import { featureEach, featureReduce, flattenEach} from '@turf/meta'; -import { lineString, featureCollection } from '@turf/helpers'; - -/** - * Split a LineString by another GeoJSON Feature. - * - * @name lineSplit - * @param {Feature} line LineString Feature to split - * @param {Feature} splitter Feature used to split line - * @returns {FeatureCollection} Split LineStrings - * @example - * var line = turf.lineString([[120, -25], [145, -25]]); - * var splitter = turf.lineString([[130, -15], [130, -35]]); - * - * var split = turf.lineSplit(line, splitter); - * - * //addToMap - * var addToMap = [line, splitter] - */ -function lineSplit(line, splitter) { - if (!line) throw new Error('line is required'); - if (!splitter) throw new Error('splitter is required'); - - var lineType = getType(line); - var splitterType = getType(splitter); - - if (lineType !== 'LineString') throw new Error('line must be LineString'); - if (splitterType === 'FeatureCollection') throw new Error('splitter cannot be a FeatureCollection'); - if (splitterType === 'GeometryCollection') throw new Error('splitter cannot be a GeometryCollection'); - - // remove excessive decimals from splitter - // to avoid possible approximation issues in rbush - var truncatedSplitter = truncate(splitter, {precision: 7}); - - switch (splitterType) { - case 'Point': - return splitLineWithPoint(line, truncatedSplitter); - case 'MultiPoint': - return splitLineWithPoints(line, truncatedSplitter); - case 'LineString': - case 'MultiLineString': - case 'Polygon': - case 'MultiPolygon': - return splitLineWithPoints(line, lineIntersect(line, truncatedSplitter)); - } -} - -/** - * Split LineString with MultiPoint - * - * @private - * @param {Feature} line LineString - * @param {FeatureCollection} splitter Point - * @returns {FeatureCollection} split LineStrings - */ -function splitLineWithPoints(line, splitter) { - var results = []; - var tree = rbush(); - - flattenEach(splitter, function (point) { - // Add index/id to features (needed for filter) - results.forEach(function (feature, index) { - feature.id = index; - }); - // First Point - doesn't need to handle any previous line results - if (!results.length) { - results = splitLineWithPoint(line, point).features; - - // Add Square BBox to each feature for GeoJSON-RBush - results.forEach(function (feature) { - if (!feature.bbox) feature.bbox = square(bbox(feature)); - }); - tree.load(featureCollection(results)); - // Split with remaining points - lines might needed to be split multiple times - } else { - // Find all lines that are within the splitter's bbox - var search = tree.search(point); - - if (search.features.length) { - // RBush might return multiple lines - only process the closest line to splitter - var closestLine = findClosestFeature(point, search); - - // Remove closest line from results since this will be split into two lines - // This removes any duplicates inside the results & index - results = results.filter(function (feature) { return feature.id !== closestLine.id; }); - tree.remove(closestLine); - - // Append the two newly split lines into the results - featureEach(splitLineWithPoint(closestLine, point), function (line) { - results.push(line); - tree.insert(line); - }); - } - } - }); - return featureCollection(results); -} - -/** - * Split LineString with Point - * - * @private - * @param {Feature} line LineString - * @param {Feature} splitter Point - * @returns {FeatureCollection} split LineStrings - */ -function splitLineWithPoint(line, splitter) { - var results = []; - - // handle endpoints - var startPoint = getCoords(line)[0]; - var endPoint = getCoords(line)[line.geometry.coordinates.length - 1]; - if (pointsEquals(startPoint, getCoord(splitter)) || - pointsEquals(endPoint, getCoord(splitter))) return featureCollection([line]); - - // Create spatial index - var tree = rbush(); - var segments = lineSegment(line); - tree.load(segments); - - // Find all segments that are within bbox of splitter - var search = tree.search(splitter); - - // Return itself if point is not within spatial index - if (!search.features.length) return featureCollection([line]); - - // RBush might return multiple lines - only process the closest line to splitter - var closestSegment = findClosestFeature(splitter, search); - - // Initial value is the first point of the first segments (beginning of line) - var initialValue = [startPoint]; - var lastCoords = featureReduce(segments, function (previous, current, index) { - var currentCoords = getCoords(current)[1]; - var splitterCoords = getCoord(splitter); - - // Location where segment intersects with line - if (index === closestSegment.id) { - previous.push(splitterCoords); - results.push(lineString(previous)); - // Don't duplicate splitter coordinate (Issue #688) - if (pointsEquals(splitterCoords, currentCoords)) return [splitterCoords]; - return [splitterCoords, currentCoords]; - - // Keep iterating over coords until finished or intersection is found - } else { - previous.push(currentCoords); - return previous; - } - }, initialValue); - // Append last line to final split results - if (lastCoords.length > 1) { - results.push(lineString(lastCoords)); - } - return featureCollection(results); -} - - -/** - * Find Closest Feature - * - * @private - * @param {Feature} point Feature must be closest to this point - * @param {FeatureCollection} lines Collection of Features - * @returns {Feature} closest LineString - */ -function findClosestFeature(point, lines) { - if (!lines.features.length) throw new Error('lines must contain features'); - // Filter to one segment that is the closest to the line - if (lines.features.length === 1) return lines.features[0]; - - var closestFeature; - var closestDistance = Infinity; - featureEach(lines, function (segment) { - var pt = nearestPointOnLine(segment, point); - var dist = pt.properties.dist; - if (dist < closestDistance) { - closestFeature = segment; - closestDistance = dist; - } - }); - return closestFeature; -} - -/** - * Compares two points and returns if they are equals - * - * @private - * @param {Array} pt1 point - * @param {Array} pt2 point - * @returns {boolean} true if they are equals - */ -function pointsEquals(pt1, pt2) { - return pt1[0] === pt2[0] && pt1[1] === pt2[1]; -} - -export default lineSplit; diff --git a/packages/turf-line-split/package.json b/packages/turf-line-split/package.json deleted file mode 100644 index 313c474bc7..0000000000 --- a/packages/turf-line-split/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "@turf/line-split", - "version": "5.1.5", - "description": "turf line-split module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "gis", - "line", - "split" - ], - "author": "Turf Authors", - "contributors": [ - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/line-intersect": "6.x", - "@turf/line-segment": "^5.1.5", - "@turf/meta": "6.x", - "@turf/nearest-point-on-line": "^5.1.5", - "@turf/square": "^5.1.5", - "@turf/truncate": "6.x", - "geojson-rbush": "3.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-line-split/test.js b/packages/turf-line-split/test.js deleted file mode 100644 index 2b319432a0..0000000000 --- a/packages/turf-line-split/test.js +++ /dev/null @@ -1,139 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import { featureEach } from '@turf/meta'; -import { point, lineString, multiPoint, featureCollection, round } from '@turf/helpers'; -import { getCoords } from '@turf/invariant'; -import lineSplit from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -let fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); -// fixtures = fixtures.filter(name => name === 'issue-#1075') - -test('turf-line-split', t => { - for (const {filename, name, geojson} of fixtures) { - const line = geojson.features[0]; - const splitter = geojson.features[1]; - const results = colorize(lineSplit(line, splitter)); - featureEach(geojson, feature => results.features.push(feature)); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEquals(results, load.sync(directories.out + filename), name); - } - t.end(); -}); - -test('turf-line-split -- lines should split the same feature 1 with 2 as 2 with 1', t => { - const featureOne = lineString([[114.58215786065353825, -14.82470576519326144], [137.21678649707752129, -16.71692980416107588]]); - const featureTwo = lineString([[119.1412061636556956, -19.83670052919270788], [133.06640625, -12.64033830684678961]]); - - const resultsOne = lineSplit(featureOne, featureTwo); - const resultsTwo = lineSplit(featureTwo, featureOne); - - const midCoordOne = getCoords(resultsOne.features[0])[1]; - const midCoordTwo = getCoords(resultsTwo.features[1])[0]; - - // Round precision to 6 decimals - midCoordOne[0] = round(midCoordOne[0], 6); - midCoordOne[1] = round(midCoordOne[1], 6); - midCoordTwo[0] = round(midCoordTwo[0], 6); - midCoordTwo[1] = round(midCoordTwo[1], 6); - t.deepEquals(midCoordOne, midCoordTwo, 'Splits were made in different locations'); - t.end(); -}); - -test('turf-line-split -- throws', t => { - const pt = point([9, 50]); - const line = lineString([[7, 50], [8, 50], [9, 50]]); - - t.throws(() => lineSplit(null, pt), ' is required'); - t.throws(() => lineSplit(line, null), ' is required'); - t.throws(() => lineSplit(pt, pt), ' must be LineString'); - t.throws(() => lineSplit(line, featureCollection([pt, line])), ' cannot be a FeatureCollection'); - t.end(); -}); - -test('turf-line-split -- splitter exactly on end of line', t => { - const pt = point([9, 50]); - const line = lineString([[7, 50], [8, 50], [9, 50]]); - const features = lineSplit(line, pt).features; - - t.deepEqual(features, [line], 'should only contain 1 line of 3 vertices'); - t.end(); -}); - - -test('turf-line-split -- lines should only contain 2 vertices #688', t => { - const middlePoint = point([8, 50]); - const line = lineString([[7, 50], [8, 50], [9, 50]]); - const [line1, line2] = lineSplit(line, middlePoint).features; - - t.deepEqual(line1, lineString([[7, 50], [8, 50]]), 'line1 should have 2 vertices'); - t.deepEqual(line2, lineString([[8, 50], [9, 50]]), 'line2 should have 2 vertices'); - t.end(); -}); - -test('turf-line-split -- precision issue #852', t => { - const line = lineString([[9.2202022, 49.1438226], [9.2199531, 49.1439048], [9.2196177, 49.1440264]]); - const startPoint = point([9.2202022, 49.1438226]); - const middlePoint = point([9.2199531, 49.1439048]); - const endPoint = point([9.2196177, 49.1440264]); - const [line1, line2] = lineSplit(line, middlePoint).features; - - t.deepEqual(line1, lineString([[9.2202022, 49.1438226], [9.2199531, 49.1439048]]), 'middlePoint: line1 should have 2 vertices'); - t.deepEqual(line2, lineString([[9.2199531, 49.1439048], [9.2196177, 49.1440264]]), 'middlePoint: line2 should have 2 vertices'); - t.deepEqual(lineSplit(line, startPoint).features, [line], 'startPoint: should only contain 1 line of 3 vertices'); - t.deepEqual(lineSplit(line, endPoint).features, [line], 'endPoint: should only contain 1 line of 3 vertices'); - t.end(); -}); - -test('turf-line-split -- prevent input mutation', t => { - const line = lineString([[9.2202022, 49.1438226], [9.2199531, 49.1439048], [9.2196177, 49.1440264]]); - const lineBefore = JSON.parse(JSON.stringify(line)); - lineSplit(line, point([9.2196177, 49.1440264])); - - t.deepEqual(line, lineBefore, 'line should be the same'); - t.end(); -}); - -test('turf-line-split -- issue #1075', t => { - const line = lineString([[-87.168433, 37.946093], [-87.168510, 37.960085]]); - const splitter = multiPoint([[-87.168446, 37.947929], [-87.168445, 37.948301]]); - const split = lineSplit(line, splitter); - t.assert(split); - t.end(); -}) - -/** - * Colorize FeatureCollection - * - * @param {FeatureCollection|Feature} geojson Feature or FeatureCollection - * @returns {FeatureCollection} colorized FeatureCollection - */ -function colorize(geojson) { - const results = []; - featureEach(geojson, (feature, index) => { - const r = (index % 2 === 0) ? 'F' : '0'; - const g = '0'; - const b = (index % 2 === 0) ? '0' : 'F'; - feature.properties = Object.assign({ - stroke: '#' + r + g + b, - 'stroke-width': 10 - }, feature.properties); - results.push(feature); - }); - return featureCollection(results); -} - diff --git a/packages/turf-line-to-polygon/.gitignore b/packages/turf-line-to-polygon/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-line-to-polygon/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-line-to-polygon/LICENSE b/packages/turf-line-to-polygon/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-line-to-polygon/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-line-to-polygon/README.md b/packages/turf-line-to-polygon/README.md deleted file mode 100644 index 818a337da7..0000000000 --- a/packages/turf-line-to-polygon/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# @turf/line-to-polygon - - - -## lineToPolygon - -Converts (Multi)LineString(s) to Polygon(s). - -**Parameters** - -- `lines` **([FeatureCollection][1] \| [Feature][2]<([LineString][3] \| [MultiLineString][4])>)** Features to convert -- `options` **[Object][5]** Optional parameters (optional, default `{}`) - - `options.properties` **[Object][5]** translates GeoJSON properties to Feature (optional, default `{}`) - - `options.autoComplete` **[boolean][6]** auto complete linestrings (matches first & last coordinates) (optional, default `true`) - - `options.orderCoords` **[boolean][6]** sorts linestrings to place outer ring at the first position of the coordinates (optional, default `true`) - -**Examples** - -```javascript -var line = turf.lineString([[125, -30], [145, -30], [145, -20], [125, -20], [125, -30]]); - -var polygon = turf.lineToPolygon(line); - -//addToMap -var addToMap = [polygon]; -``` - -Returns **[Feature][2]<([Polygon][7] \| [MultiPolygon][8])>** converted to Polygons - -[1]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[8]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/line-to-polygon -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-line-to-polygon/index.ts b/packages/turf-line-to-polygon/index.ts deleted file mode 100644 index 8b1000914e..0000000000 --- a/packages/turf-line-to-polygon/index.ts +++ /dev/null @@ -1,136 +0,0 @@ -import turfBBox from '@turf/bbox'; -import { getCoords, getType, getGeom } from '@turf/invariant'; -import { - polygon, multiPolygon, lineString, isObject, - Feature, FeatureCollection, MultiLineString, LineString, Polygon, MultiPolygon, Properties -} from '@turf/helpers'; - -/** - * Converts (Multi)LineString(s) to Polygon(s). - * - * @name lineToPolygon - * @param {FeatureCollection|Feature} lines Features to convert - * @param {Object} [options={}] Optional parameters - * @param {Object} [options.properties={}] translates GeoJSON properties to Feature - * @param {boolean} [options.autoComplete=true] auto complete linestrings (matches first & last coordinates) - * @param {boolean} [options.orderCoords=true] sorts linestrings to place outer ring at the first position of the coordinates - * @returns {Feature} converted to Polygons - * @example - * var line = turf.lineString([[125, -30], [145, -30], [145, -20], [125, -20], [125, -30]]); - * - * var polygon = turf.lineToPolygon(line); - * - * //addToMap - * var addToMap = [polygon]; - */ -function lineToPolygon( - lines: Feature | FeatureCollection | G, - options: { - properties?: Properties, - autoComplete?: boolean, - orderCoords?: boolean, - } = {} -) { - // Optional parameters - var properties = options.properties; - var autoComplete = options.autoComplete; - var orderCoords = options.orderCoords; - - // default params - autoComplete = (autoComplete !== undefined) ? autoComplete : true; - orderCoords = (orderCoords !== undefined) ? orderCoords : true; - - switch (lines.type) { - case 'FeatureCollection': - var coords = []; - lines.features.forEach(function (line) { - coords.push(getCoords(lineStringToPolygon(line, {}, autoComplete, orderCoords))); - }); - return multiPolygon(coords, properties); - default: - return lineStringToPolygon(lines, properties, autoComplete, orderCoords); - } -} - -/** - * LineString to Polygon - * - * @private - * @param {Feature} line line - * @param {Object} [properties] translates GeoJSON properties to Feature - * @param {boolean} [autoComplete=true] auto complete linestrings - * @param {boolean} [orderCoords=true] sorts linestrings to place outer ring at the first position of the coordinates - * @returns {Feature} line converted to Polygon - */ -function lineStringToPolygon(line: Feature | G, properties: Properties, autoComplete: boolean, orderCoords: boolean) { - properties = properties ? properties : (line.type === 'Feature') ? line.properties : {} - var geom = getGeom(line); - var coords: any = geom.coordinates; - var type = geom.type; - - if (!coords.length) throw new Error('line must contain coordinates'); - - switch (type) { - case 'LineString': - if (autoComplete) coords = autoCompleteCoords(coords); - return polygon([coords], properties); - case 'MultiLineString': - var multiCoords = []; - var largestArea = 0; - - coords.forEach(function (coord) { - if (autoComplete) coord = autoCompleteCoords(coord); - - // Largest LineString to be placed in the first position of the coordinates array - if (orderCoords) { - var area = calculateArea(turfBBox(lineString(coord))); - if (area > largestArea) { - multiCoords.unshift(coord); - largestArea = area; - } else multiCoords.push(coord); - } else { - multiCoords.push(coord); - } - }); - return polygon(multiCoords, properties); - default: - throw new Error('geometry type ' + type + ' is not supported'); - } -} - -/** - * Auto Complete Coords - matches first & last coordinates - * - * @private - * @param {Array>} coords Coordinates - * @returns {Array>} auto completed coordinates - */ -function autoCompleteCoords(coords) { - var first = coords[0]; - var x1 = first[0]; - var y1 = first[1]; - var last = coords[coords.length - 1]; - var x2 = last[0]; - var y2 = last[1]; - if (x1 !== x2 || y1 !== y2) { - coords.push(first); - } - return coords; -} - -/** - * area - quick approximate area calculation (used to sort) - * - * @private - * @param {Array} bbox BBox [west, south, east, north] - * @returns {number} very quick area calculation - */ -function calculateArea(bbox) { - var west = bbox[0]; - var south = bbox[1]; - var east = bbox[2]; - var north = bbox[3]; - return Math.abs(west - east) * Math.abs(south - north); -} - -export default lineToPolygon; diff --git a/packages/turf-line-to-polygon/package.json b/packages/turf-line-to-polygon/package.json deleted file mode 100644 index ce61efbbeb..0000000000 --- a/packages/turf-line-to-polygon/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "@turf/line-to-polygon", - "version": "6.0.1", - "description": "turf line-to-polygon module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis", - "polygon", - "linestring", - "line" - ], - "author": "Turf Authors", - "contributors": [ - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-line-to-polygon/test.js b/packages/turf-line-to-polygon/test.js deleted file mode 100644 index d311b1a9f7..0000000000 --- a/packages/turf-line-to-polygon/test.js +++ /dev/null @@ -1,41 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { point, lineString } = require('@turf/helpers'); -const lineToPolygon = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -let fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); -// fixtures = fixtures.filter(fixture => fixture.name === 'multi-linestrings-with-holes'); - -test('turf-linestring-to-polygon', t => { - for (const {name, filename, geojson} of fixtures) { - let {autoComplete, properties, orderCoords} = geojson.properties || {}; - properties = properties || {stroke: '#F0F', 'stroke-width': 6}; - const results = lineToPolygon(geojson, { - properties: properties, - autoComplete: autoComplete, - orderCoords: orderCoords - }); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEqual(load.sync(directories.out + filename), results, name); - } - // Handle Errors - t.throws(() => lineToPolygon(point([10, 5])), 'throws - invalid geometry'); - t.throws(() => lineToPolygon(lineString([])), 'throws - empty coordinates'); - t.assert(lineToPolygon(lineString([[10, 5], [20, 10], [30, 20]]), {autocomplete: false}), 'is valid - autoComplete=false'); - t.end(); -}); diff --git a/packages/turf-line-to-polygon/types.ts b/packages/turf-line-to-polygon/types.ts deleted file mode 100644 index 33ed394010..0000000000 --- a/packages/turf-line-to-polygon/types.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { - featureCollection, - lineString, - multiLineString, - Polygon, - LineString, - MultiLineString, - MultiPolygon, - Feature, - FeatureCollection -} from '@turf/helpers' -import lineToPolygon from './' - -// Fixtures -const coords = [[125, -30], [145, -30], [145, -20], [125, -20], [125, -30]]; -const line = lineString(coords); -const multiLine = multiLineString([coords, coords]); -const fc = featureCollection([line, multiLine]); - -// Assert results with types -const poly1 = lineToPolygon(line); // Feature -const poly2 = lineToPolygon(multiLine); // Feature -const poly3 = lineToPolygon(fc); // Feature diff --git a/packages/turf-mask/LICENSE b/packages/turf-mask/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-mask/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-mask/README.md b/packages/turf-mask/README.md deleted file mode 100644 index 33f65c9a63..0000000000 --- a/packages/turf-mask/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# @turf/mask - - - -## mask - -Takes any type of [polygon][1] and an optional mask and returns a [polygon][1] exterior ring with holes. - -**Parameters** - -- `polygon` **([FeatureCollection][2] \| [Feature][3]<([Polygon][4] \| [MultiPolygon][5])>)** GeoJSON Polygon used as interior rings or holes. -- `mask` **[Feature][3]<[Polygon][4]>?** GeoJSON Polygon used as the exterior ring (if undefined, the world extent is used) - -**Examples** - -```javascript -var polygon = turf.polygon([[[112, -21], [116, -36], [146, -39], [153, -24], [133, -10], [112, -21]]]); -var mask = turf.polygon([[[90, -55], [170, -55], [170, 10], [90, 10], [90, -55]]]); - -var masked = turf.mask(polygon, mask); - -//addToMap -var addToMap = [masked] -``` - -Returns **[Feature][3]<[Polygon][4]>** Masked Polygon (exterior ring with holes). - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/mask -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-mask/index.d.ts b/packages/turf-mask/index.d.ts deleted file mode 100644 index 7d3f469b75..0000000000 --- a/packages/turf-mask/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Feature, Polygon, MultiPolygon, FeatureCollection } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#mask - */ -export default function ( - poly: Feature | FeatureCollection | T, - mask?: Feature | Polygon -): Feature; diff --git a/packages/turf-mask/index.js b/packages/turf-mask/index.js deleted file mode 100644 index 269a3fa02e..0000000000 --- a/packages/turf-mask/index.js +++ /dev/null @@ -1,185 +0,0 @@ -import rbush from 'rbush'; -import union from '@turf/union'; -import { polygon, featureCollection } from '@turf/helpers'; -import turfBBox from '@turf/bbox'; -import { flattenEach } from '@turf/meta'; - -/** - * Takes any type of {@link Polygon|polygon} and an optional mask and returns a {@link Polygon|polygon} exterior ring with holes. - * - * @name mask - * @param {FeatureCollection|Feature} polygon GeoJSON Polygon used as interior rings or holes. - * @param {Feature} [mask] GeoJSON Polygon used as the exterior ring (if undefined, the world extent is used) - * @returns {Feature} Masked Polygon (exterior ring with holes). - * @example - * var polygon = turf.polygon([[[112, -21], [116, -36], [146, -39], [153, -24], [133, -10], [112, -21]]]); - * var mask = turf.polygon([[[90, -55], [170, -55], [170, 10], [90, 10], [90, -55]]]); - * - * var masked = turf.mask(polygon, mask); - * - * //addToMap - * var addToMap = [masked] - */ -function mask(polygon, mask) { - // Define mask - var maskPolygon = createMask(mask); - - // Define polygon - var separated = separatePolygons(polygon); - var polygonOuters = separated[0]; - var polygonInners = separated[1]; - - // Union Outers & Inners - polygonOuters = unionPolygons(polygonOuters); - polygonInners = unionPolygons(polygonInners); - - // Create masked area - var masked = buildMask(maskPolygon, polygonOuters, polygonInners); - return masked; -} - -/** - * Build Mask - * - * @private - * @param {Feature} maskPolygon Mask Outer - * @param {FeatureCollection} polygonOuters Polygon Outers - * @param {FeatureCollection} polygonInners Polygon Inners - * @returns {Feature} Feature Polygon - */ -function buildMask(maskPolygon, polygonOuters, polygonInners) { - var coordinates = []; - coordinates.push(maskPolygon.geometry.coordinates[0]); - - flattenEach(polygonOuters, function (feature) { - coordinates.push(feature.geometry.coordinates[0]); - }); - - flattenEach(polygonInners, function (feature) { - coordinates.push(feature.geometry.coordinates[0]); - }); - return polygon(coordinates); -} - -/** - * Separate Polygons to inners & outers - * - * @private - * @param {FeatureCollection|Feature} poly GeoJSON Feature - * @returns {Array, FeatureCollection>} Outer & Inner lines - */ -function separatePolygons(poly) { - var outers = []; - var inners = []; - flattenEach(poly, function (feature) { - var coordinates = feature.geometry.coordinates; - var featureOuter = coordinates[0]; - var featureInner = coordinates.slice(1); - outers.push(polygon([featureOuter])); - featureInner.forEach(function (inner) { - inners.push(polygon([inner])); - }); - }); - return [featureCollection(outers), featureCollection(inners)]; -} - -/** - * Create Mask Coordinates - * - * @private - * @param {Feature} [mask] default to world if undefined - * @returns {Feature} mask coordinate - */ -function createMask(mask) { - var world = [[[180, 90], [-180, 90], [-180, -90], [180, -90], [180, 90]]]; - var coordinates = mask && mask.geometry.coordinates || world; - return polygon(coordinates); -} - -/** - * Union Polygons - * - * @private - * @param {FeatureCollection} polygons collection of polygons - * @returns {FeatureCollection} polygons only apply union if they collide - */ -function unionPolygons(polygons) { - if (polygons.features.length <= 1) return polygons; - - var tree = createIndex(polygons); - var results = []; - var removed = {}; - - flattenEach(polygons, function (currentFeature, currentIndex) { - // Exclude any removed features - if (removed[currentIndex]) return true; - - // Don't search for itself - tree.remove({index: currentIndex}, filterByIndex); - removed[currentIndex] = true; - - // Keep applying the union operation until no more overlapping features - while (true) { - var bbox = turfBBox(currentFeature); - var search = tree.search({ - minX: bbox[0], - minY: bbox[1], - maxX: bbox[2], - maxY: bbox[3] - }); - if (search.length > 0) { - var polys = search.map(function (item) { - removed[item.index] = true; - tree.remove({index: item.index}, filterByIndex); - return item.geojson; - }); - polys.push(currentFeature); - currentFeature = union.apply(this, polys); - } - // Done - if (search.length === 0) break; - } - results.push(currentFeature); - }); - - return featureCollection(results); -} - -/** - * Filter by Index - RBush helper function - * - * @private - * @param {Object} a remove item - * @param {Object} b search item - * @returns {boolean} true if matches - */ -function filterByIndex(a, b) { - return a.index === b.index; -} - -/** - * Create RBush Tree Index - * - * @private - * @param {FeatureCollection} features GeoJSON FeatureCollection - * @returns {RBush} RBush Tree - */ -function createIndex(features) { - var tree = rbush(); - var load = []; - flattenEach(features, function (feature, index) { - var bbox = turfBBox(feature); - load.push({ - minX: bbox[0], - minY: bbox[1], - maxX: bbox[2], - maxY: bbox[3], - geojson: feature, - index: index - }); - }); - tree.load(load); - return tree; -} - -export default mask; diff --git a/packages/turf-mask/package.json b/packages/turf-mask/package.json deleted file mode 100644 index 2597d99b69..0000000000 --- a/packages/turf-mask/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "@turf/mask", - "version": "5.1.5", - "description": "turf mask module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "mask", - "polygon" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "load-json-file": "*", - "mkdirp": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/helpers": "6.x", - "@turf/meta": "6.x", - "@turf/union": "^5.1.5", - "rbush": "^2.0.1" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-mask/test.js b/packages/turf-mask/test.js deleted file mode 100644 index 1e4f0a821b..0000000000 --- a/packages/turf-mask/test.js +++ /dev/null @@ -1,30 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import mask from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -let fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(path.join(directories.in, filename)) - }; -}); - -test('turf-mask', t => { - for (const {name, filename, geojson} of fixtures) { - const [polygon, masking] = geojson.features; - const results = mask(polygon, masking); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEquals(results, load.sync(directories.out + filename), name); - } - t.end(); -}); diff --git a/packages/turf-mask/test/out/multi-polygon.geojson b/packages/turf-mask/test/out/multi-polygon.geojson deleted file mode 100644 index da16b2f889..0000000000 --- a/packages/turf-mask/test/out/multi-polygon.geojson +++ /dev/null @@ -1,523 +0,0 @@ -{ - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 180, - 90 - ], - [ - -180, - 90 - ], - [ - -180, - -90 - ], - [ - 180, - -90 - ], - [ - 180, - 90 - ] - ], - [ - [ - 174.8347149, - -36.8815236 - ], - [ - 174.835116, - -36.8807968 - ], - [ - 174.8347295, - -36.8806857 - ], - [ - 174.8350004, - -36.8802174 - ], - [ - 174.8351245, - -36.8798054 - ], - [ - 174.8353415, - -36.8797934 - ], - [ - 174.8355479, - -36.8795814 - ], - [ - 174.8354683, - -36.8795601 - ], - [ - 174.8355874, - -36.8793891 - ], - [ - 174.8357201, - -36.8790301 - ], - [ - 174.8357777, - -36.8790427 - ], - [ - 174.8360549, - -36.8784168 - ], - [ - 174.8360445, - -36.8784047 - ], - [ - 174.8369669, - -36.8778472 - ], - [ - 174.837355, - -36.8776834 - ], - [ - 174.8384676, - -36.878055 - ], - [ - 174.8376266, - -36.8798969 - ], - [ - 174.8371047, - -36.8807158 - ], - [ - 174.8362531, - -36.881711 - ], - [ - 174.8355443, - -36.8821803 - ], - [ - 174.8350392, - -36.8821049 - ], - [ - 174.8347409, - -36.8819051 - ], - [ - 174.8347774, - -36.881634 - ], - [ - 174.8347149, - -36.8815236 - ] - ], - [ - [ - 174.8257084, - -36.8869965 - ], - [ - 174.8259044, - -36.8868107 - ], - [ - 174.8261193, - -36.8867062 - ], - [ - 174.8261552, - -36.8866995 - ], - [ - 174.8261688, - -36.886697 - ], - [ - 174.8263768, - -36.8866582 - ], - [ - 174.8265485, - -36.8865621 - ], - [ - 174.8268918, - -36.8864866 - ], - [ - 174.8272938, - -36.8863759 - ], - [ - 174.827812, - -36.8862177 - ], - [ - 174.8285583, - -36.8859898 - ], - [ - 174.8285298, - -36.8854835 - ], - [ - 174.828547, - -36.8850853 - ], - [ - 174.8290133, - -36.8842478 - ], - [ - 174.8294482, - -36.8835612 - ], - [ - 174.8295855, - -36.8828026 - ], - [ - 174.829535, - -36.8828012 - ], - [ - 174.829225, - -36.8827923 - ], - [ - 174.8290019, - -36.8821676 - ], - [ - 174.8291049, - -36.8820989 - ], - [ - 174.8294238, - -36.8818914 - ], - [ - 174.8293809, - -36.8815138 - ], - [ - 174.829062, - -36.8788584 - ], - [ - 174.8290963, - -36.8787142 - ], - [ - 174.8291735, - -36.8785151 - ], - [ - 174.8291478, - -36.8783915 - ], - [ - 174.8291478, - -36.8782886 - ], - [ - 174.8302808, - -36.8777874 - ], - [ - 174.8305018, - -36.8776747 - ], - [ - 174.8309073, - -36.8774235 - ], - [ - 174.8312421, - -36.8772587 - ], - [ - 174.8312077, - -36.8771008 - ], - [ - 174.8313365, - -36.8770253 - ], - [ - 174.8315081, - -36.8771832 - ], - [ - 174.8319464, - -36.8770175 - ], - [ - 174.8320384, - -36.8768042 - ], - [ - 174.8322194, - -36.876702 - ], - [ - 174.8322845, - -36.8767656 - ], - [ - 174.8325172, - -36.8766213 - ], - [ - 174.8329038, - -36.8761774 - ], - [ - 174.8331871, - -36.8758692 - ], - [ - 174.833726, - -36.8754489 - ], - [ - 174.8343983, - -36.8756894 - ], - [ - 174.8345787, - -36.8753974 - ], - [ - 174.8345392, - -36.8752539 - ], - [ - 174.8350149, - -36.875154 - ], - [ - 174.8350022, - -36.8752449 - ], - [ - 174.8350096, - -36.8753835 - ], - [ - 174.8350415, - -36.8755096 - ], - [ - 174.8346298, - -36.8755945 - ], - [ - 174.8347802, - -36.8758729 - ], - [ - 174.8352751, - -36.8760453 - ], - [ - 174.8353743, - -36.8758963 - ], - [ - 174.8356795, - -36.8760915 - ], - [ - 174.8357668, - -36.876134 - ], - [ - 174.8357051, - -36.8761931 - ], - [ - 174.8355399, - -36.8764449 - ], - [ - 174.8353877, - -36.8766751 - ], - [ - 174.8351645, - -36.8767575 - ], - [ - 174.8349499, - -36.8768261 - ], - [ - 174.8347697, - -36.8769085 - ], - [ - 174.8343234, - -36.8772656 - ], - [ - 174.8337539, - -36.8777781 - ], - [ - 174.8333146, - -36.878309 - ], - [ - 174.8331132, - -36.8782542 - ], - [ - 174.8328699, - -36.878784 - ], - [ - 174.8342416, - -36.8795988 - ], - [ - 174.8347595, - -36.8798408 - ], - [ - 174.8349119, - -36.8798696 - ], - [ - 174.8348716, - -36.8800115 - ], - [ - 174.8346495, - -36.8804375 - ], - [ - 174.8346312, - -36.8804379 - ], - [ - 174.8325982, - -36.8803963 - ], - [ - 174.8324179, - -36.8806023 - ], - [ - 174.8321192, - -36.8820636 - ], - [ - 174.8319151, - -36.8828293 - ], - [ - 174.8311496, - -36.8842651 - ], - [ - 174.8315144, - -36.8849051 - ], - [ - 174.8321967, - -36.8848087 - ], - [ - 174.8332402, - -36.8837406 - ], - [ - 174.8340081, - -36.8834433 - ], - [ - 174.836428, - -36.8830636 - ], - [ - 174.8367485, - -36.8829628 - ], - [ - 174.8369142, - -36.88283 - ], - [ - 174.8373394, - -36.8830989 - ], - [ - 174.8373321, - -36.8831729 - ], - [ - 174.8367548, - -36.8837641 - ], - [ - 174.8356801, - -36.8844927 - ], - [ - 174.8354962, - -36.8846273 - ], - [ - 174.834388, - -36.885941 - ], - [ - 174.8341202, - -36.8862468 - ], - [ - 174.8336846, - -36.8865436 - ], - [ - 174.8314673, - -36.8878689 - ], - [ - 174.8311438, - -36.8878347 - ], - [ - 174.8296591, - -36.8874264 - ], - [ - 174.8278042, - -36.8875561 - ], - [ - 174.8276109, - -36.887539 - ], - [ - 174.8257084, - -36.8869965 - ] - ] - ] - } -} diff --git a/packages/turf-mask/types.ts b/packages/turf-mask/types.ts deleted file mode 100644 index fb7a5d7e50..0000000000 --- a/packages/turf-mask/types.ts +++ /dev/null @@ -1,8 +0,0 @@ -import {polygon} from '@turf/helpers'; -import mask from './'; - -const poly1 = polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]); -const poly2 = polygon([[[30, 5], [-40, -10], [-50, -10], [-40, 5], [30, 5]]]); - -mask(poly1) -mask(poly1, poly2) diff --git a/packages/turf-meta/.gitignore b/packages/turf-meta/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-meta/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-meta/LICENSE b/packages/turf-meta/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-meta/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-meta/README.md b/packages/turf-meta/README.md deleted file mode 100644 index d0a4742c99..0000000000 --- a/packages/turf-meta/README.md +++ /dev/null @@ -1,858 +0,0 @@ -# @turf/meta - - - -## coordEachCallback - -Callback for coordEach - -Type: [Function][1] - -**Parameters** - -- `currentCoord` **[Array][2]<[number][3]>** The current coordinate being processed. -- `coordIndex` **[number][3]** The current index of the coordinate being processed. -- `featureIndex` **[number][3]** The current index of the Feature being processed. -- `multiFeatureIndex` **[number][3]** The current index of the Multi-Feature being processed. -- `geometryIndex` **[number][3]** The current index of the Geometry being processed. - -## coordEach - -Iterate over coordinates in any GeoJSON object, similar to Array.forEach() - -**Parameters** - -- `geojson` **([FeatureCollection][4] \| [Feature][5] \| [Geometry][6])** any GeoJSON object -- `callback` **[Function][1]** a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex) -- `excludeWrapCoord` **[boolean][7]** whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration. (optional, default `false`) - -**Examples** - -```javascript -var features = turf.featureCollection([ - turf.point([26, 37], {"foo": "bar"}), - turf.point([36, 53], {"hello": "world"}) -]); - -turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) { - //=currentCoord - //=coordIndex - //=featureIndex - //=multiFeatureIndex - //=geometryIndex -}); -``` - -Returns **void** - -## coordReduce - -Reduce coordinates in any GeoJSON object, similar to Array.reduce() - -**Parameters** - -- `geojson` **([FeatureCollection][4] \| [Geometry][6] \| [Feature][5])** any GeoJSON object -- `callback` **[Function][1]** a method that takes (previousValue, currentCoord, coordIndex) -- `initialValue` **any?** Value to use as the first argument to the first call of the callback. -- `excludeWrapCoord` **[boolean][7]** whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration. (optional, default `false`) - -**Examples** - -```javascript -var features = turf.featureCollection([ - turf.point([26, 37], {"foo": "bar"}), - turf.point([36, 53], {"hello": "world"}) -]); - -turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) { - //=previousValue - //=currentCoord - //=coordIndex - //=featureIndex - //=multiFeatureIndex - //=geometryIndex - return currentCoord; -}); -``` - -Returns **any** The value that results from the reduction. - -## coordReduceCallback - -Callback for coordReduce - -The first time the callback function is called, the values provided as arguments depend -on whether the reduce method has an initialValue argument. - -If an initialValue is provided to the reduce method: - -- The previousValue argument is initialValue. -- The currentValue argument is the value of the first element present in the array. - -If an initialValue is not provided: - -- The previousValue argument is the value of the first element present in the array. -- The currentValue argument is the value of the second element present in the array. - -Type: [Function][1] - -**Parameters** - -- `previousValue` **any** The accumulated value previously returned in the last invocation - of the callback, or initialValue, if supplied. -- `currentCoord` **[Array][2]<[number][3]>** The current coordinate being processed. -- `coordIndex` **[number][3]** The current index of the coordinate being processed. - Starts at index 0, if an initialValue is provided, and at index 1 otherwise. -- `featureIndex` **[number][3]** The current index of the Feature being processed. -- `multiFeatureIndex` **[number][3]** The current index of the Multi-Feature being processed. -- `geometryIndex` **[number][3]** The current index of the Geometry being processed. - -## propEach - -Iterate over properties in any GeoJSON object, similar to Array.forEach() - -**Parameters** - -- `geojson` **([FeatureCollection][4] \| [Feature][5])** any GeoJSON object -- `callback` **[Function][1]** a method that takes (currentProperties, featureIndex) - -**Examples** - -```javascript -var features = turf.featureCollection([ - turf.point([26, 37], {foo: 'bar'}), - turf.point([36, 53], {hello: 'world'}) -]); - -turf.propEach(features, function (currentProperties, featureIndex) { - //=currentProperties - //=featureIndex -}); -``` - -Returns **void** - -## propEachCallback - -Callback for propEach - -Type: [Function][1] - -**Parameters** - -- `currentProperties` **[Object][8]** The current Properties being processed. -- `featureIndex` **[number][3]** The current index of the Feature being processed. - -## propReduceCallback - -Callback for propReduce - -The first time the callback function is called, the values provided as arguments depend -on whether the reduce method has an initialValue argument. - -If an initialValue is provided to the reduce method: - -- The previousValue argument is initialValue. -- The currentValue argument is the value of the first element present in the array. - -If an initialValue is not provided: - -- The previousValue argument is the value of the first element present in the array. -- The currentValue argument is the value of the second element present in the array. - -Type: [Function][1] - -**Parameters** - -- `previousValue` **any** The accumulated value previously returned in the last invocation - of the callback, or initialValue, if supplied. -- `currentProperties` **any** The current Properties being processed. -- `featureIndex` **[number][3]** The current index of the Feature being processed. - -## propReduce - -Reduce properties in any GeoJSON object into a single value, -similar to how Array.reduce works. However, in this case we lazily run -the reduction, so an array of all properties is unnecessary. - -**Parameters** - -- `geojson` **([FeatureCollection][4] \| [Feature][5])** any GeoJSON object -- `callback` **[Function][1]** a method that takes (previousValue, currentProperties, featureIndex) -- `initialValue` **any?** Value to use as the first argument to the first call of the callback. - -**Examples** - -```javascript -var features = turf.featureCollection([ - turf.point([26, 37], {foo: 'bar'}), - turf.point([36, 53], {hello: 'world'}) -]); - -turf.propReduce(features, function (previousValue, currentProperties, featureIndex) { - //=previousValue - //=currentProperties - //=featureIndex - return currentProperties -}); -``` - -Returns **any** The value that results from the reduction. - -## featureEachCallback - -Callback for featureEach - -Type: [Function][1] - -**Parameters** - -- `currentFeature` **[Feature][5]<any>** The current Feature being processed. -- `featureIndex` **[number][3]** The current index of the Feature being processed. - -## featureEach - -Iterate over features in any GeoJSON object, similar to -Array.forEach. - -**Parameters** - -- `geojson` **([FeatureCollection][4] \| [Feature][5] \| [Geometry][6])** any GeoJSON object -- `callback` **[Function][1]** a method that takes (currentFeature, featureIndex) - -**Examples** - -```javascript -var features = turf.featureCollection([ - turf.point([26, 37], {foo: 'bar'}), - turf.point([36, 53], {hello: 'world'}) -]); - -turf.featureEach(features, function (currentFeature, featureIndex) { - //=currentFeature - //=featureIndex -}); -``` - -Returns **void** - -## featureReduceCallback - -Callback for featureReduce - -The first time the callback function is called, the values provided as arguments depend -on whether the reduce method has an initialValue argument. - -If an initialValue is provided to the reduce method: - -- The previousValue argument is initialValue. -- The currentValue argument is the value of the first element present in the array. - -If an initialValue is not provided: - -- The previousValue argument is the value of the first element present in the array. -- The currentValue argument is the value of the second element present in the array. - -Type: [Function][1] - -**Parameters** - -- `previousValue` **any** The accumulated value previously returned in the last invocation - of the callback, or initialValue, if supplied. -- `currentFeature` **[Feature][5]** The current Feature being processed. -- `featureIndex` **[number][3]** The current index of the Feature being processed. - -## featureReduce - -Reduce features in any GeoJSON object, similar to Array.reduce(). - -**Parameters** - -- `geojson` **([FeatureCollection][4] \| [Feature][5] \| [Geometry][6])** any GeoJSON object -- `callback` **[Function][1]** a method that takes (previousValue, currentFeature, featureIndex) -- `initialValue` **any?** Value to use as the first argument to the first call of the callback. - -**Examples** - -```javascript -var features = turf.featureCollection([ - turf.point([26, 37], {"foo": "bar"}), - turf.point([36, 53], {"hello": "world"}) -]); - -turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) { - //=previousValue - //=currentFeature - //=featureIndex - return currentFeature -}); -``` - -Returns **any** The value that results from the reduction. - -## coordAll - -Get all coordinates from any GeoJSON object. - -**Parameters** - -- `geojson` **([FeatureCollection][4] \| [Feature][5] \| [Geometry][6])** any GeoJSON object - -**Examples** - -```javascript -var features = turf.featureCollection([ - turf.point([26, 37], {foo: 'bar'}), - turf.point([36, 53], {hello: 'world'}) -]); - -var coords = turf.coordAll(features); -//= [[26, 37], [36, 53]] -``` - -Returns **[Array][2]<[Array][2]<[number][3]>>** coordinate position array - -## geomEachCallback - -Callback for geomEach - -Type: [Function][1] - -**Parameters** - -- `currentGeometry` **[Geometry][6]** The current Geometry being processed. -- `featureIndex` **[number][3]** The current index of the Feature being processed. -- `featureProperties` **[Object][8]** The current Feature Properties being processed. -- `featureBBox` **[Array][2]<[number][3]>** The current Feature BBox being processed. -- `featureId` **([number][3] \| [string][9])** The current Feature Id being processed. - -## geomEach - -Iterate over each geometry in any GeoJSON object, similar to Array.forEach() - -**Parameters** - -- `geojson` **([FeatureCollection][4] \| [Feature][5] \| [Geometry][6])** any GeoJSON object -- `callback` **[Function][1]** a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) - -**Examples** - -```javascript -var features = turf.featureCollection([ - turf.point([26, 37], {foo: 'bar'}), - turf.point([36, 53], {hello: 'world'}) -]); - -turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) { - //=currentGeometry - //=featureIndex - //=featureProperties - //=featureBBox - //=featureId -}); -``` - -Returns **void** - -## geomReduceCallback - -Callback for geomReduce - -The first time the callback function is called, the values provided as arguments depend -on whether the reduce method has an initialValue argument. - -If an initialValue is provided to the reduce method: - -- The previousValue argument is initialValue. -- The currentValue argument is the value of the first element present in the array. - -If an initialValue is not provided: - -- The previousValue argument is the value of the first element present in the array. -- The currentValue argument is the value of the second element present in the array. - -Type: [Function][1] - -**Parameters** - -- `previousValue` **any** The accumulated value previously returned in the last invocation - of the callback, or initialValue, if supplied. -- `currentGeometry` **[Geometry][6]** The current Geometry being processed. -- `featureIndex` **[number][3]** The current index of the Feature being processed. -- `featureProperties` **[Object][8]** The current Feature Properties being processed. -- `featureBBox` **[Array][2]<[number][3]>** The current Feature BBox being processed. -- `featureId` **([number][3] \| [string][9])** The current Feature Id being processed. - -## geomReduce - -Reduce geometry in any GeoJSON object, similar to Array.reduce(). - -**Parameters** - -- `geojson` **([FeatureCollection][4] \| [Feature][5] \| [Geometry][6])** any GeoJSON object -- `callback` **[Function][1]** a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) -- `initialValue` **any?** Value to use as the first argument to the first call of the callback. - -**Examples** - -```javascript -var features = turf.featureCollection([ - turf.point([26, 37], {foo: 'bar'}), - turf.point([36, 53], {hello: 'world'}) -]); - -turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) { - //=previousValue - //=currentGeometry - //=featureIndex - //=featureProperties - //=featureBBox - //=featureId - return currentGeometry -}); -``` - -Returns **any** The value that results from the reduction. - -## flattenEachCallback - -Callback for flattenEach - -Type: [Function][1] - -**Parameters** - -- `currentFeature` **[Feature][5]** The current flattened feature being processed. -- `featureIndex` **[number][3]** The current index of the Feature being processed. -- `multiFeatureIndex` **[number][3]** The current index of the Multi-Feature being processed. - -## flattenEach - -Iterate over flattened features in any GeoJSON object, similar to -Array.forEach. - -**Parameters** - -- `geojson` **([FeatureCollection][4] \| [Feature][5] \| [Geometry][6])** any GeoJSON object -- `callback` **[Function][1]** a method that takes (currentFeature, featureIndex, multiFeatureIndex) - -**Examples** - -```javascript -var features = turf.featureCollection([ - turf.point([26, 37], {foo: 'bar'}), - turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'}) -]); - -turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) { - //=currentFeature - //=featureIndex - //=multiFeatureIndex -}); -``` - -## flattenReduceCallback - -Callback for flattenReduce - -The first time the callback function is called, the values provided as arguments depend -on whether the reduce method has an initialValue argument. - -If an initialValue is provided to the reduce method: - -- The previousValue argument is initialValue. -- The currentValue argument is the value of the first element present in the array. - -If an initialValue is not provided: - -- The previousValue argument is the value of the first element present in the array. -- The currentValue argument is the value of the second element present in the array. - -Type: [Function][1] - -**Parameters** - -- `previousValue` **any** The accumulated value previously returned in the last invocation - of the callback, or initialValue, if supplied. -- `currentFeature` **[Feature][5]** The current Feature being processed. -- `featureIndex` **[number][3]** The current index of the Feature being processed. -- `multiFeatureIndex` **[number][3]** The current index of the Multi-Feature being processed. - -## flattenReduce - -Reduce flattened features in any GeoJSON object, similar to Array.reduce(). - -**Parameters** - -- `geojson` **([FeatureCollection][4] \| [Feature][5] \| [Geometry][6])** any GeoJSON object -- `callback` **[Function][1]** a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex) -- `initialValue` **any?** Value to use as the first argument to the first call of the callback. - -**Examples** - -```javascript -var features = turf.featureCollection([ - turf.point([26, 37], {foo: 'bar'}), - turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'}) -]); - -turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) { - //=previousValue - //=currentFeature - //=featureIndex - //=multiFeatureIndex - return currentFeature -}); -``` - -Returns **any** The value that results from the reduction. - -## segmentEachCallback - -Callback for segmentEach - -Type: [Function][1] - -**Parameters** - -- `currentSegment` **[Feature][5]<[LineString][10]>** The current Segment being processed. -- `featureIndex` **[number][3]** The current index of the Feature being processed. -- `multiFeatureIndex` **[number][3]** The current index of the Multi-Feature being processed. -- `geometryIndex` **[number][3]** The current index of the Geometry being processed. -- `segmentIndex` **[number][3]** The current index of the Segment being processed. - -Returns **void** - -## segmentEach - -Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach() -(Multi)Point geometries do not contain segments therefore they are ignored during this operation. - -**Parameters** - -- `geojson` **([FeatureCollection][4] \| [Feature][5] \| [Geometry][6])** any GeoJSON -- `callback` **[Function][1]** a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) - -**Examples** - -```javascript -var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]); - -// Iterate over GeoJSON by 2-vertex segments -turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) { - //=currentSegment - //=featureIndex - //=multiFeatureIndex - //=geometryIndex - //=segmentIndex -}); - -// Calculate the total number of segments -var total = 0; -turf.segmentEach(polygon, function () { - total++; -}); -``` - -Returns **void** - -## segmentReduceCallback - -Callback for segmentReduce - -The first time the callback function is called, the values provided as arguments depend -on whether the reduce method has an initialValue argument. - -If an initialValue is provided to the reduce method: - -- The previousValue argument is initialValue. -- The currentValue argument is the value of the first element present in the array. - -If an initialValue is not provided: - -- The previousValue argument is the value of the first element present in the array. -- The currentValue argument is the value of the second element present in the array. - -Type: [Function][1] - -**Parameters** - -- `previousValue` **any** The accumulated value previously returned in the last invocation - of the callback, or initialValue, if supplied. -- `currentSegment` **[Feature][5]<[LineString][10]>** The current Segment being processed. -- `featureIndex` **[number][3]** The current index of the Feature being processed. -- `multiFeatureIndex` **[number][3]** The current index of the Multi-Feature being processed. -- `geometryIndex` **[number][3]** The current index of the Geometry being processed. -- `segmentIndex` **[number][3]** The current index of the Segment being processed. - -## segmentReduce - -Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce() -(Multi)Point geometries do not contain segments therefore they are ignored during this operation. - -**Parameters** - -- `geojson` **([FeatureCollection][4] \| [Feature][5] \| [Geometry][6])** any GeoJSON -- `callback` **[Function][1]** a method that takes (previousValue, currentSegment, currentIndex) -- `initialValue` **any?** Value to use as the first argument to the first call of the callback. - -**Examples** - -```javascript -var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]); - -// Iterate over GeoJSON by 2-vertex segments -turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) { - //= previousSegment - //= currentSegment - //= featureIndex - //= multiFeatureIndex - //= geometryIndex - //= segmentInex - return currentSegment -}); - -// Calculate the total number of segments -var initialValue = 0 -var total = turf.segmentReduce(polygon, function (previousValue) { - previousValue++; - return previousValue; -}, initialValue); -``` - -Returns **void** - -## lineEachCallback - -Callback for lineEach - -Type: [Function][1] - -**Parameters** - -- `currentLine` **[Feature][5]<[LineString][10]>** The current LineString|LinearRing being processed -- `featureIndex` **[number][3]** The current index of the Feature being processed -- `multiFeatureIndex` **[number][3]** The current index of the Multi-Feature being processed -- `geometryIndex` **[number][3]** The current index of the Geometry being processed - -## lineEach - -Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries, -similar to Array.forEach. - -**Parameters** - -- `geojson` **([Geometry][6] \| [Feature][5]<([LineString][10] \| [Polygon][11] \| [MultiLineString][12] \| [MultiPolygon][13])>)** object -- `callback` **[Function][1]** a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex) - -**Examples** - -```javascript -var multiLine = turf.multiLineString([ - [[26, 37], [35, 45]], - [[36, 53], [38, 50], [41, 55]] -]); - -turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) { - //=currentLine - //=featureIndex - //=multiFeatureIndex - //=geometryIndex -}); -``` - -## lineReduceCallback - -Callback for lineReduce - -The first time the callback function is called, the values provided as arguments depend -on whether the reduce method has an initialValue argument. - -If an initialValue is provided to the reduce method: - -- The previousValue argument is initialValue. -- The currentValue argument is the value of the first element present in the array. - -If an initialValue is not provided: - -- The previousValue argument is the value of the first element present in the array. -- The currentValue argument is the value of the second element present in the array. - -Type: [Function][1] - -**Parameters** - -- `previousValue` **any** The accumulated value previously returned in the last invocation - of the callback, or initialValue, if supplied. -- `currentLine` **[Feature][5]<[LineString][10]>** The current LineString|LinearRing being processed. -- `featureIndex` **[number][3]** The current index of the Feature being processed -- `multiFeatureIndex` **[number][3]** The current index of the Multi-Feature being processed -- `geometryIndex` **[number][3]** The current index of the Geometry being processed - -## lineReduce - -Reduce features in any GeoJSON object, similar to Array.reduce(). - -**Parameters** - -- `geojson` **([Geometry][6] \| [Feature][5]<([LineString][10] \| [Polygon][11] \| [MultiLineString][12] \| [MultiPolygon][13])>)** object -- `callback` **[Function][1]** a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) -- `initialValue` **any?** Value to use as the first argument to the first call of the callback. - -**Examples** - -```javascript -var multiPoly = turf.multiPolygon([ - turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]), - turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]]) -]); - -turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) { - //=previousValue - //=currentLine - //=featureIndex - //=multiFeatureIndex - //=geometryIndex - return currentLine -}); -``` - -Returns **any** The value that results from the reduction. - -## findSegment - -Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes. - -Negative indexes are permitted. -Point & MultiPoint will always return null. - -**Parameters** - -- `geojson` **([FeatureCollection][4] \| [Feature][5] \| [Geometry][6])** Any GeoJSON Feature or Geometry -- `options` **[Object][8]** Optional parameters (optional, default `{}`) - - `options.featureIndex` **[number][3]** Feature Index (optional, default `0`) - - `options.multiFeatureIndex` **[number][3]** Multi-Feature Index (optional, default `0`) - - `options.geometryIndex` **[number][3]** Geometry Index (optional, default `0`) - - `options.segmentIndex` **[number][3]** Segment Index (optional, default `0`) - - `options.properties` **[Object][8]** Translate Properties to output LineString (optional, default `{}`) - - `options.bbox` **[BBox][14]** Translate BBox to output LineString (optional, default `{}`) - - `options.id` **([number][3] \| [string][9])** Translate Id to output LineString (optional, default `{}`) - -**Examples** - -```javascript -var multiLine = turf.multiLineString([ - [[10, 10], [50, 30], [30, 40]], - [[-10, -10], [-50, -30], [-30, -40]] -]); - -// First Segment (defaults are 0) -turf.findSegment(multiLine); -// => Feature> - -// First Segment of 2nd Multi Feature -turf.findSegment(multiLine, {multiFeatureIndex: 1}); -// => Feature> - -// Last Segment of Last Multi Feature -turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1}); -// => Feature> -``` - -Returns **[Feature][5]<[LineString][10]>** 2-vertex GeoJSON Feature LineString - -## findPoint - -Finds a particular Point from a GeoJSON using `@turf/meta` indexes. - -Negative indexes are permitted. - -**Parameters** - -- `geojson` **([FeatureCollection][4] \| [Feature][5] \| [Geometry][6])** Any GeoJSON Feature or Geometry -- `options` **[Object][8]** Optional parameters (optional, default `{}`) - - `options.featureIndex` **[number][3]** Feature Index (optional, default `0`) - - `options.multiFeatureIndex` **[number][3]** Multi-Feature Index (optional, default `0`) - - `options.geometryIndex` **[number][3]** Geometry Index (optional, default `0`) - - `options.coordIndex` **[number][3]** Coord Index (optional, default `0`) - - `options.properties` **[Object][8]** Translate Properties to output Point (optional, default `{}`) - - `options.bbox` **[BBox][14]** Translate BBox to output Point (optional, default `{}`) - - `options.id` **([number][3] \| [string][9])** Translate Id to output Point (optional, default `{}`) - -**Examples** - -```javascript -var multiLine = turf.multiLineString([ - [[10, 10], [50, 30], [30, 40]], - [[-10, -10], [-50, -30], [-30, -40]] -]); - -// First Segment (defaults are 0) -turf.findPoint(multiLine); -// => Feature> - -// First Segment of the 2nd Multi-Feature -turf.findPoint(multiLine, {multiFeatureIndex: 1}); -// => Feature> - -// Last Segment of last Multi-Feature -turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1}); -// => Feature> -``` - -Returns **[Feature][5]<[Point][15]>** 2-vertex GeoJSON Feature Point - -[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function - -[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[4]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[10]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[11]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[12]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[13]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[14]: https://tools.ietf.org/html/rfc7946#section-5 - -[15]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/meta -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-meta/bench.js b/packages/turf-meta/bench.js deleted file mode 100644 index 7e2f584b1e..0000000000 --- a/packages/turf-meta/bench.js +++ /dev/null @@ -1,98 +0,0 @@ -const Benchmark = require('benchmark'); -const random = require('@turf/random'); -const meta = require('./'); - -const fixtures = { - point: random.randomPoint(), - points: random.randomPoint(1000), - polygon: random.randomPolygon(), - polygons: random.randomPolygon(1000) -}; - -const suite = new Benchmark.Suite('turf-meta'); - -/** - * Benchmark Results - * segmentEach - point x 3,541,484 ops/sec ±6.03% (88 runs sampled) - * segmentReduce - point x 3,245,821 ops/sec ±0.95% (86 runs sampled) - * flattenEach - point x 6,447,234 ops/sec ±5.56% (79 runs sampled) - * flattenReduce - point x 5,415,555 ops/sec ±1.28% (85 runs sampled) - * coordEach - point x 19,941,547 ops/sec ±0.64% (84 runs sampled) - * coordReduce - point x 11,959,189 ops/sec ±1.53% (85 runs sampled) - * propEach - point x 29,317,809 ops/sec ±1.38% (85 runs sampled) - * propReduce - point x 14,552,839 ops/sec ±1.06% (90 runs sampled) - * geomEach - point x 22,137,140 ops/sec ±0.95% (88 runs sampled) - * geomReduce - point x 12,416,033 ops/sec ±0.94% (88 runs sampled) - * featureEach - point x 29,588,658 ops/sec ±1.02% (88 runs sampled) - * featureReduce - point x 15,372,497 ops/sec ±1.11% (89 runs sampled) - * coordAll - point x 8,348,718 ops/sec ±0.68% (92 runs sampled) - * segmentEach - points x 7,568 ops/sec ±1.42% (90 runs sampled) - * segmentReduce - points x 7,719 ops/sec ±0.88% (90 runs sampled) - * flattenEach - points x 18,821 ops/sec ±7.17% (76 runs sampled) - * flattenReduce - points x 17,848 ops/sec ±1.10% (88 runs sampled) - * coordEach - points x 71,017 ops/sec ±0.80% (90 runs sampled) - * coordReduce - points x 46,986 ops/sec ±1.24% (91 runs sampled) - * propEach - points x 137,509 ops/sec ±0.38% (96 runs sampled) - * propReduce - points x 67,197 ops/sec ±1.44% (92 runs sampled) - * geomEach - points x 69,417 ops/sec ±0.77% (93 runs sampled) - * geomReduce - points x 45,830 ops/sec ±1.18% (92 runs sampled) - * featureEach - points x 151,234 ops/sec ±0.45% (92 runs sampled) - * featureReduce - points x 71,235 ops/sec ±1.51% (92 runs sampled) - * coordAll - points x 40,960 ops/sec ±0.88% (94 runs sampled) - * segmentEach - polygon x 884,579 ops/sec ±2.06% (82 runs sampled) - * segmentReduce - polygon x 770,112 ops/sec ±1.65% (85 runs sampled) - * flattenEach - polygon x 6,262,904 ops/sec ±2.84% (85 runs sampled) - * flattenReduce - polygon x 4,944,606 ops/sec ±4.15% (82 runs sampled) - * coordEach - polygon x 6,153,922 ops/sec ±2.36% (87 runs sampled) - * coordReduce - polygon x 3,348,489 ops/sec ±2.08% (91 runs sampled) - * propEach - polygon x 30,816,868 ops/sec ±0.96% (88 runs sampled) - * propReduce - polygon x 15,664,358 ops/sec ±0.88% (91 runs sampled) - * geomEach - polygon x 21,426,447 ops/sec ±1.19% (91 runs sampled) - * geomReduce - polygon x 11,585,812 ops/sec ±2.61% (84 runs sampled) - * featureEach - polygon x 29,478,632 ops/sec ±1.86% (87 runs sampled) - * featureReduce - polygon x 14,642,632 ops/sec ±2.62% (81 runs sampled) - * coordAll - polygon x 2,080,425 ops/sec ±13.27% (61 runs sampled) - * segmentEach - polygons x 1,042 ops/sec ±3.16% (76 runs sampled) - * segmentReduce - polygons x 912 ops/sec ±4.70% (80 runs sampled) - * flattenEach - polygons x 17,587 ops/sec ±3.05% (85 runs sampled) - * flattenReduce - polygons x 16,576 ops/sec ±1.33% (86 runs sampled) - * coordEach - polygons x 3,040 ops/sec ±15.62% (41 runs sampled) - * coordReduce - polygons x 4,100 ops/sec ±7.31% (85 runs sampled) - * propEach - polygons x 126,455 ops/sec ±0.85% (87 runs sampled) - * propReduce - polygons x 61,469 ops/sec ±2.96% (83 runs sampled) - * geomEach - polygons x 59,267 ops/sec ±5.22% (81 runs sampled) - * geomReduce - polygons x 24,424 ops/sec ±12.17% (52 runs sampled) - * featureEach - polygons x 110,212 ops/sec ±7.42% (71 runs sampled) - * featureReduce - polygons x 63,244 ops/sec ±3.74% (81 runs sampled) - * coordAll - polygons x 1,662 ops/sec ±19.73% (44 runs sampled) - * findSegment - polygon x 2,558,258 ops/sec ±0.80% (84 runs sampled) - * findSegment - polygons x 2,512,410 ops/sec ±0.72% (93 runs sampled) - * findPoint - point x 2,339,238 ops/sec ±0.86% (85 runs sampled) - * findPoint - points x 2,298,279 ops/sec ±1.13% (88 runs sampled) - * findPoint - polygon x 2,216,808 ops/sec ±1.63% (86 runs sampled) - * findPoint - polygons x 2,160,583 ops/sec ±1.06% (87 runs sampled) - */ -Object.keys(fixtures).forEach(name => { - const geojson = fixtures[name]; - suite - .add('segmentEach - ' + name, () => meta.segmentEach(geojson, () => {})) - .add('segmentReduce - ' + name, () => meta.segmentReduce(geojson, () => {})) - .add('flattenEach - ' + name, () => meta.flattenEach(geojson, () => {})) - .add('flattenReduce - ' + name, () => meta.flattenReduce(geojson, () => {})) - .add('coordEach - ' + name, () => meta.coordEach(geojson, () => {})) - .add('coordReduce - ' + name, () => meta.coordReduce(geojson, () => {})) - .add('propEach - ' + name, () => meta.propEach(geojson, () => {})) - .add('propReduce - ' + name, () => meta.propReduce(geojson, () => {})) - .add('geomEach - ' + name, () => meta.geomEach(geojson, () => {})) - .add('geomReduce - ' + name, () => meta.geomReduce(geojson, () => {})) - .add('featureEach - ' + name, () => meta.featureEach(geojson, () => {})) - .add('featureReduce - ' + name, () => meta.featureReduce(geojson, () => {})) - .add('coordAll - ' + name, () => meta.coordAll(geojson)) - .add('findSegment - ' + name, () => meta.findSegment(geojson)) - .add('findPoint - ' + name, () => meta.findPoint(geojson)); -}); - -suite - .on('cycle', e => console.log(String(e.target))) - .on('complete', () => {}) - .run(); diff --git a/packages/turf-meta/index.d.ts b/packages/turf-meta/index.d.ts deleted file mode 100644 index 6bcfb9459b..0000000000 --- a/packages/turf-meta/index.d.ts +++ /dev/null @@ -1,220 +0,0 @@ -import { - Point, - LineString, - Polygon, - MultiPoint, - MultiLineString, - MultiPolygon, - FeatureCollection, - Feature, - GeometryObject, - GeometryCollection, - AllGeoJSON, - Properties, - Geometries, - Lines, - BBox, - Id -} from '@turf/helpers'; - -/** - * http://turfjs.org/docs/#coordreduce - */ -export function coordReduce( - geojson: AllGeoJSON, - callback: (previousValue: Reducer, - currentCoord: number[], - coordIndex: number, - featureIndex: number, - multiFeatureIndex: number, - geometryIndex: number) => Reducer, - initialValue?: Reducer -): Reducer; - -/** - * http://turfjs.org/docs/#coordeach - */ -export function coordEach( - geojson: AllGeoJSON, - callback: (currentCoord: number[], - coordIndex: number, - featureIndex: number, - multiFeatureIndex: number, - geometryIndex: number) => void -): void; - -/** - * http://turfjs.org/docs/#propeach - */ -export function propEach( - geojson: Feature | FeatureCollection | Feature, - callback: (currentProperties: Props, - featureIndex: number) => void -): void; - -/** - * http://turfjs.org/docs/#propreduce - */ -export function propReduce( - geojson: Feature | FeatureCollection | Geometries | GeometryCollection, - callback: (previousValue: Reducer, - currentProperties: P, - featureIndex: number) => Reducer, - initialValue?: Reducer -): Reducer; - -/** - * http://turfjs.org/docs/#featurereduce - */ -export function featureReduce( - geojson: Feature | FeatureCollection | Feature, - callback: (previousValue: Reducer, - currentFeature: Feature, - featureIndex: number) => Reducer, - initialValue?: Reducer -): Reducer; - -/** - * http://turfjs.org/docs/#featureeach - */ -export function featureEach( - geojson: Feature | FeatureCollection | Feature, - callback: (currentFeature: Feature, - featureIndex: number) => void -): void; - -/** - * http://turfjs.org/docs/#coordall - */ -export function coordAll(geojson: AllGeoJSON): number[][]; - -/** - * http://turfjs.org/docs/#geomreduce - */ -export function geomReduce( - geojson: Feature | FeatureCollection | G | GeometryCollection | Feature, - callback: (previousValue: Reducer, - currentGeometry: G, - featureIndex: number, - featureProperties: P, - featureBBox: BBox, - featureId: Id) => Reducer, - initialValue?: Reducer -): Reducer; - -/** - * http://turfjs.org/docs/#geomeach - */ -export function geomEach( - geojson: Feature | FeatureCollection | G | GeometryCollection | Feature, - callback: (currentGeometry: G, - featureIndex: number, - featureProperties: P, - featureBBox: BBox, - featureId: Id) => void -): void; - -/** - * http://turfjs.org/docs/#flattenreduce - */ -export function flattenReduce( - geojson: Feature | FeatureCollection | G | GeometryCollection | Feature, - callback: (previousValue: Reducer, - currentFeature: Feature, - featureIndex: number, - multiFeatureIndex: number) => Reducer, - initialValue?: Reducer -): Reducer; - -/** - * http://turfjs.org/docs/#flatteneach - */ -export function flattenEach( - geojson: Feature | FeatureCollection | G | GeometryCollection | Feature, - callback: (currentFeature: Feature, - featureIndex: number, - multiFeatureIndex: number) => void -): void; - -/** - * http://turfjs.org/docs/#segmentreduce - */ -export function segmentReduce( - geojson: FeatureCollection | Feature | Lines | Feature | GeometryCollection, - callback: (previousValue?: Reducer, - currentSegment?: Feature, - featureIndex?: number, - multiFeatureIndex?: number, - segmentIndex?: number, - geometryIndex?: number) => Reducer, - initialValue?: Reducer -): Reducer; - -/** - * http://turfjs.org/docs/#segmenteach - */ -export function segmentEach

( - geojson: AllGeoJSON, - callback: (currentSegment?: Feature, - featureIndex?: number, - multiFeatureIndex?: number, - segmentIndex?: number, - geometryIndex?: number) => void -): void; - -/** - * http://turfjs.org/docs/#linereduce - */ -export function lineReduce( - geojson: FeatureCollection | Feature | Lines | Feature | GeometryCollection, - callback: (previousValue?: Reducer, - currentLine?: Feature, - featureIndex?: number, - multiFeatureIndex?: number, - geometryIndex?: number) => Reducer, - initialValue?: Reducer -): Reducer; - -/** - * http://turfjs.org/docs/#lineeach - */ -export function lineEach

( - geojson: FeatureCollection | Feature | Lines | Feature | GeometryCollection, - callback: (currentLine?: Feature, - featureIndex?: number, - multiFeatureIndex?: number, - geometryIndex?: number) => void -): void; - - -/** - * http://turfjs.org/docs/#findsegment - */ -export function findSegment( - geojson: Feature | FeatureCollection | G, - options?: { - featureIndex?: number, - multiFeatureIndex?: number, - geometryIndex?: number, - segmentIndex?: number, - properties?: P, - bbox?: BBox, - id?: Id - } -): Feature; - -/** - * http://turfjs.org/docs/#findpoint - */ -export function findPoint( - geojson: Feature | FeatureCollection | G, - options?: { - featureIndex?: number, - multiFeatureIndex?: number, - geometryIndex?: number, - coordIndex?: number, - properties?: P, - bbox?: BBox, - id?: Id - } -): Feature; diff --git a/packages/turf-meta/index.mjs b/packages/turf-meta/index.mjs deleted file mode 100644 index 8700d99c69..0000000000 --- a/packages/turf-meta/index.mjs +++ /dev/null @@ -1,1110 +0,0 @@ -import { feature, point, lineString, isObject } from '@turf/helpers'; - -/** - * Callback for coordEach - * - * @callback coordEachCallback - * @param {Array} currentCoord The current coordinate being processed. - * @param {number} coordIndex The current index of the coordinate being processed. - * @param {number} featureIndex The current index of the Feature being processed. - * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. - * @param {number} geometryIndex The current index of the Geometry being processed. - */ - -/** - * Iterate over coordinates in any GeoJSON object, similar to Array.forEach() - * - * @name coordEach - * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object - * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex) - * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration. - * @returns {void} - * @example - * var features = turf.featureCollection([ - * turf.point([26, 37], {"foo": "bar"}), - * turf.point([36, 53], {"hello": "world"}) - * ]); - * - * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) { - * //=currentCoord - * //=coordIndex - * //=featureIndex - * //=multiFeatureIndex - * //=geometryIndex - * }); - */ -export function coordEach(geojson, callback, excludeWrapCoord) { - // Handles null Geometry -- Skips this GeoJSON - if (geojson === null) return; - var j, k, l, geometry, stopG, coords, - geometryMaybeCollection, - wrapShrink = 0, - coordIndex = 0, - isGeometryCollection, - type = geojson.type, - isFeatureCollection = type === 'FeatureCollection', - isFeature = type === 'Feature', - stop = isFeatureCollection ? geojson.features.length : 1; - - // This logic may look a little weird. The reason why it is that way - // is because it's trying to be fast. GeoJSON supports multiple kinds - // of objects at its root: FeatureCollection, Features, Geometries. - // This function has the responsibility of handling all of them, and that - // means that some of the `for` loops you see below actually just don't apply - // to certain inputs. For instance, if you give this just a - // Point geometry, then both loops are short-circuited and all we do - // is gradually rename the input until it's called 'geometry'. - // - // This also aims to allocate as few resources as possible: just a - // few numbers and booleans, rather than any temporary arrays as would - // be required with the normalization approach. - for (var featureIndex = 0; featureIndex < stop; featureIndex++) { - geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry : - (isFeature ? geojson.geometry : geojson)); - isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false; - stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1; - - for (var geomIndex = 0; geomIndex < stopG; geomIndex++) { - var multiFeatureIndex = 0; - var geometryIndex = 0; - geometry = isGeometryCollection ? - geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection; - - // Handles null Geometry -- Skips this geometry - if (geometry === null) continue; - coords = geometry.coordinates; - var geomType = geometry.type; - - wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0; - - switch (geomType) { - case null: - break; - case 'Point': - if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false; - coordIndex++; - multiFeatureIndex++; - break; - case 'LineString': - case 'MultiPoint': - for (j = 0; j < coords.length; j++) { - if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false; - coordIndex++; - if (geomType === 'MultiPoint') multiFeatureIndex++; - } - if (geomType === 'LineString') multiFeatureIndex++; - break; - case 'Polygon': - case 'MultiLineString': - for (j = 0; j < coords.length; j++) { - for (k = 0; k < coords[j].length - wrapShrink; k++) { - if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false; - coordIndex++; - } - if (geomType === 'MultiLineString') multiFeatureIndex++; - if (geomType === 'Polygon') geometryIndex++; - } - if (geomType === 'Polygon') multiFeatureIndex++; - break; - case 'MultiPolygon': - for (j = 0; j < coords.length; j++) { - geometryIndex = 0; - for (k = 0; k < coords[j].length; k++) { - for (l = 0; l < coords[j][k].length - wrapShrink; l++) { - if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false; - coordIndex++; - } - geometryIndex++; - } - multiFeatureIndex++; - } - break; - case 'GeometryCollection': - for (j = 0; j < geometry.geometries.length; j++) - if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false; - break; - default: - throw new Error('Unknown Geometry Type'); - } - } - } -} - -/** - * Callback for coordReduce - * - * The first time the callback function is called, the values provided as arguments depend - * on whether the reduce method has an initialValue argument. - * - * If an initialValue is provided to the reduce method: - * - The previousValue argument is initialValue. - * - The currentValue argument is the value of the first element present in the array. - * - * If an initialValue is not provided: - * - The previousValue argument is the value of the first element present in the array. - * - The currentValue argument is the value of the second element present in the array. - * - * @callback coordReduceCallback - * @param {*} previousValue The accumulated value previously returned in the last invocation - * of the callback, or initialValue, if supplied. - * @param {Array} currentCoord The current coordinate being processed. - * @param {number} coordIndex The current index of the coordinate being processed. - * Starts at index 0, if an initialValue is provided, and at index 1 otherwise. - * @param {number} featureIndex The current index of the Feature being processed. - * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. - * @param {number} geometryIndex The current index of the Geometry being processed. - */ - -/** - * Reduce coordinates in any GeoJSON object, similar to Array.reduce() - * - * @name coordReduce - * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object - * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex) - * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. - * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration. - * @returns {*} The value that results from the reduction. - * @example - * var features = turf.featureCollection([ - * turf.point([26, 37], {"foo": "bar"}), - * turf.point([36, 53], {"hello": "world"}) - * ]); - * - * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) { - * //=previousValue - * //=currentCoord - * //=coordIndex - * //=featureIndex - * //=multiFeatureIndex - * //=geometryIndex - * return currentCoord; - * }); - */ -export function coordReduce(geojson, callback, initialValue, excludeWrapCoord) { - var previousValue = initialValue; - coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) { - if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord; - else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex); - }, excludeWrapCoord); - return previousValue; -} - -/** - * Callback for propEach - * - * @callback propEachCallback - * @param {Object} currentProperties The current Properties being processed. - * @param {number} featureIndex The current index of the Feature being processed. - */ - -/** - * Iterate over properties in any GeoJSON object, similar to Array.forEach() - * - * @name propEach - * @param {FeatureCollection|Feature} geojson any GeoJSON object - * @param {Function} callback a method that takes (currentProperties, featureIndex) - * @returns {void} - * @example - * var features = turf.featureCollection([ - * turf.point([26, 37], {foo: 'bar'}), - * turf.point([36, 53], {hello: 'world'}) - * ]); - * - * turf.propEach(features, function (currentProperties, featureIndex) { - * //=currentProperties - * //=featureIndex - * }); - */ -export function propEach(geojson, callback) { - var i; - switch (geojson.type) { - case 'FeatureCollection': - for (i = 0; i < geojson.features.length; i++) { - if (callback(geojson.features[i].properties, i) === false) break; - } - break; - case 'Feature': - callback(geojson.properties, 0); - break; - } -} - - -/** - * Callback for propReduce - * - * The first time the callback function is called, the values provided as arguments depend - * on whether the reduce method has an initialValue argument. - * - * If an initialValue is provided to the reduce method: - * - The previousValue argument is initialValue. - * - The currentValue argument is the value of the first element present in the array. - * - * If an initialValue is not provided: - * - The previousValue argument is the value of the first element present in the array. - * - The currentValue argument is the value of the second element present in the array. - * - * @callback propReduceCallback - * @param {*} previousValue The accumulated value previously returned in the last invocation - * of the callback, or initialValue, if supplied. - * @param {*} currentProperties The current Properties being processed. - * @param {number} featureIndex The current index of the Feature being processed. - */ - -/** - * Reduce properties in any GeoJSON object into a single value, - * similar to how Array.reduce works. However, in this case we lazily run - * the reduction, so an array of all properties is unnecessary. - * - * @name propReduce - * @param {FeatureCollection|Feature} geojson any GeoJSON object - * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex) - * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. - * @returns {*} The value that results from the reduction. - * @example - * var features = turf.featureCollection([ - * turf.point([26, 37], {foo: 'bar'}), - * turf.point([36, 53], {hello: 'world'}) - * ]); - * - * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) { - * //=previousValue - * //=currentProperties - * //=featureIndex - * return currentProperties - * }); - */ -export function propReduce(geojson, callback, initialValue) { - var previousValue = initialValue; - propEach(geojson, function (currentProperties, featureIndex) { - if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties; - else previousValue = callback(previousValue, currentProperties, featureIndex); - }); - return previousValue; -} - -/** - * Callback for featureEach - * - * @callback featureEachCallback - * @param {Feature} currentFeature The current Feature being processed. - * @param {number} featureIndex The current index of the Feature being processed. - */ - -/** - * Iterate over features in any GeoJSON object, similar to - * Array.forEach. - * - * @name featureEach - * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object - * @param {Function} callback a method that takes (currentFeature, featureIndex) - * @returns {void} - * @example - * var features = turf.featureCollection([ - * turf.point([26, 37], {foo: 'bar'}), - * turf.point([36, 53], {hello: 'world'}) - * ]); - * - * turf.featureEach(features, function (currentFeature, featureIndex) { - * //=currentFeature - * //=featureIndex - * }); - */ -export function featureEach(geojson, callback) { - if (geojson.type === 'Feature') { - callback(geojson, 0); - } else if (geojson.type === 'FeatureCollection') { - for (var i = 0; i < geojson.features.length; i++) { - if (callback(geojson.features[i], i) === false) break; - } - } -} - -/** - * Callback for featureReduce - * - * The first time the callback function is called, the values provided as arguments depend - * on whether the reduce method has an initialValue argument. - * - * If an initialValue is provided to the reduce method: - * - The previousValue argument is initialValue. - * - The currentValue argument is the value of the first element present in the array. - * - * If an initialValue is not provided: - * - The previousValue argument is the value of the first element present in the array. - * - The currentValue argument is the value of the second element present in the array. - * - * @callback featureReduceCallback - * @param {*} previousValue The accumulated value previously returned in the last invocation - * of the callback, or initialValue, if supplied. - * @param {Feature} currentFeature The current Feature being processed. - * @param {number} featureIndex The current index of the Feature being processed. - */ - -/** - * Reduce features in any GeoJSON object, similar to Array.reduce(). - * - * @name featureReduce - * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object - * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex) - * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. - * @returns {*} The value that results from the reduction. - * @example - * var features = turf.featureCollection([ - * turf.point([26, 37], {"foo": "bar"}), - * turf.point([36, 53], {"hello": "world"}) - * ]); - * - * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) { - * //=previousValue - * //=currentFeature - * //=featureIndex - * return currentFeature - * }); - */ -export function featureReduce(geojson, callback, initialValue) { - var previousValue = initialValue; - featureEach(geojson, function (currentFeature, featureIndex) { - if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature; - else previousValue = callback(previousValue, currentFeature, featureIndex); - }); - return previousValue; -} - -/** - * Get all coordinates from any GeoJSON object. - * - * @name coordAll - * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object - * @returns {Array>} coordinate position array - * @example - * var features = turf.featureCollection([ - * turf.point([26, 37], {foo: 'bar'}), - * turf.point([36, 53], {hello: 'world'}) - * ]); - * - * var coords = turf.coordAll(features); - * //= [[26, 37], [36, 53]] - */ -export function coordAll(geojson) { - var coords = []; - coordEach(geojson, function (coord) { - coords.push(coord); - }); - return coords; -} - -/** - * Callback for geomEach - * - * @callback geomEachCallback - * @param {Geometry} currentGeometry The current Geometry being processed. - * @param {number} featureIndex The current index of the Feature being processed. - * @param {Object} featureProperties The current Feature Properties being processed. - * @param {Array} featureBBox The current Feature BBox being processed. - * @param {number|string} featureId The current Feature Id being processed. - */ - -/** - * Iterate over each geometry in any GeoJSON object, similar to Array.forEach() - * - * @name geomEach - * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object - * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) - * @returns {void} - * @example - * var features = turf.featureCollection([ - * turf.point([26, 37], {foo: 'bar'}), - * turf.point([36, 53], {hello: 'world'}) - * ]); - * - * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) { - * //=currentGeometry - * //=featureIndex - * //=featureProperties - * //=featureBBox - * //=featureId - * }); - */ -export function geomEach(geojson, callback) { - var i, j, g, geometry, stopG, - geometryMaybeCollection, - isGeometryCollection, - featureProperties, - featureBBox, - featureId, - featureIndex = 0, - isFeatureCollection = geojson.type === 'FeatureCollection', - isFeature = geojson.type === 'Feature', - stop = isFeatureCollection ? geojson.features.length : 1; - - // This logic may look a little weird. The reason why it is that way - // is because it's trying to be fast. GeoJSON supports multiple kinds - // of objects at its root: FeatureCollection, Features, Geometries. - // This function has the responsibility of handling all of them, and that - // means that some of the `for` loops you see below actually just don't apply - // to certain inputs. For instance, if you give this just a - // Point geometry, then both loops are short-circuited and all we do - // is gradually rename the input until it's called 'geometry'. - // - // This also aims to allocate as few resources as possible: just a - // few numbers and booleans, rather than any temporary arrays as would - // be required with the normalization approach. - for (i = 0; i < stop; i++) { - - geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry : - (isFeature ? geojson.geometry : geojson)); - featureProperties = (isFeatureCollection ? geojson.features[i].properties : - (isFeature ? geojson.properties : {})); - featureBBox = (isFeatureCollection ? geojson.features[i].bbox : - (isFeature ? geojson.bbox : undefined)); - featureId = (isFeatureCollection ? geojson.features[i].id : - (isFeature ? geojson.id : undefined)); - isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false; - stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1; - - for (g = 0; g < stopG; g++) { - geometry = isGeometryCollection ? - geometryMaybeCollection.geometries[g] : geometryMaybeCollection; - - // Handle null Geometry - if (geometry === null) { - if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false; - continue; - } - switch (geometry.type) { - case 'Point': - case 'LineString': - case 'MultiPoint': - case 'Polygon': - case 'MultiLineString': - case 'MultiPolygon': { - if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false; - break; - } - case 'GeometryCollection': { - for (j = 0; j < geometry.geometries.length; j++) { - if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false; - } - break; - } - default: - throw new Error('Unknown Geometry Type'); - } - } - // Only increase `featureIndex` per each feature - featureIndex++; - } -} - -/** - * Callback for geomReduce - * - * The first time the callback function is called, the values provided as arguments depend - * on whether the reduce method has an initialValue argument. - * - * If an initialValue is provided to the reduce method: - * - The previousValue argument is initialValue. - * - The currentValue argument is the value of the first element present in the array. - * - * If an initialValue is not provided: - * - The previousValue argument is the value of the first element present in the array. - * - The currentValue argument is the value of the second element present in the array. - * - * @callback geomReduceCallback - * @param {*} previousValue The accumulated value previously returned in the last invocation - * of the callback, or initialValue, if supplied. - * @param {Geometry} currentGeometry The current Geometry being processed. - * @param {number} featureIndex The current index of the Feature being processed. - * @param {Object} featureProperties The current Feature Properties being processed. - * @param {Array} featureBBox The current Feature BBox being processed. - * @param {number|string} featureId The current Feature Id being processed. - */ - -/** - * Reduce geometry in any GeoJSON object, similar to Array.reduce(). - * - * @name geomReduce - * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object - * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) - * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. - * @returns {*} The value that results from the reduction. - * @example - * var features = turf.featureCollection([ - * turf.point([26, 37], {foo: 'bar'}), - * turf.point([36, 53], {hello: 'world'}) - * ]); - * - * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) { - * //=previousValue - * //=currentGeometry - * //=featureIndex - * //=featureProperties - * //=featureBBox - * //=featureId - * return currentGeometry - * }); - */ -export function geomReduce(geojson, callback, initialValue) { - var previousValue = initialValue; - geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) { - if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry; - else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId); - }); - return previousValue; -} - -/** - * Callback for flattenEach - * - * @callback flattenEachCallback - * @param {Feature} currentFeature The current flattened feature being processed. - * @param {number} featureIndex The current index of the Feature being processed. - * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. - */ - -/** - * Iterate over flattened features in any GeoJSON object, similar to - * Array.forEach. - * - * @name flattenEach - * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object - * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex) - * @example - * var features = turf.featureCollection([ - * turf.point([26, 37], {foo: 'bar'}), - * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'}) - * ]); - * - * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) { - * //=currentFeature - * //=featureIndex - * //=multiFeatureIndex - * }); - */ -export function flattenEach(geojson, callback) { - geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) { - // Callback for single geometry - var type = (geometry === null) ? null : geometry.type; - switch (type) { - case null: - case 'Point': - case 'LineString': - case 'Polygon': - if (callback(feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false; - return; - } - - var geomType; - - // Callback for multi-geometry - switch (type) { - case 'MultiPoint': - geomType = 'Point'; - break; - case 'MultiLineString': - geomType = 'LineString'; - break; - case 'MultiPolygon': - geomType = 'Polygon'; - break; - } - - for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) { - var coordinate = geometry.coordinates[multiFeatureIndex]; - var geom = { - type: geomType, - coordinates: coordinate - }; - if (callback(feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false; - } - }); -} - -/** - * Callback for flattenReduce - * - * The first time the callback function is called, the values provided as arguments depend - * on whether the reduce method has an initialValue argument. - * - * If an initialValue is provided to the reduce method: - * - The previousValue argument is initialValue. - * - The currentValue argument is the value of the first element present in the array. - * - * If an initialValue is not provided: - * - The previousValue argument is the value of the first element present in the array. - * - The currentValue argument is the value of the second element present in the array. - * - * @callback flattenReduceCallback - * @param {*} previousValue The accumulated value previously returned in the last invocation - * of the callback, or initialValue, if supplied. - * @param {Feature} currentFeature The current Feature being processed. - * @param {number} featureIndex The current index of the Feature being processed. - * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. - */ - -/** - * Reduce flattened features in any GeoJSON object, similar to Array.reduce(). - * - * @name flattenReduce - * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object - * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex) - * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. - * @returns {*} The value that results from the reduction. - * @example - * var features = turf.featureCollection([ - * turf.point([26, 37], {foo: 'bar'}), - * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'}) - * ]); - * - * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) { - * //=previousValue - * //=currentFeature - * //=featureIndex - * //=multiFeatureIndex - * return currentFeature - * }); - */ -export function flattenReduce(geojson, callback, initialValue) { - var previousValue = initialValue; - flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) { - if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature; - else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex); - }); - return previousValue; -} - -/** - * Callback for segmentEach - * - * @callback segmentEachCallback - * @param {Feature} currentSegment The current Segment being processed. - * @param {number} featureIndex The current index of the Feature being processed. - * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. - * @param {number} geometryIndex The current index of the Geometry being processed. - * @param {number} segmentIndex The current index of the Segment being processed. - * @returns {void} - */ - -/** - * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach() - * (Multi)Point geometries do not contain segments therefore they are ignored during this operation. - * - * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON - * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) - * @returns {void} - * @example - * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]); - * - * // Iterate over GeoJSON by 2-vertex segments - * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) { - * //=currentSegment - * //=featureIndex - * //=multiFeatureIndex - * //=geometryIndex - * //=segmentIndex - * }); - * - * // Calculate the total number of segments - * var total = 0; - * turf.segmentEach(polygon, function () { - * total++; - * }); - */ -export function segmentEach(geojson, callback) { - flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) { - var segmentIndex = 0; - - // Exclude null Geometries - if (!feature.geometry) return; - // (Multi)Point geometries do not contain segments therefore they are ignored during this operation. - var type = feature.geometry.type; - if (type === 'Point' || type === 'MultiPoint') return; - - // Generate 2-vertex line segments - var previousCoords; - var previousFeatureIndex = 0; - var previousMultiIndex = 0; - var prevGeomIndex = 0; - if (coordEach(feature, function (currentCoord, coordIndex, featureIndexCoord, multiPartIndexCoord, geometryIndex) { - // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false` - if (previousCoords === undefined || featureIndex > previousFeatureIndex || multiPartIndexCoord > previousMultiIndex || geometryIndex > prevGeomIndex) { - previousCoords = currentCoord; - previousFeatureIndex = featureIndex; - previousMultiIndex = multiPartIndexCoord; - prevGeomIndex = geometryIndex; - segmentIndex = 0; - return; - } - var currentSegment = lineString([previousCoords, currentCoord], feature.properties); - if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false; - segmentIndex++; - previousCoords = currentCoord; - }) === false) return false; - }); -} - -/** - * Callback for segmentReduce - * - * The first time the callback function is called, the values provided as arguments depend - * on whether the reduce method has an initialValue argument. - * - * If an initialValue is provided to the reduce method: - * - The previousValue argument is initialValue. - * - The currentValue argument is the value of the first element present in the array. - * - * If an initialValue is not provided: - * - The previousValue argument is the value of the first element present in the array. - * - The currentValue argument is the value of the second element present in the array. - * - * @callback segmentReduceCallback - * @param {*} previousValue The accumulated value previously returned in the last invocation - * of the callback, or initialValue, if supplied. - * @param {Feature} currentSegment The current Segment being processed. - * @param {number} featureIndex The current index of the Feature being processed. - * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. - * @param {number} geometryIndex The current index of the Geometry being processed. - * @param {number} segmentIndex The current index of the Segment being processed. - */ - -/** - * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce() - * (Multi)Point geometries do not contain segments therefore they are ignored during this operation. - * - * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON - * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex) - * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. - * @returns {void} - * @example - * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]); - * - * // Iterate over GeoJSON by 2-vertex segments - * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) { - * //= previousSegment - * //= currentSegment - * //= featureIndex - * //= multiFeatureIndex - * //= geometryIndex - * //= segmentInex - * return currentSegment - * }); - * - * // Calculate the total number of segments - * var initialValue = 0 - * var total = turf.segmentReduce(polygon, function (previousValue) { - * previousValue++; - * return previousValue; - * }, initialValue); - */ -export function segmentReduce(geojson, callback, initialValue) { - var previousValue = initialValue; - var started = false; - segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) { - if (started === false && initialValue === undefined) previousValue = currentSegment; - else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex); - started = true; - }); - return previousValue; -} - -/** - * Callback for lineEach - * - * @callback lineEachCallback - * @param {Feature} currentLine The current LineString|LinearRing being processed - * @param {number} featureIndex The current index of the Feature being processed - * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed - * @param {number} geometryIndex The current index of the Geometry being processed - */ - -/** - * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries, - * similar to Array.forEach. - * - * @name lineEach - * @param {Geometry|Feature} geojson object - * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex) - * @example - * var multiLine = turf.multiLineString([ - * [[26, 37], [35, 45]], - * [[36, 53], [38, 50], [41, 55]] - * ]); - * - * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) { - * //=currentLine - * //=featureIndex - * //=multiFeatureIndex - * //=geometryIndex - * }); - */ -export function lineEach(geojson, callback) { - // validation - if (!geojson) throw new Error('geojson is required'); - - flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) { - if (feature.geometry === null) return; - var type = feature.geometry.type; - var coords = feature.geometry.coordinates; - switch (type) { - case 'LineString': - if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) return false; - break; - case 'Polygon': - for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) { - if (callback(lineString(coords[geometryIndex], feature.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false; - } - break; - } - }); -} - -/** - * Callback for lineReduce - * - * The first time the callback function is called, the values provided as arguments depend - * on whether the reduce method has an initialValue argument. - * - * If an initialValue is provided to the reduce method: - * - The previousValue argument is initialValue. - * - The currentValue argument is the value of the first element present in the array. - * - * If an initialValue is not provided: - * - The previousValue argument is the value of the first element present in the array. - * - The currentValue argument is the value of the second element present in the array. - * - * @callback lineReduceCallback - * @param {*} previousValue The accumulated value previously returned in the last invocation - * of the callback, or initialValue, if supplied. - * @param {Feature} currentLine The current LineString|LinearRing being processed. - * @param {number} featureIndex The current index of the Feature being processed - * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed - * @param {number} geometryIndex The current index of the Geometry being processed - */ - -/** - * Reduce features in any GeoJSON object, similar to Array.reduce(). - * - * @name lineReduce - * @param {Geometry|Feature} geojson object - * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) - * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. - * @returns {*} The value that results from the reduction. - * @example - * var multiPoly = turf.multiPolygon([ - * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]), - * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]]) - * ]); - * - * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) { - * //=previousValue - * //=currentLine - * //=featureIndex - * //=multiFeatureIndex - * //=geometryIndex - * return currentLine - * }); - */ -export function lineReduce(geojson, callback, initialValue) { - var previousValue = initialValue; - lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) { - if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine; - else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex); - }); - return previousValue; -} - -/** - * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes. - * - * Negative indexes are permitted. - * Point & MultiPoint will always return null. - * - * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry - * @param {Object} [options={}] Optional parameters - * @param {number} [options.featureIndex=0] Feature Index - * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index - * @param {number} [options.geometryIndex=0] Geometry Index - * @param {number} [options.segmentIndex=0] Segment Index - * @param {Object} [options.properties={}] Translate Properties to output LineString - * @param {BBox} [options.bbox={}] Translate BBox to output LineString - * @param {number|string} [options.id={}] Translate Id to output LineString - * @returns {Feature} 2-vertex GeoJSON Feature LineString - * @example - * var multiLine = turf.multiLineString([ - * [[10, 10], [50, 30], [30, 40]], - * [[-10, -10], [-50, -30], [-30, -40]] - * ]); - * - * // First Segment (defaults are 0) - * turf.findSegment(multiLine); - * // => Feature> - * - * // First Segment of 2nd Multi Feature - * turf.findSegment(multiLine, {multiFeatureIndex: 1}); - * // => Feature> - * - * // Last Segment of Last Multi Feature - * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1}); - * // => Feature> - */ -export function findSegment(geojson, options) { - // Optional Parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var featureIndex = options.featureIndex || 0; - var multiFeatureIndex = options.multiFeatureIndex || 0; - var geometryIndex = options.geometryIndex || 0; - var segmentIndex = options.segmentIndex || 0; - - // Find FeatureIndex - var properties = options.properties; - var geometry; - - switch (geojson.type) { - case 'FeatureCollection': - if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex; - properties = properties || geojson.features[featureIndex].properties; - geometry = geojson.features[featureIndex].geometry; - break; - case 'Feature': - properties = properties || geojson.properties; - geometry = geojson.geometry; - break; - case 'Point': - case 'MultiPoint': - return null; - case 'LineString': - case 'Polygon': - case 'MultiLineString': - case 'MultiPolygon': - geometry = geojson; - break; - default: - throw new Error('geojson is invalid'); - } - - // Find SegmentIndex - if (geometry === null) return null; - var coords = geometry.coordinates; - switch (geometry.type) { - case 'Point': - case 'MultiPoint': - return null; - case 'LineString': - if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1; - return lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options); - case 'Polygon': - if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex; - if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1; - return lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options); - case 'MultiLineString': - if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex; - if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1; - return lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options); - case 'MultiPolygon': - if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex; - if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex; - if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1; - return lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options); - } - throw new Error('geojson is invalid'); -} - -/** - * Finds a particular Point from a GeoJSON using `@turf/meta` indexes. - * - * Negative indexes are permitted. - * - * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry - * @param {Object} [options={}] Optional parameters - * @param {number} [options.featureIndex=0] Feature Index - * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index - * @param {number} [options.geometryIndex=0] Geometry Index - * @param {number} [options.coordIndex=0] Coord Index - * @param {Object} [options.properties={}] Translate Properties to output Point - * @param {BBox} [options.bbox={}] Translate BBox to output Point - * @param {number|string} [options.id={}] Translate Id to output Point - * @returns {Feature} 2-vertex GeoJSON Feature Point - * @example - * var multiLine = turf.multiLineString([ - * [[10, 10], [50, 30], [30, 40]], - * [[-10, -10], [-50, -30], [-30, -40]] - * ]); - * - * // First Segment (defaults are 0) - * turf.findPoint(multiLine); - * // => Feature> - * - * // First Segment of the 2nd Multi-Feature - * turf.findPoint(multiLine, {multiFeatureIndex: 1}); - * // => Feature> - * - * // Last Segment of last Multi-Feature - * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1}); - * // => Feature> - */ -export function findPoint(geojson, options) { - // Optional Parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var featureIndex = options.featureIndex || 0; - var multiFeatureIndex = options.multiFeatureIndex || 0; - var geometryIndex = options.geometryIndex || 0; - var coordIndex = options.coordIndex || 0; - - // Find FeatureIndex - var properties = options.properties; - var geometry; - - switch (geojson.type) { - case 'FeatureCollection': - if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex; - properties = properties || geojson.features[featureIndex].properties; - geometry = geojson.features[featureIndex].geometry; - break; - case 'Feature': - properties = properties || geojson.properties; - geometry = geojson.geometry; - break; - case 'Point': - case 'MultiPoint': - return null; - case 'LineString': - case 'Polygon': - case 'MultiLineString': - case 'MultiPolygon': - geometry = geojson; - break; - default: - throw new Error('geojson is invalid'); - } - - // Find Coord Index - if (geometry === null) return null; - var coords = geometry.coordinates; - switch (geometry.type) { - case 'Point': - return point(coords, properties, options); - case 'MultiPoint': - if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex; - return point(coords[multiFeatureIndex], properties, options); - case 'LineString': - if (coordIndex < 0) coordIndex = coords.length + coordIndex; - return point(coords[coordIndex], properties, options); - case 'Polygon': - if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex; - if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex; - return point(coords[geometryIndex][coordIndex], properties, options); - case 'MultiLineString': - if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex; - if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex; - return point(coords[multiFeatureIndex][coordIndex], properties, options); - case 'MultiPolygon': - if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex; - if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex; - if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex; - return point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options); - } - throw new Error('geojson is invalid'); -} diff --git a/packages/turf-meta/package.json b/packages/turf-meta/package.json deleted file mode 100644 index d95ac9bc01..0000000000 --- a/packages/turf-meta/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "@turf/meta", - "version": "6.0.1", - "description": "turf meta module", - "main": "index", - "module": "index.mjs", - "types": "index.d.ts", - "files": [ - "index.js", - "index.mjs", - "index.d.ts" - ], - "scripts": { - "pretest": "rollup -f cjs -o index.js index.mjs", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "functional", - "programming", - "turfjs", - "geojson", - "meta", - "flattenEach", - "flattenReduce", - "segmentEach", - "segmentReduce", - "coordEach", - "coordReduce", - "propEach", - "propReduce", - "featureEach", - "featureReduce", - "coordAll", - "geomEach", - "geomReduce", - "lineEeach", - "lineReduce" - ], - "author": "Turf Authors", - "contributors": [ - "Tom MacWright <@tmcw>", - "Daniel Pulido <@dpmcmlxxvi>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/random": "*", - "benchmark": "*", - "rollup": "*", - "tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x" - } -} diff --git a/packages/turf-meta/test.js b/packages/turf-meta/test.js deleted file mode 100644 index 120cc85ceb..0000000000 --- a/packages/turf-meta/test.js +++ /dev/null @@ -1,1020 +0,0 @@ -const test = require('tape'); -const { - point, - lineString, - feature, - polygon, - multiPoint, - multiPolygon, - multiLineString, - geometryCollection, - featureCollection, - points, - lineStrings, - polygons -} = require('@turf/helpers'); -const meta = require('./'); - -const pt = point([0, 0], {a: 1}); -const pt2 = point([1, 1]); -const line = lineString([[0, 0], [1, 1]]); -const poly = polygon([[[0, 0], [1, 1], [0, 1], [0, 0]]]); -const polyWithHole = polygon([[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], - [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]]); -const multiPt = multiPoint([[0, 0], [1, 1]]); -const multiLine = multiLineString([[[0, 0], [1, 1]], [[3, 3], [4, 4]]]); -const multiPoly = multiPolygon([[[[0, 0], [1, 1], [0, 1], [0, 0]]], [[[3, 3], [2, 2], [1, 2], [3, 3]]]]); -const geomCollection = geometryCollection([pt.geometry, line.geometry, multiLine.geometry], {a: 0}); -const fcNull = featureCollection([feature(null), feature(null)]); -const fcMixed = featureCollection([ - point([0, 0]), - lineString([[1, 1], [2, 2]]), - multiLineString([[[1, 1], [0, 0]], [[4, 4], [5, 5]]]) -]); - -function collection(feature) { - const featureCollection = { - type: 'FeatureCollection', - features: [feature] - }; - - return [feature, featureCollection]; -} - -function featureAndCollection(geometry) { - const feature = { - type: 'Feature', - geometry: geometry, - properties: {a: 1} - }; - - const featureCollection = { - type: 'FeatureCollection', - features: [feature] - }; - - return [geometry, feature, featureCollection]; -} - -test('propEach', t => { - collection(pt).forEach(input => { - meta.propEach(input, (prop, i) => { - t.deepEqual(prop, {a: 1}); - t.equal(i, 0); - }); - }); - t.end(); -}); - -test('coordEach -- Point', t => { - featureAndCollection(pt.geometry).forEach(input => { - meta.coordEach(input, (coord, index) => { - t.deepEqual(coord, [0, 0]); - t.equal(index, 0); - }); - }); - t.end(); -}); - -test('coordEach -- LineString', t => { - featureAndCollection(line.geometry).forEach(input => { - const output = []; - let lastIndex; - meta.coordEach(input, (coord, index) => { - output.push(coord); - lastIndex = index; - }); - t.deepEqual(output, [[0, 0], [1, 1]]); - t.equal(lastIndex, 1); - }); - t.end(); -}); - -test('coordEach -- Polygon', t => { - featureAndCollection(poly.geometry).forEach(input => { - const output = []; - let lastIndex; - meta.coordEach(input, (coord, index) => { - output.push(coord); - lastIndex = index; - }); - t.deepEqual(output, [[0, 0], [1, 1], [0, 1], [0, 0]]); - t.equal(lastIndex, 3); - }); - t.end(); -}); - -test('coordEach -- Polygon excludeWrapCoord', t => { - featureAndCollection(poly.geometry).forEach(input => { - const output = []; - let lastIndex; - meta.coordEach(input, (coord, index) => { - output.push(coord); - lastIndex = index; - }, true); - t.equal(lastIndex, 2); - }); - t.end(); -}); - -test('coordEach -- MultiPolygon', t => { - const coords = []; - const coordIndexes = []; - const featureIndexes = []; - const multiFeatureIndexes = []; - meta.coordEach(multiPoly, (coord, coordIndex, featureIndex, multiFeatureIndex) => { - coords.push(coord); - coordIndexes.push(coordIndex); - featureIndexes.push(featureIndex); - multiFeatureIndexes.push(multiFeatureIndex); - }); - t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 5, 6, 7]); - t.deepEqual(featureIndexes, [0, 0, 0, 0, 0, 0, 0, 0]); - t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 1, 1, 1, 1]); - t.equal(coords.length, 8); - t.end(); -}); - -test('coordEach -- FeatureCollection', t => { - const coords = []; - const coordIndexes = []; - const featureIndexes = []; - const multiFeatureIndexes = []; - meta.coordEach(fcMixed, (coord, coordIndex, featureIndex, multiFeatureIndex) => { - coords.push(coord); - coordIndexes.push(coordIndex); - featureIndexes.push(featureIndex); - multiFeatureIndexes.push(multiFeatureIndex); - }); - t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 5, 6]); - t.deepEqual(featureIndexes, [0, 1, 1, 2, 2, 2, 2]); - t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 1, 1]); - t.equal(coords.length, 7); - t.end(); -}); - -test('coordReduce -- initialValue', t => { - let lastIndex; - const line = lineString([[126, -11], [129, -21], [135, -31]]); - const sum = meta.coordReduce(line, (previous, currentCoords, index) => { - lastIndex = index; - return previous + currentCoords[0]; - }, 0); - t.equal(lastIndex, 2); - t.equal(sum, 390); - t.end(); -}); - -test('Array.reduce() -- initialValue', t => { - let lastIndex; - const line = [[126, -11], [129, -21], [135, -31]]; - const sum = line.reduce((previous, currentCoords, index) => { - lastIndex = index; - return previous + currentCoords[0]; - }, 0); - t.equal(lastIndex, 2); - t.equal(sum, 390); - t.end(); -}); - -test('coordReduce -- previous-coordinates', t => { - let lastIndex; - const coords = []; - const line = lineString([[126, -11], [129, -21], [135, -31]]); - meta.coordReduce(line, (previousCoords, currentCoords, index) => { - lastIndex = index; - coords.push(currentCoords); - return currentCoords; - }); - t.equal(lastIndex, 2); - t.equal(coords.length, 2); - t.end(); -}); - -test('Array.reduce() -- previous-coordinates', t => { - let lastIndex; - const coords = []; - const line = [[126, -11], [129, -21], [135, -31]]; - line.reduce((previousCoords, currentCoords, index) => { - lastIndex = index; - coords.push(currentCoords); - return currentCoords; - }); - t.equal(lastIndex, 2); - t.equal(coords.length, 2); - t.end(); -}); - - -test('coordReduce -- previous-coordinates+initialValue', t => { - let lastIndex; - const coords = []; - meta.coordReduce(line, (previousCoords, currentCoords, index) => { - lastIndex = index; - coords.push(currentCoords); - return currentCoords; - }, line.geometry.coordinates[0]); - t.equal(lastIndex, 1); - t.equal(coords.length, 2); - t.end(); -}); - -test('Array.reduce() -- previous-coordinates+initialValue', t => { - let lastIndex; - const coords = []; - line.geometry.coordinates.reduce((previousCoords, currentCoords, index) => { - lastIndex = index; - coords.push(currentCoords); - return currentCoords; - }, line[0]); - t.equal(lastIndex, 1); - t.equal(coords.length, 2); - t.end(); -}); - -test('unknown', t => { - t.throws(function () { - meta.coordEach({}); - }); - t.end(); -}); - -test('geomEach -- GeometryCollection', t => { - featureAndCollection(geomCollection.geometry).forEach(input => { - const output = []; - meta.geomEach(input, geom => { - output.push(geom); - }); - t.deepEqual(output, geomCollection.geometry.geometries); - }); - t.end(); -}); - -test('geomEach -- bare-GeometryCollection', t => { - const output = []; - meta.geomEach(geomCollection, geom => { - output.push(geom); - }); - t.deepEqual(output, geomCollection.geometry.geometries); - t.end(); -}); - -test('geomEach -- bare-pointGeometry', t => { - const output = []; - meta.geomEach(pt.geometry, geom => { - output.push(geom); - }); - t.deepEqual(output, [pt.geometry]); - t.end(); -}); - -test('geomEach -- bare-pointFeature', t => { - const output = []; - meta.geomEach(pt, geom => { - output.push(geom); - }); - t.deepEqual(output, [pt.geometry]); - t.end(); -}); - -test('geomEach -- multiGeometryFeature-properties', t => { - let lastProperties; - meta.geomEach(geomCollection, (geom, index, properties) => { - lastProperties = properties; - }); - t.deepEqual(lastProperties, geomCollection.properties); - t.end(); -}); - -test('flattenEach -- MultiPoint', t => { - featureAndCollection(multiPt.geometry).forEach(input => { - const output = []; - meta.flattenEach(input, feature => { - output.push(feature.geometry); - }); - t.deepEqual(output, [pt.geometry, pt2.geometry]); - }); - t.end(); -}); - -test('flattenEach -- Mixed FeatureCollection', t => { - const features = []; - const featureIndexes = []; - const multiFeatureIndexes = []; - meta.flattenEach(fcMixed, (feature, featureIndex, multiFeatureIndex) => { - features.push(feature); - featureIndexes.push(featureIndex); - multiFeatureIndexes.push(multiFeatureIndex); - }); - t.deepEqual(featureIndexes, [0, 1, 2, 2]); - t.deepEqual(multiFeatureIndexes, [0, 0, 0, 1]); - t.equal(features.length, 4); - t.end(); -}); - -test('flattenEach -- Point-properties', t => { - collection(pt).forEach(input => { - let lastProperties; - meta.flattenEach(input, feature => { - lastProperties = feature.properties; - }); - t.deepEqual(lastProperties, pt.properties); - }); - t.end(); -}); - -test('flattenEach -- multiGeometryFeature-properties', t => { - collection(geomCollection).forEach(input => { - let lastProperties; - meta.flattenEach(input, feature => { - lastProperties = feature.properties; - }); - t.deepEqual(lastProperties, geomCollection.properties); - }); - t.end(); -}); - -test('flattenReduce -- initialValue', t => { - let lastIndex; - let lastSubIndex; - const sum = meta.flattenReduce(multiPt.geometry, (previous, current, index, subIndex) => { - lastIndex = index; - lastSubIndex = subIndex; - return previous + current.geometry.coordinates[0]; - }, 0); - t.equal(lastIndex, 0); - t.equal(lastSubIndex, 1); - t.equal(sum, 1); - t.end(); -}); - -test('flattenReduce -- previous-feature', t => { - const features = []; - const featureIndexes = []; - const multiFeatureIndexes = []; - meta.flattenReduce(multiLine, (previous, current, featureIndex, multiFeatureIndex) => { - featureIndexes.push(featureIndex); - multiFeatureIndexes.push(multiFeatureIndex); - features.push(current); - return current; - }); - t.deepEqual(featureIndexes, [0]); - t.deepEqual(multiFeatureIndexes, [1]); - t.equal(features.length, 1); - t.end(); -}); - -test('flattenReduce -- previous-feature+initialValue', t => { - const features = []; - const featureIndexes = []; - const multiFeatureIndexes = []; - const sum = meta.flattenReduce(multiPt.geometry, (previous, current, featureIndex, multiFeatureIndex) => { - featureIndexes.push(featureIndex); - multiFeatureIndexes.push(multiFeatureIndex); - features.push(current); - return current; - }, null); - t.deepEqual(featureIndexes, [0, 0]); - t.deepEqual(multiFeatureIndexes, [0, 1]); - t.equal(features.length, 2); - t.deepEqual(sum, features[features.length - 1]); - t.end(); -}); - -// https://github.com/Turfjs/turf/issues/853 -test('null geometries', t => { - // Each operations - meta.featureEach(fcNull, feature => t.equal(feature.geometry, null, 'featureEach')); - meta.geomEach(fcNull, geometry => t.equal(geometry, null), 'geomEach'); - meta.flattenEach(fcNull, feature => t.equal(feature.geometry, null, 'flattenEach')); - meta.coordEach(fcNull, () => t.fail('no coordinates should be found')); - - // Reduce operations - /* eslint-disable no-return-assign */ - t.equal(meta.featureReduce(fcNull, prev => prev += 1, 0), 2, 'featureReduce'); - t.equal(meta.geomReduce(fcNull, prev => prev += 1, 0), 2, 'geomReduce'); - t.equal(meta.flattenReduce(fcNull, prev => prev += 1, 0), 2, 'flattenReduce'); - t.equal(meta.coordReduce(fcNull, prev => prev += 1, 0), 0, 'coordReduce'); - /* eslint-enable no-return-assign */ - t.end(); -}); - -test('null geometries -- index', t => { - const fc = featureCollection([ - feature(null), // index 0 - point([0, 0]), // index 1 - feature(null), // index 2 - lineString([[1, 1], [0, 0]]) // index 3 - ]); - t.deepEqual(meta.coordReduce(fc, (prev, coords, coordIndex) => prev.concat(coordIndex), []), [0, 1, 2], 'coordReduce'); - t.deepEqual(meta.geomReduce(fc, (prev, geom, featureIndex) => prev.concat(featureIndex), []), [0, 1, 2, 3], 'geomReduce'); - t.deepEqual(meta.flattenReduce(fc, (prev, feature, featureIndex) => prev.concat(featureIndex), []), [0, 1, 2, 3], 'flattenReduce'); - t.end(); -}); - -test('segmentEach', t => { - const segments = []; - let total = 0; - meta.segmentEach(poly.geometry, currentSegment => { - segments.push(currentSegment); - total++; - }); - t.equal(segments[0].geometry.coordinates.length, 2); - t.equal(total, 3); - t.end(); -}); - -test('segmentEach -- MultiPoint', t => { - const segments = []; - let total = 0; - meta.segmentEach(multiPt.geometry, currentSegment => { - segments.push(currentSegment); - total++; - }); - t.equal(total, 0); // No segments are created from MultiPoint geometry - t.end(); -}); - -test('segmentReduce', t => { - const segments = []; - const total = meta.segmentReduce(poly.geometry, (previousValue, currentSegment) => { - segments.push(currentSegment); - previousValue++; - return previousValue; - }, 0); - t.equal(segments[0].geometry.coordinates.length, 2); - t.equal(total, 3); - t.end(); -}); - -test('segmentReduce -- no initialValue', t => { - const segments = []; - var total = 0; - meta.segmentReduce(poly.geometry, (previousValue, currentSegment) => { - segments.push(currentSegment); - total++; - }); - t.equal(segments[0].geometry.coordinates.length, 2); - t.equal(total, 2); - t.end(); -}); - -const geojsonSegments = featureCollection([ - point([0, 1]), // ignored - lineString([[0, 0], [2, 2], [4, 4]]), - polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]]), - point([0, 1]), // ignored - multiLineString([ - [[0, 0], [2, 2], [4, 4]], - [[0, 0], [2, 2], [4, 4]] - ]) -]); - -test('segmentEach -- index & subIndex', t => { - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; - const segmentIndexes = []; - let total = 0; - - meta.segmentEach(geojsonSegments, (segment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) => { - featureIndexes.push(featureIndex); - multiFeatureIndexes.push(multiFeatureIndex); - geometryIndexes.push(geometryIndex); - segmentIndexes.push(segmentIndex); - total++; - }); - t.equal(total, 10, 'total'); - t.deepEqual(featureIndexes, [1, 1, 2, 2, 2, 2, 4, 4, 4, 4], 'segmentEach.featureIndex'); - t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 1, 1], 'segmentEach.multiFeatureIndex'); - t.deepEqual(geometryIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'segmentEach.geometryIndex'); - t.deepEqual(segmentIndexes, [0, 1, 0, 1, 2, 3, 0, 1, 0, 1], 'segmentEach.segmentIndex'); - t.end(); -}); - -test('segmentReduce -- index & subIndex', t => { - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; - const segmentIndexes = []; - let total = 0; - - meta.segmentReduce(geojsonSegments, (previousValue, segment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) => { - featureIndexes.push(featureIndex); - multiFeatureIndexes.push(multiFeatureIndex); - geometryIndexes.push(geometryIndex); - segmentIndexes.push(segmentIndex); - total++; - }); - t.equal(total, 9, 'total'); - t.deepEqual(featureIndexes, [1, 2, 2, 2, 2, 4, 4, 4, 4], 'segmentReduce.featureIndex'); - t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 0, 0, 1, 1], 'segmentReduce.multiFeatureIndex'); - t.deepEqual(geometryIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0], 'segmentReduce.geometryIndex'); - t.deepEqual(segmentIndexes, [1, 0, 1, 2, 3, 0, 1, 0, 1], 'segmentReduce.segmentIndex'); - t.end(); -}); - -test('lineEach -- lineString', t => { - const line = lineString([[0, 0], [2, 2], [4, 4]]); - const featureIndexes = []; - const multiFeatureIndexes = []; - const lineIndexes = []; - let total = 0; - - meta.lineEach(line, (currentLine, featureIndex, multiFeatureIndex, lineIndex) => { - featureIndexes.push(featureIndex); - multiFeatureIndexes.push(multiFeatureIndex); - lineIndexes.push(lineIndex); - total++; - }); - t.equal(total, 1, 'total'); - t.deepEqual(featureIndexes, [0], 'featureIndex'); - t.deepEqual(multiFeatureIndexes, [0], 'multiFeatureIndex'); - t.deepEqual(lineIndexes, [0], 'lineIndex'); - t.end(); -}); - -test('lineEach -- multiLineString', t => { - const multiLine = multiLineString([ - [[0, 0], [2, 2], [4, 4]], - [[1, 1], [3, 3], [5, 5]] - ]); - const featureIndexes = []; - const multiFeatureIndexes = []; - const lineIndexes = []; - let total = 0; - - meta.lineEach(multiLine, (currentLine, featureIndex, multiFeatureIndex, lineIndex) => { - featureIndexes.push(featureIndex); - multiFeatureIndexes.push(multiFeatureIndex); - lineIndexes.push(lineIndex); - total++; - }); - t.equal(total, 2, 'total'); - t.deepEqual(featureIndexes, [0, 0], 'featureIndex'); - t.deepEqual(multiFeatureIndexes, [0, 1], 'multiFeatureIndex'); - t.deepEqual(lineIndexes, [0, 0], 'lineIndex'); - t.end(); -}); - -test('lineEach -- multiPolygon', t => { - const multiPoly = multiPolygon([ - [ - [[12, 48], [2, 41], [24, 38], [12, 48]], // outer - [[9, 44], [13, 41], [13, 45], [9, 44]] // inner - ], - [ - [[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]] // outer - ] - ]); - const featureIndexes = []; - const multiFeatureIndexes = []; - const lineIndexes = []; - let total = 0; - - meta.lineEach(multiPoly, (currentLine, featureIndex, multiFeatureIndex, lineIndex) => { - featureIndexes.push(featureIndex); - multiFeatureIndexes.push(multiFeatureIndex); - lineIndexes.push(lineIndex); - total++; - }); - t.equal(total, 3, 'total'); - t.deepEqual(featureIndexes, [0, 0, 0], 'featureIndex'); - t.deepEqual(multiFeatureIndexes, [0, 0, 1], 'multiFeatureIndex'); - t.deepEqual(lineIndexes, [0, 1, 0], 'lineIndex'); - t.end(); -}); - -test('lineEach -- featureCollection', t => { - const line = lineString([[0, 0], [2, 2], [4, 4]]); - const multiLine = multiLineString([ - [[0, 0], [2, 2], [4, 4]], - [[1, 1], [3, 3], [5, 5]] - ]); - const multiPoly = multiPolygon([ - [ - [[12, 48], [2, 41], [24, 38], [12, 48]], // outer - [[9, 44], [13, 41], [13, 45], [9, 44]] // inner - ], - [ - [[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]] // outer - ] - ]); - const featureIndexes = []; - const multiFeatureIndexes = []; - const lineIndexes = []; - let total = 0; - - meta.lineEach(featureCollection([line, multiLine, multiPoly]), (currentLine, featureIndex, multiFeatureIndex, lineIndex) => { - featureIndexes.push(featureIndex); - multiFeatureIndexes.push(multiFeatureIndex); - lineIndexes.push(lineIndex); - total++; - }); - t.equal(total, 6, 'total'); - t.deepEqual(featureIndexes, [0, 1, 1, 2, 2, 2], 'featureIndex'); - t.deepEqual(multiFeatureIndexes, [0, 0, 1, 0, 0, 1], 'multiFeatureIndex'); - t.deepEqual(lineIndexes, [0, 0, 0, 0, 1, 0], 'lineIndex'); - t.end(); -}); - -test('lineReduce -- multiLineString', t => { - const multiLine = multiLineString([ - [[0, 0], [2, 2], [4, 4]], - [[1, 1], [3, 3], [5, 5]] - ]); - - const total = meta.lineReduce(multiLine, previousValue => { - previousValue++; - return previousValue; - }, 0); - - t.equal(total, 2, 'total'); - t.end(); -}); - -test('lineReduce -- multiPolygon', t => { - const multiPoly = multiPolygon([ - [ - [[12, 48], [2, 41], [24, 38], [12, 48]], // outer - [[9, 44], [13, 41], [13, 45], [9, 44]]], // inner - [ - [[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]] // outer - ] - ]); - - const total = meta.lineReduce(multiPoly, previousValue => { - previousValue++; - return previousValue; - }, 0); - - t.equal(total, 3, 'total'); - t.end(); -}); - -test('lineEach & lineReduce -- assert', t => { - const pt = point([0, 0]); - const multiPt = multiPoint([[0, 0], [10, 10]]); - meta.lineEach(pt, () => {}); // Point geometry is supported - meta.lineEach(multiPt, () => {}); // MultiPoint geometry is supported - meta.lineReduce(pt, () => {}); // Point geometry is supported - meta.lineReduce(multiPt, () => {}); // MultiPoint geometry is supported - meta.lineReduce(geomCollection, () => {}); // GeometryCollection is is supported - meta.lineReduce(featureCollection([lineString([[10, 10], [0, 0]])]), () => {}); // FeatureCollection is is supported - meta.lineReduce(feature(null), () => {}); // Feature with null geometry is supported - t.end(); -}); - -test('geomEach -- callback BBox & Id', t => { - const properties = {foo: 'bar'}; - const bbox = [0, 0, 0, 0]; - const id = 'foo'; - const pt = point([0, 0], properties, {bbox, id}); - - meta.geomEach(pt, (currentGeometry, featureIndex, currentProperties, currentBBox, currentId) => { - t.equal(featureIndex, 0, 'featureIndex'); - t.deepEqual(currentProperties, properties, 'currentProperties'); - t.deepEqual(currentBBox, bbox, 'currentBBox'); - t.deepEqual(currentId, id, 'currentId'); - }); - t.end(); -}); - -test('lineEach -- callback BBox & Id', t => { - const properties = {foo: 'bar'}; - const bbox = [0, 0, 10, 10]; - const id = 'foo'; - const line = lineString([[0, 0], [10, 10]], properties, {bbox, id}); - - meta.lineEach(line, (currentLine, featureIndex) => { - t.equal(featureIndex, 0, 'featureIndex'); - t.deepEqual(currentLine.properties, properties, 'currentProperties'); - t.deepEqual(currentLine.bbox, bbox, 'currentBBox'); - t.deepEqual(currentLine.id, id, 'currentId'); - }); - t.end(); -}); - -test('lineEach -- return lineString', t => { - const properties = {foo: 'bar'}; - const bbox = [0, 0, 10, 10]; - const id = 'foo'; - const line = lineString([[0, 0], [10, 10]], properties, {bbox, id}); - - meta.lineEach(line, (currentLine) => { - t.deepEqual(line, currentLine, 'return itself'); - }); - t.end(); -}); - - -test('meta.coordEach -- indexes -- PolygonWithHole', t => { - const coordIndexes = []; - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; - - meta.coordEach(polyWithHole, (coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) => { - coordIndexes.push(coordIndex) - featureIndexes.push(featureIndex) - multiFeatureIndexes.push(multiFeatureIndex) - geometryIndexes.push(geometryIndex) - }); - t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); - t.deepEqual(featureIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - t.deepEqual(geometryIndexes, [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]); - t.end(); -}); - -test('meta.lineEach -- indexes -- PolygonWithHole', t => { - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; - - meta.lineEach(polyWithHole, (line, featureIndex, multiFeatureIndex, geometryIndex) => { - featureIndexes.push(featureIndex) - multiFeatureIndexes.push(multiFeatureIndex) - geometryIndexes.push(geometryIndex) - }); - t.deepEqual(featureIndexes, [0, 0]); - t.deepEqual(multiFeatureIndexes, [0, 0]); - t.deepEqual(geometryIndexes, [0, 1]); - t.end(); -}); - -test('meta.segmentEach -- indexes -- PolygonWithHole', t => { - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; - const segmentIndexes = []; - - meta.segmentEach(polyWithHole, (segment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) => { - featureIndexes.push(featureIndex); - multiFeatureIndexes.push(multiFeatureIndex); - geometryIndexes.push(geometryIndex); - segmentIndexes.push(segmentIndex); - }); - - t.deepEqual(featureIndexes, [0, 0, 0, 0, 0, 0, 0, 0]); - t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 0, 0, 0]); - t.deepEqual(geometryIndexes, [0, 0, 0, 0, 1, 1, 1, 1]); - t.deepEqual(segmentIndexes, [0, 1, 2, 3, 0, 1, 2, 3]); - t.end(); -}); - -test('meta.coordEach -- indexes -- Multi-Polygon with hole', t => { - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; - const coordIndexes = []; - - // MultiPolygon with hole - // ====================== - // FeatureIndex => 0 - const multiPolyWithHole = multiPolygon([ - // Polygon 1 - // --------- - // MultiFeature Index => 0 - [ - // Outer Ring - // ---------- - // Geometry Index => 0 - // Coord Index => [0, 1, 2, 3, 4] (Major Release Change v6.x) - [[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]] - ], - // Polygon 2 with Hole - // ------------------- - // MultiFeature Index => 1 - [ - // Outer Ring - // ---------- - // Geometry Index => 0 - // Coord Index => [0, 1, 2, 3, 4] (Major Release Change v6.x) - [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], - - // Inner Ring - // ---------- - // Geometry Index => 1 - // Coord Index => [0, 1, 2, 3, 4] (Major Release Change v6.x) - [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]] - ] - ]); - - meta.coordEach(multiPolyWithHole, (coord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) => { - featureIndexes.push(featureIndex); - multiFeatureIndexes.push(multiFeatureIndex); - geometryIndexes.push(geometryIndex); - coordIndexes.push(coordIndex); - }); - - t.deepEqual(featureIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]); - t.deepEqual(geometryIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1]); - t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]); - // Major Release Change v6.x - // t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4]); - t.end(); -}); - -test('meta.coordEach -- indexes -- Polygon with hole', t => { - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; - const coordIndexes = []; - - // Polygon with Hole - // ================= - // Feature Index => 0 - const polyWithHole = polygon([ - // Outer Ring - // ---------- - // Geometry Index => 0 - // Coord Index => [0, 1, 2, 3, 4] (Major Release Change v6.x) - [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], - - // Inner Ring - // ---------- - // Geometry Index => 1 - // Coord Index => [0, 1, 2, 3, 4] (Major Release Change v6.x) - [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]] - ]); - - meta.coordEach(polyWithHole, (coord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) => { - featureIndexes.push(featureIndex); - multiFeatureIndexes.push(multiFeatureIndex); - geometryIndexes.push(geometryIndex); - coordIndexes.push(coordIndex); - }); - - t.deepEqual(featureIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - t.deepEqual(geometryIndexes, [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]); - t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); - // Major Release Change v6.x - // t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]); - t.end(); -}); - -test('meta.coordEach -- indexes -- FeatureCollection of LineString', t => { - const featureIndexes = []; - const multiFeatureIndexes = []; - const geometryIndexes = []; - const coordIndexes = []; - - // FeatureCollection of LineStrings - const line = lineStrings([ - // LineString 1 - // Feature Index => 0 - // Geometry Index => 0 - // Coord Index => [0, 1, 2, 3, 4] (Major Release Change v6.x) - [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], - - // LineString 2 - // Feature Index => 1 - // Geometry Index => 0 - // Coord Index => [0, 1, 2, 3, 4] (Major Release Change v6.x) - [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]] - ]); - - meta.coordEach(line, (coord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) => { - featureIndexes.push(featureIndex); - multiFeatureIndexes.push(multiFeatureIndex); - geometryIndexes.push(geometryIndex); - coordIndexes.push(coordIndex); - }); - - t.deepEqual(featureIndexes, [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]); - t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - t.deepEqual(geometryIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); - // Major Release Change v6.x - // t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]); - t.end(); -}); - - -test('meta -- breaking of iterations', t => { - const lines = lineStrings([ - [[10, 10], [50, 30], [30, 40]], - [[-10, -10], [-50, -30], [-30, -40]] - ]); - const multiLine = multiLineString([ - [[10, 10], [50, 30], [30, 40]], - [[-10, -10], [-50, -30], [-30, -40]] - ]); - - // Each Iterators - // meta.segmentEach has been purposely excluded from this list - for (const func of [meta.coordEach, meta.featureEach, meta.flattenEach, meta.geomEach, meta.lineEach, meta.propEach, meta.segmentEach]) { - // Meta Each function should only a value of 1 after returning `false` - - // FeatureCollection - let count = 0; - func(lines, () => { - count += 1; - return false; - }); - t.equal(count, 1, func.name); - - // Multi Geometry - let multiCount = 0; - func(multiLine, () => { - multiCount += 1; - return false; - }); - t.equal(multiCount, 1, func.name); - } - t.end(); -}); - -test('meta -- findSegment', t => { - const nullFeature = feature(null); - const pt = point([10, 10]); - const line = lineString([[10, 10], [50, 30], [30, 40]]); - const poly = polygon([ - [[10, 10], [50, 30], [30, 40], [10, 10]], - [[-10, -10], [-50, -30], [-30, -40], [-10, -10]] - ]); - const multiLine = multiLineString([ - [[10, 10], [50, 30], [30, 40]], - [[-10, -10], [-50, -30], [-30, -40]] - ]); - const lines = lineStrings([ - [[10, 10], [50, 30], [30, 40], [10, 10]], - [[-10, -10], [-50, -30], [-30, -40], [-10, -10]] - ]); - // firstSegment - t.deepEqual(meta.findSegment(nullFeature), null, 'findSegment (default) -- nullFeature') - t.deepEqual(meta.findSegment(pt), null, 'findSegment (default) -- pt') - t.deepEqual(meta.findSegment(line), lineString([[10, 10], [50, 30]]), 'findSegment (default) -- line') - t.deepEqual(meta.findSegment(poly), lineString([[10, 10], [50, 30]]), 'findSegment (default) -- poly') - t.deepEqual(meta.findSegment(multiLine), lineString([[10, 10], [50, 30]]), 'findSegment (default) -- multiLine') - t.deepEqual(meta.findSegment(lines), lineString([[10, 10], [50, 30]]), 'findSegment (default) -- lines') - - // lastSegment - t.deepEqual(meta.findSegment(nullFeature), null, 'findSegment (last) -- nullFeature') - t.deepEqual(meta.findSegment(pt), null, 'findSegment (last) -- pt') - t.deepEqual(meta.findSegment(line, {segmentIndex: -1}), lineString([[50, 30], [30, 40]]), 'findSegment (last) -- line') - t.deepEqual(meta.findSegment(poly, {segmentIndex: -1, geometryIndex: -1}), lineString([[-30, -40], [-10, -10]]), 'findSegment (last) -- poly') - t.deepEqual(meta.findSegment(multiLine, {segmentIndex: -1, multiFeatureIndex: -1}), lineString([[-50, -30], [-30, -40]]), 'findSegment (last) -- multiLine') - t.deepEqual(meta.findSegment(lines, {segmentIndex: -1, featureIndex: -1}), lineString([[-30, -40], [-10, -10]]), 'findSegment (last) -- lines') - t.end() -}) - -test('meta -- findPoint', t => { - const nullFeature = feature(null); - const pt = point([10, 10]); - const line = lineString([[10, 10], [50, 30], [30, 40]]); - const poly = polygon([ - [[10, 10], [50, 30], [30, 40], [10, 10]], - [[-10, -10], [-50, -30], [-30, -40], [-10, -10]] - ]); - const multiLine = multiLineString([ - [[10, 10], [50, 30], [30, 40]], - [[-10, -10], [-50, -30], [-30, -40]] - ]); - const lines = lineStrings([ - [[10, 10], [50, 30], [30, 40], [10, 10]], - [[-10, -10], [-50, -30], [-30, -40], [-10, -10]] - ]); - // firstPoint - t.deepEqual(meta.findPoint(nullFeature), null, 'findPoint (default) -- nullFeature') - t.deepEqual(meta.findPoint(pt), point([10, 10]), 'findPoint (default) -- pt') - t.deepEqual(meta.findPoint(line), point([10, 10]), 'findPoint (default) -- line') - t.deepEqual(meta.findPoint(poly), point([10, 10]), 'findPoint (default) -- poly') - t.deepEqual(meta.findPoint(multiLine), point([10, 10]), 'findPoint (default) -- multiLine') - t.deepEqual(meta.findPoint(lines), point([10, 10]), 'findPoint (default) -- lines') - - // lastPoint - t.deepEqual(meta.findPoint(nullFeature), null, 'findPoint (last) -- nullFeature') - t.deepEqual(meta.findPoint(pt), point([10, 10]), 'findPoint (last) -- pt') - t.deepEqual(meta.findPoint(line, {coordIndex: -1}), point([30, 40]), 'findPoint (last) -- line') - t.deepEqual(meta.findPoint(poly, {coordIndex: -1, geometryIndex: -1}), point([-10, -10]), 'findPoint (last) -- poly') - t.deepEqual(meta.findPoint(multiLine, {coordIndex: -1, multiFeatureIndex: -1}), point([-30, -40]), 'findPoint (last) -- multiLine') - t.deepEqual(meta.findPoint(lines, {coordIndex: -1, featureIndex: -1}), point([-10, -10]), 'findPoint (last) -- lines') - t.end() -}) - -test('meta -- segmentEach -- Issue #1273', t => { - // https://github.com/Turfjs/turf/issues/1273 - const poly = polygon([ - // Outer Ring - // Segment = 0 - // Geometries = 0,1,2 - [[10, 10], [50, 30], [30, 40], [10, 10]], - // Inner Ring - // Segment => 1 - // Geometries => 0,1,2 - [[-10, -10], [-50, -30], [-30, -40], [-10, -10]] - ]); - const segmentIndexes = []; - const geometryIndexes = []; - meta.segmentEach(poly, (line, featureIndex, multiFeatureIndex, segmentIndex, geometryIndex) => { - segmentIndexes.push(segmentIndex); - geometryIndexes.push(geometryIndex); - }); - t.deepEqual(segmentIndexes, [0, 0, 0, 1, 1, 1]); - t.deepEqual(geometryIndexes, [0, 1, 2, 0, 1, 2]); - t.end(); -}); diff --git a/packages/turf-meta/types.ts b/packages/turf-meta/types.ts deleted file mode 100644 index 6c523b5c6b..0000000000 --- a/packages/turf-meta/types.ts +++ /dev/null @@ -1,231 +0,0 @@ -import * as helpers from '@turf/helpers' -import { - featureCollection, - point, - lineString, - Feature, - Point, - LineString -} from '@turf/helpers' -import * as meta from './' -import { - coordReduce, - coordEach, - propEach, - propReduce, - featureReduce, - featureEach, - coordAll, - geomReduce, - geomEach, - flattenReduce, - flattenEach, - segmentReduce, - segmentEach, - lineReduce, - lineEach -} from './' - -// Fixtures -const pt = helpers.point([0, 0]) -const line = helpers.lineString([[0, 0], [1, 1]]) -const poly = helpers.polygon([[[0, 0], [1, 1], [0, 1], [0, 0]]]) -const multiPoly = helpers.multiPolygon([[[[0, 0], [1, 1], [0, 1], [0, 0]]]]) -const multiLine = helpers.multiLineString([[[0, 0], [1, 1], [0, 1], [0, 0]], [[2, 2], [3, 3]]]) -const geomCollection = helpers.geometryCollection([pt.geometry, line.geometry]) -const features = helpers.featureCollection([pt, line]) - -const customPoint = point([10, 20], {foo: 'abc', bar: 123}) -const customPoints = featureCollection([customPoint]) -const customLineString = lineString([[0, 0], [10, 20]], {foo: 'abc', bar: 123}) -const customLineStrings = featureCollection([customLineString]) - -/** - * meta.coordEach - */ -const coordEachValue: void = meta.coordEach(pt, coords => coords) -coordEach(pt, (coords, index) => coords) -meta.coordEach(pt, (coords, index) => coords) -meta.coordEach(pt.geometry, coords => { const equal: number[] = coords }) -meta.coordEach(line, coords => { const equal: number[] = coords }) -meta.coordEach(poly, coords => { const equal: number[] = coords }) -meta.coordEach(multiPoly, coords => { const equal: number[] = coords }) -meta.coordEach(geomCollection, coords => coords) - -/** - * meta.coordReduce - */ -const coordReduceValue: number = meta.coordReduce(pt, (previous, coords) => 1 + 1) -coordReduce(pt, (previous, coords, index) => coords) -meta.coordReduce(pt, (previous, coords, index) => coords) -meta.coordReduce(pt, (previous, coords, index) => 1 + 1, 0) -meta.coordReduce(pt, (previous, coords) => coords) -meta.coordReduce(geomCollection, (previous, coords) => coords) - -/** - * meta.propReduce - */ -const propReduceValue: number = meta.propReduce(poly, (previous, prop) => 1 + 1) -propReduce(poly, (previous, prop) => 1 + 1, 0) -meta.propReduce(poly, (previous, prop) => 1 + 1, 0) -meta.propReduce(features, (previous, prop) => prop) -meta.propReduce(poly, (previous, prop, index) => prop) -meta.propReduce(poly, (previous, prop) => 1 + 1) -meta.propReduce(geomCollection, (previous, prop) => prop) - -/** - * meta.propEach - */ -const propEachValue: void = meta.propEach(poly, prop => prop) -propEach(features, prop => prop) -meta.propEach(features, prop => prop) -meta.propEach(poly, (prop, index) => prop) -meta.propEach<{bar: string}>(poly, prop => prop.bar) -meta.propEach(geomCollection, prop => prop) - -/** - * meta.coordAll - */ -coordAll(poly) -const coords: Array> = meta.coordAll(poly) - -/** - * meta.featureReduce - */ -const featureReduceValue: number = meta.featureReduce(poly, (previous, feature) => 1 + 1) -featureReduce(poly, (previous, feature) => 1 + 1, 0) -meta.featureReduce(poly, (previous, feature) => 1 + 1, 0) -meta.featureReduce(features, (previous, feature) => feature) -meta.featureReduce(poly, (previous, feature, index) => feature) -meta.featureReduce(geomCollection, (previous, feature, index) => feature) - -/** - * meta.featureEach - */ -const featureEachValue: void = meta.featureEach(poly, feature => feature) -featureEach(features, feature => feature) -meta.featureEach(features, feature => feature) -meta.featureEach(poly, (feature, index) => feature) -meta.featureEach(geomCollection, (feature, index) => feature) - -// Access custom properties -featureEach(customPoints, pt => { - pt.properties.bar - // pt.properties.hello // [ts] Property 'hello' does not exist on type '{ foo: string; bar: number; }'. -}) - -/** - * meta.geomReduce - */ -const geomReduceValue: number = meta.geomReduce(poly, (previous, geom) => 1 + 1) -geomReduce(poly, (previous, geom) => 1 + 1, 0) -meta.geomReduce(poly, (previous, geom) => 1 + 1, 0) -meta.geomReduce(features, (previous, geom) => geom) -meta.geomReduce(poly, (previous, geom, index, props) => geom) -meta.geomReduce(geomCollection, (previous, geom, index, props) => geom) - -/** - * meta.geomEach - */ -const geomEachValue: void = meta.geomEach(poly, geom => geom) -geomEach(features, geom => geom) -meta.geomEach(features, geom => geom) -meta.geomEach(poly, (geom, index, props) => geom) -meta.geomEach(geomCollection, (geom, index, props) => geom) - -/** - * meta.flattenReduce - */ -const flattenReduceValue: number = meta.flattenReduce(poly, (previous, feature) => 1 + 1) -flattenReduce(poly, (previous, feature) => 1 + 1, 0) -meta.flattenReduce(poly, (previous, feature) => 1 + 1, 0) -meta.flattenReduce(features, (previous, feature) => feature) -meta.flattenReduce(poly, (previous, feature, index, props) => feature) -meta.flattenReduce(geomCollection, (previous, feature, index, props) => feature) - -/** - * meta.flattenEach - */ -const flattenEachValue: void = meta.flattenEach(poly, feature => feature) -flattenEach(features, feature => feature) -meta.flattenEach(features, feature => feature) -meta.flattenEach(poly.geometry, (feature, index, props) => feature) -meta.flattenEach(geomCollection, (feature, index, props) => feature) - -/** - * meta.segmentReduce - */ -const lines = helpers.featureCollection([line]) -const segmentReduceValue: number = meta.segmentReduce(poly, () => 1 + 1) -segmentReduce(poly, previousValue => previousValue) -meta.segmentReduce(poly, previousValue => previousValue) -meta.segmentReduce(poly, (previousValue, currentSegment) => currentSegment) -meta.segmentReduce(poly, (previousValue, currentSegment) => 1 + 1, 0) -meta.segmentReduce(lines, (previousValue, currentSegment) => currentSegment) -meta.segmentReduce(poly, (previousValue, currentSegment, currentIndex) => currentSegment) -meta.segmentReduce(geomCollection, (previousValue, currentSegment, currentIndex) => currentSegment) -meta.segmentReduce(geomCollection, (previousValue, currentSegment, currentIndex, currentSubIndex) => currentSegment) - -/** - * meta.segmentEach - */ -const segmentEachValue: void = meta.segmentEach(poly, () => {}) -segmentEach(poly, currentSegment => currentSegment) -meta.segmentEach(poly, currentSegment => currentSegment) -meta.segmentEach(features, currentSegment => currentSegment) -meta.segmentEach(poly.geometry, (currentSegment, currentIndex) => currentSegment) -meta.segmentEach(geomCollection, (currentSegment, currentIndex) => currentSegment) -meta.segmentEach(geomCollection, (currentSegment, currentIndex, currentSubIndex) => currentSegment) - -/** - * meta.lineEach - */ -// meta.lineEach(pt, () => {}) // Argument of type 'Feature' is not assignable to parameter of type 'LineString | Polygon | MultiPolygon | MultiLineString | Feature'. -const lineEachValue: void = meta.lineEach(line, () => {}) -lineEach(line, currentLine => currentLine) -meta.lineEach(line, currentLine => currentLine) -meta.lineEach(multiLine, (currentLine, featureIndex, featureSubIndex) => currentLine) -meta.lineEach(poly, currentLine => currentLine) -meta.lineEach(poly, (currentLine, featureIndex, featureSubIndex, lineIndex) => currentLine) -meta.lineEach(multiPoly, (currentLine, featureIndex, featureSubIndex, lineIndex) => currentLine) - -// Able to load custom LineStrings -lineEach(customLineString, line => {}) -lineEach(customLineStrings, line => { - line.properties.bar - // line.properties.hello // [ts] Property 'hello' does not exist on type '{ foo: string; bar: string; }'. -}) - -/** - * meta.lineReduce - */ -// meta.lineReduce(pt, () => {}) // Argument of type 'Feature' is not assignable to parameter of type 'LineString | Polygon | MultiPolygon | MultiLineString | Feature'. -const lineReduceValue: number = meta.lineReduce(line, () => 1 + 1) -lineReduce(line, previousValue => previousValue) -meta.lineReduce(line, previousValue => previousValue) -meta.lineReduce(line, (previousValue, currentLine) => currentLine) -meta.lineReduce(line, (previousValue, currentLine) => 1 + 1, 0) -meta.lineReduce(multiLine, (previousValue, currentLine) => currentLine) -meta.lineReduce(multiLine, (previousValue, currentLine, featureIndex, featureSubIndex) => currentLine) -meta.lineReduce(poly, (previousValue, currentLine) => currentLine) -meta.lineReduce(poly, (previousValue, currentLine, featureIndex, featureSubIndex) => currentLine) -meta.lineReduce(poly, (previousValue, currentLine, featureIndex, featureSubIndex) => 1 + 1, 1) -meta.lineReduce(multiPoly, (previousValue, currentLine, featureIndex, featureSubIndex, lineIndex) => currentLine) -meta.lineReduce(multiPoly, (previousValue, currentLine, featureIndex, featureSubIndex, lineIndex) => 1 + 1, 1) - -/** - * findSegment - */ -meta.findSegment(line) -meta.findSegment(line.geometry) -meta.findSegment(line, {segmentIndex: -1}) - -/** - * findPoint - */ -meta.findPoint(line) -meta.findPoint(line.geometry) -meta.findPoint(line, {coordIndex: -1}) -meta.findPoint(customLineString).properties.foo -meta.findPoint(customLineString).properties.bar -// meta.findPoint(customLineString).properties.hello // [ts] Property 'hello' does not exist on type '{ foo: string; bar: number; }'. diff --git a/packages/turf-midpoint/LICENSE b/packages/turf-midpoint/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-midpoint/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-midpoint/README.md b/packages/turf-midpoint/README.md deleted file mode 100644 index 9f9bcd22a5..0000000000 --- a/packages/turf-midpoint/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# @turf/midpoint - - - -## midpoint - -Takes two [points][1] and returns a point midway between them. -The midpoint is calculated geodesically, meaning the curvature of the earth is taken into account. - -**Parameters** - -- `point1` **[Coord][2]** first point -- `point2` **[Coord][2]** second point - -**Examples** - -```javascript -var point1 = turf.point([144.834823, -37.771257]); -var point2 = turf.point([145.14244, -37.830937]); - -var midpoint = turf.midpoint(point1, point2); - -//addToMap -var addToMap = [point1, point2, midpoint]; -midpoint.properties['marker-color'] = '#f00'; -``` - -Returns **[Feature][3]<[Point][4]>** a point midway between `pt1` and `pt2` - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/midpoint -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-midpoint/bench.js b/packages/turf-midpoint/bench.js deleted file mode 100644 index 094d3c0f2a..0000000000 --- a/packages/turf-midpoint/bench.js +++ /dev/null @@ -1,16 +0,0 @@ -import fs from 'fs'; -import Benchmark from 'benchmark'; -import { point } from '@turf/helpers'; -import midpoint from './'; - -var pt1 = point([0,0]); -var pt2 = point([10,0]); - -new Benchmark.Suite('turf-midpoint') -.add('turf-midpoint',function () { - midpoint(pt1, pt2); -}) -.on('cycle', function (event) { - console.log(String(event.target)); -}) -.run(); \ No newline at end of file diff --git a/packages/turf-midpoint/index.d.ts b/packages/turf-midpoint/index.d.ts deleted file mode 100644 index 5616fd70ae..0000000000 --- a/packages/turf-midpoint/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Feature, Point, Coord } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#midpoint - */ -export default function midpoint( - point1: Coord, - point2: Coord -): Feature; \ No newline at end of file diff --git a/packages/turf-midpoint/index.js b/packages/turf-midpoint/index.js deleted file mode 100644 index a66970ed63..0000000000 --- a/packages/turf-midpoint/index.js +++ /dev/null @@ -1,31 +0,0 @@ -import bearing from '@turf/bearing'; -import destination from '@turf/destination'; -import distance from '@turf/distance'; - -/** - * Takes two {@link Point|points} and returns a point midway between them. - * The midpoint is calculated geodesically, meaning the curvature of the earth is taken into account. - * - * @name midpoint - * @param {Coord} point1 first point - * @param {Coord} point2 second point - * @returns {Feature} a point midway between `pt1` and `pt2` - * @example - * var point1 = turf.point([144.834823, -37.771257]); - * var point2 = turf.point([145.14244, -37.830937]); - * - * var midpoint = turf.midpoint(point1, point2); - * - * //addToMap - * var addToMap = [point1, point2, midpoint]; - * midpoint.properties['marker-color'] = '#f00'; - */ -function midpoint(point1, point2) { - var dist = distance(point1, point2); - var heading = bearing(point1, point2); - var midpoint = destination(point1, dist / 2, heading); - - return midpoint; -} - -export default midpoint; diff --git a/packages/turf-midpoint/package.json b/packages/turf-midpoint/package.json deleted file mode 100644 index e73cd0985e..0000000000 --- a/packages/turf-midpoint/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@turf/midpoint", - "version": "5.1.5", - "description": "turf midpoint module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "midpoint", - "bisect", - "geojson", - "line" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "rollup": "*", - "tape": "*" - }, - "dependencies": { - "@turf/bearing": "6.x", - "@turf/destination": "6.x", - "@turf/distance": "6.x", - "@turf/helpers": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-midpoint/test.js b/packages/turf-midpoint/test.js deleted file mode 100644 index be2087b265..0000000000 --- a/packages/turf-midpoint/test.js +++ /dev/null @@ -1,70 +0,0 @@ -import test from 'tape'; -import midpoint from '.'; -import distance from '@turf/distance'; -import { point } from '@turf/helpers'; - -test('midpoint -- horizontal equator', function (t) { - var pt1 = point([0, 0]); - var pt2 = point([10, 0]); - - var mid = midpoint(pt1, pt2); - - t.equal(distance(pt1, mid).toFixed(6), distance(pt2, mid).toFixed(6)); - - t.end(); -}); - -test('midpoint -- vertical from equator', function (t) { - var pt1 = point([0, 0]); - var pt2 = point([0, 10]); - - var mid = midpoint(pt1, pt2); - - t.equal(distance(pt1, mid).toFixed(6), distance(pt2, mid).toFixed(6)); - - t.end(); -}); - -test('midpoint -- vertical to equator', function (t) { - var pt1 = point([0, 10]); - var pt2 = point([0, 0]); - - var mid = midpoint(pt1, pt2); - - t.equal(distance(pt1, mid).toFixed(6), distance(pt2, mid).toFixed(6)); - - t.end(); -}); - -test('midpoint -- diagonal back over equator', function (t) { - var pt1 = point([-1, 10]); - var pt2 = point([1, -1]); - - var mid = midpoint(pt1, pt2); - - t.equal(distance(pt1, mid).toFixed(6), distance(pt2, mid).toFixed(6)); - - t.end(); -}); - -test('midpoint -- diagonal forward over equator', function (t) { - var pt1 = point([-5, -1]); - var pt2 = point([5, 10]); - - var mid = midpoint(pt1, pt2); - - t.equal(distance(pt1, mid).toFixed(6), distance(pt2, mid).toFixed(6)); - - t.end(); -}); - -test('midpoint -- long distance', function (t) { - var pt1 = point([22.5, 21.94304553343818]); - var pt2 = point([92.10937499999999, 46.800059446787316]); - - var mid = midpoint(pt1, pt2); - - t.equal(distance(pt1, mid).toFixed(6), distance(pt2, mid).toFixed(6)); - - t.end(); -}); diff --git a/packages/turf-moran-index/.gitignore b/packages/turf-moran-index/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-moran-index/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-moran-index/LICENSE b/packages/turf-moran-index/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-moran-index/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-moran-index/README.md b/packages/turf-moran-index/README.md deleted file mode 100644 index 8eb49cbda1..0000000000 --- a/packages/turf-moran-index/README.md +++ /dev/null @@ -1,107 +0,0 @@ -# @turf/moran-index - - - -## moranIndex - -Moran's I measures patterns of attribute values associated with features. -The method reveal whether similar values tend to occur near each other, -or whether high or low values are interspersed. - -Moran's I > 0 means a clusterd pattern. -Moran's I < 0 means a dispersed pattern. -Moran's I = 0 means a random pattern. - -In order to test the significance of the result. The z score is calculated. -A positive enough z-score (ex. >1.96) indicates clustering, -while a negative enough z-score (ex. <-1.96) indicates a dispersed pattern. - -the z-score can be calculated based on a normal or random assumption. - -**Bibliography\*** - -1. [Moran's I](https://en.wikipedia.org/wiki/Moran%27s_I) - -2. [pysal](http://pysal.readthedocs.io/en/latest/index.html) - -3. Andy Mitchell, The ESRI Guide to GIS Analysis Volume 2: Spatial Measurements & Statistics. - -**Parameters** - -- `fc` **[FeatureCollection](https://tools.ietf.org/html/rfc7946#section-3.3)<any>** -- `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** - - `options.inputField` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the property name, must contain numeric values - - `options.threshold` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the distance threshold (optional, default `100000`) - - `options.p` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the Minkowski p-norm distance parameter (optional, default `2`) - - `options.binary` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** whether transfrom the distance to binary (optional, default `false`) - - `options.alpha` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the distance decay parameter (optional, default `-1`) - - `options.standardization` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** wheter row standardization the distance (optional, default `true`) - -**Examples** - -```javascript -const bbox = [-65, 40, -63, 42]; -const dataset = turf.randomPoint(100, { bbox: bbox }); - -const result = moranIndex(pts, { - inputField: 'CRIME', -}); -``` - -Returns **[MoranIndex](#moranindex)** - -## mean - -get mean of a list - -**Parameters** - -- `y` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)>** - -Returns **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** - -## variance - -get variance of a list - -**Parameters** - -- `y` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)>** - -Returns **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** - -## MoranIndex - -Type: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) - -**Properties** - -- `moranIndex` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the moran's Index of the observed feature set -- `expectedMoranIndex` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the moran's Index of the random distribution -- `stdNorm` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the standard devitaion of the random distribution -- `zNorm` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the z-score of the observe samples with regard to the random distribution - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/moran-index -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-moran-index/index.d.ts b/packages/turf-moran-index/index.d.ts deleted file mode 100644 index c4c8d7ee23..0000000000 --- a/packages/turf-moran-index/index.d.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { FeatureCollection } from "@turf/helpers"; -/** - * Moran's I measures patterns of attribute values associated with features. - * The method reveal whether similar values tend to occur near each other, - * or whether high or low values are interspersed. - * - * Moran's I > 0 means a clusterd pattern. - * Moran's I < 0 means a dispersed pattern. - * Moran's I = 0 means a random pattern. - * - * In order to test the significance of the result. The z score is calculated. - * A positive enough z-score (ex. >1.96) indicates clustering, - * while a negative enough z-score (ex. <-1.96) indicates a dispersed pattern. - * - * the z-score can be calculated based on a normal or random assumption. - * - * **Bibliography*** - * - * 1. [Moran's I](https://en.wikipedia.org/wiki/Moran%27s_I) - * - * 2. [pysal](http://pysal.readthedocs.io/en/latest/index.html) - * - * 3. Andy Mitchell, The ESRI Guide to GIS Analysis Volume 2: Spatial Measurements & Statistics. - * - * @name moranIndex - * @param {FeatureCollection} fc - * @param {Object} options - * @param {string} options.inputField the property name, must contain numeric values - * @param {number} [options.threshold=100000] the distance threshold - * @param {number} [options.p=2] the Minkowski p-norm distance parameter - * @param {boolean} [options.binary=false] whether transfrom the distance to binary - * @param {number} [options.alpha=-1] the distance decay parameter - * @param {boolean} [options.standardization=true] wheter row standardization the distance - * @returns {MoranIndex} - * @example - * - * const bbox = [-65, 40, -63, 42]; - * const dataset = turf.randomPoint(100, { bbox: bbox }); - * - * const result = turf.moranIndex(dataset, { - * inputField: 'CRIME', - * }); - */ -export default function (fc: FeatureCollection, options: { - inputField: string; - threshold?: number; - p?: number; - binary?: boolean; - alpha?: number; - standardization?: boolean; -}): { - moranIndex: number; - expectedMoranIndex: number; - stdNorm: number; - zNorm: number; -}; diff --git a/packages/turf-moran-index/index.ts b/packages/turf-moran-index/index.ts deleted file mode 100644 index efdcaebaa3..0000000000 --- a/packages/turf-moran-index/index.ts +++ /dev/null @@ -1,155 +0,0 @@ -import spatialWeight from "@turf/distance-weight"; -import { Feature, FeatureCollection } from "@turf/helpers"; -import { featureEach } from "@turf/meta"; - -/** - * Moran's I measures patterns of attribute values associated with features. - * The method reveal whether similar values tend to occur near each other, - * or whether high or low values are interspersed. - * - * Moran's I > 0 means a clusterd pattern. - * Moran's I < 0 means a dispersed pattern. - * Moran's I = 0 means a random pattern. - * - * In order to test the significance of the result. The z score is calculated. - * A positive enough z-score (ex. >1.96) indicates clustering, - * while a negative enough z-score (ex. <-1.96) indicates a dispersed pattern. - * - * the z-score can be calculated based on a normal or random assumption. - * - * **Bibliography*** - * - * 1. [Moran's I](https://en.wikipedia.org/wiki/Moran%27s_I) - * - * 2. [pysal](http://pysal.readthedocs.io/en/latest/index.html) - * - * 3. Andy Mitchell, The ESRI Guide to GIS Analysis Volume 2: Spatial Measurements & Statistics. - * - * @name moranIndex - * @param {FeatureCollection} fc - * @param {Object} options - * @param {string} options.inputField the property name, must contain numeric values - * @param {number} [options.threshold=100000] the distance threshold - * @param {number} [options.p=2] the Minkowski p-norm distance parameter - * @param {boolean} [options.binary=false] whether transfrom the distance to binary - * @param {number} [options.alpha=-1] the distance decay parameter - * @param {boolean} [options.standardization=true] wheter row standardization the distance - * @returns {MoranIndex} - * @example - * - * const bbox = [-65, 40, -63, 42]; - * const dataset = turf.randomPoint(100, { bbox: bbox }); - * - * const result = turf.moranIndex(dataset, { - * inputField: 'CRIME', - * }); - */ - -export default function(fc: FeatureCollection, options: { - inputField: string, - threshold?: number; - p?: number; - binary?: boolean; - alpha?: number; - standardization?: boolean; -}): { - moranIndex: number; - expectedMoranIndex: number; - stdNorm: number; - zNorm: number; - } { - - const inputField = options.inputField; - const threshold = options.threshold || 100000; - const p = options.p || 2; - const binary = options.binary || false; - const alpha = options.alpha || -1; - const standardization = options.standardization || true; - - const weight = spatialWeight(fc, { - alpha, - binary, - p, - standardization, - threshold, - }); - - const y: number[] = []; - featureEach(fc, (feature) => { - const feaProperties = feature.properties || {}; - // validate inputField exists - y.push(feaProperties[inputField]); - }); - - const yMean = mean(y); - const yVar = variance(y); - let weightSum = 0; - let s0: number = 0; - let s1: number = 0; - let s2: number = 0; - const n = weight.length; - // validate y.length is the same as weight.length - for (let i = 0; i < n; i++) { - let subS2 = 0; - for (let j = 0; j < n; j++) { - weightSum += weight[i][j] * (y[i] - yMean) * (y[j] - yMean); - s0 += weight[i][j]; - s1 += Math.pow((weight[i][j] + weight[j][i]), 2); - subS2 += weight[i][j] + weight[j][i]; - } - s2 += Math.pow(subS2, 2); - } - s1 = 0.5 * s1; - - const moranIndex = weightSum / s0 / yVar; - const expectedMoranIndex = -1 / (n - 1); - const vNum = (n * n) * s1 - n * s2 + 3 * (s0 * s0); - const vDen = (n - 1) * (n + 1) * (s0 * s0); - const vNorm = vNum / vDen - (expectedMoranIndex * expectedMoranIndex); - const stdNorm = Math.sqrt(vNorm); - const zNorm = (moranIndex - expectedMoranIndex) / stdNorm; - - return { - expectedMoranIndex, - moranIndex, - stdNorm, - zNorm, - }; - -} - -/** - * get mean of a list - * @param {number[]} y - * @returns {number} - * - */ -function mean(y: number[]): number { - let sum = 0; - for (const item of y) { - sum += item; - } - return sum / y.length; -} -/** - * get variance of a list - * @param {number[]} y - * @returns {number} - * - */ -function variance(y: number[]): number { - const yMean = mean(y); - let sum = 0; - for (const item of y) { - sum += Math.pow(item - yMean, 2); - } - return sum / y.length; -} - -/** - * @typedef {Object} MoranIndex - * @property {number} moranIndex the moran's Index of the observed feature set - * @property {number} expectedMoranIndex the moran's Index of the random distribution - * @property {number} stdNorm the standard devitaion of the random distribution - * @property {number} zNorm the z-score of the observe samples with regard to the random distribution - */ diff --git a/packages/turf-moran-index/package.json b/packages/turf-moran-index/package.json deleted file mode 100644 index b592c4b4d0..0000000000 --- a/packages/turf-moran-index/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@turf/moran-index", - "version": "6.0.1", - "description": "turf moran-index module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "moran-index" - ], - "author": "Turf Authors", - "contributors": [ - "Haoming Zhuang <@zhuang-hao-ming>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "write-json-file": "*", - "load-json-file": "*", - "tape": "*", - "typescript": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/distance-weight": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-moran-index/test.js b/packages/turf-moran-index/test.js deleted file mode 100644 index 44a70277ed..0000000000 --- a/packages/turf-moran-index/test.js +++ /dev/null @@ -1,39 +0,0 @@ -const test = require('tape'); -const glob = require('glob'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const moranIndex = require('.').default; - -test('turf-moran-index', t => { - - const pointPath = path.join(__dirname, 'test', 'in', 'point.json'); - const pointJson = load.sync(pointPath); - - const result = moranIndex(pointJson, { - inputField: 'CRIME', - }); - - t.deepEqual(result, { - moranIndex: 0.15665417693293948, - expectedMoranIndex: -0.020833333333333332, - stdNorm: 0.022208244679327364, - zNorm: 7.991964823383264, - }, 'point clustered pattern'); - - const columbusPath = path.join(__dirname, 'test', 'in', 'columbus.json'); - const columbusJson = load.sync(columbusPath); - - const result1 = moranIndex(columbusJson, { - inputField: 'CRIME', - }); - - t.deepEqual(result1, { - moranIndex: 0.1485081274747776, - expectedMoranIndex: -0.020833333333333332, - stdNorm: 0.02374513825431575, - zNorm: 7.131626651082253 - }, 'polygon clustered pattern'); - - t.end(); -}); diff --git a/packages/turf-moran-index/tsconfig.json b/packages/turf-moran-index/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-moran-index/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-moran-index/tslint.json b/packages/turf-moran-index/tslint.json deleted file mode 100644 index 9dd5998b9c..0000000000 --- a/packages/turf-moran-index/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {"interface-name": false}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-nearest-neighbor-analysis/.gitignore b/packages/turf-nearest-neighbor-analysis/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-nearest-neighbor-analysis/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-nearest-neighbor-analysis/LICENSE b/packages/turf-nearest-neighbor-analysis/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-nearest-neighbor-analysis/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-nearest-neighbor-analysis/README.md b/packages/turf-nearest-neighbor-analysis/README.md deleted file mode 100644 index ae8e7945cf..0000000000 --- a/packages/turf-nearest-neighbor-analysis/README.md +++ /dev/null @@ -1,105 +0,0 @@ -# @turf/nearest-neighbor-analysis - - - -## nearestNeighborAnalysis - -Nearest Neighbor Analysis calculates an index based the average distances -between points in the dataset, thereby providing inference as to whether the -data is clustered, dispersed, or randomly distributed within the study area. - -It returns a [Feature<Polygon>][1] of the study area, with the results of -the analysis attached as part of of the `nearestNeighborAnalysis` property -of the study area's `properties`. The attached -[_z_-score][2] indicates how many -standard deviations above or below the expected mean distance the data's -observed mean distance is. The more negative, the more clustered. The more -positive, the more evenly dispersed. A _z_-score between -2 and 2 indicates -a seemingly random distribution. That is, within _p_ of less than 0.05, the -distribution appears statistically significantly neither clustered nor -dispersed. - -**Remarks** - -- Though the analysis will work on any [FeatureCollection][3] type, it - works best with [Point][4] collections. - -- This analysis is _very_ sensitive to the study area provided. If no [Feature<Polygon>][1] is passed as the study area, the function draws a box - around the data, which may distort the findings. This analysis works best - with a bounded area of interest within with the data is either clustered, - dispersed, or randomly distributed. For example, a city's subway stops may - look extremely clustered if the study area is an entire state. On the other - hand, they may look rather evenly dispersed if the study area is limited to - the city's downtown. - -**Bibliography** - -Philip J. Clark and Francis C. Evans, “Distance to Nearest Neighbor as a -Measure of Spatial Relationships in Populations,” _Ecology_ 35, no. 4 -(1954): 445–453, doi:[10.2307/1931034][5]. - -**Parameters** - -- `dataset` **[FeatureCollection][6]<any>** FeatureCollection (pref. of points) to study -- `options` **[Object][7]** Optional parameters (optional, default `{}`) - - `options.studyArea` **[Feature][8]<[Polygon][9]>?** polygon representing the study area - - `options.units` **[string][10]** unit of measurement for distances and, squared, area. (optional, default `'kilometers'`) - - `options.properties` **[Object][7]** properties (optional, default `{}`) - -**Examples** - -```javascript -var bbox = [-65, 40, -63, 42]; -var dataset = turf.randomPoint(100, { bbox: bbox }); -var nearestNeighborStudyArea = turf.nearestNeighborAnalysis(dataset); - -//addToMap -var addToMap = [dataset, nearestNeighborStudyArea]; -``` - -Returns **[Feature][8]<[Polygon][9]>** A polygon of the study area or an approximation of one. - -[1]: Feature - -[2]: https://en.wikipedia.org/wiki/Standard_score - -[3]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[5]: http://doi.org/10.2307/1931034 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[8]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[9]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/nearest-neighbor-analysis -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-nearest-neighbor-analysis/index.d.ts b/packages/turf-nearest-neighbor-analysis/index.d.ts deleted file mode 100644 index d6ca6bcf17..0000000000 --- a/packages/turf-nearest-neighbor-analysis/index.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { FeatureCollection, Feature, Polygon, Units, Properties } from '@turf/helpers'; -export interface NearestNeighborStatistics { - units: Units; - arealUnits: string; - observedMeanDistance: number; - expectedMeanDistance: number; - numberOfPoints: number; - zScore: number; -} -export interface NearestNeighborStudyArea extends Feature { - properties: { - nearestNeighborAnalysis: NearestNeighborStatistics; - [key: string]: any; - }; -} -/** - * Nearest Neighbor Analysis calculates an index based the average distances - * between points in the dataset, thereby providing inference as to whether the - * data is clustered, dispersed, or randomly distributed within the study area. - * - * It returns a {@link Feature} of the study area, with the results of - * the analysis attached as part of of the `nearestNeighborAnalysis` property - * of the study area's `properties`. The attached - * [_z_-score](https://en.wikipedia.org/wiki/Standard_score) indicates how many - * standard deviations above or below the expected mean distance the data's - * observed mean distance is. The more negative, the more clustered. The more - * positive, the more evenly dispersed. A _z_-score between -2 and 2 indicates - * a seemingly random distribution. That is, within _p_ of less than 0.05, the - * distribution appears statistically significantly neither clustered nor - * dispersed. - * - * **Remarks** - * - * - Though the analysis will work on any {@link FeatureCollection} type, it - * works best with {@link Point} collections. - * - * - This analysis is _very_ sensitive to the study area provided. - * If no {@link Feature} is passed as the study area, the function draws a box - * around the data, which may distort the findings. This analysis works best - * with a bounded area of interest within with the data is either clustered, - * dispersed, or randomly distributed. For example, a city's subway stops may - * look extremely clustered if the study area is an entire state. On the other - * hand, they may look rather evenly dispersed if the study area is limited to - * the city's downtown. - * - * **Bibliography** - * - * Philip J. Clark and Francis C. Evans, “Distance to Nearest Neighbor as a - * Measure of Spatial Relationships in Populations,” _Ecology_ 35, no. 4 - * (1954): 445–453, doi:[10.2307/1931034](http://doi.org/10.2307/1931034). - * - * @name nearestNeighborAnalysis - * @param {FeatureCollection} dataset FeatureCollection (pref. of points) to study - * @param {Object} [options={}] Optional parameters - * @param {Feature} [options.studyArea] polygon representing the study area - * @param {string} [options.units='kilometers'] unit of measurement for distances and, squared, area. - * @param {Object} [options.properties={}] properties - * @returns {Feature} A polygon of the study area or an approximation of one. - * @example - * var bbox = [-65, 40, -63, 42]; - * var dataset = turf.randomPoint(100, { bbox: bbox }); - * var nearestNeighborStudyArea = turf.nearestNeighborAnalysis(dataset); - * - * //addToMap - * var addToMap = [dataset, nearestNeighborStudyArea]; - */ -declare function nearestNeighborAnalysis(dataset: FeatureCollection, options?: { - studyArea?: Feature; - units?: Units; - properties?: Properties; -}): NearestNeighborStudyArea; -export default nearestNeighborAnalysis; diff --git a/packages/turf-nearest-neighbor-analysis/index.ts b/packages/turf-nearest-neighbor-analysis/index.ts deleted file mode 100644 index a4481d4cd1..0000000000 --- a/packages/turf-nearest-neighbor-analysis/index.ts +++ /dev/null @@ -1,120 +0,0 @@ -import area from '@turf/area'; -import bbox from '@turf/bbox'; -import bboxPolygon from '@turf/bbox-polygon'; -import centroid from '@turf/centroid'; -import distance from '@turf/distance'; -import nearestPoint from '@turf/nearest-point'; -import { featureEach } from '@turf/meta'; -import { convertArea, featureCollection } from '@turf/helpers'; -import { FeatureCollection, Feature, Point, Polygon, Units, Properties } from '@turf/helpers'; - -export interface NearestNeighborStatistics { - units: Units; - arealUnits: string; - observedMeanDistance: number; - expectedMeanDistance: number; - numberOfPoints: number; - zScore: number; -} - -export interface NearestNeighborStudyArea extends Feature { - properties: { - nearestNeighborAnalysis: NearestNeighborStatistics; - [key: string]: any; - }; -} - -/** - * Nearest Neighbor Analysis calculates an index based the average distances - * between points in the dataset, thereby providing inference as to whether the - * data is clustered, dispersed, or randomly distributed within the study area. - * - * It returns a {@link Feature} of the study area, with the results of - * the analysis attached as part of of the `nearestNeighborAnalysis` property - * of the study area's `properties`. The attached - * [_z_-score](https://en.wikipedia.org/wiki/Standard_score) indicates how many - * standard deviations above or below the expected mean distance the data's - * observed mean distance is. The more negative, the more clustered. The more - * positive, the more evenly dispersed. A _z_-score between -2 and 2 indicates - * a seemingly random distribution. That is, within _p_ of less than 0.05, the - * distribution appears statistically significantly neither clustered nor - * dispersed. - * - * **Remarks** - * - * - Though the analysis will work on any {@link FeatureCollection} type, it - * works best with {@link Point} collections. - * - * - This analysis is _very_ sensitive to the study area provided. - * If no {@link Feature} is passed as the study area, the function draws a box - * around the data, which may distort the findings. This analysis works best - * with a bounded area of interest within with the data is either clustered, - * dispersed, or randomly distributed. For example, a city's subway stops may - * look extremely clustered if the study area is an entire state. On the other - * hand, they may look rather evenly dispersed if the study area is limited to - * the city's downtown. - * - * **Bibliography** - * - * Philip J. Clark and Francis C. Evans, “Distance to Nearest Neighbor as a - * Measure of Spatial Relationships in Populations,” _Ecology_ 35, no. 4 - * (1954): 445–453, doi:[10.2307/1931034](http://doi.org/10.2307/1931034). - * - * @name nearestNeighborAnalysis - * @param {FeatureCollection} dataset FeatureCollection (pref. of points) to study - * @param {Object} [options={}] Optional parameters - * @param {Feature} [options.studyArea] polygon representing the study area - * @param {string} [options.units='kilometers'] unit of measurement for distances and, squared, area. - * @param {Object} [options.properties={}] properties - * @returns {Feature} A polygon of the study area or an approximation of one. - * @example - * var bbox = [-65, 40, -63, 42]; - * var dataset = turf.randomPoint(100, { bbox: bbox }); - * var nearestNeighborStudyArea = turf.nearestNeighborAnalysis(dataset); - * - * //addToMap - * var addToMap = [dataset, nearestNeighborStudyArea]; - */ -function nearestNeighborAnalysis(dataset: FeatureCollection, options?: { - studyArea?: Feature; - units?: Units; - properties?: Properties; -}): NearestNeighborStudyArea { - // Optional params - options = options || {}; - const studyArea = options.studyArea || bboxPolygon(bbox(dataset)); - const properties = options.properties || {}; - const units = options.units || 'kilometers'; - - const features: Array> = []; - featureEach(dataset, (feature) => { - features.push(centroid(feature)); - }); - const n = features.length; - const observedMeanDistance = features.map((feature, index) => { - const otherFeatures = featureCollection(features.filter((f, i) => { - return i !== index; - })); - // Have to add the ! to make typescript validation pass - // see https://stackoverflow.com/a/40350534/1979085 - return distance(feature, nearestPoint(feature, otherFeatures).geometry!.coordinates, {units}); - }).reduce((sum, value) => { return sum + value; }, 0) / n; - - const populationDensity = n / convertArea(area(studyArea), 'meters', units); - const expectedMeanDistance = 1 / (2 * Math.sqrt(populationDensity)); - const variance = 0.26136 / (Math.sqrt(n * populationDensity)); - properties.nearestNeighborAnalysis = { - units: units, - arealUnits: units + '²', - observedMeanDistance: observedMeanDistance, - expectedMeanDistance: expectedMeanDistance, - nearestNeighborIndex: observedMeanDistance / expectedMeanDistance, - numberOfPoints: n, - zScore: (observedMeanDistance - expectedMeanDistance) / variance, - }; - studyArea.properties = properties; - - return studyArea as NearestNeighborStudyArea; -} - -export default nearestNeighborAnalysis; diff --git a/packages/turf-nearest-neighbor-analysis/package.json b/packages/turf-nearest-neighbor-analysis/package.json deleted file mode 100644 index a2a7b3bf45..0000000000 --- a/packages/turf-nearest-neighbor-analysis/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "@turf/nearest-neighbor-analysis", - "version": "6.0.1", - "description": "turf nearest-neighbor-analysis module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "nearest-neighbor" - ], - "author": "Turf Authors", - "contributors": [ - "Moacir P. de Sá Pereira <@muziejus>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/truncate": "*", - "benchmark": "*", - "write-json-file": "*", - "load-json-file": "*", - "tape": "*", - "typescript": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/area": "6.x", - "@turf/bbox": "6.x", - "@turf/bbox-polygon": "6.x", - "@turf/centroid": "6.x", - "@turf/distance": "6.x", - "@turf/helpers": "6.x", - "@turf/meta": "6.x", - "@turf/nearest-point": "6.x" - } -} diff --git a/packages/turf-nearest-neighbor-analysis/test.js b/packages/turf-nearest-neighbor-analysis/test.js deleted file mode 100644 index de802d0888..0000000000 --- a/packages/turf-nearest-neighbor-analysis/test.js +++ /dev/null @@ -1,32 +0,0 @@ -const test = require('tape'); -const glob = require('glob'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const truncate = require('@turf/truncate').default; -const centroid = require('@turf/centroid').default; -const { featureEach } = require('@turf/meta'); -const { featureCollection } = require('@turf/helpers'); -const nearestNeighborAnalysis = require('.').default; - - - -test('turf-nearest-neighbor', t => { - glob.sync(path.join(__dirname, 'test', 'in', '*.json')).forEach(filepath => { - // Define params - const {name} = path.parse(filepath); - const geojson = load.sync(filepath); - const options = geojson.options; - const results = featureCollection([]); - featureEach(geojson, feature => results.features.push(truncate(feature))); - if (geojson.features[0].geometry.type === "Polygon") { - featureEach(geojson, feature => results.features.push(truncate(centroid(feature, {properties: {"marker-color": "#0a0"}})))); - } - results.features.push(truncate(nearestNeighborAnalysis(geojson, options))); - const out = filepath.replace('in', 'out'); - if (process.env.REGEN) write.sync(out, results); - t.deepEqual(results, load.sync(out), name); - - }); - t.end(); -}); diff --git a/packages/turf-nearest-neighbor-analysis/test/out/squares.json b/packages/turf-nearest-neighbor-analysis/test/out/squares.json deleted file mode 100644 index 50115a9b70..0000000000 --- a/packages/turf-nearest-neighbor-analysis/test/out/squares.json +++ /dev/null @@ -1,2519 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299993, - 38.120136 - ], - [ - -9.299993, - 38.165102 - ], - [ - -9.242852, - 38.165102 - ], - [ - -9.242852, - 38.120136 - ], - [ - -9.299993, - 38.120136 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299993, - 38.165102 - ], - [ - -9.299993, - 38.210068 - ], - [ - -9.242852, - 38.210068 - ], - [ - -9.242852, - 38.165102 - ], - [ - -9.299993, - 38.165102 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299993, - 38.210068 - ], - [ - -9.299993, - 38.255034 - ], - [ - -9.242852, - 38.255034 - ], - [ - -9.242852, - 38.210068 - ], - [ - -9.299993, - 38.210068 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299993, - 38.255034 - ], - [ - -9.299993, - 38.3 - ], - [ - -9.242852, - 38.3 - ], - [ - -9.242852, - 38.255034 - ], - [ - -9.299993, - 38.255034 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299993, - 38.3 - ], - [ - -9.299993, - 38.344966 - ], - [ - -9.242852, - 38.344966 - ], - [ - -9.242852, - 38.3 - ], - [ - -9.299993, - 38.3 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299993, - 38.344966 - ], - [ - -9.299993, - 38.389932 - ], - [ - -9.242852, - 38.389932 - ], - [ - -9.242852, - 38.344966 - ], - [ - -9.299993, - 38.344966 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299993, - 38.389932 - ], - [ - -9.299993, - 38.434898 - ], - [ - -9.242852, - 38.434898 - ], - [ - -9.242852, - 38.389932 - ], - [ - -9.299993, - 38.389932 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299993, - 38.434898 - ], - [ - -9.299993, - 38.479864 - ], - [ - -9.242852, - 38.479864 - ], - [ - -9.242852, - 38.434898 - ], - [ - -9.299993, - 38.434898 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242852, - 38.120136 - ], - [ - -9.242852, - 38.165102 - ], - [ - -9.185711, - 38.165102 - ], - [ - -9.185711, - 38.120136 - ], - [ - -9.242852, - 38.120136 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242852, - 38.165102 - ], - [ - -9.242852, - 38.210068 - ], - [ - -9.185711, - 38.210068 - ], - [ - -9.185711, - 38.165102 - ], - [ - -9.242852, - 38.165102 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242852, - 38.210068 - ], - [ - -9.242852, - 38.255034 - ], - [ - -9.185711, - 38.255034 - ], - [ - -9.185711, - 38.210068 - ], - [ - -9.242852, - 38.210068 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242852, - 38.255034 - ], - [ - -9.242852, - 38.3 - ], - [ - -9.185711, - 38.3 - ], - [ - -9.185711, - 38.255034 - ], - [ - -9.242852, - 38.255034 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242852, - 38.3 - ], - [ - -9.242852, - 38.344966 - ], - [ - -9.185711, - 38.344966 - ], - [ - -9.185711, - 38.3 - ], - [ - -9.242852, - 38.3 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242852, - 38.344966 - ], - [ - -9.242852, - 38.389932 - ], - [ - -9.185711, - 38.389932 - ], - [ - -9.185711, - 38.344966 - ], - [ - -9.242852, - 38.344966 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242852, - 38.389932 - ], - [ - -9.242852, - 38.434898 - ], - [ - -9.185711, - 38.434898 - ], - [ - -9.185711, - 38.389932 - ], - [ - -9.242852, - 38.389932 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.242852, - 38.434898 - ], - [ - -9.242852, - 38.479864 - ], - [ - -9.185711, - 38.479864 - ], - [ - -9.185711, - 38.434898 - ], - [ - -9.242852, - 38.434898 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711, - 38.120136 - ], - [ - -9.185711, - 38.165102 - ], - [ - -9.12857, - 38.165102 - ], - [ - -9.12857, - 38.120136 - ], - [ - -9.185711, - 38.120136 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711, - 38.165102 - ], - [ - -9.185711, - 38.210068 - ], - [ - -9.12857, - 38.210068 - ], - [ - -9.12857, - 38.165102 - ], - [ - -9.185711, - 38.165102 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711, - 38.210068 - ], - [ - -9.185711, - 38.255034 - ], - [ - -9.12857, - 38.255034 - ], - [ - -9.12857, - 38.210068 - ], - [ - -9.185711, - 38.210068 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711, - 38.255034 - ], - [ - -9.185711, - 38.3 - ], - [ - -9.12857, - 38.3 - ], - [ - -9.12857, - 38.255034 - ], - [ - -9.185711, - 38.255034 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711, - 38.3 - ], - [ - -9.185711, - 38.344966 - ], - [ - -9.12857, - 38.344966 - ], - [ - -9.12857, - 38.3 - ], - [ - -9.185711, - 38.3 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711, - 38.344966 - ], - [ - -9.185711, - 38.389932 - ], - [ - -9.12857, - 38.389932 - ], - [ - -9.12857, - 38.344966 - ], - [ - -9.185711, - 38.344966 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711, - 38.389932 - ], - [ - -9.185711, - 38.434898 - ], - [ - -9.12857, - 38.434898 - ], - [ - -9.12857, - 38.389932 - ], - [ - -9.185711, - 38.389932 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.185711, - 38.434898 - ], - [ - -9.185711, - 38.479864 - ], - [ - -9.12857, - 38.479864 - ], - [ - -9.12857, - 38.434898 - ], - [ - -9.185711, - 38.434898 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857, - 38.120136 - ], - [ - -9.12857, - 38.165102 - ], - [ - -9.07143, - 38.165102 - ], - [ - -9.07143, - 38.120136 - ], - [ - -9.12857, - 38.120136 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857, - 38.165102 - ], - [ - -9.12857, - 38.210068 - ], - [ - -9.07143, - 38.210068 - ], - [ - -9.07143, - 38.165102 - ], - [ - -9.12857, - 38.165102 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857, - 38.210068 - ], - [ - -9.12857, - 38.255034 - ], - [ - -9.07143, - 38.255034 - ], - [ - -9.07143, - 38.210068 - ], - [ - -9.12857, - 38.210068 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857, - 38.255034 - ], - [ - -9.12857, - 38.3 - ], - [ - -9.07143, - 38.3 - ], - [ - -9.07143, - 38.255034 - ], - [ - -9.12857, - 38.255034 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857, - 38.3 - ], - [ - -9.12857, - 38.344966 - ], - [ - -9.07143, - 38.344966 - ], - [ - -9.07143, - 38.3 - ], - [ - -9.12857, - 38.3 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857, - 38.344966 - ], - [ - -9.12857, - 38.389932 - ], - [ - -9.07143, - 38.389932 - ], - [ - -9.07143, - 38.344966 - ], - [ - -9.12857, - 38.344966 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857, - 38.389932 - ], - [ - -9.12857, - 38.434898 - ], - [ - -9.07143, - 38.434898 - ], - [ - -9.07143, - 38.389932 - ], - [ - -9.12857, - 38.389932 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.12857, - 38.434898 - ], - [ - -9.12857, - 38.479864 - ], - [ - -9.07143, - 38.479864 - ], - [ - -9.07143, - 38.434898 - ], - [ - -9.12857, - 38.434898 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.07143, - 38.120136 - ], - [ - -9.07143, - 38.165102 - ], - [ - -9.014289, - 38.165102 - ], - [ - -9.014289, - 38.120136 - ], - [ - -9.07143, - 38.120136 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.07143, - 38.165102 - ], - [ - -9.07143, - 38.210068 - ], - [ - -9.014289, - 38.210068 - ], - [ - -9.014289, - 38.165102 - ], - [ - -9.07143, - 38.165102 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.07143, - 38.210068 - ], - [ - -9.07143, - 38.255034 - ], - [ - -9.014289, - 38.255034 - ], - [ - -9.014289, - 38.210068 - ], - [ - -9.07143, - 38.210068 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.07143, - 38.255034 - ], - [ - -9.07143, - 38.3 - ], - [ - -9.014289, - 38.3 - ], - [ - -9.014289, - 38.255034 - ], - [ - -9.07143, - 38.255034 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.07143, - 38.3 - ], - [ - -9.07143, - 38.344966 - ], - [ - -9.014289, - 38.344966 - ], - [ - -9.014289, - 38.3 - ], - [ - -9.07143, - 38.3 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.07143, - 38.344966 - ], - [ - -9.07143, - 38.389932 - ], - [ - -9.014289, - 38.389932 - ], - [ - -9.014289, - 38.344966 - ], - [ - -9.07143, - 38.344966 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.07143, - 38.389932 - ], - [ - -9.07143, - 38.434898 - ], - [ - -9.014289, - 38.434898 - ], - [ - -9.014289, - 38.389932 - ], - [ - -9.07143, - 38.389932 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.07143, - 38.434898 - ], - [ - -9.07143, - 38.479864 - ], - [ - -9.014289, - 38.479864 - ], - [ - -9.014289, - 38.434898 - ], - [ - -9.07143, - 38.434898 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.014289, - 38.120136 - ], - [ - -9.014289, - 38.165102 - ], - [ - -8.957148, - 38.165102 - ], - [ - -8.957148, - 38.120136 - ], - [ - -9.014289, - 38.120136 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.014289, - 38.165102 - ], - [ - -9.014289, - 38.210068 - ], - [ - -8.957148, - 38.210068 - ], - [ - -8.957148, - 38.165102 - ], - [ - -9.014289, - 38.165102 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.014289, - 38.210068 - ], - [ - -9.014289, - 38.255034 - ], - [ - -8.957148, - 38.255034 - ], - [ - -8.957148, - 38.210068 - ], - [ - -9.014289, - 38.210068 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.014289, - 38.255034 - ], - [ - -9.014289, - 38.3 - ], - [ - -8.957148, - 38.3 - ], - [ - -8.957148, - 38.255034 - ], - [ - -9.014289, - 38.255034 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.014289, - 38.3 - ], - [ - -9.014289, - 38.344966 - ], - [ - -8.957148, - 38.344966 - ], - [ - -8.957148, - 38.3 - ], - [ - -9.014289, - 38.3 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.014289, - 38.344966 - ], - [ - -9.014289, - 38.389932 - ], - [ - -8.957148, - 38.389932 - ], - [ - -8.957148, - 38.344966 - ], - [ - -9.014289, - 38.344966 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.014289, - 38.389932 - ], - [ - -9.014289, - 38.434898 - ], - [ - -8.957148, - 38.434898 - ], - [ - -8.957148, - 38.389932 - ], - [ - -9.014289, - 38.389932 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.014289, - 38.434898 - ], - [ - -9.014289, - 38.479864 - ], - [ - -8.957148, - 38.479864 - ], - [ - -8.957148, - 38.434898 - ], - [ - -9.014289, - 38.434898 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -8.957148, - 38.120136 - ], - [ - -8.957148, - 38.165102 - ], - [ - -8.900007, - 38.165102 - ], - [ - -8.900007, - 38.120136 - ], - [ - -8.957148, - 38.120136 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -8.957148, - 38.165102 - ], - [ - -8.957148, - 38.210068 - ], - [ - -8.900007, - 38.210068 - ], - [ - -8.900007, - 38.165102 - ], - [ - -8.957148, - 38.165102 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -8.957148, - 38.210068 - ], - [ - -8.957148, - 38.255034 - ], - [ - -8.900007, - 38.255034 - ], - [ - -8.900007, - 38.210068 - ], - [ - -8.957148, - 38.210068 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -8.957148, - 38.255034 - ], - [ - -8.957148, - 38.3 - ], - [ - -8.900007, - 38.3 - ], - [ - -8.900007, - 38.255034 - ], - [ - -8.957148, - 38.255034 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -8.957148, - 38.3 - ], - [ - -8.957148, - 38.344966 - ], - [ - -8.900007, - 38.344966 - ], - [ - -8.900007, - 38.3 - ], - [ - -8.957148, - 38.3 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -8.957148, - 38.344966 - ], - [ - -8.957148, - 38.389932 - ], - [ - -8.900007, - 38.389932 - ], - [ - -8.900007, - 38.344966 - ], - [ - -8.957148, - 38.344966 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -8.957148, - 38.389932 - ], - [ - -8.957148, - 38.434898 - ], - [ - -8.900007, - 38.434898 - ], - [ - -8.900007, - 38.389932 - ], - [ - -8.957148, - 38.389932 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -8.957148, - 38.434898 - ], - [ - -8.957148, - 38.479864 - ], - [ - -8.900007, - 38.479864 - ], - [ - -8.900007, - 38.434898 - ], - [ - -8.957148, - 38.434898 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.277136, - 38.138122 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.277136, - 38.183088 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.277136, - 38.228054 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.277136, - 38.27302 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.277136, - 38.317986 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.277136, - 38.362952 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.277136, - 38.407918 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.277136, - 38.452884 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.219996, - 38.138122 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.219996, - 38.183088 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.219996, - 38.228054 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.219996, - 38.27302 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.219996, - 38.317986 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.219996, - 38.362952 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.219996, - 38.407918 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.219996, - 38.452884 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.162855, - 38.138122 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.162855, - 38.183088 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.162855, - 38.228054 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.162855, - 38.27302 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.162855, - 38.317986 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.162855, - 38.362952 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.162855, - 38.407918 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.162855, - 38.452884 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.105714, - 38.138122 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.105714, - 38.183088 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.105714, - 38.228054 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.105714, - 38.27302 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.105714, - 38.317986 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.105714, - 38.362952 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.105714, - 38.407918 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.105714, - 38.452884 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.048573, - 38.138122 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.048573, - 38.183088 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.048573, - 38.228054 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.048573, - 38.27302 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.048573, - 38.317986 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.048573, - 38.362952 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.048573, - 38.407918 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -9.048573, - 38.452884 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.991433, - 38.138122 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.991433, - 38.183088 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.991433, - 38.228054 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.991433, - 38.27302 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.991433, - 38.317986 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.991433, - 38.362952 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.991433, - 38.407918 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.991433, - 38.452884 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.934292, - 38.138122 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.934292, - 38.183088 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.934292, - 38.228054 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.934292, - 38.27302 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.934292, - 38.317986 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.934292, - 38.362952 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.934292, - 38.407918 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#0a0" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -8.934292, - 38.452884 - ] - } - }, - { - "type": "Feature", - "bbox": [ - -9.299992605418552, - 38.12013592725509, - -8.900007394581449, - 38.47986407274493 - ], - "properties": { - "fill-opacity": 0, - "stroke-width": 5, - "stroke": "#a00", - "nearestNeighborAnalysis": { - "units": "kilometers", - "arealUnits": "kilometers²", - "observedMeanDistance": 4.986589186008142, - "expectedMeanDistance": 2.499360952873312, - "nearestNeighborIndex": 1.9951456712466704, - "numberOfPoints": 56, - "zScore": 14.246610620355893 - } - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -9.299993, - 38.120136 - ], - [ - -8.900007, - 38.120136 - ], - [ - -8.900007, - 38.479864 - ], - [ - -9.299993, - 38.479864 - ], - [ - -9.299993, - 38.120136 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-nearest-neighbor-analysis/tsconfig.json b/packages/turf-nearest-neighbor-analysis/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-nearest-neighbor-analysis/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-nearest-neighbor-analysis/tslint.json b/packages/turf-nearest-neighbor-analysis/tslint.json deleted file mode 100644 index 9dd5998b9c..0000000000 --- a/packages/turf-nearest-neighbor-analysis/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {"interface-name": false}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-nearest-point-on-line/.gitignore b/packages/turf-nearest-point-on-line/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-nearest-point-on-line/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-nearest-point-on-line/LICENSE b/packages/turf-nearest-point-on-line/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-nearest-point-on-line/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-nearest-point-on-line/README.md b/packages/turf-nearest-point-on-line/README.md deleted file mode 100644 index a4401d936a..0000000000 --- a/packages/turf-nearest-point-on-line/README.md +++ /dev/null @@ -1,83 +0,0 @@ -# @turf/nearest-point-on-line - - - -## nearestPointOnLine - -Takes a [Point][1] and a [LineString][2] and calculates the closest Point on the (Multi)LineString. - -**Parameters** - -- `lines` **([Geometry][3] \| [Feature][4]<([LineString][5] \| [MultiLineString][6])>)** lines to snap to -- `pt` **([Geometry][3] \| [Feature][4]<[Point][7]> | [Array][8]<[number][9]>)** point to snap from -- `options` **[Object][10]** Optional parameters (optional, default `{}`) - - `options.units` **[string][11]** can be degrees, radians, miles, or kilometers (optional, default `'kilometers'`) - -**Examples** - -```javascript -var line = turf.lineString([ - [-77.031669, 38.878605], - [-77.029609, 38.881946], - [-77.020339, 38.884084], - [-77.025661, 38.885821], - [-77.021884, 38.889563], - [-77.019824, 38.892368] -]); -var pt = turf.point([-77.037076, 38.884017]); - -var snapped = turf.nearestPointOnLine(line, pt, {units: 'miles'}); - -//addToMap -var addToMap = [line, pt, snapped]; -snapped.properties['marker-color'] = '#00f'; -``` - -Returns **[Feature][4]<[Point][7]>** closest point on the `line` to `point`. The properties object will contain three values: `index`: closest point was found on nth line part, `dist`: distance between pt and the closest point, `location`: distance along the line between start and the closest point. - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array - -[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[11]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/nearest-point-on-line -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-nearest-point-on-line/index.ts b/packages/turf-nearest-point-on-line/index.ts deleted file mode 100644 index 5049a5e01b..0000000000 --- a/packages/turf-nearest-point-on-line/index.ts +++ /dev/null @@ -1,108 +0,0 @@ -import bearing from '@turf/bearing'; -import distance from '@turf/distance'; -import destination from '@turf/destination'; -import lineIntersects from '@turf/line-intersect'; -import { flattenEach } from '@turf/meta'; -import { - point, lineString, isObject, - Feature, Point, LineString, MultiLineString, Coord, Units -} from '@turf/helpers'; -import { getCoords } from '@turf/invariant'; - -export interface NearestPointOnLine extends Feature { - properties: { - index?: number - dist?: number - location?: number - [key: string]: any - } -} - -/** - * Takes a {@link Point} and a {@link LineString} and calculates the closest Point on the (Multi)LineString. - * - * @name nearestPointOnLine - * @param {Geometry|Feature} lines lines to snap to - * @param {Geometry|Feature|number[]} pt point to snap from - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers - * @returns {Feature} closest point on the `line` to `point`. The properties object will contain three values: `index`: closest point was found on nth line part, `dist`: distance between pt and the closest point, `location`: distance along the line between start and the closest point. - * @example - * var line = turf.lineString([ - * [-77.031669, 38.878605], - * [-77.029609, 38.881946], - * [-77.020339, 38.884084], - * [-77.025661, 38.885821], - * [-77.021884, 38.889563], - * [-77.019824, 38.892368] - * ]); - * var pt = turf.point([-77.037076, 38.884017]); - * - * var snapped = turf.nearestPointOnLine(line, pt, {units: 'miles'}); - * - * //addToMap - * var addToMap = [line, pt, snapped]; - * snapped.properties['marker-color'] = '#00f'; - */ -function nearestPointOnLine( - lines: Feature | G, - pt: Coord, - options: {units?: Units} = {} -): NearestPointOnLine { - let closestPt: any = point([Infinity, Infinity], { - dist: Infinity - }); - - let length = 0.0; - flattenEach(lines, function (line: any) { - const coords: any = getCoords(line); - - for (let i = 0; i < coords.length - 1; i++) { - //start - const start = point(coords[i]); - start.properties.dist = distance(pt, start, options); - //stop - const stop = point(coords[i + 1]); - stop.properties.dist = distance(pt, stop, options); - // sectionLength - const sectionLength = distance(start, stop, options); - //perpendicular - const heightDistance = Math.max(start.properties.dist, stop.properties.dist); - const direction = bearing(start, stop); - const perpendicularPt1 = destination(pt, heightDistance, direction + 90, options); - const perpendicularPt2 = destination(pt, heightDistance, direction - 90, options); - const intersect = lineIntersects( - lineString([perpendicularPt1.geometry.coordinates, perpendicularPt2.geometry.coordinates]), - lineString([start.geometry.coordinates, stop.geometry.coordinates]) - ); - let intersectPt = null; - if (intersect.features.length > 0) { - intersectPt = intersect.features[0]; - intersectPt.properties.dist = distance(pt, intersectPt, options); - intersectPt.properties.location = length + distance(start, intersectPt, options); - } - - if (start.properties.dist < closestPt.properties.dist) { - closestPt = start; - closestPt.properties.index = i; - closestPt.properties.location = length; - } - if (stop.properties.dist < closestPt.properties.dist) { - closestPt = stop; - closestPt.properties.index = i + 1; - closestPt.properties.location = length + sectionLength; - } - if (intersectPt && intersectPt.properties.dist < closestPt.properties.dist) { - closestPt = intersectPt; - closestPt.properties.index = i; - } - // update length - length += sectionLength; - } - - }); - - return closestPt; -} - -export default nearestPointOnLine; diff --git a/packages/turf-nearest-point-on-line/package.json b/packages/turf-nearest-point-on-line/package.json deleted file mode 100644 index fe86dc735e..0000000000 --- a/packages/turf-nearest-point-on-line/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@turf/nearest-point-on-line", - "version": "6.0.2", - "description": "turf nearest-point-on-line module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/along": "*", - "@turf/length": "*", - "@turf/truncate": "*", - "benchmark": "*", - "load-json-file": "*", - "tape": "*", - "write-json-file": "*", - "typescript": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/bearing": "6.x", - "@turf/destination": "6.x", - "@turf/distance": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/line-intersect": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-nearest-point-on-line/test.js b/packages/turf-nearest-point-on-line/test.js deleted file mode 100644 index 0fb44744da..0000000000 --- a/packages/turf-nearest-point-on-line/test.js +++ /dev/null @@ -1,211 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const along = require('@turf/along').default; -const distance = require('@turf/distance').default; -const truncate = require('@turf/truncate').default; -const length = require('@turf/length').default; -const { lineString, multiLineString, point, featureCollection, round } = require('@turf/helpers'); -const nearestPointOnLine = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-linestring-to-polygon', t => { - for (const {name, filename, geojson} of fixtures) { - const [line, point] = geojson.features; - const onLine = nearestPointOnLine(line, point); - onLine.properties['marker-color'] = '#F0F'; - onLine.properties.dist = round(onLine.properties.dist, 6); - onLine.properties.location = round(onLine.properties.location, 6); - const between = lineString([onLine.geometry.coordinates, point.geometry.coordinates], {stroke: '#F00', 'stroke-width': 6}); - const results = truncate(featureCollection([line, between, point, onLine])); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEqual(load.sync(directories.out + filename), results, name); - } - t.end(); -}); - -test('turf-point-on-line - first point', t => { - const line = lineString([[-122.457175, 37.720033], [-122.457175, 37.718242]]); - const pt = point([-122.457175, 37.720033]); - - const snapped = truncate(nearestPointOnLine(line, pt)); - - t.deepEqual(pt.geometry.coordinates, snapped.geometry.coordinates, 'pt on start does not move'); - t.equal(Number(snapped.properties.location.toFixed(6)), 0, 'properties.location'); - - t.end(); -}); - -test('turf-point-on-line - points behind first point', t => { - const line = lineString([[-122.457175, 37.720033], [-122.457175, 37.718242]]); - const first = point(line.geometry.coordinates[0]); - const pts = [ - point([-122.457175, 37.720093]), - point([-122.457175, 37.820093]), - point([-122.457165, 37.720093]), - point([-122.455165, 37.720093]) - ]; - const expectedLocation = [0, 0, 0, 0]; - - pts.forEach(pt => { - const snapped = truncate(nearestPointOnLine(line, pt)); - t.deepEqual(first.geometry.coordinates, snapped.geometry.coordinates, 'pt behind start moves to first vertex'); - expectedLocation.push(Number(snapped.properties.location.toFixed(6))); - }); - - const filepath = directories.out + 'expectedLocation - points behind first point.json'; - if (process.env.REGEN) write.sync(filepath, expectedLocation); - t.deepEqual(load.sync(filepath), expectedLocation, 'properties.location'); - t.end(); -}); - -test('turf-point-on-line - points in front of last point', t => { - const line = lineString([[-122.456161, 37.721259], [-122.457175, 37.720033], [-122.457175, 37.718242]]); - const last = point(line.geometry.coordinates[line.geometry.coordinates.length - 1]); - const pts = [ - point([-122.456960, 37.718140]), - point([-122.457363, 37.718132]), - point([-122.457309, 37.717979]), - point([-122.457180, 37.717045]) - ]; - const expectedLocation = []; - - pts.forEach(pt => { - const snapped = truncate(nearestPointOnLine(line, pt)); - t.deepEqual(last.geometry.coordinates, snapped.geometry.coordinates, 'pt behind start moves to last vertex'); - expectedLocation.push(Number(snapped.properties.location.toFixed(6))); - }); - - const filepath = directories.out + 'expectedLocation - points in front of last point.json'; - if (process.env.REGEN) write.sync(filepath, expectedLocation); - t.deepEqual(load.sync(filepath), expectedLocation, 'properties.location'); - t.end(); -}); - -test('turf-point-on-line - points on joints', t => { - const lines = [ - lineString([[-122.456161, 37.721259], [-122.457175, 37.720033], [-122.457175, 37.718242]]), - lineString([[26.279296, 31.728167], [21.796875, 32.694865], [18.808593, 29.993002], [12.919921, 33.137551], [10.195312, 35.603718], [4.921875, 36.527294], [-1.669921, 36.527294], [-5.449218, 34.741612], [-8.789062, 32.990235]]), - lineString([[-0.109198, 51.522042], [-0.109230, 51.521942], [-0.109165, 51.521862], [-0.109047, 51.521775], [-0.108865, 51.521601], [-0.108747, 51.521381], [-0.108554, 51.520687], [-0.108436, 51.520279], [-0.108393, 51.519952], [-0.108178, 51.519578], [-0.108146, 51.519285], [-0.107899, 51.518624], [-0.107599, 51.517782]]) - ]; - const expectedLocation = []; - - lines.forEach((line, i) => { - line.geometry.coordinates.map(coord => { - return point(coord); - }).forEach((pt, j) => { - const snapped = truncate(nearestPointOnLine(line, pt)); - t.deepEqual(pt.geometry.coordinates, snapped.geometry.coordinates, 'pt on joint stayed in place'); - if (!expectedLocation[i]) expectedLocation[i] = []; - expectedLocation[i][j] = Number(snapped.properties.location.toFixed(6)); - }); - }); - - const filepath = directories.out + 'expectedLocation - points on joints.json'; - if (process.env.REGEN) write.sync(filepath, expectedLocation); - t.deepEqual(load.sync(filepath), expectedLocation, 'properties.location'); - t.end(); -}); - -test('turf-point-on-line - points on top of line', t => { - const line = lineString([[-0.109198, 51.522042], [-0.109230, 51.521942], [-0.109165, 51.521862], [-0.109047, 51.521775], [-0.108865, 51.521601], [-0.108747, 51.521381], [-0.108554, 51.520687], [-0.108436, 51.520279], [-0.108393, 51.519952], [-0.108178, 51.519578], [-0.108146, 51.519285], [-0.107899, 51.518624], [-0.107599, 51.517782]]); - const expectedLocation = []; - - const dist = length(line, {units: 'miles'}); - const increment = dist / 10; - - for (let i = 0; i < 10; i++) { - const pt = along(line, increment * i, {units: 'miles'}); - const snapped = nearestPointOnLine(line, pt, {units: 'miles'}); - const shift = distance(pt, snapped, {units: 'miles'}); - t.true(shift < 0.000001, 'pt did not shift far'); - expectedLocation.push(Number(snapped.properties.location.toFixed(6))); - } - - const filepath = directories.out + 'expectedLocation - points on top of line.json'; - if (process.env.REGEN) write.sync(filepath, expectedLocation); - t.deepEqual(load.sync(filepath), expectedLocation, 'properties.location'); - t.end(); -}); - -test('turf-point-on-line - point along line', t => { - const line = lineString([[-122.457175, 37.720033], [-122.457175, 37.718242]]); - - const pt = along(line, 0.019, {units: 'miles'}); - const snapped = nearestPointOnLine(line, pt); - const shift = distance(pt, snapped, {units: 'miles'}); - - t.true(shift < 0.00001, 'pt did not shift far'); - - t.end(); -}); - -test('turf-point-on-line - points on sides of lines', t => { - const line = lineString([[-122.456161, 37.721259], [-122.457175, 37.718242]]); - const first = line.geometry.coordinates[0]; - const last = line.geometry.coordinates[line.geometry.coordinates.length - 1]; - const pts = [ - point([-122.457025, 37.718810]), - point([-122.457336, 37.719235]), - point([-122.456864, 37.720270]), - point([-122.456520, 37.720635]) - ]; - - pts.forEach(pt => { - const snapped = nearestPointOnLine(line, pt); - t.notDeepEqual(snapped.geometry.coordinates, first, 'pt did not snap to first vertex'); - t.notDeepEqual(snapped.geometry.coordinates, last, 'pt did not snap to last vertex'); - }); - - t.end(); -}); - -test('turf-point-on-line - check dist and index', t => { - const line = lineString([[-92.090492, 41.102897], [-92.191085, 41.079868], [-92.228507, 41.056055], [-92.237091, 41.008143], [-92.225761, 40.966937], [-92.150230, 40.936858], [-92.112464, 40.977565], [-92.062683, 41.034564], [-92.100791, 41.040002]]); - const pt = point([-92.110576, 41.040649]); - const snapped = truncate(nearestPointOnLine(line, pt)); - - t.equal(snapped.properties.index, 8, 'properties.index'); - t.equal(Number(snapped.properties.dist.toFixed(6)), 0.823802, 'properties.dist'); - t.deepEqual(snapped.geometry.coordinates, [-92.100791, 41.040002], 'coordinates'); - - t.end(); -}); - -test('turf-point-on-line -- Issue #691', t => { - const line1 = lineString([[7, 50], [8, 50], [9, 50]]); - const pointAlong = along(line1, 10); - const {location} = nearestPointOnLine(line1, pointAlong).properties; - - t.false(isNaN(location)); - t.end(); -}); - -test('turf-point-on-line -- Geometry Support', t => { - const pt = point([7, 55]); - const line = lineString([[7, 50], [8, 50], [9, 50]]); - const multiLine = multiLineString([ - [[7, 50], [8, 50], [9, 50]], - [[17, 30], [4, 30], [2, 30]] - ]); - t.assert(nearestPointOnLine(line.geometry, pt), 'line Geometry'); - t.assert(nearestPointOnLine(multiLine.geometry, pt), 'multiLine Geometry'); - t.assert(nearestPointOnLine(line, pt.geometry), 'point Geometry'); - t.assert(nearestPointOnLine(line, pt.geometry.coordinates), 'point Coordinates'); - t.end(); -}); diff --git a/packages/turf-nearest-point-on-line/types.ts b/packages/turf-nearest-point-on-line/types.ts deleted file mode 100644 index 5e204ebb16..0000000000 --- a/packages/turf-nearest-point-on-line/types.ts +++ /dev/null @@ -1,26 +0,0 @@ -import nearestPointOnLine from './' -import { point, lineString, multiLineString } from '@turf/helpers' - -const units = 'miles' -const pt = point([1.5, 1.5]) -const line = lineString([[0, 0], [1, 1]]) -const multiLine = multiLineString([[ - [0, 0], [1, 1], - [2, 2], [0, 0] -]]) - -// All combinations of parameters -nearestPointOnLine(line, pt) -nearestPointOnLine(multiLine, pt) -nearestPointOnLine(line.geometry, pt) -nearestPointOnLine(multiLine.geometry, pt) -nearestPointOnLine(line, pt, {units: 'miles'}) - -// Output can be used as Input -const output = nearestPointOnLine(line, pt) -nearestPointOnLine(line, output) - -// Extra properties being generated from module -output.properties.dist -output.properties.index -output.properties.location diff --git a/packages/turf-nearest-point-to-line/.gitignore b/packages/turf-nearest-point-to-line/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-nearest-point-to-line/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-nearest-point-to-line/LICENSE b/packages/turf-nearest-point-to-line/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-nearest-point-to-line/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-nearest-point-to-line/README.md b/packages/turf-nearest-point-to-line/README.md deleted file mode 100644 index 0c67827288..0000000000 --- a/packages/turf-nearest-point-to-line/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# @turf/nearest-point-to-line - - - -## nearestPointToLine - -Returns the closest [point][1], of a [collection][2] of points, to a [line][3]. -The returned point has a `dist` property indicating its distance to the line. - -**Parameters** - -- `points` **([FeatureCollection][4] \| [GeometryCollection][5]<[Point][6]>)** Point Collection -- `line` **([Feature][7] \| [Geometry][8]<[LineString][9]>)** Line Feature -- `options` **[Object][10]?** Optional parameters - - `options.units` **[string][11]** unit of the output distance property, can be degrees, radians, miles, or kilometers (optional, default `'kilometers'`) - - `options.properties` **[Object][10]** Translate Properties to Point (optional, default `{}`) - -**Examples** - -```javascript -var pt1 = turf.point([0, 0]); -var pt2 = turf.point([0.5, 0.5]); -var points = turf.featureCollection([pt1, pt2]); -var line = turf.lineString([[1,1], [-1,1]]); - -var nearest = turf.nearestPointToLine(points, line); - -//addToMap -var addToMap = [nearest, line]; -``` - -Returns **[Feature][7]<[Point][6]>** the closest point - -## pt - -Translate Properties to final Point, priorities: -1\. options.properties -2\. inherent Point properties -3\. dist custom properties created by NearestPointToLine - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.8 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[8]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[9]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[11]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/nearest-point-to-line -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-nearest-point-to-line/index.d.ts b/packages/turf-nearest-point-to-line/index.d.ts deleted file mode 100644 index e18e0e0560..0000000000 --- a/packages/turf-nearest-point-to-line/index.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Feature, FeatureCollection, GeometryCollection, LineString, Point, Properties, Units } from "@turf/helpers"; -/** - * Returns the closest {@link Point|point}, of a {@link FeatureCollection|collection} of points, - * to a {@link LineString|line}. The returned point has a `dist` property indicating its distance to the line. - * - * @name nearestPointToLine - * @param {FeatureCollection|GeometryCollection} points Point Collection - * @param {Feature|Geometry} line Line Feature - * @param {Object} [options] Optional parameters - * @param {string} [options.units='kilometers'] unit of the output distance property - * (eg: degrees, radians, miles, or kilometers) - * @param {Object} [options.properties={}] Translate Properties to Point - * @returns {Feature} the closest point - * @example - * var pt1 = turf.point([0, 0]); - * var pt2 = turf.point([0.5, 0.5]); - * var points = turf.featureCollection([pt1, pt2]); - * var line = turf.lineString([[1,1], [-1,1]]); - * - * var nearest = turf.nearestPointToLine(points, line); - * - * //addToMap - * var addToMap = [nearest, line]; - */ -declare function nearestPointToLine

(points: FeatureCollection | Feature | GeometryCollection, line: Feature | LineString, options?: { - units?: Units; - properties?: Properties; -}): Feature; -export default nearestPointToLine; diff --git a/packages/turf-nearest-point-to-line/index.ts b/packages/turf-nearest-point-to-line/index.ts deleted file mode 100644 index 9e39ee3322..0000000000 --- a/packages/turf-nearest-point-to-line/index.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Feature, FeatureCollection, GeometryCollection, LineString, Point, Properties, Units } from "@turf/helpers"; -import { getType } from "@turf/invariant"; -import { featureEach, geomEach } from "@turf/meta"; -import pointToLineDistance from "@turf/point-to-line-distance"; -import objectAssign from "object-assign"; - -/** - * Returns the closest {@link Point|point}, of a {@link FeatureCollection|collection} of points, - * to a {@link LineString|line}. The returned point has a `dist` property indicating its distance to the line. - * - * @name nearestPointToLine - * @param {FeatureCollection|GeometryCollection} points Point Collection - * @param {Feature|Geometry} line Line Feature - * @param {Object} [options] Optional parameters - * @param {string} [options.units='kilometers'] unit of the output distance property - * (eg: degrees, radians, miles, or kilometers) - * @param {Object} [options.properties={}] Translate Properties to Point - * @returns {Feature} the closest point - * @example - * var pt1 = turf.point([0, 0]); - * var pt2 = turf.point([0.5, 0.5]); - * var points = turf.featureCollection([pt1, pt2]); - * var line = turf.lineString([[1,1], [-1,1]]); - * - * var nearest = turf.nearestPointToLine(points, line); - * - * //addToMap - * var addToMap = [nearest, line]; - */ -function nearestPointToLine

( - points: FeatureCollection | Feature | GeometryCollection, - line: Feature | LineString, - options: { - units?: Units, - properties?: Properties, - } = {}, -): Feature { - const units = options.units; - const properties = options.properties || {}; - - // validation - const pts = normalize(points); - if (!pts.features.length) { throw new Error("points must contain features"); } - - if (!line) { throw new Error("line is required"); } - if (getType(line) !== "LineString") { throw new Error("line must be a LineString"); } - - let dist = Infinity; - let pt: any = null; - - featureEach(pts, (point) => { - const d = pointToLineDistance(point, line, { units }); - if (d < dist) { - dist = d; - pt = point; - } - }); - /** - * Translate Properties to final Point, priorities: - * 1. options.properties - * 2. inherent Point properties - * 3. dist custom properties created by NearestPointToLine - */ - if (pt) { pt.properties = objectAssign({dist}, pt.properties, properties); } - // if (pt) { pt.properties = objectAssign({dist}, pt.properties, properties); } - return pt; -} - -/** - * Convert Collection to FeatureCollection - * - * @private - * @param {FeatureCollection|GeometryCollection} points Points - * @returns {FeatureCollection} points - */ -function normalize(points: any): FeatureCollection { - const features: any[] = []; - const type = points.geometry ? points.geometry.type : points.type; - switch (type) { - case "GeometryCollection": - geomEach(points, (geom) => { - if (geom.type === "Point") { features.push({type: "Feature", properties: {}, geometry: geom}); } - }); - return {type: "FeatureCollection", features}; - case "FeatureCollection": - points.features = points.features.filter((feature: any) => { - return feature.geometry.type === "Point"; - }); - return points; - default: - throw new Error("points must be a Point Collection"); - } -} - -export default nearestPointToLine; diff --git a/packages/turf-nearest-point-to-line/package.json b/packages/turf-nearest-point-to-line/package.json deleted file mode 100644 index b0cfbe57ca..0000000000 --- a/packages/turf-nearest-point-to-line/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "@turf/nearest-point-to-line", - "version": "6.0.0", - "description": "turf nearest-point-to-line module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "gis", - "near", - "nearest-point-to-line" - ], - "author": "Turf Authors", - "contributors": [ - "Stefano Borghi <@stebogit>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/circle": "*", - "@turf/truncate": "*", - "@types/object-assign": "*", - "@types/tape": "*", - "benchmark": "*", - "load-json-file": "*", - "tape": "*", - "tslint": "*", - "typescript": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x", - "@turf/point-to-line-distance": "6.x", - "object-assign": "*" - } -} diff --git a/packages/turf-nearest-point-to-line/test.js b/packages/turf-nearest-point-to-line/test.js deleted file mode 100644 index f1ef3e6bd5..0000000000 --- a/packages/turf-nearest-point-to-line/test.js +++ /dev/null @@ -1,83 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const circle = require('@turf/circle').default; -const truncate = require('@turf/truncate').default; -const { geometryCollection, featureCollection, point, lineString, round } = require('@turf/helpers'); -const nearestPointToLine = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-nearest-point-to-line', t => { - fixtures.forEach(fixture => { - const filename = fixture.filename; - const name = fixture.name; - const geojson = fixture.geojson; - const points = geojson.features[0]; - const line = geojson.features[1]; - const units = (geojson.properties || {}).units; - - const nearest = nearestPointToLine(points, line, {units: units}); - const distance = round(nearest.properties.dist, 6); - nearest.properties.dist = distance; - nearest.properties = Object.assign(nearest.properties, { - 'marker-color': '#F00', - 'marker-size': 'large', - 'marker-symbol': 'star' - }); - const distanceCircle = truncate(circle(nearest, distance || 1, { units: units, properties: {fill: '#F00'} })); - const results = featureCollection([points, nearest, line, distanceCircle]); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEqual(results, load.sync(directories.out + filename), name); - }); - t.end(); -}); - - -test('turf-nearest-point-to-line -- throws', t => { - const points = featureCollection([point([0, 0]), point([0, 1])]); - const line = lineString([[1, 1], [-1, 1]]); - - // Handled by Typescript - // t.throws(() => nearestPointToLine(null, line), /points is required/, 'missing points'); - // t.throws(() => nearestPointToLine(points, null), /line is required/, 'missing line'); - // t.throws(() => nearestPointToLine(points, line, 'invalid'), /options is invalid/, 'options is invalid'); - - t.throws(() => nearestPointToLine(points, line, {units: 'invalid'}), /units is invalid/, 'invalid units'); - t.throws(() => nearestPointToLine(points, points), /line must be a LineString/, 'invalid line'); - t.throws(() => nearestPointToLine(line, line), /points must be a Point Collection/, 'invalid points'); - - t.end(); -}); - -test('turf-nearest-point-to-line -- Geometry', t => { - const points = featureCollection([point([0, 0]), point([0, 1])]); - const geomPoints = geometryCollection([point([0, 0]).geometry, point([0, 1]).geometry]); - const line = lineString([[1, 1], [-1, 1]]); - - t.assert(nearestPointToLine(points, line.geometry)); - t.assert(nearestPointToLine(geomPoints, line.geometry)); - t.end(); -}); - -test('turf-nearest-point-to-line -- Empty FeatureCollection', t => { - const points = featureCollection([]); - const line = lineString([[1, 1], [-1, 1]]); - - t.throws(() => nearestPointToLine(points, line), /points must contain features/, 'points must contain features'); - t.end(); -}); diff --git a/packages/turf-nearest-point-to-line/tsconfig.json b/packages/turf-nearest-point-to-line/tsconfig.json deleted file mode 100644 index 91cffcbf55..0000000000 --- a/packages/turf-nearest-point-to-line/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - }, - "files": [ - "index.ts" - ] -} \ No newline at end of file diff --git a/packages/turf-nearest-point-to-line/tslint.json b/packages/turf-nearest-point-to-line/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-nearest-point-to-line/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-nearest-point-to-line/types.ts b/packages/turf-nearest-point-to-line/types.ts deleted file mode 100644 index a6957bff61..0000000000 --- a/packages/turf-nearest-point-to-line/types.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { - geometryCollection, - featureCollection, - point, - lineString, - Point -} from '@turf/helpers' -import nearestPointToLine from './' - -const points = featureCollection([point([0, 0]), point([0.5, 0.5])]); -const line = lineString([[1,1], [-1,1]]); - -const nearest = nearestPointToLine<{foo: string, dist: number}>(points, line, {properties: {foo: 'bar'}}) -nearest.properties.foo -nearest.properties.dist -// nearest.properties.bar // [ts] Property 'bar' does not exist on type '{ dist?: number; foo: string; }'. - -// GeometryCollection -const geomPoints = geometryCollection([point([0, 0]).geometry, point([0.5, 0.5]).geometry]); -nearestPointToLine(geomPoints, line) \ No newline at end of file diff --git a/packages/turf-nearest-point/.gitignore b/packages/turf-nearest-point/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-nearest-point/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-nearest-point/LICENSE b/packages/turf-nearest-point/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-nearest-point/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-nearest-point/README.md b/packages/turf-nearest-point/README.md deleted file mode 100644 index 38a0885a1d..0000000000 --- a/packages/turf-nearest-point/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# @turf/nearest-point - - - -## nearestPoint - -Takes a reference [point][1] and a FeatureCollection of Features -with Point geometries and returns the -point from the FeatureCollection closest to the reference. This calculation -is geodesic. - -**Parameters** - -- `targetPoint` **[Coord][2]** the reference point -- `points` **[FeatureCollection][3]<[Point][4]>** against input point set - -**Examples** - -```javascript -var targetPoint = turf.point([28.965797, 41.010086], {"marker-color": "#0F0"}); -var points = turf.featureCollection([ - turf.point([28.973865, 41.011122]), - turf.point([28.948459, 41.024204]), - turf.point([28.938674, 41.013324]) -]); - -var nearest = turf.nearestPoint(targetPoint, points); - -//addToMap -var addToMap = [targetPoint, points, nearest]; -nearest.properties['marker-color'] = '#F00'; -``` - -Returns **[Feature][5]<[Point][4]>** the closest point in the set to the reference point - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/nearest-point -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-nearest-point/index.d.ts b/packages/turf-nearest-point/index.d.ts deleted file mode 100644 index d8ab680cd5..0000000000 --- a/packages/turf-nearest-point/index.d.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Coord, Feature, FeatureCollection, Point } from '@turf/helpers'; -export interface NearestPoint extends Feature { - properties: { - featureIndex: number; - distanceToPoint: number; - [key: string]: any; - }; -} -/** - * Takes a reference {@link Point|point} and a FeatureCollection of Features - * with Point geometries and returns the - * point from the FeatureCollection closest to the reference. This calculation - * is geodesic. - * - * @name nearestPoint - * @param {Coord} targetPoint the reference point - * @param {FeatureCollection} points against input point set - * @returns {Feature} the closest point in the set to the reference point - * @example - * var targetPoint = turf.point([28.965797, 41.010086], {"marker-color": "#0F0"}); - * var points = turf.featureCollection([ - * turf.point([28.973865, 41.011122]), - * turf.point([28.948459, 41.024204]), - * turf.point([28.938674, 41.013324]) - * ]); - * - * var nearest = turf.nearestPoint(targetPoint, points); - * - * //addToMap - * var addToMap = [targetPoint, points, nearest]; - * nearest.properties['marker-color'] = '#F00'; - */ -declare function nearestPoint(targetPoint: Coord, points: FeatureCollection): NearestPoint; -export default nearestPoint; diff --git a/packages/turf-nearest-point/index.ts b/packages/turf-nearest-point/index.ts deleted file mode 100644 index fafd3537be..0000000000 --- a/packages/turf-nearest-point/index.ts +++ /dev/null @@ -1,59 +0,0 @@ -import clone from '@turf/clone'; -import distance from '@turf/distance'; -import { featureEach } from '@turf/meta'; -import { Coord, Feature, FeatureCollection, Point } from '@turf/helpers'; - -export interface NearestPoint extends Feature { - properties: { - featureIndex: number; - distanceToPoint: number; - [key: string]: any; - }; -} - -/** - * Takes a reference {@link Point|point} and a FeatureCollection of Features - * with Point geometries and returns the - * point from the FeatureCollection closest to the reference. This calculation - * is geodesic. - * - * @name nearestPoint - * @param {Coord} targetPoint the reference point - * @param {FeatureCollection} points against input point set - * @returns {Feature} the closest point in the set to the reference point - * @example - * var targetPoint = turf.point([28.965797, 41.010086], {"marker-color": "#0F0"}); - * var points = turf.featureCollection([ - * turf.point([28.973865, 41.011122]), - * turf.point([28.948459, 41.024204]), - * turf.point([28.938674, 41.013324]) - * ]); - * - * var nearest = turf.nearestPoint(targetPoint, points); - * - * //addToMap - * var addToMap = [targetPoint, points, nearest]; - * nearest.properties['marker-color'] = '#F00'; - */ -function nearestPoint(targetPoint: Coord, points: FeatureCollection): NearestPoint { - // Input validation - if (!targetPoint) throw new Error('targetPoint is required'); - if (!points) throw new Error('points is required'); - - let nearest: NearestPoint; - let minDist: number = Infinity; - let bestFeatureIndex: number = 0; - featureEach(points, (pt, featureIndex) => { - const distanceToPoint = distance(targetPoint, pt); - if (distanceToPoint < minDist) { - bestFeatureIndex = featureIndex; - minDist = distanceToPoint; - } - }); - nearest = clone(points.features[bestFeatureIndex]); - nearest.properties.featureIndex = bestFeatureIndex; - nearest.properties.distanceToPoint = minDist; - return nearest; -} - -export default nearestPoint; diff --git a/packages/turf-nearest-point/package.json b/packages/turf-nearest-point/package.json deleted file mode 100644 index 61159f45f3..0000000000 --- a/packages/turf-nearest-point/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@turf/nearest-point", - "version": "6.0.1", - "description": "turf nearest-point module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "gis", - "near", - "nearest", - "point" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "tape": "*", - "typescript": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/clone": "6.x", - "@turf/distance": "6.x", - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-nearest-point/test.js b/packages/turf-nearest-point/test.js deleted file mode 100644 index 6089632c70..0000000000 --- a/packages/turf-nearest-point/test.js +++ /dev/null @@ -1,59 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const glob = require('glob'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const {featureCollection, point} = require('@turf/helpers'); -const nearestPoint = require('./').default; - - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-nearest-point', t => { - fixtures.forEach(fixture => { - const filename = fixture.filename; - const name = fixture.name; - const geojson = fixture.geojson; - const targetPoint = point(geojson.properties.targetPoint); - const nearestPt = nearestPoint(targetPoint, geojson); - - // Style results - nearestPt.properties['marker-color'] = '#F00'; - nearestPt.properties['marker-symbol'] = 'star'; - targetPoint.properties['marker-color'] = '#00F'; - targetPoint.properties['marker-symbol'] = 'circle'; - const results = featureCollection([...geojson.features, targetPoint, nearestPt]); - - // Save output - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEqual(results, load.sync(directories.out + filename), name); - }); - t.end(); -}); - -test('nearest-point -- prevent input mutation', t => { - const pt1 = point([40, 50], {featureIndex: 'foo'}) - const pt2 = point([20, -10], {distanceToPoint: 'bar'}) - const pts = featureCollection([pt1, pt2]); - const nearestPt = nearestPoint([0, 0], pts) - - // Check if featureIndex properties was added to properties - t.equal(nearestPt.properties.featureIndex, 1) - - // Check if previous input points have been modified - t.deepEqual(pt1.properties, {featureIndex: 'foo'}) - t.deepEqual(pt2.properties, {distanceToPoint: 'bar'}) - t.end(); -}) \ No newline at end of file diff --git a/packages/turf-nearest-point/tsconfig.json b/packages/turf-nearest-point/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-nearest-point/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-nearest-point/tslint.json b/packages/turf-nearest-point/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-nearest-point/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-nearest-point/types.ts b/packages/turf-nearest-point/types.ts deleted file mode 100644 index 74a39545ac..0000000000 --- a/packages/turf-nearest-point/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {point, featureCollection} from '@turf/helpers' -import nearestPoint from './index' - -const targetPoint = point([28.965797, 41.010086], {"marker-color": "#0F0"}); -const points = featureCollection([ - point([28.973865, 41.011122]), - point([28.948459, 41.024204]), - point([28.938674, 41.013324]) -]); -const nearest = nearestPoint(targetPoint, points); -nearest.properties.distanceToPoint; -nearest.properties.featureIndex; diff --git a/packages/turf-planepoint/LICENSE b/packages/turf-planepoint/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-planepoint/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-planepoint/README.md b/packages/turf-planepoint/README.md deleted file mode 100644 index 4a7460a9f3..0000000000 --- a/packages/turf-planepoint/README.md +++ /dev/null @@ -1,79 +0,0 @@ -# @turf/planepoint - - - -## planepoint - -Takes a triangular plane as a [Polygon][1] -and a [Point][2] within that triangle and returns the z-value -at that point. The Polygon should have properties `a`, `b`, and `c` -that define the values at its three corners. Alternatively, the z-values -of each triangle point can be provided by their respective 3rd coordinate -if their values are not provided as properties. - -**Parameters** - -- `point` **[Coord][3]** the Point for which a z-value will be calculated -- `triangle` **[Feature][4]<[Polygon][5]>** a Polygon feature with three vertices - -**Examples** - -```javascript -var point = turf.point([-75.3221, 39.529]); -// "a", "b", and "c" values represent the values of the coordinates in order. -var triangle = turf.polygon([[ - [-75.1221, 39.57], - [-75.58, 39.18], - [-75.97, 39.86], - [-75.1221, 39.57] -]], { - "a": 11, - "b": 122, - "c": 44 -}); - -var zValue = turf.planepoint(point, triangle); -point.properties.zValue = zValue; - -//addToMap -var addToMap = [triangle, point]; -``` - -Returns **[number][6]** the z-value for `interpolatedPoint` - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/planepoint -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-planepoint/bench.js b/packages/turf-planepoint/bench.js deleted file mode 100644 index c7768d99fa..0000000000 --- a/packages/turf-planepoint/bench.js +++ /dev/null @@ -1,18 +0,0 @@ -import Benchmark from 'benchmark'; -import { polygon } from '@turf/helpers'; -import planepoint from './'; - -const point = [1, 1]; -const triangle = polygon([[[0, 0, 0], [2, 0, 0], [1, 2, 2], [0, 0, 0]]], {a: 0, b: 0, c: 2}); - -/** - * Benchmmark Results - * - * turf-planepoint x 14,905,445 ops/sec ±4.54% (75 runs sampled) - */ -const suite = new Benchmark.Suite('turf-planepoint'); -suite - .add('turf-planepoint', () => planepoint(point, triangle)) - .on('cycle', e => console.log(String(e.target))) - .on('complete', () => {}) - .run(); diff --git a/packages/turf-planepoint/index.d.ts b/packages/turf-planepoint/index.d.ts deleted file mode 100644 index cf37348f0b..0000000000 --- a/packages/turf-planepoint/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Feature, Coord, Polygon } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#planepoint - */ -export default function planepoint( - point: Coord, - triangle: Feature | Polygon -): number; diff --git a/packages/turf-planepoint/index.js b/packages/turf-planepoint/index.js deleted file mode 100644 index 5493c614f8..0000000000 --- a/packages/turf-planepoint/index.js +++ /dev/null @@ -1,67 +0,0 @@ -import { getCoord, getGeom } from '@turf/invariant'; - -/** - * Takes a triangular plane as a {@link Polygon} - * and a {@link Point} within that triangle and returns the z-value - * at that point. The Polygon should have properties `a`, `b`, and `c` - * that define the values at its three corners. Alternatively, the z-values - * of each triangle point can be provided by their respective 3rd coordinate - * if their values are not provided as properties. - * - * @name planepoint - * @param {Coord} point the Point for which a z-value will be calculated - * @param {Feature} triangle a Polygon feature with three vertices - * @returns {number} the z-value for `interpolatedPoint` - * @example - * var point = turf.point([-75.3221, 39.529]); - * // "a", "b", and "c" values represent the values of the coordinates in order. - * var triangle = turf.polygon([[ - * [-75.1221, 39.57], - * [-75.58, 39.18], - * [-75.97, 39.86], - * [-75.1221, 39.57] - * ]], { - * "a": 11, - * "b": 122, - * "c": 44 - * }); - * - * var zValue = turf.planepoint(point, triangle); - * point.properties.zValue = zValue; - * - * //addToMap - * var addToMap = [triangle, point]; - */ -function planepoint(point, triangle) { - // Normalize input - var coord = getCoord(point); - var geom = getGeom(triangle); - var coords = geom.coordinates; - var outer = coords[0]; - if (outer.length < 4) throw new Error('OuterRing of a Polygon must have 4 or more Positions.'); - var properties = triangle.properties || {}; - var a = properties.a; - var b = properties.b; - var c = properties.c; - - // Planepoint - var x = coord[0]; - var y = coord[1]; - var x1 = outer[0][0]; - var y1 = outer[0][1]; - var z1 = (a !== undefined ? a : outer[0][2]); - var x2 = outer[1][0]; - var y2 = outer[1][1]; - var z2 = (b !== undefined ? b : outer[1][2]); - var x3 = outer[2][0]; - var y3 = outer[2][1]; - var z3 = (c !== undefined ? c : outer[2][2]); - var z = (z3 * (x - x1) * (y - y2) + z1 * (x - x2) * (y - y3) + z2 * (x - x3) * (y - y1) - - z2 * (x - x1) * (y - y3) - z3 * (x - x2) * (y - y1) - z1 * (x - x3) * (y - y2)) / - ((x - x1) * (y - y2) + (x - x2) * (y - y3) + (x - x3) * (y - y1) - - (x - x1) * (y - y3) - (x - x2) * (y - y1) - (x - x3) * (y - y2)); - - return z; -} - -export default planepoint; diff --git a/packages/turf-planepoint/package.json b/packages/turf-planepoint/package.json deleted file mode 100644 index f130aee17c..0000000000 --- a/packages/turf-planepoint/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "@turf/planepoint", - "version": "5.1.5", - "description": "turf planepoint module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "plane", - "point", - "interpolation" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "rollup": "*", - "tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-planepoint/test.js b/packages/turf-planepoint/test.js deleted file mode 100644 index eff5402890..0000000000 --- a/packages/turf-planepoint/test.js +++ /dev/null @@ -1,17 +0,0 @@ -// http://math.stackexchange.com/questions/28043/finding-the-z-value-on-a-plane-with-x-y-values -// http://stackoverflow.com/a/13916669/461015 -import test from 'tape'; - -import { polygon } from '@turf/helpers'; -import planepoint from '.'; - - -test('turf-planepoint', t => { - const point = [1, 1]; - const triangleProps = polygon([[[0, 0], [2, 0], [1, 2], [0, 0]]], {a: 0, b: 0, c: 2}); - const triangleZ = polygon([[[0, 0, 0], [2, 0, 0], [1, 2, 2], [0, 0, 0]]]); - - t.equal(planepoint(point, triangleProps), 1, 'properties'); - t.equal(planepoint(point, triangleZ), 1, 'z coordinates'); - t.end(); -}); diff --git a/packages/turf-point-grid/.gitignore b/packages/turf-point-grid/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-point-grid/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-point-grid/LICENSE b/packages/turf-point-grid/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-point-grid/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-point-grid/README.md b/packages/turf-point-grid/README.md deleted file mode 100644 index 0c0018b034..0000000000 --- a/packages/turf-point-grid/README.md +++ /dev/null @@ -1,80 +0,0 @@ -# @turf/point-grid - - - -## pointGrid - -Creates a [Point][1] grid from a bounding box, [FeatureCollection][2] or [Feature][3]. - -**Parameters** - -- `bbox` **[Array][4]<[number][5]>** extent in [minX, minY, maxX, maxY] order -- `cellSide` **[number][5]** the distance between points, in units -- `options` **[Object][6]** Optional parameters (optional, default `{}`) - - `options.units` **[string][7]** used in calculating cellSide, can be degrees, radians, miles, or kilometers (optional, default `'kilometers'`) - - `options.mask` **[Feature][8]<([Polygon][9] \| [MultiPolygon][10])>?** if passed a Polygon or MultiPolygon, the grid Points will be created only inside it - - `options.properties` **[Object][6]** passed to each point of the grid (optional, default `{}`) - -**Examples** - -```javascript -var extent = [-70.823364, -33.553984, -70.473175, -33.302986]; -var cellSide = 3; -var options = {units: 'miles'}; - -var grid = turf.pointGrid(extent, cellSide, options); - -//addToMap -var addToMap = [grid]; -``` - -Returns **[FeatureCollection][11]<[Point][12]>** grid of points - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[8]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[9]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[10]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[11]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[12]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/point-grid -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-point-grid/bench.js b/packages/turf-point-grid/bench.js deleted file mode 100644 index 674d4d70b3..0000000000 --- a/packages/turf-point-grid/bench.js +++ /dev/null @@ -1,29 +0,0 @@ -const Benchmark = require('benchmark'); -const { polygon } = require('@turf/helpers'); -const grid = require('./'); - -var bbox = [-95, 30, -85, 40]; -var mask = polygon([[[6.5, 44.6 ], [ 9.2, 44.8 ], [ 8.3, 46.4 ], [ 6.5, 44.6 ]]]); - -var highres = grid(bbox, 100, {units: 'miles'}).features.length; -var midres = grid(bbox, 10, {units: 'miles'}).features.length; -var lowres = grid(bbox, 1, {units: 'miles'}).features.length; -var masked = grid(mask, 1, {units: 'miles', mask: mask}).features.length; -var suite = new Benchmark.Suite('turf-square-grid'); - -/** - * Benchmark Results - * - * highres -- 42 cells x 274,666 ops/sec ±1.96% (77 runs sampled) - * midres -- 4200 cells x 2,725 ops/sec ±3.86% (73 runs sampled) - * lowres -- 414508 cells x 2.09 ops/sec ±21.02% (10 runs sampled) - * masked -- 7658 cells x 9,794 ops/sec ±2.08% (75 runs sampled) - */ -suite - .add('highres -- ' + highres + ' cells', () => grid(bbox, 100, {units: 'miles'})) - .add('midres -- ' + midres + ' cells', () => grid(bbox, 10, {units: 'miles'})) - .add('lowres -- ' + lowres + ' cells', () => grid(bbox, 1, {units: 'miles'})) - .add('masked -- ' + masked + ' cells', () => grid(mask, 10, {units: 'miles', mask: mask})) - .on('cycle', e => console.log(String(e.target))) - .on('complete', () => {}) - .run(); diff --git a/packages/turf-point-grid/index.ts b/packages/turf-point-grid/index.ts deleted file mode 100644 index 07f58209af..0000000000 --- a/packages/turf-point-grid/index.ts +++ /dev/null @@ -1,86 +0,0 @@ -import within from '@turf/boolean-within'; -import distance from '@turf/distance'; -import {getType} from '@turf/invariant'; -import { - point, featureCollection, isObject, isNumber, - BBox, Feature, Polygon, MultiPolygon, FeatureCollection, Point, Properties, Units -} from '@turf/helpers'; - -/** - * Creates a {@link Point} grid from a bounding box, {@link FeatureCollection} or {@link Feature}. - * - * @name pointGrid - * @param {Array} bbox extent in [minX, minY, maxX, maxY] order - * @param {number} cellSide the distance between points, in units - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] used in calculating cellSide, can be degrees, radians, miles, or kilometers - * @param {Feature} [options.mask] if passed a Polygon or MultiPolygon, the grid Points will be created only inside it - * @param {Object} [options.properties={}] passed to each point of the grid - * @returns {FeatureCollection} grid of points - * @example - * var extent = [-70.823364, -33.553984, -70.473175, -33.302986]; - * var cellSide = 3; - * var options = {units: 'miles'}; - * - * var grid = turf.pointGrid(extent, cellSide, options); - * - * //addToMap - * var addToMap = [grid]; - */ -function pointGrid

(bbox: BBox, cellSide: number, options: { - units?: Units, - mask?: Feature, - properties?: P, -} = {}): FeatureCollection { - // Default parameters - if (options.mask && !options.units) options.units = 'kilometers'; - - // Containers - var results = []; - - // Typescript handles the Type Validation - // if (cellSide === null || cellSide === undefined) throw new Error('cellSide is required'); - // if (!isNumber(cellSide)) throw new Error('cellSide is invalid'); - // if (!bbox) throw new Error('bbox is required'); - // if (!Array.isArray(bbox)) throw new Error('bbox must be array'); - // if (bbox.length !== 4) throw new Error('bbox must contain 4 numbers'); - // if (mask && ['Polygon', 'MultiPolygon'].indexOf(getType(mask)) === -1) throw new Error('options.mask must be a (Multi)Polygon'); - - var west = bbox[0]; - var south = bbox[1]; - var east = bbox[2]; - var north = bbox[3]; - - var xFraction = cellSide / (distance([west, south], [east, south], options)); - var cellWidth = xFraction * (east - west); - var yFraction = cellSide / (distance([west, south], [west, north], options)); - var cellHeight = yFraction * (north - south); - - var bboxWidth = (east - west); - var bboxHeight = (north - south); - var columns = Math.floor(bboxWidth / cellWidth); - var rows = Math.floor(bboxHeight / cellHeight); - - // adjust origin of the grid - var deltaX = (bboxWidth - columns * cellWidth) / 2; - var deltaY = (bboxHeight - rows * cellHeight) / 2; - - var currentX = west + deltaX; - while (currentX <= east) { - var currentY = south + deltaY; - while (currentY <= north) { - var cellPt = point([currentX, currentY], options.properties); - if (options.mask) { - if (within(cellPt, options.mask)) results.push(cellPt); - } else { - results.push(cellPt); - } - currentY += cellHeight; - } - currentX += cellWidth; - } - - return featureCollection(results); -} - -export default pointGrid; diff --git a/packages/turf-point-grid/package.json b/packages/turf-point-grid/package.json deleted file mode 100644 index 037e29af08..0000000000 --- a/packages/turf-point-grid/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "@turf/point-grid", - "version": "6.0.1", - "description": "turf point-grid module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "grid", - "points", - "geojson" - ], - "author": "Turf Authors", - "contributors": [ - "Stefano Borghi <@stebogit>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/bbox-polygon": "*", - "@turf/truncate": "*", - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/boolean-within": "6.x", - "@turf/distance": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-point-grid/test.js b/packages/turf-point-grid/test.js deleted file mode 100644 index 0e97804749..0000000000 --- a/packages/turf-point-grid/test.js +++ /dev/null @@ -1,79 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const bboxPoly = require('@turf/bbox-polygon').default; -const truncate = require('@turf/truncate').default; -const { point } = require('@turf/helpers'); -const pointGrid = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -let fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - json: load.sync(directories.in + filename) - }; -}); - -test('turf-point-grid', t => { - for (const {name, json} of fixtures) { - const {bbox, cellSide} = json; - const options = json; - const result = truncate(pointGrid(bbox, cellSide, options)); - - // Add styled GeoJSON to the result - const poly = bboxPoly(bbox); - poly.properties = { - stroke: '#F00', - 'stroke-width': 6, - 'fill-opacity': 0 - }; - result.features.push(poly); - if (options.mask) { - options.mask.properties = { - "stroke": "#00F", - "stroke-width": 6, - "fill-opacity": 0 - }; - result.features.push(options.mask); - } - - if (process.env.REGEN) write.sync(directories.out + name + '.geojson', result); - t.deepEqual(result, load.sync(directories.out + name + '.geojson'), name); - } - t.end(); -}); - - -test('point-grid -- throw', t => { - const bbox = [0, 0, 1, 1]; - // Typescript handles Types - // t.throws(() => pointGrid(null, 0), /bbox is required/, 'missing bbox'); - // t.throws(() => pointGrid('foo', 0), /bbox must be array/, 'invalid bbox'); - // t.throws(() => pointGrid([0, 2], 1), /bbox must contain 4 numbers/, 'invalid bbox'); - // t.throws(() => pointGrid(bbox, null), /cellSide is required/, 'missing cellSide'); - // t.throws(() => pointGrid(bbox, 'foo'), /cellSide is invalid/, 'invalid cellSide'); - // t.throws(() => pointGrid(bbox, 1, 'foo'), /options is invalid/, 'invalid options'); - // t.throws(() => pointGrid(bbox, 1, {mask: point([0, 10])}), /options.mask must be a \(Multi\)Polygon/, 'invalid options.mask'); - t.end(); -}); - -test('point-grid -- #1177', t => { - const bbox = [0, 0, 1, 1]; - const mask = bboxPoly([0.2, 0.2, 0.8, 0.8]); - let options = {mask: mask}; - t.doesNotThrow(() => pointGrid(bbox, 1, options)); - t.equal(options.units, 'kilometers'); - - let options2 = {mask: mask, units: 'miles'}; - t.doesNotThrow(() => pointGrid(bbox, 1, options2)); - t.equal(options2.units, 'miles'); - - t.end(); -}); diff --git a/packages/turf-point-grid/types.ts b/packages/turf-point-grid/types.ts deleted file mode 100644 index 94c4bf98b7..0000000000 --- a/packages/turf-point-grid/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { BBox, polygon, Polygon} from '@turf/helpers'; -import pointGrid from './'; - -const cellSide = 50; -const bbox: BBox = [-95, 30, -85, 40]; -const poly = polygon([[[20, 30], [10, 10], [20, 20], [20, 30]]]); - -pointGrid(bbox, cellSide); -pointGrid(bbox, cellSide, {units: 'miles'}); -pointGrid(bbox, cellSide, {units: 'miles', mask: poly}); -pointGrid(bbox, cellSide, {units: 'miles', mask: poly, properties: {foo: 'bar'}}); diff --git a/packages/turf-point-on-feature/LICENSE b/packages/turf-point-on-feature/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-point-on-feature/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-point-on-feature/README.md b/packages/turf-point-on-feature/README.md deleted file mode 100644 index 7219ce6bd1..0000000000 --- a/packages/turf-point-on-feature/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# @turf/point-on-feature - - - -## pointOnFeature - -Takes a Feature or FeatureCollection and returns a [Point][1] guaranteed to be on the surface of the feature. - -- Given a [Polygon][2], the point will be in the area of the polygon -- Given a [LineString][3], the point will be along the string -- Given a [Point][1], the point will the same as the input - -**Parameters** - -- `geojson` **[GeoJSON][4]** any Feature or FeatureCollection - -**Examples** - -```javascript -var polygon = turf.polygon([[ - [116, -36], - [131, -32], - [146, -43], - [155, -25], - [133, -9], - [111, -22], - [116, -36] -]]); - -var pointOnPolygon = turf.pointOnFeature(polygon); - -//addToMap -var addToMap = [polygon, pointOnPolygon]; -``` - -Returns **[Feature][5]<[Point][6]>** a point on the surface of `input` - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[4]: https://tools.ietf.org/html/rfc7946#section-3 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/point-on-feature -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-point-on-feature/index.d.ts b/packages/turf-point-on-feature/index.d.ts deleted file mode 100644 index 3a844890f4..0000000000 --- a/packages/turf-point-on-feature/index.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Feature, Point, AllGeoJSON } from '@turf/helpers'; - -/** - * http://turfjs.org/docs/#pointonfeature - */ -export default function pointOnFeature( - geojson: AllGeoJSON -): Feature; diff --git a/packages/turf-point-on-feature/index.js b/packages/turf-point-on-feature/index.js deleted file mode 100644 index 2fe76b3055..0000000000 --- a/packages/turf-point-on-feature/index.js +++ /dev/null @@ -1,143 +0,0 @@ -import explode from '@turf/explode'; -import centroid from '@turf/center'; -import nearestPoint from '@turf/nearest-point'; -import booleanPointInPolygon from '@turf/boolean-point-in-polygon'; -import { featureCollection, feature, point } from '@turf/helpers'; - -/** - * Takes a Feature or FeatureCollection and returns a {@link Point} guaranteed to be on the surface of the feature. - * - * * Given a {@link Polygon}, the point will be in the area of the polygon - * * Given a {@link LineString}, the point will be along the string - * * Given a {@link Point}, the point will the same as the input - * - * @name pointOnFeature - * @param {GeoJSON} geojson any Feature or FeatureCollection - * @returns {Feature} a point on the surface of `input` - * @example - * var polygon = turf.polygon([[ - * [116, -36], - * [131, -32], - * [146, -43], - * [155, -25], - * [133, -9], - * [111, -22], - * [116, -36] - * ]]); - * - * var pointOnPolygon = turf.pointOnFeature(polygon); - * - * //addToMap - * var addToMap = [polygon, pointOnPolygon]; - */ -function pointOnFeature(geojson) { - // normalize - var fc = normalize(geojson); - - // get centroid - var cent = centroid(fc); - - // check to see if centroid is on surface - var onSurface = false; - var i = 0; - while (!onSurface && i < fc.features.length) { - var geom = fc.features[i].geometry; - var x, y, x1, y1, x2, y2, k; - var onLine = false; - if (geom.type === 'Point') { - if (cent.geometry.coordinates[0] === geom.coordinates[0] && - cent.geometry.coordinates[1] === geom.coordinates[1]) { - onSurface = true; - } - } else if (geom.type === 'MultiPoint') { - var onMultiPoint = false; - k = 0; - while (!onMultiPoint && k < geom.coordinates.length) { - if (cent.geometry.coordinates[0] === geom.coordinates[k][0] && - cent.geometry.coordinates[1] === geom.coordinates[k][1]) { - onSurface = true; - onMultiPoint = true; - } - k++; - } - } else if (geom.type === 'LineString') { - k = 0; - while (!onLine && k < geom.coordinates.length - 1) { - x = cent.geometry.coordinates[0]; - y = cent.geometry.coordinates[1]; - x1 = geom.coordinates[k][0]; - y1 = geom.coordinates[k][1]; - x2 = geom.coordinates[k + 1][0]; - y2 = geom.coordinates[k + 1][1]; - if (pointOnSegment(x, y, x1, y1, x2, y2)) { - onLine = true; - onSurface = true; - } - k++; - } - } else if (geom.type === 'MultiLineString') { - var j = 0; - while (j < geom.coordinates.length) { - onLine = false; - k = 0; - var line = geom.coordinates[j]; - while (!onLine && k < line.length - 1) { - x = cent.geometry.coordinates[0]; - y = cent.geometry.coordinates[1]; - x1 = line[k][0]; - y1 = line[k][1]; - x2 = line[k + 1][0]; - y2 = line[k + 1][1]; - if (pointOnSegment(x, y, x1, y1, x2, y2)) { - onLine = true; - onSurface = true; - } - k++; - } - j++; - } - } else if (geom.type === 'Polygon' || geom.type === 'MultiPolygon') { - if (booleanPointInPolygon(cent, geom)) { - onSurface = true; - } - } - i++; - } - if (onSurface) { - return cent; - } else { - var vertices = featureCollection([]); - for (i = 0; i < fc.features.length; i++) { - vertices.features = vertices.features.concat(explode(fc.features[i]).features); - } - // Remove distanceToPoint properties from nearestPoint() - return point(nearestPoint(cent, vertices).geometry.coordinates); - } -} - -/** - * Normalizes any GeoJSON to a FeatureCollection - * - * @private - * @name normalize - * @param {GeoJSON} geojson Any GeoJSON - * @returns {FeatureCollection} FeatureCollection - */ -function normalize(geojson) { - if (geojson.type !== 'FeatureCollection') { - if (geojson.type !== 'Feature') { - return featureCollection([feature(geojson)]); - } - return featureCollection([geojson]); - } - return geojson; -} - -function pointOnSegment(x, y, x1, y1, x2, y2) { - var ab = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); - var ap = Math.sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1)); - var pb = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)); - return ab === ap + pb; -} - -export default pointOnFeature; diff --git a/packages/turf-point-on-feature/package.json b/packages/turf-point-on-feature/package.json deleted file mode 100644 index 47e9681f61..0000000000 --- a/packages/turf-point-on-feature/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "@turf/point-on-feature", - "version": "5.1.5", - "description": "turf point-on-feature module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "centroid", - "geojson", - "point", - "surface", - "polygon" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/meta": "6.x", - "@turf/truncate": "6.x", - "benchmark": "*", - "rollup": "*", - "tape": "*" - }, - "dependencies": { - "@turf/boolean-point-in-polygon": "6.x", - "@turf/center": "6.x", - "@turf/explode": "^5.1.5", - "@turf/helpers": "6.x", - "@turf/nearest-point": "^5.1.5" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-point-on-feature/test.js b/packages/turf-point-on-feature/test.js deleted file mode 100644 index abc76bdbad..0000000000 --- a/packages/turf-point-on-feature/test.js +++ /dev/null @@ -1,31 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import glob from 'glob'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import truncate from '@turf/truncate'; -import { featureEach } from '@turf/meta'; -import { featureCollection } from '@turf/helpers'; -import pointOnFeature from '.'; - -test('turf-point-on-feature', t => { - glob.sync(path.join(__dirname, 'test', 'in', '*.json')).forEach(filepath => { - const {name} = path.parse(filepath); - const geojson = load.sync(filepath); - const ptOnFeature = pointOnFeature(geojson); - - // Style Results - const results = featureCollection([]) - featureEach(geojson, feature => results.features.push(feature)); - ptOnFeature.properties['marker-color'] = '#F00' - ptOnFeature.properties['marker-style'] = 'star' - results.features.push(truncate(ptOnFeature)); - - // Save Tests - const out = filepath.replace(path.join('test', 'in'), path.join('test', 'out')) - if (process.env.REGEN) write.sync(out, results); - t.deepEqual(results, load.sync(out), name); - }); - t.end(); -}); diff --git a/packages/turf-point-on-feature/test/in/lines.json b/packages/turf-point-on-feature/test/in/lines.json deleted file mode 100644 index e308e76cb1..0000000000 --- a/packages/turf-point-on-feature/test/in/lines.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - 24.08203125, - -16.59408141271846 - ], - [ - 25.059814453125, - -14.519780046326073 - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - 28.410644531249996, - -14.955399325942619 - ], - [ - 28.7841796875, - -15.845104902273452 - ], - [ - 27.6416015625, - -16.13026201203474 - ], - [ - 27.432861328125, - -17.518344187852218 - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - 26.652832031249996, - -13.485789593908478 - ], - [ - 26.268310546875, - -14.891704754215462 - ], - [ - 25.86181640625, - -14.88108715909066 - ], - [ - 25.894775390625, - -15.421910399947057 - ], - [ - 26.323242187499996, - -15.5701278526594 - ], - [ - 26.224365234375, - -16.066928957450106 - ], - [ - 26.510009765625, - -16.583552354072005 - ], - [ - 25.927734374999996, - -16.836089974560213 - ], - [ - 25.147705078125, - -17.245744208007117 - ], - [ - 26.34521484375, - -18.271086109608863 - ], - [ - 25.33447265625, - -18.531700307384043 - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - 24.466552734375, - -14.211138758545781 - ], - [ - 25.389404296875, - -13.710035342476669 - ], - [ - 25.609130859375, - -13.944729974920154 - ], - [ - 26.3671875, - -13.090179355733726 - ] - ] - } - } - ] -} \ No newline at end of file diff --git a/packages/turf-point-on-feature/test/in/multiline.json b/packages/turf-point-on-feature/test/in/multiline.json deleted file mode 100644 index 08ad7d864c..0000000000 --- a/packages/turf-point-on-feature/test/in/multiline.json +++ /dev/null @@ -1,115 +0,0 @@ -{ - "type": "Feature", - "properties": {}, - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 92.08740234375, - 50.708634400828224 - ], - [ - 93.0322265625, - 50.84757295365389 - ], - [ - 94.32861328125, - 50.499452103967734 - ], - [ - 95.25146484374999, - 50.0077390146369 - ], - [ - 97.470703125, - 49.908787000867136 - ], - [ - 98.4375, - 50.51342652633956 - ], - [ - 98.10791015625, - 51.467696956223385 - ], - [ - 99.5361328125, - 52.07950600379697 - ], - [ - 101.14013671875, - 51.645294049305406 - ], - [ - 102.37060546875, - 51.22064743038333 - ], - [ - 102.37060546875, - 50.764259357116465 - ], - [ - 103.18359375, - 50.30337575356313 - ], - [ - 104.56787109374999, - 50.24720490139267 - ], - [ - 105.84228515625, - 50.54136296522161 - ], - [ - 106.89697265625, - 50.2612538275847 - ] - ], - [ - [ - 97.294921875, - 53.605544099237974 - ], - [ - 99.4482421875, - 54.213861000644926 - ], - [ - 99.73388671874999, - 54.04648911335576 - ], - [ - 100.8984375, - 53.969012350740314 - ], - [ - 101.29394531249999, - 53.69670647530323 - ] - ], - [ - [ - 95.0537109375, - 47.68018294648414 - ], - [ - 96.416015625, - 47.502358951968574 - ], - [ - 97.05322265625, - 46.84516443029276 - ], - [ - 98.41552734375, - 47.76886840424207 - ], - [ - 98.89892578125, - 47.45780853075031 - ] - ] - ] - } -} \ No newline at end of file diff --git a/packages/turf-point-on-feature/test/in/multipoint.json b/packages/turf-point-on-feature/test/in/multipoint.json deleted file mode 100644 index 23aaf43c48..0000000000 --- a/packages/turf-point-on-feature/test/in/multipoint.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "type": "Feature", - "properties": {}, - "geometry": { - "type": "MultiPoint", - "coordinates": [ - [ - 63.6328125, - 57.7041472343419 - ], - [ - 42.1875, - 52.482780222078226 - ], - [ - 71.015625, - 29.22889003019423 - ], - [ - 48.1640625, - 37.71859032558816 - ], - [ - 73.47656249999999, - 49.61070993807422 - ] - ] - } -} \ No newline at end of file diff --git a/packages/turf-point-on-feature/test/in/multipolygon.json b/packages/turf-point-on-feature/test/in/multipolygon.json deleted file mode 100644 index 95d7afb771..0000000000 --- a/packages/turf-point-on-feature/test/in/multipolygon.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "type": "Feature", - "properties": {}, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - 12.041015625, - 36.66841891894786 - ], - [ - 12.041015625, - 39.16414104768742 - ], - [ - 15.161132812500002, - 39.16414104768742 - ], - [ - 15.161132812500002, - 36.66841891894786 - ], - [ - 12.041015625, - 36.66841891894786 - ] - ] - ], - [ - [ - [ - 15.732421875, - 31.42866311735861 - ], - [ - 15.732421875, - 34.92197103616377 - ], - [ - 19.775390625, - 34.92197103616377 - ], - [ - 19.775390625, - 31.42866311735861 - ], - [ - 15.732421875, - 31.42866311735861 - ] - ] - ], - [ - [ - [ - 18.3251953125, - 37.68382032669382 - ], - [ - 18.3251953125, - 42.65012181368025 - ], - [ - 22.0166015625, - 42.65012181368025 - ], - [ - 22.0166015625, - 37.68382032669382 - ], - [ - 18.3251953125, - 37.68382032669382 - ] - ] - ] - ] - } -} \ No newline at end of file diff --git a/packages/turf-point-on-feature/test/in/polygon-in-center.json b/packages/turf-point-on-feature/test/in/polygon-in-center.json deleted file mode 100644 index 4473d97fff..0000000000 --- a/packages/turf-point-on-feature/test/in/polygon-in-center.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 13.270797729492186, - 52.42042920678164 - ], - [ - 13.270797729492186, - 52.573846203920276 - ], - [ - 13.5186767578125, - 52.573846203920276 - ], - [ - 13.5186767578125, - 52.42042920678164 - ], - [ - 13.270797729492186, - 52.42042920678164 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 13.526229858398438, - 52.58177420312145 - ], - [ - 13.526229858398438, - 52.61013634893439 - ], - [ - 13.572921752929686, - 52.61013634893439 - ], - [ - 13.572921752929686, - 52.58177420312145 - ], - [ - 13.526229858398438, - 52.58177420312145 - ] - ] - ] - } - } - ] -} \ No newline at end of file diff --git a/packages/turf-point-on-feature/test/in/polygons.json b/packages/turf-point-on-feature/test/in/polygons.json deleted file mode 100644 index a18c18244f..0000000000 --- a/packages/turf-point-on-feature/test/in/polygons.json +++ /dev/null @@ -1,171 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -80.4638671875, - 38.496593518947556 - ], - [ - -81.05712890625, - 38.22091976683121 - ], - [ - -80.518798828125, - 37.640334898059486 - ], - [ - -78.81591796875, - 36.730079507078415 - ], - [ - -78.167724609375, - 37.01132594307015 - ], - [ - -78.673095703125, - 37.55328764595765 - ], - [ - -78.94775390625, - 37.49229399862877 - ], - [ - -79.112548828125, - 37.68382032669382 - ], - [ - -79.51904296874999, - 37.75334401310656 - ], - [ - -79.090576171875, - 38.039438891821746 - ], - [ - -79.47509765625, - 38.1172716583054 - ], - [ - -79.969482421875, - 38.315801006824984 - ], - [ - -79.683837890625, - 38.47939467327645 - ], - [ - -79.793701171875, - 38.62545397209084 - ], - [ - -80.09033203125, - 38.71123253895224 - ], - [ - -80.33203125, - 39.104488809440475 - ], - [ - -80.4638671875, - 38.496593518947556 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.17919921875, - 41.00477542222949 - ], - [ - -77.091064453125, - 40.97160353279909 - ], - [ - -77.28881835937499, - 40.27952566881291 - ], - [ - -77.080078125, - 40.271143686084194 - ], - [ - -77.003173828125, - 40.136890695345905 - ], - [ - -76.7724609375, - 40.195659093364654 - ], - [ - -76.86035156249999, - 39.93501296038254 - ], - [ - -76.66259765625, - 40.0360265298117 - ], - [ - -76.37695312499999, - 39.614152077002636 - ], - [ - -75.992431640625, - 39.614152077002636 - ], - [ - -75.76171875, - 39.42770738465604 - ], - [ - -75.465087890625, - 39.40224434029275 - ], - [ - -75.377197265625, - 39.68182601089365 - ], - [ - -75.5419921875, - 40.455307212131494 - ], - [ - -76.17919921875, - 40.55554790286311 - ], - [ - -75.750732421875, - 40.697299008636755 - ], - [ - -76.1572265625, - 40.72228267283148 - ], - [ - -75.992431640625, - 40.94671366508002 - ], - [ - -76.17919921875, - 41.00477542222949 - ] - ] - ] - } - } - ] -} \ No newline at end of file diff --git a/packages/turf-point-to-line-distance/.gitignore b/packages/turf-point-to-line-distance/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-point-to-line-distance/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-point-to-line-distance/LICENSE b/packages/turf-point-to-line-distance/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-point-to-line-distance/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-point-to-line-distance/README.md b/packages/turf-point-to-line-distance/README.md deleted file mode 100644 index a777edf000..0000000000 --- a/packages/turf-point-to-line-distance/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# @turf/point-to-line-distance - - - -## pointToLineDistance - -Returns the minimum distance between a [Point][1] and a [LineString][2], being the distance from a line the -minimum distance between the point and any segment of the `LineString`. - -**Parameters** - -- `pt` **([Feature][3]<[Point][4]> | [Array][5]<[number][6]>)** Feature or Geometry -- `line` **[Feature][3]<[LineString][7]>** GeoJSON Feature or Geometry -- `options` **[Object][8]** Optional parameters (optional, default `{}`) - - `options.units` **[string][9]** can be anything supported by turf/convertLength, eg degrees, radians, miles, or kilometers (optional, default `'kilometers'`) - - `options.method` **[string][9]** wehther to calculate the distance based on geodesic (spheroid) or planar (flat) method. Valid options are 'geodesic' or 'planar'. (optional, default `'geodesic'`) - -**Examples** - -```javascript -var pt = turf.point([0, 0]); -var line = turf.lineString([[1, 1],[-1, 1]]); - -var distance = turf.pointToLineDistance(pt, line, {units: 'miles'}); -//=69.11854715938406 -``` - -Returns **[number][6]** distance between point and line - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/point-to-line-distance -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-point-to-line-distance/index.d.ts b/packages/turf-point-to-line-distance/index.d.ts deleted file mode 100644 index b777529bab..0000000000 --- a/packages/turf-point-to-line-distance/index.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Coord, Feature, LineString, Units } from "@turf/helpers"; -/** - * Returns the minimum distance between a {@link Point} and a {@link LineString}, being the distance from a line the - * minimum distance between the point and any segment of the `LineString`. - * - * @name pointToLineDistance - * @param {Feature|Array} pt Feature or Geometry - * @param {Feature} line GeoJSON Feature or Geometry - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units="kilometers"] can be anything supported by turf/convertLength - * (ex: degrees, radians, miles, or kilometers) - * @param {string} [options.method="geodesic"] wether to calculate the distance based on geodesic (spheroid) or - * planar (flat) method. Valid options are 'geodesic' or 'planar'. - * @returns {number} distance between point and line - * @example - * var pt = turf.point([0, 0]); - * var line = turf.lineString([[1, 1],[-1, 1]]); - * - * var distance = turf.pointToLineDistance(pt, line, {units: 'miles'}); - * //=69.11854715938406 - */ -declare function pointToLineDistance(pt: Coord, line: Feature | LineString, options?: { - units?: Units; - method?: "geodesic" | "planar"; -}): number; -export default pointToLineDistance; diff --git a/packages/turf-point-to-line-distance/index.ts b/packages/turf-point-to-line-distance/index.ts deleted file mode 100644 index 2cd441ecab..0000000000 --- a/packages/turf-point-to-line-distance/index.ts +++ /dev/null @@ -1,99 +0,0 @@ -// Taken from http://geomalgorithms.com/a02-_lines.html -import getDistance from "@turf/distance"; -import { - convertLength, - Coord, - feature, - Feature, - lineString, - LineString, - point, - Point, - Units, -} from "@turf/helpers"; -import { featureOf } from "@turf/invariant"; -import { segmentEach } from "@turf/meta"; -import getPlanarDistance from "@turf/rhumb-distance"; - -/** - * Returns the minimum distance between a {@link Point} and a {@link LineString}, being the distance from a line the - * minimum distance between the point and any segment of the `LineString`. - * - * @name pointToLineDistance - * @param {Feature|Array} pt Feature or Geometry - * @param {Feature} line GeoJSON Feature or Geometry - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units="kilometers"] can be anything supported by turf/convertLength - * (ex: degrees, radians, miles, or kilometers) - * @param {string} [options.method="geodesic"] wether to calculate the distance based on geodesic (spheroid) or - * planar (flat) method. Valid options are 'geodesic' or 'planar'. - * @returns {number} distance between point and line - * @example - * var pt = turf.point([0, 0]); - * var line = turf.lineString([[1, 1],[-1, 1]]); - * - * var distance = turf.pointToLineDistance(pt, line, {units: 'miles'}); - * //=69.11854715938406 - */ -function pointToLineDistance(pt: Coord, line: Feature | LineString, options: { - units?: Units, - method?: "geodesic" | "planar", -} = {}): number { - // Optional parameters - if (!options.method) { options.method = "geodesic"; } - if (!options.units) { options.units = "kilometers"; } - - // validation - if (!pt) { throw new Error("pt is required"); } - if (Array.isArray(pt)) { pt = point(pt); - } else if (pt.type === "Point") { pt = feature(pt); - } else { featureOf(pt, "Point", "point"); } - - if (!line) { throw new Error("line is required"); } - if (Array.isArray(line)) { line = lineString(line); - } else if (line.type === "LineString") { line = feature(line); - } else { featureOf(line, "LineString", "line"); } - - let distance = Infinity; - const p = pt.geometry.coordinates; - segmentEach(line, (segment) => { - const a = segment!.geometry.coordinates[0]; - const b = segment!.geometry.coordinates[1]; - const d = distanceToSegment(p, a, b, options); - if (d < distance) { distance = d; } - }); - return convertLength(distance, "degrees", options.units); -} - -/** - * Returns the distance between a point P on a segment AB. - * - * @private - * @param {Array} p external point - * @param {Array} a first segment point - * @param {Array} b second segment point - * @param {Object} [options={}] Optional parameters - * @returns {number} distance - */ -function distanceToSegment(p: number[], a: number[], b: number[], options: any) { - const v = [b[0] - a[0], b[1] - a[1]]; - const w = [p[0] - a[0], p[1] - a[1]]; - - const c1 = dot(w, v); - if (c1 <= 0) { return calcDistance(p, a, {method: options.method, units: "degrees"}); } - const c2 = dot(v, v); - if (c2 <= c1) { return calcDistance(p, b, {method: options.method, units: "degrees"}); } - const b2 = c1 / c2; - const Pb = [a[0] + (b2 * v[0]), a[1] + (b2 * v[1])]; - return calcDistance(p, Pb, {method: options.method, units: "degrees"}); -} - -function dot(u: number[], v: number[]) { - return (u[0] * v[0] + u[1] * v[1]); -} - -function calcDistance(a: number[], b: number[], options: any) { - return options.method === "planar" ? getPlanarDistance(a, b, options) : getDistance(a, b, options); -} - -export default pointToLineDistance; diff --git a/packages/turf-point-to-line-distance/package.json b/packages/turf-point-to-line-distance/package.json deleted file mode 100644 index 0834955ac2..0000000000 --- a/packages/turf-point-to-line-distance/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "@turf/point-to-line-distance", - "version": "6.0.0", - "description": "turf point-to-line-distance module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "point-to-line-distance", - "distance" - ], - "author": "Turf Authors", - "contributors": [ - "Stefano Borghi <@stebogit>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/circle": "*", - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/bearing": "6.x", - "@turf/distance": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x", - "@turf/projection": "6.x", - "@turf/rhumb-bearing": "6.x", - "@turf/rhumb-distance": "6.x" - } -} diff --git a/packages/turf-point-to-line-distance/test.js b/packages/turf-point-to-line-distance/test.js deleted file mode 100644 index 057105784c..0000000000 --- a/packages/turf-point-to-line-distance/test.js +++ /dev/null @@ -1,80 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const circle = require('@turf/circle').default; -const { point, lineString, round } = require('@turf/helpers'); -const pointToLineDistance = require('.').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-point-to-line-distance', t => { - const results = {}; - fixtures.forEach(fixture => { - const filename = fixture.filename; - const name = fixture.name; - const geojson = fixture.geojson; - const point = geojson.features[0]; - const line = geojson.features[1]; - const properties = geojson.properties || {}; - const units = properties.units || 'kilometers'; - // main method - const options = {units: units}; - options.method = 'geodesic'; - const distance = pointToLineDistance(point, line, options); - - // Store results - results[name] = round(distance, 10); - - // debug purposes - geojson.features.push(circle(point, distance, {steps: 200, units: units})); - if (process.env.REGEN) write.sync(directories.out + filename, geojson); - }); - if (process.env.REGEN) write.sync(directories.out + 'distances.json', results); - t.deepEqual(load.sync(directories.out + 'distances.json'), results); - t.end(); -}); - -test('turf-point-to-line-distance -- throws', t => { - const pt = point([0, 0]); - const line = lineString([[1, 1], [-1, 1]]); - - t.throws(() => pointToLineDistance(null, line), /pt is required/, 'missing point'); - t.throws(() => pointToLineDistance(pt, null), /line is required/, 'missing line'); - t.throws(() => pointToLineDistance(pt, line, {units: 'invalid'}), /units is invalid/, 'invalid units'); - t.throws(() => pointToLineDistance(line, line), /Invalid input to point: must be a Point, given LineString/, 'invalid line'); - t.throws(() => pointToLineDistance(pt, pt), /Invalid input to line: must be a LineString, given Point/, 'invalid point'); - - t.end(); -}); - -test('turf-point-to-line-distance -- Geometry', t => { - const pt = point([0, 0]); - const line = lineString([[1, 1], [-1, 1]]); - - t.assert(pointToLineDistance(pt.geometry, line.geometry)); - t.end(); -}); - - -test('turf-point-to-line-distance -- Check planar and geodesic results are different', t => { - const pt = point([0, 0]); - const line = lineString([[10, 10], [-1, 1]]); - - const geoOut = pointToLineDistance(pt.geometry, line.geometry, {method: 'geodesic'}); - const planarOut = pointToLineDistance(pt.geometry, line.geometry, {method: 'planar'}); - t.notEqual(geoOut, planarOut); - t.end(); -}); diff --git a/packages/turf-point-to-line-distance/tsconfig.json b/packages/turf-point-to-line-distance/tsconfig.json deleted file mode 100644 index 91cffcbf55..0000000000 --- a/packages/turf-point-to-line-distance/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - }, - "files": [ - "index.ts" - ] -} \ No newline at end of file diff --git a/packages/turf-point-to-line-distance/tslint.json b/packages/turf-point-to-line-distance/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-point-to-line-distance/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-point-to-line-distance/types.ts b/packages/turf-point-to-line-distance/types.ts deleted file mode 100644 index 5843eb56d6..0000000000 --- a/packages/turf-point-to-line-distance/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { point, lineString } from '@turf/helpers' -import pointToLineDistance from './' - -const pt = point([0, 0]) -const line = lineString([[1, 1],[-1, 1]]) -const distance: number = pointToLineDistance(pt, line, {units: 'miles'}) - -pointToLineDistance(pt, line) -pointToLineDistance(pt, line, {units: 'miles'}) -pointToLineDistance(pt, line, {units: 'miles', method: 'planar'}) diff --git a/packages/turf-points-within-polygon/LICENSE b/packages/turf-points-within-polygon/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-points-within-polygon/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-points-within-polygon/README.md b/packages/turf-points-within-polygon/README.md deleted file mode 100644 index e287cbd545..0000000000 --- a/packages/turf-points-within-polygon/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# @turf/points-within-polygon - - - -## pointsWithinPolygon - -Finds [Points][1] that fall within [(Multi)Polygon(s)][2]. - -**Parameters** - -- `points` **([Feature][3] \| [FeatureCollection][4]<[Point][5]>)** Points as input search -- `polygons` **([FeatureCollection][4] \| [Geometry][6] \| [Feature][3]<([Polygon][7] \| [MultiPolygon][8])>)** Points must be within these (Multi)Polygon(s) - -**Examples** - -```javascript -var points = turf.points([ - [-46.6318, -23.5523], - [-46.6246, -23.5325], - [-46.6062, -23.5513], - [-46.663, -23.554], - [-46.643, -23.557] -]); - -var searchWithin = turf.polygon([[ - [-46.653,-23.543], - [-46.634,-23.5346], - [-46.613,-23.543], - [-46.614,-23.559], - [-46.631,-23.567], - [-46.653,-23.560], - [-46.653,-23.543] -]]); - -var ptsWithin = turf.pointsWithinPolygon(points, searchWithin); - -//addToMap -var addToMap = [points, searchWithin, ptsWithin] -turf.featureEach(ptsWithin, function (currentFeature) { - currentFeature.properties['marker-size'] = 'large'; - currentFeature.properties['marker-color'] = '#000'; -}); -``` - -Returns **[FeatureCollection][4]<[Point][5]>** points that land within at least one polygon - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[8]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/points-within-polygon -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-points-within-polygon/bench.js b/packages/turf-points-within-polygon/bench.js deleted file mode 100644 index b9d333d646..0000000000 --- a/packages/turf-points-within-polygon/bench.js +++ /dev/null @@ -1,22 +0,0 @@ -import fs from 'fs'; -import Benchmark from 'benchmark'; -import { featureCollection, point, polygon } from '@turf/helpers'; -import pointsWithinPolygon from './'; - -var poly1 = polygon([[[0, 0], [10, 0], [10, 10], [0, 0]]]); -var poly2 = polygon([[[10, 0], [20, 10], [20, 20], [10, 0]]]); -var polyFC = featureCollection([poly1, poly2]); -var pt1 = point([1, 1], {population: 500}); -var pt2 = point([1, 3], {population: 400}); -var pt3 = point([14, 2], {population: 600}); -var pt4 = point([13, 1], {population: 500}); -var pt5 = point([19, 7], {population: 200}); -var pt6 = point([100, 7], {population: 200}); -var ptFC = featureCollection([pt1, pt2, pt3, pt4, pt5, pt6]); - -var suite = new Benchmark.Suite('turf-points-within-polygon'); -suite - .add('turf-points-within-polygon', () => pointsWithinPolygon(ptFC, polyFC)) - .on('cycle', e => console.log(String(e.target))) - .on('complete', () => {}) - .run(); diff --git a/packages/turf-points-within-polygon/index.d.ts b/packages/turf-points-within-polygon/index.d.ts deleted file mode 100644 index 7729ec19ec..0000000000 --- a/packages/turf-points-within-polygon/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Feature, FeatureCollection, Polygon, MultiPolygon, Point } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#pointswithinpolygon - */ -export default function pointsWithinPolygon( - points: Feature | FeatureCollection, - polygons: Feature | FeatureCollection | G -): FeatureCollection; diff --git a/packages/turf-points-within-polygon/index.js b/packages/turf-points-within-polygon/index.js deleted file mode 100644 index 86c8a8d876..0000000000 --- a/packages/turf-points-within-polygon/index.js +++ /dev/null @@ -1,54 +0,0 @@ -import pointInPolygon from '@turf/boolean-point-in-polygon'; -import { featureCollection } from '@turf/helpers'; -import { geomEach, featureEach } from '@turf/meta'; - -/** - * Finds {@link Points} that fall within {@link (Multi)Polygon(s)}. - * - * @name pointsWithinPolygon - * @param {Feature|FeatureCollection} points Points as input search - * @param {FeatureCollection|Geometry|Feature} polygons Points must be within these (Multi)Polygon(s) - * @returns {FeatureCollection} points that land within at least one polygon - * @example - * var points = turf.points([ - * [-46.6318, -23.5523], - * [-46.6246, -23.5325], - * [-46.6062, -23.5513], - * [-46.663, -23.554], - * [-46.643, -23.557] - * ]); - * - * var searchWithin = turf.polygon([[ - * [-46.653,-23.543], - * [-46.634,-23.5346], - * [-46.613,-23.543], - * [-46.614,-23.559], - * [-46.631,-23.567], - * [-46.653,-23.560], - * [-46.653,-23.543] - * ]]); - * - * var ptsWithin = turf.pointsWithinPolygon(points, searchWithin); - * - * //addToMap - * var addToMap = [points, searchWithin, ptsWithin] - * turf.featureEach(ptsWithin, function (currentFeature) { - * currentFeature.properties['marker-size'] = 'large'; - * currentFeature.properties['marker-color'] = '#000'; - * }); - */ -function pointsWithinPolygon(points, polygons) { - var results = []; - featureEach(points, function (point) { - var contained = false; - geomEach(polygons, function (polygon) { - if (pointInPolygon(point, polygon)) contained = true; - }); - if (contained) { - results.push(point); - } - }); - return featureCollection(results); -} - -export default pointsWithinPolygon; diff --git a/packages/turf-points-within-polygon/package.json b/packages/turf-points-within-polygon/package.json deleted file mode 100644 index c1776a6375..0000000000 --- a/packages/turf-points-within-polygon/package.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "name": "@turf/points-within-polygon", - "version": "5.1.5", - "description": "turf points-within-polygon module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "geojson", - "within", - "point", - "polygon", - "featurecollection" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "rollup": "*", - "tape": "*" - }, - "dependencies": { - "@turf/boolean-point-in-polygon": "6.x", - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-points-within-polygon/test.js b/packages/turf-points-within-polygon/test.js deleted file mode 100644 index 212ba6f229..0000000000 --- a/packages/turf-points-within-polygon/test.js +++ /dev/null @@ -1,71 +0,0 @@ -import test from 'tape'; -import { point, points } from '@turf/helpers'; -import { polygon } from '@turf/helpers'; -import { featureCollection } from '@turf/helpers'; -import pointsWithinPolygon from '.'; - -test('turf-points-within-polygon', t => { - t.plan(4); - - // test with a single point - var poly = polygon([[[0, 0], [0, 100], [100, 100], [100, 0], [0, 0]]]); - var pt = point([50, 50]); - var polyFC = featureCollection([poly]); - var ptFC = featureCollection([pt]); - - var counted = pointsWithinPolygon(ptFC, polyFC); - - t.ok(counted, 'returns a featurecollection'); - t.equal(counted.features.length, 1, '1 point in 1 polygon'); - - // test with multiple points and multiple polygons - var poly1 = polygon([[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]); - var poly2 = polygon([[[10, 0], [20, 10], [20, 20], [20, 0], [10, 0]]]); - var polyFC = featureCollection([poly1, poly2]); - var pt1 = point([1, 1], {population: 500}); - var pt2 = point([1, 3], {population: 400}); - var pt3 = point([14, 2], {population: 600}); - var pt4 = point([13, 1], {population: 500}); - var pt5 = point([19, 7], {population: 200}); - var pt6 = point([100, 7], {population: 200}); - var ptFC = featureCollection([pt1, pt2, pt3, pt4, pt5, pt6]); - - var counted = pointsWithinPolygon(ptFC, polyFC); - t.ok(counted, 'returns a featurecollection'); - t.equal(counted.features.length, 5, 'multiple points in multiple polygons'); -}); - -test('turf-points-within-polygon -- support extra geometry', t => { - const pts = points([ - [-46.6318, -23.5523], - [-46.6246, -23.5325], - [-46.6062, -23.5513], - [-46.663, -23.554], - [-46.643, -23.557] - ]); - const searchWithin = polygon([[ - [-46.653,-23.543], - [-46.634,-23.5346], - [-46.613,-23.543], - [-46.614,-23.559], - [-46.631,-23.567], - [-46.653,-23.560], - [-46.653,-23.543] - ]]); - t.assert(pointsWithinPolygon(pts, searchWithin)); - t.assert(pointsWithinPolygon(pts.features[0], searchWithin)); - t.assert(pointsWithinPolygon(pts, searchWithin.geometry)); - t.end() -}); - -test('turf-points-within-polygon -- no duplicates when multiple geometry contain a point', t => { - const poly1 = polygon([[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]); - const poly2 = polygon([[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]); - const polyFC = featureCollection([poly1, poly2]); - const pt1 = point([5, 5]); - const ptFC = featureCollection([pt1]); - - const counted = pointsWithinPolygon(ptFC, polyFC); - t.equal(counted.features.length, 1, 'although point is contained by two polygons it is only counted once'); - t.end(); -}); diff --git a/packages/turf-points-within-polygon/types.ts b/packages/turf-points-within-polygon/types.ts deleted file mode 100644 index 02f55ba6c1..0000000000 --- a/packages/turf-points-within-polygon/types.ts +++ /dev/null @@ -1,20 +0,0 @@ -import pointsWithinPolygon from './' -import { points, polygon } from '@turf/helpers' - -const pts = points([ - [-46.6318, -23.5523], - [-46.6246, -23.5325], - [-46.6062, -23.5513], - [-46.663, -23.554], - [-46.643, -23.557] -]); -const searchWithin = polygon([[ - [-46.653,-23.543], - [-46.634,-23.5346], - [-46.613,-23.543], - [-46.614,-23.559], - [-46.631,-23.567], - [-46.653,-23.560], - [-46.653,-23.543] -]]); -const ptsWithin = pointsWithinPolygon(pts, searchWithin); diff --git a/packages/turf-polygon-smooth/LICENSE b/packages/turf-polygon-smooth/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-polygon-smooth/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-polygon-smooth/README.md b/packages/turf-polygon-smooth/README.md deleted file mode 100644 index 2dd1814bfa..0000000000 --- a/packages/turf-polygon-smooth/README.md +++ /dev/null @@ -1,70 +0,0 @@ -# @turf/polygon-smooth - - - -## polygonSmooth - -Smooths a [Polygon][1] or [MultiPolygon][2]. Based on [Chaikin's algorithm][3]. -Warning: may create degenerate polygons. - -**Parameters** - -- `inputPolys` **([FeatureCollection][4] \| [Feature][5]<([Polygon][6] \| [MultiPolygon][7])>)** (Multi)Polygon(s) to smooth -- `options` **[Object][8]** Optional parameters (optional, default `{}`) - - `options.iterations` **[string][9]** THe number of times to smooth the polygon. A higher value means a smoother polygon. (optional, default `1`) - -**Examples** - -```javascript -var polygon = turf.polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); - -var smoothed = turf.polygonSmooth(polygon, {iterations: 3}) - -//addToMap -var addToMap = [smoothed, polygon]; -``` - -Returns **[FeatureCollection][4]<[Polygon][6]>** FeatureCollection containing the smoothed polygon/poylgons - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[3]: http://graphics.cs.ucdavis.edu/education/CAGDNotes/Chaikins-Algorithm/Chaikins-Algorithm.html - -[4]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/polygon-smooth -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-polygon-smooth/index.js b/packages/turf-polygon-smooth/index.js deleted file mode 100644 index a73fe40d85..0000000000 --- a/packages/turf-polygon-smooth/index.js +++ /dev/null @@ -1,129 +0,0 @@ -import { coordEach, geomEach } from '@turf/meta'; -import { featureCollection, polygon, multiPolygon } from '@turf/helpers'; - -/** - * Smooths a {@link Polygon} or {@link MultiPolygon}. Based on [Chaikin's algorithm](http://graphics.cs.ucdavis.edu/education/CAGDNotes/Chaikins-Algorithm/Chaikins-Algorithm.html). - * Warning: may create degenerate polygons. - * - * @name polygonSmooth - * @param {FeatureCollection|Feature} inputPolys (Multi)Polygon(s) to smooth - * @param {Object} [options={}] Optional parameters - * @param {string} [options.iterations=1] THe number of times to smooth the polygon. A higher value means a smoother polygon. - * @returns {FeatureCollection} FeatureCollection containing the smoothed polygon/poylgons - * @example - * var polygon = turf.polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); - * - * var smoothed = turf.polygonSmooth(polygon, {iterations: 3}) - * - * //addToMap - * var addToMap = [smoothed, polygon]; - */ -function polygonSmooth(inputPolys, options) { - var outPolys = []; - // Optional parameters - var iterations = options.iterations || 1; - if (!inputPolys) throw new Error('inputPolys is required'); - - geomEach(inputPolys, function (geom, geomIndex, properties) { - var outCoords; - var poly; - var tempOutput; - - switch (geom.type) { - case 'Polygon': - outCoords = [[]]; - for (var i = 0; i < iterations; i++) { - tempOutput = [[]]; - poly = geom; - if (i > 0) poly = polygon(outCoords).geometry; - processPolygon(poly, tempOutput); - outCoords = tempOutput.slice(0); - } - outPolys.push(polygon(outCoords, properties)); - break; - case 'MultiPolygon': - outCoords = [[[]]]; - for (var y = 0; y < iterations; y++) { - tempOutput = [[[]]]; - poly = geom; - if (y > 0) poly = multiPolygon(outCoords).geometry; - processMultiPolygon(poly, tempOutput); - outCoords = tempOutput.slice(0); - } - outPolys.push(multiPolygon(outCoords, properties)); - break; - default: - throw new Error('geometry is invalid, must be Polygon or MultiPolygon'); - } - }); - return featureCollection(outPolys); -} - -/** - * @param {poly} poly to process - * @param {poly} tempOutput to place the results in - * @private - */ -function processPolygon(poly, tempOutput) { - var prevGeomIndex = 0; - var subtractCoordIndex = 0; - - coordEach(poly, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) { - if (geometryIndex > prevGeomIndex) { - prevGeomIndex = geometryIndex; - subtractCoordIndex = coordIndex; - tempOutput.push([]); - } - var realCoordIndex = coordIndex - subtractCoordIndex; - var p1 = poly.coordinates[geometryIndex][realCoordIndex + 1]; - var p0x = currentCoord[0]; - var p0y = currentCoord[1]; - var p1x = p1[0]; - var p1y = p1[1]; - tempOutput[geometryIndex].push([0.75 * p0x + 0.25 * p1x, 0.75 * p0y + 0.25 * p1y]); - tempOutput[geometryIndex].push([0.25 * p0x + 0.75 * p1x, 0.25 * p0y + 0.75 * p1y]); - }, true); - tempOutput.forEach(function (ring) { - ring.push(ring[0]); - }); -} - -/** - * @param {poly} poly to process - * @param {poly} tempOutput to place the results in - * @private - */ -function processMultiPolygon(poly, tempOutput) { - var prevGeomIndex = 0; - var subtractCoordIndex = 0; - var prevMultiIndex = 0; - - coordEach(poly, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) { - if (multiFeatureIndex > prevMultiIndex) { - prevMultiIndex = multiFeatureIndex; - subtractCoordIndex = coordIndex; - tempOutput.push([[]]); - } - if (geometryIndex > prevGeomIndex) { - prevGeomIndex = geometryIndex; - subtractCoordIndex = coordIndex; - tempOutput[multiFeatureIndex].push([]); - } - var realCoordIndex = coordIndex - subtractCoordIndex; - var p1 = poly.coordinates[multiFeatureIndex][geometryIndex][realCoordIndex + 1]; - var p0x = currentCoord[0]; - var p0y = currentCoord[1]; - var p1x = p1[0]; - var p1y = p1[1]; - tempOutput[multiFeatureIndex][geometryIndex].push([0.75 * p0x + 0.25 * p1x, 0.75 * p0y + 0.25 * p1y]); - tempOutput[multiFeatureIndex][geometryIndex].push([0.25 * p0x + 0.75 * p1x, 0.25 * p0y + 0.75 * p1y]); - }, true); - - tempOutput.forEach(function (poly) { - poly.forEach(function (ring) { - ring.push(ring[0]); - }); - }); -} - -export default polygonSmooth; diff --git a/packages/turf-polygon-smooth/package.json b/packages/turf-polygon-smooth/package.json deleted file mode 100644 index b3c2829174..0000000000 --- a/packages/turf-polygon-smooth/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "@turf/polygon-smooth", - "version": "5.0.1", - "description": "turf polygon smooth module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "polygon" - ], - "author": "Turf Authors", - "contributors": [ - "Rowan Winsemius <@rowanwins>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "glob": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-polygon-smooth/test.js b/packages/turf-polygon-smooth/test.js deleted file mode 100644 index efe246e59a..0000000000 --- a/packages/turf-polygon-smooth/test.js +++ /dev/null @@ -1,25 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import glob from 'glob'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import polygonSmooth from '.'; - -test('turf-polygon-smooth', t => { - glob.sync(path.join(__dirname, 'test', 'in', '*.json')).forEach(filepath => { - // Inputs - const geojson = load.sync(filepath); - const options = geojson.options || {}; - const iterations = options.iterations || 3; - - // Results - const results = polygonSmooth(geojson, {iterations}); - - // Save Results - const out = filepath.replace(path.join('test', 'in'), path.join('test', 'out')) - if (process.env.REGEN) write.sync(out, results); - t.deepEqual(results, load.sync(out), path.parse(filepath).name); - }); - t.end(); -}); diff --git a/packages/turf-polygon-smooth/types.ts b/packages/turf-polygon-smooth/types.ts deleted file mode 100644 index b438b8845c..0000000000 --- a/packages/turf-polygon-smooth/types.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { polygon } from '@turf/helpers' -import polygonSmooth from '.' - -const poly = polygon([[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]]) - -polygonSmooth(poly) -polygonSmooth(poly, {iterations: 3}) diff --git a/packages/turf-polygon-tangents/LICENSE b/packages/turf-polygon-tangents/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-polygon-tangents/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-polygon-tangents/README.md b/packages/turf-polygon-tangents/README.md deleted file mode 100644 index da499c7cad..0000000000 --- a/packages/turf-polygon-tangents/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# @turf/polygon-tangents - - - -## polygonTangents - -Finds the tangents of a [(Multi)Polygon][1] from a [Point][2]. - -**Parameters** - -- `pt` **[Coord][3]** to calculate the tangent points from -- `polygon` **[Feature][4]<([Polygon][5] \| [MultiPolygon][6])>** to get tangents from - -**Examples** - -```javascript -var polygon = turf.polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); -var point = turf.point([61, 5]); - -var tangents = turf.polygonTangents(point, polygon) - -//addToMap -var addToMap = [tangents, point, polygon]; -``` - -Returns **[FeatureCollection][7]<[Point][8]>** Feature Collection containing the two tangent points - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[8]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/polygon-tangents -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-polygon-tangents/index.d.ts b/packages/turf-polygon-tangents/index.d.ts deleted file mode 100644 index 7698ef6883..0000000000 --- a/packages/turf-polygon-tangents/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Feature, FeatureCollection, Coord, Point, Polygon, MultiPolygon } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#polygontangents - */ -export default function ( - point: Coord, - polygon: Feature | T -): FeatureCollection; diff --git a/packages/turf-polygon-tangents/index.js b/packages/turf-polygon-tangents/index.js deleted file mode 100644 index db07a89e37..0000000000 --- a/packages/turf-polygon-tangents/index.js +++ /dev/null @@ -1,118 +0,0 @@ -import { getCoords, getType } from '@turf/invariant'; -import { point, featureCollection } from '@turf/helpers'; -import calcBbox from '@turf/bbox'; -import explode from '@turf/explode'; -import nearestPoint from '@turf/nearest-point'; - -/** - * Finds the tangents of a {@link Polygon|(Multi)Polygon} from a {@link Point}. - * - * @name polygonTangents - * @param {Coord} pt to calculate the tangent points from - * @param {Feature} polygon to get tangents from - * @returns {FeatureCollection} Feature Collection containing the two tangent points - * @example - * var polygon = turf.polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); - * var point = turf.point([61, 5]); - * - * var tangents = turf.polygonTangents(point, polygon) - * - * //addToMap - * var addToMap = [tangents, point, polygon]; - */ -function polygonTangents(pt, polygon) { - var pointCoords = getCoords(pt); - var polyCoords = getCoords(polygon); - - var rtan; - var ltan; - var enext; - var eprev; - var bbox = calcBbox(polygon); - var nearestPtIndex = 0; - var nearest = null; - - // If the point lies inside the polygon bbox then we need to be a bit trickier - // otherwise points lying inside reflex angles on concave polys can have issues - if (pointCoords[0] > bbox[0] && pointCoords[0] < bbox[2] && pointCoords[1] > bbox[1] && pointCoords[1] < bbox[3]) { - nearest = nearestPoint(pt, explode(polygon)); - nearestPtIndex = nearest.properties.featureIndex; - } - var type = getType(polygon); - switch (type) { - case 'Polygon': - rtan = polyCoords[0][nearestPtIndex]; - ltan = polyCoords[0][0]; - if (nearest !== null) { - if (nearest.geometry.coordinates[1] < pointCoords[1]) ltan = polyCoords[0][nearestPtIndex]; - } - eprev = isLeft(polyCoords[0][0], polyCoords[0][polyCoords[0].length - 1], pointCoords); - var out = processPolygon(polyCoords[0], pointCoords, eprev, enext, rtan, ltan, polygon); - rtan = out[0]; - ltan = out[1]; - break; - case 'MultiPolygon': - var closestFeature = 0; - var closestVertex = 0; - var verticesCounted = 0; - for (var i = 0; i < polyCoords[0].length; i++) { - closestFeature = i; - var verticeFound = false; - for (var i2 = 0; i2 < polyCoords[0][i].length; i2++) { - closestVertex = i2; - if (verticesCounted === nearestPtIndex) { - verticeFound = true; - break; - } - verticesCounted++; - } - if (verticeFound) break; - } - rtan = polyCoords[0][closestFeature][closestVertex]; - ltan = polyCoords[0][closestFeature][closestVertex]; - eprev = isLeft(polyCoords[0][0][0], polyCoords[0][0][polyCoords[0][0].length - 1], pointCoords); - polyCoords.forEach(function (ring) { - var out = processPolygon(ring[0], pointCoords, eprev, enext, rtan, ltan, polygon); - rtan = out[0]; - ltan = out[1]; - }); - break; - } - return featureCollection([point(rtan), point(ltan)]); -} - -function processPolygon(polygonCoords, ptCoords, eprev, enext, rtan, ltan) { - for (var i = 0; i < polygonCoords.length; i++) { - var currentCoords = polygonCoords[i]; - var nextCoordPair = polygonCoords[i + 1]; - if (i === polygonCoords.length - 1) { - nextCoordPair = polygonCoords[0]; - } - enext = isLeft(currentCoords, nextCoordPair, ptCoords); - if (eprev <= 0 && enext > 0) { - if (!isBelow(ptCoords, currentCoords, rtan)) { - rtan = currentCoords; - } - } else if (eprev > 0 && enext <= 0) { - if (!isAbove(ptCoords, currentCoords, ltan)) { - ltan = currentCoords; - } - } - eprev = enext; - } - return [rtan, ltan]; -} - -function isAbove(point1, point2, point3) { - return isLeft(point1, point2, point3) > 0; -} - -function isBelow(point1, point2, point3) { - return isLeft(point1, point2, point3) < 0; -} - -function isLeft(point1, point2, point3) { - return (point2[0] - point1[0]) * (point3[1] - point1[1]) - (point3[0] - point1[0]) * (point2[1] - point1[1]); -} - -export default polygonTangents; diff --git a/packages/turf-polygon-tangents/package.json b/packages/turf-polygon-tangents/package.json deleted file mode 100644 index 82ed925b53..0000000000 --- a/packages/turf-polygon-tangents/package.json +++ /dev/null @@ -1,63 +0,0 @@ - -{ - "name": "@turf/polygon-tangents", - "version": "5.1.5", - "description": "turf polygon tangents module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "point", - "tangent", - "polygon" - ], - "author": "Turf Authors", - "contributors": [ - "Rowan Winsemius <@rowanwins>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/boolean-within": "6.x", - "@turf/explode": "^5.1.5", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/nearest-point": "^5.1.5" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-polygon-tangents/test.js b/packages/turf-polygon-tangents/test.js deleted file mode 100644 index 79011fa774..0000000000 --- a/packages/turf-polygon-tangents/test.js +++ /dev/null @@ -1,74 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import { polygon, point } from '@turf/helpers'; -import polygonTangents from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-polygon-tangents', t => { - for (const {name, filename, geojson} of fixtures) { - const [poly, pt] = geojson.features; - const results = polygonTangents(pt, poly); - results.features = results.features.concat(geojson.features); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEqual(load.sync(directories.out + filename), results, name); - } - t.end(); -}); - -test('turf-polygon-tangents - Geometry Objects', t => { - const pt = point([61, 5]); - const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); - t.assert(polygonTangents(pt.geometry, poly.geometry)); - t.end(); -}); - -test('turf-polygon-tangents - Prevent Input Mutation', t => { - const pt = point([61, 5]); - const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); - const beforePoly = JSON.parse(JSON.stringify(poly)); - const beforePt = JSON.parse(JSON.stringify(pt)); - polygonTangents(pt.geometry, poly.geometry); - t.deepEqual(poly, beforePoly, 'pt should not mutate'); - t.deepEqual(pt, beforePt, 'poly should not mutate'); - t.end(); -}); - -test('turf-polygon-tangents - Issue #1050', t => { - const pt = [8.725,51.57]; - const poly = polygon([[ - [8.788482103824089,51.56063487730164], - [8.788583,51.561554],[8.78839,51.562241], - [8.78705,51.563616],[8.785483,51.564445], - [8.785481,51.564446],[8.785479,51.564447], - [8.785479,51.564449],[8.785478,51.56445], - [8.785478,51.564452],[8.785479,51.564454], - [8.78548,51.564455],[8.785482,51.564457], - [8.786358,51.565053],[8.787022,51.565767], - [8.787024,51.565768],[8.787026,51.565769], - [8.787028,51.56577],[8.787031,51.565771], - [8.787033,51.565771],[8.789951649580397,51.56585502173034], - [8.789734,51.563604],[8.788482103824089,51.56063487730164] - ]]); - try { - t.assert(polygonTangents(pt, poly)); - } catch (e) { - t.skip('issue #1050 failed') - } - t.end(); -}) diff --git a/packages/turf-polygon-tangents/types.ts b/packages/turf-polygon-tangents/types.ts deleted file mode 100644 index 5a6b32d44a..0000000000 --- a/packages/turf-polygon-tangents/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { polygon, point } from '@turf/helpers' -import tangents from './' - -const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]) -const pt = point([61, 5]) -tangents(pt, poly) diff --git a/packages/turf-polygon-to-line/.gitignore b/packages/turf-polygon-to-line/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-polygon-to-line/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-polygon-to-line/LICENSE b/packages/turf-polygon-to-line/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-polygon-to-line/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-polygon-to-line/README.md b/packages/turf-polygon-to-line/README.md deleted file mode 100644 index 01236454d1..0000000000 --- a/packages/turf-polygon-to-line/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# @turf/polygon-to-line - - - -## polygonToLine - -Converts a [Polygon][1] to [(Multi)LineString][2] or [MultiPolygon][3] to a [FeatureCollection][4] of [(Multi)LineString][2]. - -**Parameters** - -- `poly` **[Feature][5]<([Polygon][6] \| [MultiPolygon][7])>** Feature to convert -- `options` **[Object][8]** Optional parameters (optional, default `{}`) - - `options.properties` **[Object][8]** translates GeoJSON properties to Feature (optional, default `{}`) - -**Examples** - -```javascript -var poly = turf.polygon([[[125, -30], [145, -30], [145, -20], [125, -20], [125, -30]]]); - -var line = turf.polygonToLine(poly); - -//addToMap -var addToMap = [line]; -``` - -Returns **([FeatureCollection][9] \| [Feature][5]<([LineString][10] | MultiLinestring)>)** converted (Multi)Polygon to (Multi)LineString - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[9]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[10]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/polygon-to-line -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-polygon-to-line/index.d.ts b/packages/turf-polygon-to-line/index.d.ts deleted file mode 100644 index 039ede7ec0..0000000000 --- a/packages/turf-polygon-to-line/index.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Feature, FeatureCollection, LineString, MultiLineString, MultiPolygon, Polygon, Properties } from "@turf/helpers"; -/** - * Converts a {@link Polygon} to {@link LineString|(Multi)LineString} or {@link MultiPolygon} to a - * {@link FeatureCollection} of {@link LineString|(Multi)LineString}. - * - * @name polygonToLine - * @param {Feature} poly Feature to convert - * @param {Object} [options={}] Optional parameters - * @param {Object} [options.properties={}] translates GeoJSON properties to Feature - * @returns {FeatureCollection|Feature} converted (Multi)Polygon to (Multi)LineString - * @example - * var poly = turf.polygon([[[125, -30], [145, -30], [145, -20], [125, -20], [125, -30]]]); - * - * var line = turf.polygonToLine(poly); - * - * //addToMap - * var addToMap = [line]; - */ -export default function (poly: Feature | G, options?: { - properties?: any; -}): Feature | FeatureCollection; -/** - * @private - */ -export declare function polygonToLine(poly: Feature | G, options?: { - properties?: any; -}): Feature; -/** - * @private - */ -export declare function multiPolygonToLine(multiPoly: Feature | G, options?: { - properties?: P; -}): FeatureCollection; -/** - * @private - */ -export declare function coordsToLine

(coords: number[][][], properties: P): Feature; diff --git a/packages/turf-polygon-to-line/index.ts b/packages/turf-polygon-to-line/index.ts deleted file mode 100644 index fe519070a8..0000000000 --- a/packages/turf-polygon-to-line/index.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { featureCollection, lineString, multiLineString } from "@turf/helpers"; -import { - Feature, FeatureCollection, LineString, MultiLineString, MultiPolygon, Polygon, Properties, -} from "@turf/helpers"; -import { getCoords, getGeom } from "@turf/invariant"; - -/** - * Converts a {@link Polygon} to {@link LineString|(Multi)LineString} or {@link MultiPolygon} to a - * {@link FeatureCollection} of {@link LineString|(Multi)LineString}. - * - * @name polygonToLine - * @param {Feature} poly Feature to convert - * @param {Object} [options={}] Optional parameters - * @param {Object} [options.properties={}] translates GeoJSON properties to Feature - * @returns {FeatureCollection|Feature} converted (Multi)Polygon to (Multi)LineString - * @example - * var poly = turf.polygon([[[125, -30], [145, -30], [145, -20], [125, -20], [125, -30]]]); - * - * var line = turf.polygonToLine(poly); - * - * //addToMap - * var addToMap = [line]; - */ -export default function ( - poly: Feature | G, - options: { properties?: any } = {}, -): Feature | FeatureCollection { - const geom: any = getGeom(poly); - if (!options.properties && poly.type === "Feature") { options.properties = poly.properties; } - switch (geom.type) { - case "Polygon": return polygonToLine(geom, options); - case "MultiPolygon": return multiPolygonToLine(geom, options); - default: throw new Error("invalid poly"); - } -} - -/** - * @private - */ -export function polygonToLine( - poly: Feature | G, - options: { properties?: any } = {}, -): Feature { - const geom = getGeom(poly); - const type = geom.type; - const coords: any[] = geom.coordinates; - const properties: any = options.properties ? options.properties : poly.type === "Feature" ? poly.properties : {}; - - return coordsToLine(coords, properties); -} - -/** - * @private - */ -export function multiPolygonToLine( - multiPoly: Feature | G, - options: { properties?: P } = {}, -): FeatureCollection { - const geom = getGeom(multiPoly); - const type = geom.type; - const coords: any[] = geom.coordinates; - const properties: any = options.properties ? options.properties : - multiPoly.type === "Feature" ? multiPoly.properties : {}; - - const lines: Array> = []; - coords.forEach((coord) => { - lines.push(coordsToLine(coord, properties)); - }); - return featureCollection(lines); -} - -/** - * @private - */ -export function coordsToLine

( - coords: number[][][], - properties: P, -): Feature { - if (coords.length > 1) { return multiLineString(coords, properties); } - return lineString(coords[0], properties); -} diff --git a/packages/turf-polygon-to-line/package.json b/packages/turf-polygon-to-line/package.json deleted file mode 100644 index aa01d6da74..0000000000 --- a/packages/turf-polygon-to-line/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "@turf/polygon-to-line", - "version": "6.0.3", - "description": "turf polygon-to-line module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis", - "line", - "linestring", - "polygon" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "load-json-file": "*", - "tape": "*", - "typescript": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-polygon-to-line/test.js b/packages/turf-polygon-to-line/test.js deleted file mode 100644 index 023937a475..0000000000 --- a/packages/turf-polygon-to-line/test.js +++ /dev/null @@ -1,36 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { point } = require('@turf/helpers'); -const { polygon } = require('@turf/helpers'); -const polygonToLine = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-polygon-to-linestring', t => { - for (const {name, filename, geojson} of fixtures) { - const results = polygonToLine(geojson); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEqual(load.sync(directories.out + filename), results, name); - } - // Handle Errors - t.throws(() => polygonToLine(point([10, 5])), 'throws - invalid geometry'); - t.throws(() => polygonToLine(polygon([])), 'throws - empty coordinates'); - t.end(); -}); - - diff --git a/packages/turf-polygon-to-line/tsconfig.json b/packages/turf-polygon-to-line/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-polygon-to-line/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-polygon-to-line/tslint.json b/packages/turf-polygon-to-line/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-polygon-to-line/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-polygonize/LICENSE b/packages/turf-polygonize/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-polygonize/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-polygonize/README.md b/packages/turf-polygonize/README.md deleted file mode 100644 index fdf8d2ed19..0000000000 --- a/packages/turf-polygonize/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# @turf/polygonize - - - -## polygonize - -Polygonizes [(Multi)LineString(s)][1] into [Polygons][2]. - -Implementation of GEOSPolygonize function (`geos::operation::polygonize::Polygonizer`). - -Polygonizes a set of lines that represents edges in a planar graph. Edges must be correctly -noded, i.e., they must only meet at their endpoints. - -The implementation correctly handles: - -- Dangles: edges which have one or both ends which are not incident on another edge endpoint. -- Cut Edges (bridges): edges that are connected at both ends but which do not form part of a polygon. - -**Parameters** - -- `geoJson` **([FeatureCollection][3] \| [Geometry][4] \| [Feature][5]<([LineString][6] \| [MultiLineString][7])>)** Lines in order to polygonize - - -- Throws **[Error][8]** if geoJson is invalid. - -Returns **[FeatureCollection][3]<[Polygon][9]>** Polygons created - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.5 - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error - -[9]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/polygonize -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-polygonize/index.d.ts b/packages/turf-polygonize/index.d.ts deleted file mode 100644 index 81bc7546d7..0000000000 --- a/packages/turf-polygonize/index.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Feature, FeatureCollection, Coord, Polygon, LineString, MultiLineString } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#polygonize - */ -export default function ( - geojson: Feature | FeatureCollection | T -): FeatureCollection; diff --git a/packages/turf-polygonize/package.json b/packages/turf-polygonize/package.json deleted file mode 100644 index 5c9bc9ea26..0000000000 --- a/packages/turf-polygonize/package.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "@turf/polygonize", - "version": "5.1.5", - "description": "turf polygonize module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "lib", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "gis", - "polygonize" - ], - "author": "Turf Authors", - "contributors": [ - "Nicolas Cisco <@nickcis>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/boolean-point-in-polygon": "6.x", - "@turf/envelope": "^5.1.5", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-polygonize/test.js b/packages/turf-polygonize/test.js deleted file mode 100644 index 768d51c457..0000000000 --- a/packages/turf-polygonize/test.js +++ /dev/null @@ -1,70 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import { featureEach } from '@turf/meta'; -import { featureCollection, lineString } from '@turf/helpers'; -import polygonize from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-polygonize', t => { - for (const {filename, name, geojson} of fixtures) { - const polygonized = polygonize(geojson); - - const results = featureCollection([]); - featureEach(geojson, feature => results.features.push(colorize(feature))); - featureEach(polygonized, feature => results.features.push(colorize(feature, '#00F', 3))); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEquals(results, load.sync(directories.out + filename), name); - } - t.end(); -}); - -test('turf-polygonize -- Geometry Support', t => { - const line = lineString([[0, 0], [1, 1], [5, 2], [0, 0]]); - - t.assert(polygonize(line.geometry), 'line geometry'); - t.end(); -}); - -test('turf-polygonize -- throws', t => { - // const line = lineString([[0, 0], [1, 1]]); - - // t.throws(() => polygonize(line)); - t.end(); -}); - -test('turf-polygonize -- input mutation', t => { - const lines = featureCollection([ - lineString([[0, 0], [1, 1]]), - lineString([[1, 1], [-1, -1]]), - lineString([[-1, -1], [0, 0]]) - ]); - const linesBefore = JSON.parse(JSON.stringify(lines)); - polygonize(lines); - - t.deepEquals(lines, linesBefore, 'input does not mutate'); - t.end(); -}); - -function colorize(feature, color = '#F00', width = 6) { - feature.properties['fill'] = color; - feature.properties['fill-opacity'] = 0.3; - feature.properties['stroke'] = color; - feature.properties['stroke-width'] = width; - return feature; -} diff --git a/packages/turf-polygonize/types.ts b/packages/turf-polygonize/types.ts deleted file mode 100644 index aa1ad1658a..0000000000 --- a/packages/turf-polygonize/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { lineString } from '@turf/helpers' -import polygonize from './' - -const line = lineString([[10, 10], [0, 0], [3, -5], [10, 10]]) -polygonize(line) diff --git a/packages/turf-projection/.gitignore b/packages/turf-projection/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-projection/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-projection/LICENSE b/packages/turf-projection/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-projection/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-projection/README.md b/packages/turf-projection/README.md deleted file mode 100644 index 68dc611851..0000000000 --- a/packages/turf-projection/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# @turf/projection - - - -## toMercator - -Converts a WGS84 GeoJSON object into Mercator (EPSG:900913) projection - -**Parameters** - -- `geojson` **([GeoJSON][1] | Position)** WGS84 GeoJSON object -- `options` **[Object][2]?** Optional parameters - - `options.mutate` **[boolean][3]** allows GeoJSON input to be mutated (significant performance increase if true) (optional, default `false`) - -**Examples** - -```javascript -var pt = turf.point([-71,41]); -var converted = turf.toMercator(pt); - -//addToMap -var addToMap = [pt, converted]; -``` - -Returns **[GeoJSON][1]** Projected GeoJSON - -## toWgs84 - -Converts a Mercator (EPSG:900913) GeoJSON object into WGS84 projection - -**Parameters** - -- `geojson` **([GeoJSON][1] | Position)** Mercator GeoJSON object -- `options` **[Object][2]?** Optional parameters - - `options.mutate` **[boolean][3]** allows GeoJSON input to be mutated (significant performance increase if true) (optional, default `false`) - -**Examples** - -```javascript -var pt = turf.point([-7903683.846322424, 5012341.663847514]); -var converted = turf.toWgs84(pt); - -//addToMap -var addToMap = [pt, converted]; -``` - -Returns **[GeoJSON][1]** Projected GeoJSON - -[1]: https://tools.ietf.org/html/rfc7946#section-3 - -[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/projection -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-projection/index.ts b/packages/turf-projection/index.ts deleted file mode 100644 index 0599ce724d..0000000000 --- a/packages/turf-projection/index.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { coordEach } from '@turf/meta'; -import { AllGeoJSON, Position, isNumber } from '@turf/helpers'; -import clone from '@turf/clone'; - -/** - * Converts a WGS84 GeoJSON object into Mercator (EPSG:900913) projection - * - * @name toMercator - * @param {GeoJSON|Position} geojson WGS84 GeoJSON object - * @param {Object} [options] Optional parameters - * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) - * @returns {GeoJSON} Projected GeoJSON - * @example - * var pt = turf.point([-71,41]); - * var converted = turf.toMercator(pt); - * - * //addToMap - * var addToMap = [pt, converted]; - */ -export function toMercator(geojson: G, options: {mutate?: boolean} = {}): G { - return convert(geojson, 'mercator', options); -} - -/** - * Converts a Mercator (EPSG:900913) GeoJSON object into WGS84 projection - * - * @name toWgs84 - * @param {GeoJSON|Position} geojson Mercator GeoJSON object - * @param {Object} [options] Optional parameters - * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) - * @returns {GeoJSON} Projected GeoJSON - * @example - * var pt = turf.point([-7903683.846322424, 5012341.663847514]); - * var converted = turf.toWgs84(pt); - * - * //addToMap - * var addToMap = [pt, converted]; - */ -export function toWgs84(geojson: G, options: {mutate?: boolean} = {}): G { - return convert(geojson, 'wgs84', options); -} - - -/** - * Converts a GeoJSON coordinates to the defined `projection` - * - * @private - * @param {GeoJSON} geojson GeoJSON Feature or Geometry - * @param {string} projection defines the projection system to convert the coordinates to - * @param {Object} [options] Optional parameters - * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) - * @returns {GeoJSON} Converted GeoJSON - */ -function convert(geojson: any, projection: string, options: {mutate?: boolean} = {}): any { - // Optional parameters - options = options || {}; - var mutate = options.mutate; - - // Validation - if (!geojson) throw new Error('geojson is required'); - - // Handle Position - if (Array.isArray(geojson) && isNumber(geojson[0])) geojson = (projection === 'mercator') ? convertToMercator(geojson) : convertToWgs84(geojson); - - // Handle GeoJSON - else { - // Handle possible data mutation - if (mutate !== true) geojson = clone(geojson); - - coordEach(geojson, function (coord) { - var newCoord = (projection === 'mercator') ? convertToMercator(coord) : convertToWgs84(coord); - coord[0] = newCoord[0]; - coord[1] = newCoord[1]; - }); - } - return geojson; -} - -/** - * Convert lon/lat values to 900913 x/y. - * (from https://github.com/mapbox/sphericalmercator) - * - * @private - * @param {Array} lonLat WGS84 point - * @returns {Array} Mercator [x, y] point - */ -function convertToMercator(lonLat) { - var D2R = Math.PI / 180, - // 900913 properties - A = 6378137.0, - MAXEXTENT = 20037508.342789244; - - // compensate longitudes passing the 180th meridian - // from https://github.com/proj4js/proj4js/blob/master/lib/common/adjust_lon.js - var adjusted = (Math.abs(lonLat[0]) <= 180) ? lonLat[0] : (lonLat[0] - (sign(lonLat[0]) * 360)); - var xy = [ - A * adjusted * D2R, - A * Math.log(Math.tan((Math.PI * 0.25) + (0.5 * lonLat[1] * D2R))) - ]; - - // if xy value is beyond maxextent (e.g. poles), return maxextent - if (xy[0] > MAXEXTENT) xy[0] = MAXEXTENT; - if (xy[0] < -MAXEXTENT) xy[0] = -MAXEXTENT; - if (xy[1] > MAXEXTENT) xy[1] = MAXEXTENT; - if (xy[1] < -MAXEXTENT) xy[1] = -MAXEXTENT; - - return xy; -} - -/** - * Convert 900913 x/y values to lon/lat. - * (from https://github.com/mapbox/sphericalmercator) - * - * @private - * @param {Array} xy Mercator [x, y] point - * @returns {Array} WGS84 [lon, lat] point - */ -function convertToWgs84(xy) { - // 900913 properties. - var R2D = 180 / Math.PI; - var A = 6378137.0; - - return [ - (xy[0] * R2D / A), - ((Math.PI * 0.5) - 2.0 * Math.atan(Math.exp(-xy[1] / A))) * R2D - ]; -} - -/** - * Returns the sign of the input, or zero - * - * @private - * @param {number} x input - * @returns {number} -1|0|1 output - */ -function sign(x) { - return (x < 0) ? -1 : (x > 0) ? 1 : 0; -} diff --git a/packages/turf-projection/package.json b/packages/turf-projection/package.json deleted file mode 100644 index c8f2952a9a..0000000000 --- a/packages/turf-projection/package.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "@turf/projection", - "version": "6.0.1", - "description": "turf projection module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "projection", - "to-mercator", - "to-wgs84", - "EPSG:4326", - "WGS84", - "mercator", - "web-mercator", - "EPSG:3857", - "EPSG:3785", - "900913", - "EPSG:900913", - "EPSG:102113" - ], - "author": "Turf Authors", - "contributors": [ - "Stefano Borghi <@stebogit>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/truncate": "*", - "benchmark": "*", - "load-json-file": "*", - "proj4": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/clone": "6.x", - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-projection/test.js b/packages/turf-projection/test.js deleted file mode 100644 index cfcaad0c9d..0000000000 --- a/packages/turf-projection/test.js +++ /dev/null @@ -1,106 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const proj4 = require('proj4'); -const write = require('write-json-file'); -const clone = require('@turf/clone').default; -const { point } = require('@turf/helpers'); -const truncate = require('@turf/truncate').default; -const { coordEach } = require('@turf/meta'); -const { toMercator, toWgs84 } = require('.'); - -const directories = { - mercator: path.join(__dirname, 'test', 'mercator') + path.sep, - wgs84: path.join(__dirname, 'test', 'wgs84') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fromWgs84 = fs.readdirSync(directories.wgs84).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: truncate(load.sync(directories.wgs84 + filename)) - }; -}); - -test('to-mercator', t => { - for (const {filename, name, geojson} of fromWgs84) { - var expected = clone(geojson); - coordEach(expected, function (coord) { - var newCoord = proj4('WGS84', 'EPSG:900913', coord); - coord[0] = newCoord[0]; - coord[1] = newCoord[1]; - }); - const results = truncate(toMercator(geojson)); - - if (process.env.REGEN) write.sync(directories.out + 'mercator-' + filename, results); - t.deepEqual(results, truncate(expected), name); - t.deepEqual(results, load.sync(directories.out + 'mercator-' + filename)); - } - t.end(); -}); - -const fromMercator = fs.readdirSync(directories.mercator).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: truncate(load.sync(directories.mercator + filename)) - }; -}); - -test('to-wgs84', t => { - for (const {filename, name, geojson} of fromMercator) { - var expected = clone(geojson); - coordEach(expected, function (coord) { - var newCoord = proj4('EPSG:900913', 'WGS84', coord); - coord[0] = newCoord[0]; - coord[1] = newCoord[1]; - }); - const results = truncate(toWgs84(geojson)); - - if (process.env.REGEN) write.sync(directories.out + 'wgs84-' + filename, results); - t.deepEqual(results, truncate(expected), name); - t.deepEqual(results, load.sync(directories.out + 'wgs84-' + filename)); - } - t.end(); -}); - - - -test('projection -- throws', t => { - t.throws(() => toMercator(null), /geojson is required/, 'throws missing geojson'); - t.throws(() => toWgs84(null), /geojson is required/, 'throws missing geojson'); - t.end(); -}); - -test('projection -- verify mutation', t => { - const pt1 = point([10, 10]); - const pt2 = point([15, 15]); - const pt1Before = clone(pt1); - const pt2Before = clone(pt2); - - toMercator(pt1); - toMercator(pt1, {mutate: false}); - t.deepEqual(pt1, pt1Before, 'mutate = undefined - input should NOT be mutated'); - t.deepEqual(pt1, pt1Before, 'mutate = false - input should NOT be mutated'); - toMercator(pt1, {mutate: true}); - t.notEqual(pt1, pt1Before, 'input should be mutated'); - - toWgs84(pt2); - toWgs84(pt2, {mutate: false}); - t.deepEqual(pt2, pt2Before, 'mutate = undefined - input should NOT be mutated'); - t.deepEqual(pt2, pt2Before, 'mutate = false - input should NOT be mutated'); - toWgs84(pt2, {mutate: true}); - t.notEqual(pt2, pt2Before, 'input should be mutated'); - - t.end(); -}); - -test('projection -- handle Position', t => { - const coord = [10, 40]; - const mercator = toMercator(coord); - const wgs84 = toWgs84(mercator); - t.deepEqual(coord, wgs84, 'coord equal same as wgs84'); - t.end(); -}); \ No newline at end of file diff --git a/packages/turf-projection/types.ts b/packages/turf-projection/types.ts deleted file mode 100644 index fcfaa5e950..0000000000 --- a/packages/turf-projection/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -import * as projection from './' -import { toMercator, toWgs84 } from './' -import { point } from '@turf/helpers' - -// Types test -const pt = point([3, 51]) -const projected = toMercator(pt) -const degrees = toWgs84(projected) - -// default import -projection.toMercator(pt) -projection.toWgs84(projected) diff --git a/packages/turf-quadrat-analysis/.gitignore b/packages/turf-quadrat-analysis/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-quadrat-analysis/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-quadrat-analysis/LICENSE b/packages/turf-quadrat-analysis/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-quadrat-analysis/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-quadrat-analysis/README.md b/packages/turf-quadrat-analysis/README.md deleted file mode 100644 index 9cf4b5595a..0000000000 --- a/packages/turf-quadrat-analysis/README.md +++ /dev/null @@ -1,96 +0,0 @@ -# @turf/quadrat-analysis - - - -## quadratAnalysis - -Quadrat analysis lays a set of equal-size areas(quadrat) over the study area and counts -the number of features in each quadrat and creates a frequency table. -The table lists the number of quadrats containing no features, the number containing one feature, two features, and so on, -all the way up to the quadrat containing the most features. -The method then creates the frequency table for the random distribution, usually based on a Poisson distribution. -The method uses the distribution to calculate the probability for 0 feature occuring, 1 feature occuring, 2 features, and so on, -and lists these probabilities in the frequency table. -By comparing the two frequency tables, you can see whether the features create a pattern. -If the table for the observed distribution has more quadrats containing many features than the table for the random distribution dose, -then the features create a clustered pattern. - -It is hard to judge the frequency tables are similar or different just by looking at them. -So, we can use serval statistical tests to find out how much the frequency tables differ. -We use Kolmogorov-Smirnov test.This method calculates cumulative probabilities for both distributions, -and then compares the cumulative probabilities at each class level and selects the largest absolute difference D. -Then, the test compares D to the critical value for a confidence level you specify. -If D is greater than the critical value, the difference between the observed distribution and the random distribution is significant. -The greater the value the bigger the difference. - -Traditionally, squares are used for the shape of the quadrats, in a regular grid(square-grid). -Some researchers suggest that the quadrat size equal twice the size of mean area per feature, -which is simply the area of the study area divided by the number of features. - -**Parameters** - -- `pointFeatureSet` **[FeatureCollection](https://tools.ietf.org/html/rfc7946#section-3.3)<[Point](https://tools.ietf.org/html/rfc7946#section-3.1.2)>** point set to study -- `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** optional parameters (optional, default `{}`) - - `options.studyBbox` **bbox?** bbox representing the study area - - `options.confidenceLevel` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** a confidence level .The unit is percentage . 5 means 95% ,value must be in [K_TABLE](#k_table) (optional, default `20`) - -**Examples** - -```javascript -var bbox = [-65, 40, -63, 42]; -var dataset = turf.randomPoint(100, { bbox: bbox }); -var result = turf.quadratAnalysis(dataset); -``` - -Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** result [QuadratAnalysisResult](#quadratanalysisresult) - -## K_TABLE - -the confidence level - -**Properties** - -- `20` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** -- `15` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** -- `10` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** -- `5` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** -- `2` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** -- `1` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** - -## QuadratAnalysisResult - -the return type of the quadratAnalysis - -Type: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) - -**Properties** - -- `criticalValue` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** -- `maxAbsoluteDifference` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** -- `isRandom` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `observedDistribution` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)>** the cumulative distribution of observed features, the index represents the number of features in the quadrat. - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/quadrat-analysis -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-quadrat-analysis/bench.js b/packages/turf-quadrat-analysis/bench.js deleted file mode 100644 index 06034fe56f..0000000000 --- a/packages/turf-quadrat-analysis/bench.js +++ /dev/null @@ -1,47 +0,0 @@ -const glob = require('glob'); -const path = require('path'); -const load = require('load-json-file'); -const Benchmark = require('benchmark'); -const { randomPoint } = require('@turf/random'); -const bbox = require('@turf/bbox').default; -const nearestNeighborAnalysis = require('@turf/nearest-neighbor-analysis').default; -const quadratAnalysis = require('.').default; - -/** - * Benchmark Results - * quadrat: 1383.768ms - * nearest: 12259.498ms - * quadrat x 0.76 ops/sec ±1.24% (6 runs sampled) - * nearest x 0.08 ops/sec ±0.97% (5 runs sampled) - */ -const suite = new Benchmark.Suite('turf-quadrat-analysis'); - - -const smallBbox = [-10, -10, 10, 10]; -const dataset = randomPoint(10000, { bbox: smallBbox }); - - -var nameQ = 'quadrat'; -var nameN = 'nearest' -console.time(nameQ); -quadratAnalysis(dataset, { - studyBbox: smallBbox, - confidenceLevel: 20 -}); -console.timeEnd(nameQ); - -console.time(nameN); -nearestNeighborAnalysis(dataset); -console.timeEnd(nameN); - -suite.add(nameQ, () => quadratAnalysis(dataset, { - studyBbox: smallBbox, - confidenceLevel: 20 -})); -suite.add(nameN, () => nearestNeighborAnalysis(dataset)); - - -suite - .on('cycle', e => console.log(String(e.target))) - .on('complete', () => { }) - .run(); diff --git a/packages/turf-quadrat-analysis/index.d.ts b/packages/turf-quadrat-analysis/index.d.ts deleted file mode 100644 index 1f756f0a6b..0000000000 --- a/packages/turf-quadrat-analysis/index.d.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { FeatureCollection, Point } from "@turf/helpers"; -export interface QuadratAnalysisResult { - criticalValue: number; - maxAbsoluteDifference: number; - isRandom: boolean; - observedDistribution: number[]; -} -/** - * Quadrat analysis lays a set of equal-size areas(quadrat) over the study area and counts - * the number of features in each quadrat and creates a frequency table. - * The table lists the number of quadrats containing no features, - * the number containing one feature, two features, and so on, - * all the way up to the quadrat containing the most features. - * The method then creates the frequency table for the random distribution, usually based on a Poisson distribution. - * The method uses the distribution to calculate the probability for 0 feature occuring, - * 1 feature occuring, 2 features, and so on, - * and lists these probabilities in the frequency table. - * By comparing the two frequency tables, you can see whether the features create a pattern. - * If the table for the observed distribution has more quadrats containing many features than the - * table for the random distribution dose, then the features create a clustered pattern. - * - * It is hard to judge the frequency tables are similar or different just by looking at them. - * So, we can use serval statistical tests to find out how much the frequency tables differ. - * We use Kolmogorov-Smirnov test.This method calculates cumulative probabilities for both distributions, - * and then compares the cumulative probabilities at each class level and selects the largest absolute difference D. - * Then, the test compares D to the critical value for a confidence level you specify. - * If D is greater than the critical value, the difference between the observed distribution and - * the random distribution is significant. The greater the value the bigger the difference. - * - * Traditionally, squares are used for the shape of the quadrats, in a regular grid(square-grid). - * Some researchers suggest that the quadrat size equal twice the size of mean area per feature, - * which is simply the area of the study area divided by the number of features. - * - * - * @name quadratAnalysis - * @param {FeatureCollection} pointFeatureSet point set to study - * @param {Object} [options={}] optional parameters - * @param {bbox} [options.studyBbox] bbox representing the study area - * @param {number} [options.confidenceLevel=20] a confidence level. - * The unit is percentage . 5 means 95%, value must be in {@link K_TABLE} - * @returns {Object} result {@link QuadratAnalysisResult} - * @example - * - * var bbox = [-65, 40, -63, 42]; - * var dataset = turf.randomPoint(100, { bbox: bbox }); - * var result = turf.quadratAnalysis(dataset); - * - */ -export default function quadratAnalysis(pointFeatureSet: FeatureCollection, options: { - studyBbox?: [number, number, number, number]; - confidenceLevel?: 20 | 15 | 10 | 5 | 2 | 1; -}): QuadratAnalysisResult; diff --git a/packages/turf-quadrat-analysis/index.ts b/packages/turf-quadrat-analysis/index.ts deleted file mode 100644 index 4f7e797140..0000000000 --- a/packages/turf-quadrat-analysis/index.ts +++ /dev/null @@ -1,217 +0,0 @@ -import area from "@turf/area"; -import turfBBox from "@turf/bbox"; -import bboxPolygon from "@turf/bbox-polygon"; -import { round } from "@turf/helpers"; -import { BBox, Feature, FeatureCollection, GeometryObject, Point } from "@turf/helpers"; -import { getCoord } from "@turf/invariant"; -import squareGrid from "@turf/square-grid"; - -export interface QuadratAnalysisResult { - criticalValue: number; - maxAbsoluteDifference: number; - isRandom: boolean; - observedDistribution: number[]; -} - -/** - * Quadrat analysis lays a set of equal-size areas(quadrat) over the study area and counts - * the number of features in each quadrat and creates a frequency table. - * The table lists the number of quadrats containing no features, - * the number containing one feature, two features, and so on, - * all the way up to the quadrat containing the most features. - * The method then creates the frequency table for the random distribution, usually based on a Poisson distribution. - * The method uses the distribution to calculate the probability for 0 feature occuring, - * 1 feature occuring, 2 features, and so on, - * and lists these probabilities in the frequency table. - * By comparing the two frequency tables, you can see whether the features create a pattern. - * If the table for the observed distribution has more quadrats containing many features than the - * table for the random distribution dose, then the features create a clustered pattern. - * - * It is hard to judge the frequency tables are similar or different just by looking at them. - * So, we can use serval statistical tests to find out how much the frequency tables differ. - * We use Kolmogorov-Smirnov test.This method calculates cumulative probabilities for both distributions, - * and then compares the cumulative probabilities at each class level and selects the largest absolute difference D. - * Then, the test compares D to the critical value for a confidence level you specify. - * If D is greater than the critical value, the difference between the observed distribution and - * the random distribution is significant. The greater the value the bigger the difference. - * - * Traditionally, squares are used for the shape of the quadrats, in a regular grid(square-grid). - * Some researchers suggest that the quadrat size equal twice the size of mean area per feature, - * which is simply the area of the study area divided by the number of features. - * - * - * @name quadratAnalysis - * @param {FeatureCollection} pointFeatureSet point set to study - * @param {Object} [options={}] optional parameters - * @param {bbox} [options.studyBbox] bbox representing the study area - * @param {number} [options.confidenceLevel=20] a confidence level. - * The unit is percentage . 5 means 95%, value must be in {@link K_TABLE} - * @returns {Object} result {@link QuadratAnalysisResult} - * @example - * - * var bbox = [-65, 40, -63, 42]; - * var dataset = turf.randomPoint(100, { bbox: bbox }); - * var result = turf.quadratAnalysis(dataset); - * - */ -export default function quadratAnalysis(pointFeatureSet: FeatureCollection, options: { - studyBbox?: [number, number, number, number] - confidenceLevel?: 20 | 15 | 10 | 5 | 2 | 1, -}): QuadratAnalysisResult { - - options = options || {}; - const studyBbox = options.studyBbox || turfBBox(pointFeatureSet); - const confidenceLevel = options.confidenceLevel || 20; - const points = pointFeatureSet.features; - - // create square-grid - const numOfPoints = points.length; - const sizeOfArea = area(bboxPolygon(studyBbox)); - const lengthOfSide = Math.sqrt((sizeOfArea / numOfPoints) * 2); - const grid = squareGrid(studyBbox, lengthOfSide, { - units: "meters", - }); - const quadrats = grid.features; - - // count the number of features in each quadrat - const quadratIdDict: {[key: string]: {box: BBox, cnt: number}} = {}; - for (let i = 0; i < quadrats.length; i++) { - quadratIdDict[i] = { - box: turfBBox(quadrats[i]), - cnt: 0, - }; - } - - let sumOfPoint = 0; - for (const pt of points) { - for (const key of Object.keys(quadratIdDict)) { - const box = quadratIdDict[key].box; - if (inBBox(getCoord(pt), box)) { - quadratIdDict[key].cnt += 1; - sumOfPoint += 1; - break; - } - } - } - - // the most amount of features in quadrat - let maxCnt = 0; - for (const key of Object.keys(quadratIdDict)) { - const cnt = quadratIdDict[key].cnt; - if (cnt > maxCnt) { - maxCnt = cnt; - } - } - - const expectedDistribution = []; - const numOfQuadrat = Object.keys(quadratIdDict).length; - const lambda = sumOfPoint / numOfQuadrat; - - // get the cumulative probability of the random distribution - let cumulativeProbility = 0.0; - for (let x = 0; x < maxCnt + 1; x++) { - cumulativeProbility += Math.exp(-lambda) * Math.pow(lambda, x) / factorial(x); - expectedDistribution.push(cumulativeProbility); - } - - // get the cumulative probability of the observed distribution - const observedDistribution = []; - let cumulativeObservedQuads = 0; - for (let x = 0; x < maxCnt + 1; x++) { - for (const key of Object.keys(quadratIdDict)) { - if (quadratIdDict[key].cnt === x) { - cumulativeObservedQuads += 1; - } - } - const p = cumulativeObservedQuads / numOfQuadrat; - observedDistribution.push(p); - } - - // get the largest absolute difference between two distributions - let maxDifference = 0; - for (let x = 0; x < maxCnt + 1; x++) { - const difference = Math.abs(expectedDistribution[x] - observedDistribution[x]); - if (difference > maxDifference) { - maxDifference = difference; - } - } - - const k = K_TABLE[confidenceLevel]; - - // statistical test - const criticalValue = k / Math.sqrt(numOfQuadrat); - const result: QuadratAnalysisResult = { - criticalValue, - isRandom: true, - maxAbsoluteDifference: maxDifference, - observedDistribution, - }; - - if (maxDifference > criticalValue) { result.isRandom = false; } - - return result; -} - -/** - * the confidence level - * @type {Object} K_TABLE - * @property {number} 20 - * @property {number} 15 - * @property {number} 10 - * @property {number} 5 - * @property {number} 2 - * @property {number} 1 - */ -const K_TABLE = { - 20: 1.07275, - 15: 1.13795, - 10: 1.22385, - 5: 1.35810, - 2: 1.51743, - 1: 1.62762, -}; - -/** - * the return type of the quadratAnalysis - * @typedef {Object} QuadratAnalysisResult - * @property {number} criticalValue - * @property {number} maxAbsoluteDifference - * @property {boolean} isRandom - * @property {Array.} observedDistribution the cumulative distribution of observed features, - * the index represents the number of features in the quadrat. - */ - -/** - * inBBox from @turf/boolean-point-in-polygon - * - * @private - * @param {Array} pt point [x,y] - * @param {BBox} bbox BBox [west, south, east, north] - * @returns {boolean} true/false if point is inside BBox - */ -function inBBox(pt: number[], bbox: BBox) { - return bbox[0] <= pt[0] && - bbox[1] <= pt[1] && - bbox[2] >= pt[0] && - bbox[3] >= pt[1]; -} - -/** - * https://stackoverflow.com/questions/3959211/fast-factorial-function-in-javascript - * @private - * @param {number} num Number - * @returns {number} the factorial of num - */ -function factorial(num: number) { - const f: number[] = []; - function inner(n: number): number { - if (n === 0 || n === 1) { - return 1; - } - if (f[n] > 0) { - return f[n]; - } - return f[n] = inner(n - 1) * n; - } - return inner(num); -} diff --git a/packages/turf-quadrat-analysis/package.json b/packages/turf-quadrat-analysis/package.json deleted file mode 100644 index 4b8904c034..0000000000 --- a/packages/turf-quadrat-analysis/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "@turf/quadrat-analysis", - "version": "6.0.1", - "description": "turf quadrat-analysis module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "quadrat-analysis" - ], - "author": "Turf Authors", - "contributors": [ - "Haoming Zhuang <@zhuang-hao-ming>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@types/tape": "*", - "@turf/nearest-neighbor-analysis": "*", - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tslint": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/area": "6.x", - "@turf/bbox": "6.x", - "@turf/bbox-polygon": "6.x", - "@turf/centroid": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/point-grid": "6.x", - "@turf/random": "5.x", - "@turf/square-grid": "6.x" - } -} diff --git a/packages/turf-quadrat-analysis/test.js b/packages/turf-quadrat-analysis/test.js deleted file mode 100644 index 21e681dc28..0000000000 --- a/packages/turf-quadrat-analysis/test.js +++ /dev/null @@ -1,100 +0,0 @@ -const test = require('tape'); -const glob = require('glob'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const bbox = require('@turf/bbox').default; -const centroid = require('@turf/centroid').default; -const squareGrid = require('@turf/square-grid').default; -const bboxPolygon = require('@turf/bbox-polygon').default; -const { randomPoint } = require('@turf/random'); -const { featureCollection } = require('@turf/helpers'); -const quadratAnalysis = require('./').default; - -test('turf-quadrat-analysis geojson file', t => { - const futianBboxPath = path.join(__dirname, 'test', 'in', 'futian_bbox.json'); - const futianPointPath = path.join(__dirname, 'test', 'in', 'futian_random_point.json'); - const shenzhenBboxPath = path.join(__dirname, 'test', 'in', 'shenzhen_bbox.json'); - - const futianBbox = load.sync(futianBboxPath); - const futianPoint = load.sync(futianPointPath); - const shenzhenBbox = load.sync(shenzhenBboxPath); - - const resultFutian = quadratAnalysis(futianPoint, { - studyBbox: bbox(futianBbox), - confidenceLevel: 20 - }); - - const resultShenzhen = quadratAnalysis(futianPoint, { - studyBbox: bbox(shenzhenBbox), - confidenceLevel: 20 - }); - - t.ok(resultFutian.isRandom, 'ramdom pattern ok'); - t.ok(resultFutian.maxAbsoluteDifference < resultFutian.criticalValue, 'random pattern maxAbsoluteDifference < criticalValue'); - - t.ok(!resultShenzhen.isRandom, 'cluster pattern ok'); - t.ok(resultShenzhen.maxAbsoluteDifference > resultShenzhen.criticalValue, 'cluster pattern maxAbsoluteDifference > criticalValue') - - t.end(); - -}); - -test('turf-quadrat-analysis random point', t => { - // random - const smallBbox = [-1, -1, 1, 1]; - const randomPointSet = randomPoint(400, { bbox: smallBbox }); - const result1 = quadratAnalysis(randomPointSet, { - studyBbox: smallBbox, - confidenceLevel: 20 - }); - - t.ok(result1.isRandom, 'random pattern ok'); - t.ok(result1.maxAbsoluteDifference < result1.criticalValue, 'random pattern maxAbsoluteDifference < criticalValue'); - - // cluster - const bigBbox = [-3, -3, 3, 3]; - const result2 = quadratAnalysis(randomPointSet, { - studyBbox: bigBbox, - confidenceLevel: 20 - }); - - t.ok(!result2.isRandom, 'cluster pattern ok'); - t.ok(result2.maxAbsoluteDifference > result2.criticalValue, 'cluster pattern maxAbsoluteDifference > criticalValue'); - - // uniform - const smallGrid = squareGrid(smallBbox, 0.1, { - units: 'degrees' - }) - let uniformPointSet = []; - smallGrid.features.map(function (feature) { - uniformPointSet.push(centroid(feature)); - }); - uniformPointSet = featureCollection(uniformPointSet); - const result3 = quadratAnalysis(uniformPointSet, { - studyBbox: smallBbox, - confidenceLevel: 20 - }); - - t.ok(!result3.isRandom, 'uniform pattern ok'); - t.ok(result3.maxAbsoluteDifference > result3.criticalValue, 'uniform pattern maxAbsoluteDifference > criticalValue'); - - const randomPointSetPath = path.join(__dirname, 'test', 'out', 'randomPoint.json'); - const uniformPointSetPath = path.join(__dirname, 'test', 'out', 'uniformPoint.json'); - const smallBboxPath = path.join(__dirname, 'test', 'out', 'smallBox.json'); - const bigBboxPath = path.join(__dirname, 'test', 'out', 'bigBox.json'); - const smallGridPath = path.join(__dirname, 'test', 'out', 'smallGrid.json'); - - // console.log(result1, result2, result3); - - if (process.env.REGEN) { - write.sync(randomPointSetPath, randomPointSet); - write.sync(uniformPointSetPath, uniformPointSet); - write.sync(smallBboxPath, bboxPolygon(smallBbox)); - write.sync(bigBboxPath, bboxPolygon(bigBbox)); - write.sync(smallGridPath, smallGrid); - } - - t.end(); - -}); diff --git a/packages/turf-quadrat-analysis/tsconfig.json b/packages/turf-quadrat-analysis/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-quadrat-analysis/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-quadrat-analysis/tslint.json b/packages/turf-quadrat-analysis/tslint.json deleted file mode 100644 index 9dd5998b9c..0000000000 --- a/packages/turf-quadrat-analysis/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {"interface-name": false}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-random/.gitignore b/packages/turf-random/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-random/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-random/LICENSE b/packages/turf-random/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-random/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-random/README.md b/packages/turf-random/README.md deleted file mode 100644 index a36b5dd7b4..0000000000 --- a/packages/turf-random/README.md +++ /dev/null @@ -1,129 +0,0 @@ -# @turf/random - - - -## randomPosition - -Returns a random position within a [box][1]. - -**Parameters** - -- `bbox` **[Array][2]<[number][3]>** a bounding box inside of which positions are placed. (optional, default `[-180,-90,180,90]`) - -**Examples** - -```javascript -var position = turf.randomPosition([-180, -90, 180, 90]) -// => position -``` - -Returns **[Array][2]<[number][3]>** Position [longitude, latitude] - -## randomPoint - -Returns a random [point][4]. - -**Parameters** - -- `count` **[number][3]** how many geometries will be generated (optional, default `1`) -- `options` **[Object][5]** Optional parameters (optional, default `{}`) - - `options.bbox` **[Array][2]<[number][3]>** a bounding box inside of which geometries are placed. (optional, default `[-180,-90,180,90]`) - -**Examples** - -```javascript -var points = turf.randomPoint(25, {bbox: [-180, -90, 180, 90]}) -// => points -``` - -Returns **[FeatureCollection][6]<[Point][7]>** GeoJSON FeatureCollection of points - -## randomPolygon - -Returns a random [polygon][8]. - -**Parameters** - -- `count` **[number][3]** how many geometries will be generated (optional, default `1`) -- `options` **[Object][5]** Optional parameters (optional, default `{}`) - - `options.bbox` **[Array][2]<[number][3]>** a bounding box inside of which geometries are placed. (optional, default `[-180,-90,180,90]`) - - `options.num_vertices` **[number][3]** is how many coordinates each LineString will contain. (optional, default `10`) - - `options.max_radial_length` **[number][3]** is the maximum number of decimal degrees latitude or longitude that a vertex can reach out of the center of the Polygon. (optional, default `10`) - -**Examples** - -```javascript -var polygons = turf.randomPolygon(25, {bbox: [-180, -90, 180, 90]}) -// => polygons -``` - -Returns **[FeatureCollection][6]<[Polygon][9]>** GeoJSON FeatureCollection of polygons - -## randomLineString - -Returns a random [linestring][10]. - -**Parameters** - -- `count` **[number][3]** how many geometries will be generated (optional, default `1`) -- `options` **[Object][5]** Optional parameters (optional, default `{}`) - - `options.bbox` **[Array][2]<[number][3]>** a bounding box inside of which geometries are placed. (optional, default `[-180,-90,180,90]`) - - `options.num_vertices` **[number][3]** is how many coordinates each LineString will contain. (optional, default `10`) - - `options.max_length` **[number][3]** is the maximum number of decimal degrees that a vertex can be from its predecessor (optional, default `0.0001`) - - `options.max_rotation` **[number][3]** is the maximum number of radians that a line segment can turn from the previous segment. (optional, default `Math.PI/8`) - -**Examples** - -```javascript -var lineStrings = turf.randomLineString(25, {bbox: [-180, -90, 180, 90]}) -// => lineStrings -``` - -Returns **[FeatureCollection][6]<[LineString][11]>** GeoJSON FeatureCollection of linestrings - -[1]: bounding - -[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[4]: point - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[6]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[8]: polygon - -[9]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[10]: linestring - -[11]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/random -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-random/index.d.ts b/packages/turf-random/index.d.ts deleted file mode 100644 index ed052ab98b..0000000000 --- a/packages/turf-random/index.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { BBox, FeatureCollection, LineString, Point, Polygon, Position } from "@turf/helpers"; -/** - * Returns a random position within a {@link bounding box}. - * - * @name randomPosition - * @param {Array} [bbox=[-180, -90, 180, 90]] a bounding box inside of which positions are placed. - * @returns {Array} Position [longitude, latitude] - * @example - * var position = turf.randomPosition([-180, -90, 180, 90]) - * // => position - */ -export declare function randomPosition(bbox?: BBox | { - bbox: BBox; -}): Position; -/** - * Returns a random {@link point}. - * - * @name randomPoint - * @param {number} [count=1] how many geometries will be generated - * @param {Object} [options={}] Optional parameters - * @param {Array} [options.bbox=[-180, -90, 180, 90]] a bounding box inside of which geometries are placed. - * @returns {FeatureCollection} GeoJSON FeatureCollection of points - * @example - * var points = turf.randomPoint(25, {bbox: [-180, -90, 180, 90]}) - * // => points - */ -export declare function randomPoint(count?: number, options?: { - bbox?: BBox; -}): FeatureCollection; -/** - * Returns a random {@link polygon}. - * - * @name randomPolygon - * @param {number} [count=1] how many geometries will be generated - * @param {Object} [options={}] Optional parameters - * @param {Array} [options.bbox=[-180, -90, 180, 90]] a bounding box inside of which geometries are placed. - * @param {number} [options.num_vertices=10] is how many coordinates each LineString will contain. - * @param {number} [options.max_radial_length=10] is the maximum number of decimal degrees latitude or longitude that a - * vertex can reach out of the center of the Polygon. - * @returns {FeatureCollection} GeoJSON FeatureCollection of polygons - * @example - * var polygons = turf.randomPolygon(25, {bbox: [-180, -90, 180, 90]}) - * // => polygons - */ -export declare function randomPolygon(count?: number, options?: { - bbox?: BBox; - num_vertices?: number; - max_radial_length?: number; -}): FeatureCollection; -/** - * Returns a random {@link linestring}. - * - * @name randomLineString - * @param {number} [count=1] how many geometries will be generated - * @param {Object} [options={}] Optional parameters - * @param {Array} [options.bbox=[-180, -90, 180, 90]] a bounding box inside of which geometries are placed. - * @param {number} [options.num_vertices=10] is how many coordinates each LineString will contain. - * @param {number} [options.max_length=0.0001] is the maximum number of decimal degrees that a - * vertex can be from its predecessor - * @param {number} [options.max_rotation=Math.PI / 8] is the maximum number of radians that a - * line segment can turn from the previous segment. - * @returns {FeatureCollection} GeoJSON FeatureCollection of linestrings - * @example - * var lineStrings = turf.randomLineString(25, {bbox: [-180, -90, 180, 90]}) - * // => lineStrings - */ -export declare function randomLineString(count?: number, options?: { - bbox?: BBox; - num_vertices?: number; - max_length?: number; - max_rotation?: number; -}): FeatureCollection; diff --git a/packages/turf-random/index.ts b/packages/turf-random/index.ts deleted file mode 100644 index 4c63237aaf..0000000000 --- a/packages/turf-random/index.ts +++ /dev/null @@ -1,177 +0,0 @@ -import { - BBox, Feature, featureCollection, FeatureCollection, isNumber, isObject, - LineString, lineString, point, Point, polygon, Polygon, Position, -} from "@turf/helpers"; - -/** - * Returns a random position within a {@link bounding box}. - * - * @name randomPosition - * @param {Array} [bbox=[-180, -90, 180, 90]] a bounding box inside of which positions are placed. - * @returns {Array} Position [longitude, latitude] - * @example - * var position = turf.randomPosition([-180, -90, 180, 90]) - * // => position - */ -export function randomPosition(bbox?: BBox | {bbox: BBox}): Position { - if (Array.isArray(bbox)) { return coordInBBox(bbox); } - if (bbox && bbox.bbox) { return coordInBBox(bbox.bbox); } - return [lon(), lat()]; -} - -/** - * Returns a random {@link point}. - * - * @name randomPoint - * @param {number} [count=1] how many geometries will be generated - * @param {Object} [options={}] Optional parameters - * @param {Array} [options.bbox=[-180, -90, 180, 90]] a bounding box inside of which geometries are placed. - * @returns {FeatureCollection} GeoJSON FeatureCollection of points - * @example - * var points = turf.randomPoint(25, {bbox: [-180, -90, 180, 90]}) - * // => points - */ -export function randomPoint(count?: number, options: { - bbox?: BBox, -} = {}): FeatureCollection { - if (count === undefined || count === null) { count = 1; } - const features = []; - for (let i = 0; i < count; i++) { - features.push(point(randomPosition(options.bbox))); - } - return featureCollection(features); -} - -/** - * Returns a random {@link polygon}. - * - * @name randomPolygon - * @param {number} [count=1] how many geometries will be generated - * @param {Object} [options={}] Optional parameters - * @param {Array} [options.bbox=[-180, -90, 180, 90]] a bounding box inside of which geometries are placed. - * @param {number} [options.num_vertices=10] is how many coordinates each LineString will contain. - * @param {number} [options.max_radial_length=10] is the maximum number of decimal degrees latitude or longitude that a - * vertex can reach out of the center of the Polygon. - * @returns {FeatureCollection} GeoJSON FeatureCollection of polygons - * @example - * var polygons = turf.randomPolygon(25, {bbox: [-180, -90, 180, 90]}) - * // => polygons - */ -export function randomPolygon(count?: number, options: { - bbox?: BBox, - num_vertices?: number, - max_radial_length?: number, -} = {}): FeatureCollection { - // Default param - if (count === undefined || count === null) { count = 1; } - if (!isNumber(options.num_vertices) || options.num_vertices === undefined) { - options.num_vertices = 10; - } - if (!isNumber(options.max_radial_length) || options.max_radial_length === undefined) { - options.max_radial_length = 10; - } - - const features = []; - for (let i = 0; i < count; i++) { - let vertices: any[] = []; - const circleOffsets = Array.apply(null, new Array(options.num_vertices + 1)).map(Math.random); - - // Sum Offsets - circleOffsets.forEach((cur: any, index: number, arr: any[]) => { - arr[index] = (index > 0) ? cur + arr[index - 1] : cur; - }); - - // scaleOffsets - circleOffsets.forEach((cur: any) => { - cur = cur * 2 * Math.PI / circleOffsets[circleOffsets.length - 1]; - const radialScaler = Math.random(); - vertices.push([ - radialScaler * (options.max_radial_length || 10) * Math.sin(cur), - radialScaler * (options.max_radial_length || 10) * Math.cos(cur), - ]); - }); - vertices[vertices.length - 1] = vertices[0]; // close the ring - - // center the polygon around something - vertices = vertices.map(vertexToCoordinate(randomPosition(options.bbox))); - features.push(polygon([vertices])); - } - return featureCollection(features); -} - -/** - * Returns a random {@link linestring}. - * - * @name randomLineString - * @param {number} [count=1] how many geometries will be generated - * @param {Object} [options={}] Optional parameters - * @param {Array} [options.bbox=[-180, -90, 180, 90]] a bounding box inside of which geometries are placed. - * @param {number} [options.num_vertices=10] is how many coordinates each LineString will contain. - * @param {number} [options.max_length=0.0001] is the maximum number of decimal degrees that a - * vertex can be from its predecessor - * @param {number} [options.max_rotation=Math.PI / 8] is the maximum number of radians that a - * line segment can turn from the previous segment. - * @returns {FeatureCollection} GeoJSON FeatureCollection of linestrings - * @example - * var lineStrings = turf.randomLineString(25, {bbox: [-180, -90, 180, 90]}) - * // => lineStrings - */ -export function randomLineString(count?: number, options: { - bbox?: BBox, - num_vertices?: number, - max_length?: number, - max_rotation?: number, -} = {}): FeatureCollection { - // Optional parameters - options = options || {}; - if (!isObject(options)) { throw new Error("options is invalid"); } - const bbox = options.bbox; - let num_vertices = options.num_vertices; - let max_length = options.max_length; - let max_rotation = options.max_rotation; - if (count === undefined || count === null) { count = 1; } - - // Default parameters - if (!isNumber(num_vertices) || num_vertices === undefined || num_vertices < 2) { num_vertices = 10; } - if (!isNumber(max_length) || max_length === undefined) { max_length = 0.0001; } - if (!isNumber(max_rotation) || max_rotation === undefined) { max_rotation = Math.PI / 8; } - - const features = []; - for (let i = 0; i < count; i++) { - const startingPoint = randomPosition(bbox); - const vertices = [startingPoint]; - for (let j = 0; j < num_vertices - 1; j++) { - const priorAngle = (j === 0) ? - Math.random() * 2 * Math.PI : - Math.tan( - (vertices[j][1] - vertices[j - 1][1]) / - (vertices[j][0] - vertices[j - 1][0]), - ); - const angle = priorAngle + (Math.random() - 0.5) * max_rotation * 2; - const distance = Math.random() * max_length; - vertices.push([ - vertices[j][0] + distance * Math.cos(angle), - vertices[j][1] + distance * Math.sin(angle), - ]); - } - features.push(lineString(vertices)); - } - - return featureCollection(features); -} - -function vertexToCoordinate(hub: number[]) { - return (cur: number[]) => { - return [cur[0] + hub[0], cur[1] + hub[1]]; - }; -} - -function rnd() { return Math.random() - 0.5; } -function lon() { return rnd() * 360; } -function lat() { return rnd() * 180; } - -function coordInBBox(bbox: BBox) { - return [ - (Math.random() * (bbox[2] - bbox[0])) + bbox[0], - (Math.random() * (bbox[3] - bbox[1])) + bbox[1]]; -} diff --git a/packages/turf-random/package.json b/packages/turf-random/package.json deleted file mode 100644 index 08cb4b17f8..0000000000 --- a/packages/turf-random/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "@turf/random", - "version": "6.0.2", - "description": "turf random module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "glob": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x" - } -} diff --git a/packages/turf-random/tsconfig.json b/packages/turf-random/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-random/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-random/tslint.json b/packages/turf-random/tslint.json deleted file mode 100644 index 9dd5998b9c..0000000000 --- a/packages/turf-random/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {"interface-name": false}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-rectangle-grid/LICENSE b/packages/turf-rectangle-grid/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-rectangle-grid/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-rectangle-grid/README.md b/packages/turf-rectangle-grid/README.md deleted file mode 100644 index a34a53a790..0000000000 --- a/packages/turf-rectangle-grid/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# @turf/rectangle-grid - - - -## rectangleGrid - -Creates a grid of rectangles from a bounding box, [Feature](https://tools.ietf.org/html/rfc7946#section-3.2) or [FeatureCollection](https://tools.ietf.org/html/rfc7946#section-3.3). - -**Parameters** - -- `bbox` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)>** extent in [minX, minY, maxX, maxY] order -- `cellWidth` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** of each cell, in units -- `cellHeight` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** of each cell, in units -- `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Optional parameters (optional, default `{}`) - - `options.units` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** units ("degrees", "radians", "miles", "kilometers") that the given cellWidth - and cellHeight are expressed in. Converted at the southern border. (optional, default `'kilometers'`) - - `options.mask` **[Feature](https://tools.ietf.org/html/rfc7946#section-3.2)<([Polygon](https://tools.ietf.org/html/rfc7946#section-3.1.6) \| [MultiPolygon](https://tools.ietf.org/html/rfc7946#section-3.1.7))>?** if passed a Polygon or MultiPolygon, - the grid Points will be created only inside it - - `options.properties` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** passed to each point of the grid (optional, default `{}`) - -**Examples** - -```javascript -var bbox = [-95, 30 ,-85, 40]; -var cellWidth = 50; -var cellHeight = 20; -var options = {units: 'miles'}; - -var rectangleGrid = turf.rectangleGrid(bbox, cellWidth, cellHeight, options); - -//addToMap -var addToMap = [rectangleGrid] -``` - -Returns **[FeatureCollection](https://tools.ietf.org/html/rfc7946#section-3.3)<[Polygon](https://tools.ietf.org/html/rfc7946#section-3.1.6)>** a grid of polygons - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/rectangle-grid -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-rectangle-grid/index.d.ts b/packages/turf-rectangle-grid/index.d.ts deleted file mode 100644 index aa82fd9494..0000000000 --- a/packages/turf-rectangle-grid/index.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { BBox, Feature, FeatureCollection, MultiPolygon, Polygon, Properties, Units } from "@turf/helpers"; - -/** - * http://turfjs.org/docs/#rectanglegrid - */ - -export default function rectangleGrid

(bbox: BBox, cellWidth: number, cellHeight: number, options?: { - units?: Units; - properties?: P; - mask?: Feature | Polygon | MultiPolygon; -}): FeatureCollection; diff --git a/packages/turf-rectangle-grid/index.js b/packages/turf-rectangle-grid/index.js deleted file mode 100644 index 5498445234..0000000000 --- a/packages/turf-rectangle-grid/index.js +++ /dev/null @@ -1,77 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var boolean_intersects_1 = require("@turf/boolean-intersects"); -var distance_1 = require("@turf/distance"); -var helpers_1 = require("@turf/helpers"); -/** - * Creates a grid of rectangles from a bounding box, {@link Feature} or {@link FeatureCollection}. - * - * @name rectangleGrid - * @param {Array} bbox extent in [minX, minY, maxX, maxY] order - * @param {number} cellWidth of each cell, in units - * @param {number} cellHeight of each cell, in units - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] units ("degrees", "radians", "miles", "kilometers") that the given cellWidth - * and cellHeight are expressed in. Converted at the southern border. - * @param {Feature} [options.mask] if passed a Polygon or MultiPolygon, - * the grid Points will be created only inside it - * @param {Object} [options.properties={}] passed to each point of the grid - * @returns {FeatureCollection} a grid of polygons - * @example - * var bbox = [-95, 30 ,-85, 40]; - * var cellWidth = 50; - * var cellHeight = 20; - * var options = {units: 'miles'}; - * - * var rectangleGrid = turf.rectangleGrid(bbox, cellWidth, cellHeight, options); - * - * //addToMap - * var addToMap = [rectangleGrid] - */ -function rectangleGrid(bbox, cellWidth, cellHeight, options) { - if (options === void 0) { options = {}; } - // Containers - var results = []; - var west = bbox[0]; - var south = bbox[1]; - var east = bbox[2]; - var north = bbox[3]; - var xFraction = cellWidth / (distance_1.default([west, south], [east, south], options)); - var cellWidthDeg = xFraction * (east - west); - var yFraction = cellHeight / (distance_1.default([west, south], [west, north], options)); - var cellHeightDeg = yFraction * (north - south); - // rows & columns - var bboxWidth = (east - west); - var bboxHeight = (north - south); - var columns = Math.floor(bboxWidth / cellWidthDeg); - var rows = Math.floor(bboxHeight / cellHeightDeg); - // if the grid does not fill the bbox perfectly, center it. - var deltaX = (bboxWidth - columns * cellWidthDeg) / 2; - var deltaY = (bboxHeight - rows * cellHeightDeg) / 2; - // iterate over columns & rows - var currentX = west + deltaX; - for (var column = 0; column < columns; column++) { - var currentY = south + deltaY; - for (var row = 0; row < rows; row++) { - var cellPoly = helpers_1.polygon([[ - [currentX, currentY], - [currentX, currentY + cellHeightDeg], - [currentX + cellWidthDeg, currentY + cellHeightDeg], - [currentX + cellWidthDeg, currentY], - [currentX, currentY], - ]], options.properties); - if (options.mask) { - if (boolean_intersects_1.default(options.mask, cellPoly)) { - results.push(cellPoly); - } - } - else { - results.push(cellPoly); - } - currentY += cellHeightDeg; - } - currentX += cellWidthDeg; - } - return helpers_1.featureCollection(results); -} -exports.default = rectangleGrid; diff --git a/packages/turf-rectangle-grid/index.ts b/packages/turf-rectangle-grid/index.ts deleted file mode 100644 index 7324cf961c..0000000000 --- a/packages/turf-rectangle-grid/index.ts +++ /dev/null @@ -1,86 +0,0 @@ -import intersect from "@turf/boolean-intersects"; -import distance from "@turf/distance"; -import { - BBox, Feature, featureCollection, - FeatureCollection, isNumber, MultiPolygon, polygon, Polygon, Properties, Units, -} from "@turf/helpers"; -import {getType} from "@turf/invariant"; - -/** - * Creates a grid of rectangles from a bounding box, {@link Feature} or {@link FeatureCollection}. - * - * @name rectangleGrid - * @param {Array} bbox extent in [minX, minY, maxX, maxY] order - * @param {number} cellWidth of each cell, in units - * @param {number} cellHeight of each cell, in units - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] units ("degrees", "radians", "miles", "kilometers") that the given cellWidth - * and cellHeight are expressed in. Converted at the southern border. - * @param {Feature} [options.mask] if passed a Polygon or MultiPolygon, - * the grid Points will be created only inside it - * @param {Object} [options.properties={}] passed to each point of the grid - * @returns {FeatureCollection} a grid of polygons - * @example - * var bbox = [-95, 30 ,-85, 40]; - * var cellWidth = 50; - * var cellHeight = 20; - * var options = {units: 'miles'}; - * - * var rectangleGrid = turf.rectangleGrid(bbox, cellWidth, cellHeight, options); - * - * //addToMap - * var addToMap = [rectangleGrid] - */ -function rectangleGrid

(bbox: BBox, cellWidth: number, cellHeight: number, options: { - units?: Units, - properties?: P, - mask?: Feature | Polygon | MultiPolygon, -} = {}): FeatureCollection { - // Containers - const results = []; - const west = bbox[0]; - const south = bbox[1]; - const east = bbox[2]; - const north = bbox[3]; - - const xFraction = cellWidth / (distance([west, south], [east, south], options)); - const cellWidthDeg = xFraction * (east - west); - const yFraction = cellHeight / (distance([west, south], [west, north], options)); - const cellHeightDeg = yFraction * (north - south); - - // rows & columns - const bboxWidth = (east - west); - const bboxHeight = (north - south); - const columns = Math.floor(bboxWidth / cellWidthDeg); - const rows = Math.floor(bboxHeight / cellHeightDeg); - - // if the grid does not fill the bbox perfectly, center it. - const deltaX = (bboxWidth - columns * cellWidthDeg) / 2; - const deltaY = (bboxHeight - rows * cellHeightDeg) / 2; - - // iterate over columns & rows - let currentX = west + deltaX; - for (let column = 0; column < columns; column++) { - let currentY = south + deltaY; - for (let row = 0; row < rows; row++) { - const cellPoly = polygon([[ - [currentX, currentY], - [currentX, currentY + cellHeightDeg], - [currentX + cellWidthDeg, currentY + cellHeightDeg], - [currentX + cellWidthDeg, currentY], - [currentX, currentY], - ]], options.properties); - if (options.mask) { - if (intersect(options.mask, cellPoly)) { results.push(cellPoly); } - } else { - results.push(cellPoly); - } - - currentY += cellHeightDeg; - } - currentX += cellWidthDeg; - } - return featureCollection(results); -} - -export default rectangleGrid; \ No newline at end of file diff --git a/packages/turf-rectangle-grid/package.json b/packages/turf-rectangle-grid/package.json deleted file mode 100644 index 3bb8fac4d0..0000000000 --- a/packages/turf-rectangle-grid/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@turf/rectangle-grid", - "version": "6.0.2", - "description": "turf rectangle-grid module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "grid", - "regular", - "cartesian" - ], - "author": "Turf Authors", - "contributors": [ - "Steve Bennett <@stevage>", - "Adam Michaleski <@adam3039>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/bbox-polygon": "*", - "@turf/truncate": "*", - "@std/esm": "*", - "benchmark": "*", - "rollup": "*", - "write-json-file": "*", - "load-json-file": "*", - "tape": "*" - }, - "dependencies": { - "@turf/distance": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/boolean-intersects": "6.x" - } -} diff --git a/packages/turf-rectangle-grid/test.js b/packages/turf-rectangle-grid/test.js deleted file mode 100644 index 53871707aa..0000000000 --- a/packages/turf-rectangle-grid/test.js +++ /dev/null @@ -1,55 +0,0 @@ - -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const bboxPoly = require('@turf/bbox-polygon').default; -const truncate = require('@turf/truncate').default; -const rectangleGrid = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -let fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - json: load.sync(directories.in + filename) - }; -}); - -test('rectangle-grid', t => { - for (const {name, json} of fixtures) { - const {bbox, cellWidth, cellHeight, units, properties, mask} = json; - const options = { - mask, - units, - properties, - } - const result = truncate(rectangleGrid(bbox, cellWidth, cellHeight, options)); - - // Add styled GeoJSON to the result - const poly = bboxPoly(bbox); - poly.properties = { - stroke: '#F00', - 'stroke-width': 6, - 'fill-opacity': 0 - }; - result.features.push(poly); - if (options.mask) { - options.mask.properties = { - "stroke": "#00F", - "stroke-width": 6, - "fill-opacity": 0 - }; - result.features.push(options.mask); - } - - if (process.env.REGEN) write.sync(directories.out + name + '.geojson', result); - t.deepEqual(result, load.sync(directories.out + name + '.geojson'), name); - } - t.end(); -}); diff --git a/packages/turf-rectangle-grid/test/out/10x10-1degree.geojson b/packages/turf-rectangle-grid/test/out/10x10-1degree.geojson deleted file mode 100644 index 16d36c9b6e..0000000000 --- a/packages/turf-rectangle-grid/test/out/10x10-1degree.geojson +++ /dev/null @@ -1,3146 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -5.025791, - -5.005842 - ], - [ - -5.025791, - -4.004674 - ], - [ - -4.020633, - -4.004674 - ], - [ - -4.020633, - -5.005842 - ], - [ - -5.025791, - -5.005842 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -5.025791, - -4.004674 - ], - [ - -5.025791, - -3.003505 - ], - [ - -4.020633, - -3.003505 - ], - [ - -4.020633, - -4.004674 - ], - [ - -5.025791, - -4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -5.025791, - -3.003505 - ], - [ - -5.025791, - -2.002337 - ], - [ - -4.020633, - -2.002337 - ], - [ - -4.020633, - -3.003505 - ], - [ - -5.025791, - -3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -5.025791, - -2.002337 - ], - [ - -5.025791, - -1.001168 - ], - [ - -4.020633, - -1.001168 - ], - [ - -4.020633, - -2.002337 - ], - [ - -5.025791, - -2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -5.025791, - -1.001168 - ], - [ - -5.025791, - 0 - ], - [ - -4.020633, - 0 - ], - [ - -4.020633, - -1.001168 - ], - [ - -5.025791, - -1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -5.025791, - 0 - ], - [ - -5.025791, - 1.001168 - ], - [ - -4.020633, - 1.001168 - ], - [ - -4.020633, - 0 - ], - [ - -5.025791, - 0 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -5.025791, - 1.001168 - ], - [ - -5.025791, - 2.002337 - ], - [ - -4.020633, - 2.002337 - ], - [ - -4.020633, - 1.001168 - ], - [ - -5.025791, - 1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -5.025791, - 2.002337 - ], - [ - -5.025791, - 3.003505 - ], - [ - -4.020633, - 3.003505 - ], - [ - -4.020633, - 2.002337 - ], - [ - -5.025791, - 2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -5.025791, - 3.003505 - ], - [ - -5.025791, - 4.004674 - ], - [ - -4.020633, - 4.004674 - ], - [ - -4.020633, - 3.003505 - ], - [ - -5.025791, - 3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -5.025791, - 4.004674 - ], - [ - -5.025791, - 5.005842 - ], - [ - -4.020633, - 5.005842 - ], - [ - -4.020633, - 4.004674 - ], - [ - -5.025791, - 4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -4.020633, - -5.005842 - ], - [ - -4.020633, - -4.004674 - ], - [ - -3.015475, - -4.004674 - ], - [ - -3.015475, - -5.005842 - ], - [ - -4.020633, - -5.005842 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -4.020633, - -4.004674 - ], - [ - -4.020633, - -3.003505 - ], - [ - -3.015475, - -3.003505 - ], - [ - -3.015475, - -4.004674 - ], - [ - -4.020633, - -4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -4.020633, - -3.003505 - ], - [ - -4.020633, - -2.002337 - ], - [ - -3.015475, - -2.002337 - ], - [ - -3.015475, - -3.003505 - ], - [ - -4.020633, - -3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -4.020633, - -2.002337 - ], - [ - -4.020633, - -1.001168 - ], - [ - -3.015475, - -1.001168 - ], - [ - -3.015475, - -2.002337 - ], - [ - -4.020633, - -2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -4.020633, - -1.001168 - ], - [ - -4.020633, - 0 - ], - [ - -3.015475, - 0 - ], - [ - -3.015475, - -1.001168 - ], - [ - -4.020633, - -1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -4.020633, - 0 - ], - [ - -4.020633, - 1.001168 - ], - [ - -3.015475, - 1.001168 - ], - [ - -3.015475, - 0 - ], - [ - -4.020633, - 0 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -4.020633, - 1.001168 - ], - [ - -4.020633, - 2.002337 - ], - [ - -3.015475, - 2.002337 - ], - [ - -3.015475, - 1.001168 - ], - [ - -4.020633, - 1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -4.020633, - 2.002337 - ], - [ - -4.020633, - 3.003505 - ], - [ - -3.015475, - 3.003505 - ], - [ - -3.015475, - 2.002337 - ], - [ - -4.020633, - 2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -4.020633, - 3.003505 - ], - [ - -4.020633, - 4.004674 - ], - [ - -3.015475, - 4.004674 - ], - [ - -3.015475, - 3.003505 - ], - [ - -4.020633, - 3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -4.020633, - 4.004674 - ], - [ - -4.020633, - 5.005842 - ], - [ - -3.015475, - 5.005842 - ], - [ - -3.015475, - 4.004674 - ], - [ - -4.020633, - 4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -3.015475, - -5.005842 - ], - [ - -3.015475, - -4.004674 - ], - [ - -2.010316, - -4.004674 - ], - [ - -2.010316, - -5.005842 - ], - [ - -3.015475, - -5.005842 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -3.015475, - -4.004674 - ], - [ - -3.015475, - -3.003505 - ], - [ - -2.010316, - -3.003505 - ], - [ - -2.010316, - -4.004674 - ], - [ - -3.015475, - -4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -3.015475, - -3.003505 - ], - [ - -3.015475, - -2.002337 - ], - [ - -2.010316, - -2.002337 - ], - [ - -2.010316, - -3.003505 - ], - [ - -3.015475, - -3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -3.015475, - -2.002337 - ], - [ - -3.015475, - -1.001168 - ], - [ - -2.010316, - -1.001168 - ], - [ - -2.010316, - -2.002337 - ], - [ - -3.015475, - -2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -3.015475, - -1.001168 - ], - [ - -3.015475, - 0 - ], - [ - -2.010316, - 0 - ], - [ - -2.010316, - -1.001168 - ], - [ - -3.015475, - -1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -3.015475, - 0 - ], - [ - -3.015475, - 1.001168 - ], - [ - -2.010316, - 1.001168 - ], - [ - -2.010316, - 0 - ], - [ - -3.015475, - 0 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -3.015475, - 1.001168 - ], - [ - -3.015475, - 2.002337 - ], - [ - -2.010316, - 2.002337 - ], - [ - -2.010316, - 1.001168 - ], - [ - -3.015475, - 1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -3.015475, - 2.002337 - ], - [ - -3.015475, - 3.003505 - ], - [ - -2.010316, - 3.003505 - ], - [ - -2.010316, - 2.002337 - ], - [ - -3.015475, - 2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -3.015475, - 3.003505 - ], - [ - -3.015475, - 4.004674 - ], - [ - -2.010316, - 4.004674 - ], - [ - -2.010316, - 3.003505 - ], - [ - -3.015475, - 3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -3.015475, - 4.004674 - ], - [ - -3.015475, - 5.005842 - ], - [ - -2.010316, - 5.005842 - ], - [ - -2.010316, - 4.004674 - ], - [ - -3.015475, - 4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -2.010316, - -5.005842 - ], - [ - -2.010316, - -4.004674 - ], - [ - -1.005158, - -4.004674 - ], - [ - -1.005158, - -5.005842 - ], - [ - -2.010316, - -5.005842 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -2.010316, - -4.004674 - ], - [ - -2.010316, - -3.003505 - ], - [ - -1.005158, - -3.003505 - ], - [ - -1.005158, - -4.004674 - ], - [ - -2.010316, - -4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -2.010316, - -3.003505 - ], - [ - -2.010316, - -2.002337 - ], - [ - -1.005158, - -2.002337 - ], - [ - -1.005158, - -3.003505 - ], - [ - -2.010316, - -3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -2.010316, - -2.002337 - ], - [ - -2.010316, - -1.001168 - ], - [ - -1.005158, - -1.001168 - ], - [ - -1.005158, - -2.002337 - ], - [ - -2.010316, - -2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -2.010316, - -1.001168 - ], - [ - -2.010316, - 0 - ], - [ - -1.005158, - 0 - ], - [ - -1.005158, - -1.001168 - ], - [ - -2.010316, - -1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -2.010316, - 0 - ], - [ - -2.010316, - 1.001168 - ], - [ - -1.005158, - 1.001168 - ], - [ - -1.005158, - 0 - ], - [ - -2.010316, - 0 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -2.010316, - 1.001168 - ], - [ - -2.010316, - 2.002337 - ], - [ - -1.005158, - 2.002337 - ], - [ - -1.005158, - 1.001168 - ], - [ - -2.010316, - 1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -2.010316, - 2.002337 - ], - [ - -2.010316, - 3.003505 - ], - [ - -1.005158, - 3.003505 - ], - [ - -1.005158, - 2.002337 - ], - [ - -2.010316, - 2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -2.010316, - 3.003505 - ], - [ - -2.010316, - 4.004674 - ], - [ - -1.005158, - 4.004674 - ], - [ - -1.005158, - 3.003505 - ], - [ - -2.010316, - 3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -2.010316, - 4.004674 - ], - [ - -2.010316, - 5.005842 - ], - [ - -1.005158, - 5.005842 - ], - [ - -1.005158, - 4.004674 - ], - [ - -2.010316, - 4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -1.005158, - -5.005842 - ], - [ - -1.005158, - -4.004674 - ], - [ - 0, - -4.004674 - ], - [ - 0, - -5.005842 - ], - [ - -1.005158, - -5.005842 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -1.005158, - -4.004674 - ], - [ - -1.005158, - -3.003505 - ], - [ - 0, - -3.003505 - ], - [ - 0, - -4.004674 - ], - [ - -1.005158, - -4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -1.005158, - -3.003505 - ], - [ - -1.005158, - -2.002337 - ], - [ - 0, - -2.002337 - ], - [ - 0, - -3.003505 - ], - [ - -1.005158, - -3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -1.005158, - -2.002337 - ], - [ - -1.005158, - -1.001168 - ], - [ - 0, - -1.001168 - ], - [ - 0, - -2.002337 - ], - [ - -1.005158, - -2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -1.005158, - -1.001168 - ], - [ - -1.005158, - 0 - ], - [ - 0, - 0 - ], - [ - 0, - -1.001168 - ], - [ - -1.005158, - -1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -1.005158, - 0 - ], - [ - -1.005158, - 1.001168 - ], - [ - 0, - 1.001168 - ], - [ - 0, - 0 - ], - [ - -1.005158, - 0 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -1.005158, - 1.001168 - ], - [ - -1.005158, - 2.002337 - ], - [ - 0, - 2.002337 - ], - [ - 0, - 1.001168 - ], - [ - -1.005158, - 1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -1.005158, - 2.002337 - ], - [ - -1.005158, - 3.003505 - ], - [ - 0, - 3.003505 - ], - [ - 0, - 2.002337 - ], - [ - -1.005158, - 2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -1.005158, - 3.003505 - ], - [ - -1.005158, - 4.004674 - ], - [ - 0, - 4.004674 - ], - [ - 0, - 3.003505 - ], - [ - -1.005158, - 3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -1.005158, - 4.004674 - ], - [ - -1.005158, - 5.005842 - ], - [ - 0, - 5.005842 - ], - [ - 0, - 4.004674 - ], - [ - -1.005158, - 4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0, - -5.005842 - ], - [ - 0, - -4.004674 - ], - [ - 1.005158, - -4.004674 - ], - [ - 1.005158, - -5.005842 - ], - [ - 0, - -5.005842 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0, - -4.004674 - ], - [ - 0, - -3.003505 - ], - [ - 1.005158, - -3.003505 - ], - [ - 1.005158, - -4.004674 - ], - [ - 0, - -4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0, - -3.003505 - ], - [ - 0, - -2.002337 - ], - [ - 1.005158, - -2.002337 - ], - [ - 1.005158, - -3.003505 - ], - [ - 0, - -3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0, - -2.002337 - ], - [ - 0, - -1.001168 - ], - [ - 1.005158, - -1.001168 - ], - [ - 1.005158, - -2.002337 - ], - [ - 0, - -2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0, - -1.001168 - ], - [ - 0, - 0 - ], - [ - 1.005158, - 0 - ], - [ - 1.005158, - -1.001168 - ], - [ - 0, - -1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0, - 0 - ], - [ - 0, - 1.001168 - ], - [ - 1.005158, - 1.001168 - ], - [ - 1.005158, - 0 - ], - [ - 0, - 0 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0, - 1.001168 - ], - [ - 0, - 2.002337 - ], - [ - 1.005158, - 2.002337 - ], - [ - 1.005158, - 1.001168 - ], - [ - 0, - 1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0, - 2.002337 - ], - [ - 0, - 3.003505 - ], - [ - 1.005158, - 3.003505 - ], - [ - 1.005158, - 2.002337 - ], - [ - 0, - 2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0, - 3.003505 - ], - [ - 0, - 4.004674 - ], - [ - 1.005158, - 4.004674 - ], - [ - 1.005158, - 3.003505 - ], - [ - 0, - 3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0, - 4.004674 - ], - [ - 0, - 5.005842 - ], - [ - 1.005158, - 5.005842 - ], - [ - 1.005158, - 4.004674 - ], - [ - 0, - 4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 1.005158, - -5.005842 - ], - [ - 1.005158, - -4.004674 - ], - [ - 2.010316, - -4.004674 - ], - [ - 2.010316, - -5.005842 - ], - [ - 1.005158, - -5.005842 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 1.005158, - -4.004674 - ], - [ - 1.005158, - -3.003505 - ], - [ - 2.010316, - -3.003505 - ], - [ - 2.010316, - -4.004674 - ], - [ - 1.005158, - -4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 1.005158, - -3.003505 - ], - [ - 1.005158, - -2.002337 - ], - [ - 2.010316, - -2.002337 - ], - [ - 2.010316, - -3.003505 - ], - [ - 1.005158, - -3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 1.005158, - -2.002337 - ], - [ - 1.005158, - -1.001168 - ], - [ - 2.010316, - -1.001168 - ], - [ - 2.010316, - -2.002337 - ], - [ - 1.005158, - -2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 1.005158, - -1.001168 - ], - [ - 1.005158, - 0 - ], - [ - 2.010316, - 0 - ], - [ - 2.010316, - -1.001168 - ], - [ - 1.005158, - -1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 1.005158, - 0 - ], - [ - 1.005158, - 1.001168 - ], - [ - 2.010316, - 1.001168 - ], - [ - 2.010316, - 0 - ], - [ - 1.005158, - 0 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 1.005158, - 1.001168 - ], - [ - 1.005158, - 2.002337 - ], - [ - 2.010316, - 2.002337 - ], - [ - 2.010316, - 1.001168 - ], - [ - 1.005158, - 1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 1.005158, - 2.002337 - ], - [ - 1.005158, - 3.003505 - ], - [ - 2.010316, - 3.003505 - ], - [ - 2.010316, - 2.002337 - ], - [ - 1.005158, - 2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 1.005158, - 3.003505 - ], - [ - 1.005158, - 4.004674 - ], - [ - 2.010316, - 4.004674 - ], - [ - 2.010316, - 3.003505 - ], - [ - 1.005158, - 3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 1.005158, - 4.004674 - ], - [ - 1.005158, - 5.005842 - ], - [ - 2.010316, - 5.005842 - ], - [ - 2.010316, - 4.004674 - ], - [ - 1.005158, - 4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 2.010316, - -5.005842 - ], - [ - 2.010316, - -4.004674 - ], - [ - 3.015475, - -4.004674 - ], - [ - 3.015475, - -5.005842 - ], - [ - 2.010316, - -5.005842 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 2.010316, - -4.004674 - ], - [ - 2.010316, - -3.003505 - ], - [ - 3.015475, - -3.003505 - ], - [ - 3.015475, - -4.004674 - ], - [ - 2.010316, - -4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 2.010316, - -3.003505 - ], - [ - 2.010316, - -2.002337 - ], - [ - 3.015475, - -2.002337 - ], - [ - 3.015475, - -3.003505 - ], - [ - 2.010316, - -3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 2.010316, - -2.002337 - ], - [ - 2.010316, - -1.001168 - ], - [ - 3.015475, - -1.001168 - ], - [ - 3.015475, - -2.002337 - ], - [ - 2.010316, - -2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 2.010316, - -1.001168 - ], - [ - 2.010316, - 0 - ], - [ - 3.015475, - 0 - ], - [ - 3.015475, - -1.001168 - ], - [ - 2.010316, - -1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 2.010316, - 0 - ], - [ - 2.010316, - 1.001168 - ], - [ - 3.015475, - 1.001168 - ], - [ - 3.015475, - 0 - ], - [ - 2.010316, - 0 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 2.010316, - 1.001168 - ], - [ - 2.010316, - 2.002337 - ], - [ - 3.015475, - 2.002337 - ], - [ - 3.015475, - 1.001168 - ], - [ - 2.010316, - 1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 2.010316, - 2.002337 - ], - [ - 2.010316, - 3.003505 - ], - [ - 3.015475, - 3.003505 - ], - [ - 3.015475, - 2.002337 - ], - [ - 2.010316, - 2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 2.010316, - 3.003505 - ], - [ - 2.010316, - 4.004674 - ], - [ - 3.015475, - 4.004674 - ], - [ - 3.015475, - 3.003505 - ], - [ - 2.010316, - 3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 2.010316, - 4.004674 - ], - [ - 2.010316, - 5.005842 - ], - [ - 3.015475, - 5.005842 - ], - [ - 3.015475, - 4.004674 - ], - [ - 2.010316, - 4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 3.015475, - -5.005842 - ], - [ - 3.015475, - -4.004674 - ], - [ - 4.020633, - -4.004674 - ], - [ - 4.020633, - -5.005842 - ], - [ - 3.015475, - -5.005842 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 3.015475, - -4.004674 - ], - [ - 3.015475, - -3.003505 - ], - [ - 4.020633, - -3.003505 - ], - [ - 4.020633, - -4.004674 - ], - [ - 3.015475, - -4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 3.015475, - -3.003505 - ], - [ - 3.015475, - -2.002337 - ], - [ - 4.020633, - -2.002337 - ], - [ - 4.020633, - -3.003505 - ], - [ - 3.015475, - -3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 3.015475, - -2.002337 - ], - [ - 3.015475, - -1.001168 - ], - [ - 4.020633, - -1.001168 - ], - [ - 4.020633, - -2.002337 - ], - [ - 3.015475, - -2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 3.015475, - -1.001168 - ], - [ - 3.015475, - 0 - ], - [ - 4.020633, - 0 - ], - [ - 4.020633, - -1.001168 - ], - [ - 3.015475, - -1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 3.015475, - 0 - ], - [ - 3.015475, - 1.001168 - ], - [ - 4.020633, - 1.001168 - ], - [ - 4.020633, - 0 - ], - [ - 3.015475, - 0 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 3.015475, - 1.001168 - ], - [ - 3.015475, - 2.002337 - ], - [ - 4.020633, - 2.002337 - ], - [ - 4.020633, - 1.001168 - ], - [ - 3.015475, - 1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 3.015475, - 2.002337 - ], - [ - 3.015475, - 3.003505 - ], - [ - 4.020633, - 3.003505 - ], - [ - 4.020633, - 2.002337 - ], - [ - 3.015475, - 2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 3.015475, - 3.003505 - ], - [ - 3.015475, - 4.004674 - ], - [ - 4.020633, - 4.004674 - ], - [ - 4.020633, - 3.003505 - ], - [ - 3.015475, - 3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 3.015475, - 4.004674 - ], - [ - 3.015475, - 5.005842 - ], - [ - 4.020633, - 5.005842 - ], - [ - 4.020633, - 4.004674 - ], - [ - 3.015475, - 4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.020633, - -5.005842 - ], - [ - 4.020633, - -4.004674 - ], - [ - 5.025791, - -4.004674 - ], - [ - 5.025791, - -5.005842 - ], - [ - 4.020633, - -5.005842 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.020633, - -4.004674 - ], - [ - 4.020633, - -3.003505 - ], - [ - 5.025791, - -3.003505 - ], - [ - 5.025791, - -4.004674 - ], - [ - 4.020633, - -4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.020633, - -3.003505 - ], - [ - 4.020633, - -2.002337 - ], - [ - 5.025791, - -2.002337 - ], - [ - 5.025791, - -3.003505 - ], - [ - 4.020633, - -3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.020633, - -2.002337 - ], - [ - 4.020633, - -1.001168 - ], - [ - 5.025791, - -1.001168 - ], - [ - 5.025791, - -2.002337 - ], - [ - 4.020633, - -2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.020633, - -1.001168 - ], - [ - 4.020633, - 0 - ], - [ - 5.025791, - 0 - ], - [ - 5.025791, - -1.001168 - ], - [ - 4.020633, - -1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.020633, - 0 - ], - [ - 4.020633, - 1.001168 - ], - [ - 5.025791, - 1.001168 - ], - [ - 5.025791, - 0 - ], - [ - 4.020633, - 0 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.020633, - 1.001168 - ], - [ - 4.020633, - 2.002337 - ], - [ - 5.025791, - 2.002337 - ], - [ - 5.025791, - 1.001168 - ], - [ - 4.020633, - 1.001168 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.020633, - 2.002337 - ], - [ - 4.020633, - 3.003505 - ], - [ - 5.025791, - 3.003505 - ], - [ - 5.025791, - 2.002337 - ], - [ - 4.020633, - 2.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.020633, - 3.003505 - ], - [ - 4.020633, - 4.004674 - ], - [ - 5.025791, - 4.004674 - ], - [ - 5.025791, - 3.003505 - ], - [ - 4.020633, - 3.003505 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 4.020633, - 4.004674 - ], - [ - 4.020633, - 5.005842 - ], - [ - 5.025791, - 5.005842 - ], - [ - 5.025791, - 4.004674 - ], - [ - 4.020633, - 4.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "bbox": [ - -5.1, - -5.1, - 5.1, - 5.1 - ], - "properties": { - "stroke": "#F00", - "stroke-width": 6, - "fill-opacity": 0 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -5.1, - -5.1 - ], - [ - 5.1, - -5.1 - ], - [ - 5.1, - 5.1 - ], - [ - -5.1, - 5.1 - ], - [ - -5.1, - -5.1 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-rectangle-grid/test/out/australia-mask.geojson b/packages/turf-rectangle-grid/test/out/australia-mask.geojson deleted file mode 100644 index 7004711aa7..0000000000 --- a/packages/turf-rectangle-grid/test/out/australia-mask.geojson +++ /dev/null @@ -1,12937 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 113.47488, - -22.997663 - ], - [ - 113.47488, - -25 - ], - [ - 114.476048, - -25 - ], - [ - 114.476048, - -22.997663 - ], - [ - 113.47488, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 113.47488, - -25 - ], - [ - 113.47488, - -27.002337 - ], - [ - 114.476048, - -27.002337 - ], - [ - 114.476048, - -25 - ], - [ - 113.47488, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 113.47488, - -27.002337 - ], - [ - 113.47488, - -29.004674 - ], - [ - 114.476048, - -29.004674 - ], - [ - 114.476048, - -27.002337 - ], - [ - 113.47488, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 114.476048, - -18.99299 - ], - [ - 114.476048, - -20.995326 - ], - [ - 115.477216, - -20.995326 - ], - [ - 115.477216, - -18.99299 - ], - [ - 114.476048, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 114.476048, - -20.995326 - ], - [ - 114.476048, - -22.997663 - ], - [ - 115.477216, - -22.997663 - ], - [ - 115.477216, - -20.995326 - ], - [ - 114.476048, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 114.476048, - -22.997663 - ], - [ - 114.476048, - -25 - ], - [ - 115.477216, - -25 - ], - [ - 115.477216, - -22.997663 - ], - [ - 114.476048, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 114.476048, - -25 - ], - [ - 114.476048, - -27.002337 - ], - [ - 115.477216, - -27.002337 - ], - [ - 115.477216, - -25 - ], - [ - 114.476048, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 114.476048, - -27.002337 - ], - [ - 114.476048, - -29.004674 - ], - [ - 115.477216, - -29.004674 - ], - [ - 115.477216, - -27.002337 - ], - [ - 114.476048, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 114.476048, - -29.004674 - ], - [ - 114.476048, - -31.00701 - ], - [ - 115.477216, - -31.00701 - ], - [ - 115.477216, - -29.004674 - ], - [ - 114.476048, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 114.476048, - -31.00701 - ], - [ - 114.476048, - -33.009347 - ], - [ - 115.477216, - -33.009347 - ], - [ - 115.477216, - -31.00701 - ], - [ - 114.476048, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 114.476048, - -33.009347 - ], - [ - 114.476048, - -35.011684 - ], - [ - 115.477216, - -35.011684 - ], - [ - 115.477216, - -33.009347 - ], - [ - 114.476048, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 115.477216, - -18.99299 - ], - [ - 115.477216, - -20.995326 - ], - [ - 116.478385, - -20.995326 - ], - [ - 116.478385, - -18.99299 - ], - [ - 115.477216, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 115.477216, - -20.995326 - ], - [ - 115.477216, - -22.997663 - ], - [ - 116.478385, - -22.997663 - ], - [ - 116.478385, - -20.995326 - ], - [ - 115.477216, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 115.477216, - -22.997663 - ], - [ - 115.477216, - -25 - ], - [ - 116.478385, - -25 - ], - [ - 116.478385, - -22.997663 - ], - [ - 115.477216, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 115.477216, - -25 - ], - [ - 115.477216, - -27.002337 - ], - [ - 116.478385, - -27.002337 - ], - [ - 116.478385, - -25 - ], - [ - 115.477216, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 115.477216, - -27.002337 - ], - [ - 115.477216, - -29.004674 - ], - [ - 116.478385, - -29.004674 - ], - [ - 116.478385, - -27.002337 - ], - [ - 115.477216, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 115.477216, - -29.004674 - ], - [ - 115.477216, - -31.00701 - ], - [ - 116.478385, - -31.00701 - ], - [ - 116.478385, - -29.004674 - ], - [ - 115.477216, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 115.477216, - -31.00701 - ], - [ - 115.477216, - -33.009347 - ], - [ - 116.478385, - -33.009347 - ], - [ - 116.478385, - -31.00701 - ], - [ - 115.477216, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 115.477216, - -33.009347 - ], - [ - 115.477216, - -35.011684 - ], - [ - 116.478385, - -35.011684 - ], - [ - 116.478385, - -33.009347 - ], - [ - 115.477216, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 115.477216, - -35.011684 - ], - [ - 115.477216, - -37.014021 - ], - [ - 116.478385, - -37.014021 - ], - [ - 116.478385, - -35.011684 - ], - [ - 115.477216, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 116.478385, - -18.99299 - ], - [ - 116.478385, - -20.995326 - ], - [ - 117.479553, - -20.995326 - ], - [ - 117.479553, - -18.99299 - ], - [ - 116.478385, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 116.478385, - -20.995326 - ], - [ - 116.478385, - -22.997663 - ], - [ - 117.479553, - -22.997663 - ], - [ - 117.479553, - -20.995326 - ], - [ - 116.478385, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 116.478385, - -22.997663 - ], - [ - 116.478385, - -25 - ], - [ - 117.479553, - -25 - ], - [ - 117.479553, - -22.997663 - ], - [ - 116.478385, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 116.478385, - -25 - ], - [ - 116.478385, - -27.002337 - ], - [ - 117.479553, - -27.002337 - ], - [ - 117.479553, - -25 - ], - [ - 116.478385, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 116.478385, - -27.002337 - ], - [ - 116.478385, - -29.004674 - ], - [ - 117.479553, - -29.004674 - ], - [ - 117.479553, - -27.002337 - ], - [ - 116.478385, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 116.478385, - -29.004674 - ], - [ - 116.478385, - -31.00701 - ], - [ - 117.479553, - -31.00701 - ], - [ - 117.479553, - -29.004674 - ], - [ - 116.478385, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 116.478385, - -31.00701 - ], - [ - 116.478385, - -33.009347 - ], - [ - 117.479553, - -33.009347 - ], - [ - 117.479553, - -31.00701 - ], - [ - 116.478385, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 116.478385, - -33.009347 - ], - [ - 116.478385, - -35.011684 - ], - [ - 117.479553, - -35.011684 - ], - [ - 117.479553, - -33.009347 - ], - [ - 116.478385, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 117.479553, - -18.99299 - ], - [ - 117.479553, - -20.995326 - ], - [ - 118.480721, - -20.995326 - ], - [ - 118.480721, - -18.99299 - ], - [ - 117.479553, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 117.479553, - -20.995326 - ], - [ - 117.479553, - -22.997663 - ], - [ - 118.480721, - -22.997663 - ], - [ - 118.480721, - -20.995326 - ], - [ - 117.479553, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 117.479553, - -22.997663 - ], - [ - 117.479553, - -25 - ], - [ - 118.480721, - -25 - ], - [ - 118.480721, - -22.997663 - ], - [ - 117.479553, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 117.479553, - -25 - ], - [ - 117.479553, - -27.002337 - ], - [ - 118.480721, - -27.002337 - ], - [ - 118.480721, - -25 - ], - [ - 117.479553, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 117.479553, - -27.002337 - ], - [ - 117.479553, - -29.004674 - ], - [ - 118.480721, - -29.004674 - ], - [ - 118.480721, - -27.002337 - ], - [ - 117.479553, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 117.479553, - -29.004674 - ], - [ - 117.479553, - -31.00701 - ], - [ - 118.480721, - -31.00701 - ], - [ - 118.480721, - -29.004674 - ], - [ - 117.479553, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 117.479553, - -31.00701 - ], - [ - 117.479553, - -33.009347 - ], - [ - 118.480721, - -33.009347 - ], - [ - 118.480721, - -31.00701 - ], - [ - 117.479553, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 117.479553, - -33.009347 - ], - [ - 117.479553, - -35.011684 - ], - [ - 118.480721, - -35.011684 - ], - [ - 118.480721, - -33.009347 - ], - [ - 117.479553, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 118.480721, - -18.99299 - ], - [ - 118.480721, - -20.995326 - ], - [ - 119.48189, - -20.995326 - ], - [ - 119.48189, - -18.99299 - ], - [ - 118.480721, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 118.480721, - -20.995326 - ], - [ - 118.480721, - -22.997663 - ], - [ - 119.48189, - -22.997663 - ], - [ - 119.48189, - -20.995326 - ], - [ - 118.480721, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 118.480721, - -22.997663 - ], - [ - 118.480721, - -25 - ], - [ - 119.48189, - -25 - ], - [ - 119.48189, - -22.997663 - ], - [ - 118.480721, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 118.480721, - -25 - ], - [ - 118.480721, - -27.002337 - ], - [ - 119.48189, - -27.002337 - ], - [ - 119.48189, - -25 - ], - [ - 118.480721, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 118.480721, - -27.002337 - ], - [ - 118.480721, - -29.004674 - ], - [ - 119.48189, - -29.004674 - ], - [ - 119.48189, - -27.002337 - ], - [ - 118.480721, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 118.480721, - -29.004674 - ], - [ - 118.480721, - -31.00701 - ], - [ - 119.48189, - -31.00701 - ], - [ - 119.48189, - -29.004674 - ], - [ - 118.480721, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 118.480721, - -31.00701 - ], - [ - 118.480721, - -33.009347 - ], - [ - 119.48189, - -33.009347 - ], - [ - 119.48189, - -31.00701 - ], - [ - 118.480721, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 118.480721, - -33.009347 - ], - [ - 118.480721, - -35.011684 - ], - [ - 119.48189, - -35.011684 - ], - [ - 119.48189, - -33.009347 - ], - [ - 118.480721, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 119.48189, - -18.99299 - ], - [ - 119.48189, - -20.995326 - ], - [ - 120.483058, - -20.995326 - ], - [ - 120.483058, - -18.99299 - ], - [ - 119.48189, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 119.48189, - -20.995326 - ], - [ - 119.48189, - -22.997663 - ], - [ - 120.483058, - -22.997663 - ], - [ - 120.483058, - -20.995326 - ], - [ - 119.48189, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 119.48189, - -22.997663 - ], - [ - 119.48189, - -25 - ], - [ - 120.483058, - -25 - ], - [ - 120.483058, - -22.997663 - ], - [ - 119.48189, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 119.48189, - -25 - ], - [ - 119.48189, - -27.002337 - ], - [ - 120.483058, - -27.002337 - ], - [ - 120.483058, - -25 - ], - [ - 119.48189, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 119.48189, - -27.002337 - ], - [ - 119.48189, - -29.004674 - ], - [ - 120.483058, - -29.004674 - ], - [ - 120.483058, - -27.002337 - ], - [ - 119.48189, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 119.48189, - -29.004674 - ], - [ - 119.48189, - -31.00701 - ], - [ - 120.483058, - -31.00701 - ], - [ - 120.483058, - -29.004674 - ], - [ - 119.48189, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 119.48189, - -31.00701 - ], - [ - 119.48189, - -33.009347 - ], - [ - 120.483058, - -33.009347 - ], - [ - 120.483058, - -31.00701 - ], - [ - 119.48189, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 119.48189, - -33.009347 - ], - [ - 119.48189, - -35.011684 - ], - [ - 120.483058, - -35.011684 - ], - [ - 120.483058, - -33.009347 - ], - [ - 119.48189, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 120.483058, - -16.990653 - ], - [ - 120.483058, - -18.99299 - ], - [ - 121.484227, - -18.99299 - ], - [ - 121.484227, - -16.990653 - ], - [ - 120.483058, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 120.483058, - -18.99299 - ], - [ - 120.483058, - -20.995326 - ], - [ - 121.484227, - -20.995326 - ], - [ - 121.484227, - -18.99299 - ], - [ - 120.483058, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 120.483058, - -20.995326 - ], - [ - 120.483058, - -22.997663 - ], - [ - 121.484227, - -22.997663 - ], - [ - 121.484227, - -20.995326 - ], - [ - 120.483058, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 120.483058, - -22.997663 - ], - [ - 120.483058, - -25 - ], - [ - 121.484227, - -25 - ], - [ - 121.484227, - -22.997663 - ], - [ - 120.483058, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 120.483058, - -25 - ], - [ - 120.483058, - -27.002337 - ], - [ - 121.484227, - -27.002337 - ], - [ - 121.484227, - -25 - ], - [ - 120.483058, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 120.483058, - -27.002337 - ], - [ - 120.483058, - -29.004674 - ], - [ - 121.484227, - -29.004674 - ], - [ - 121.484227, - -27.002337 - ], - [ - 120.483058, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 120.483058, - -29.004674 - ], - [ - 120.483058, - -31.00701 - ], - [ - 121.484227, - -31.00701 - ], - [ - 121.484227, - -29.004674 - ], - [ - 120.483058, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 120.483058, - -31.00701 - ], - [ - 120.483058, - -33.009347 - ], - [ - 121.484227, - -33.009347 - ], - [ - 121.484227, - -31.00701 - ], - [ - 120.483058, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 120.483058, - -33.009347 - ], - [ - 120.483058, - -35.011684 - ], - [ - 121.484227, - -35.011684 - ], - [ - 121.484227, - -33.009347 - ], - [ - 120.483058, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 121.484227, - -16.990653 - ], - [ - 121.484227, - -18.99299 - ], - [ - 122.485395, - -18.99299 - ], - [ - 122.485395, - -16.990653 - ], - [ - 121.484227, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 121.484227, - -18.99299 - ], - [ - 121.484227, - -20.995326 - ], - [ - 122.485395, - -20.995326 - ], - [ - 122.485395, - -18.99299 - ], - [ - 121.484227, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 121.484227, - -20.995326 - ], - [ - 121.484227, - -22.997663 - ], - [ - 122.485395, - -22.997663 - ], - [ - 122.485395, - -20.995326 - ], - [ - 121.484227, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 121.484227, - -22.997663 - ], - [ - 121.484227, - -25 - ], - [ - 122.485395, - -25 - ], - [ - 122.485395, - -22.997663 - ], - [ - 121.484227, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 121.484227, - -25 - ], - [ - 121.484227, - -27.002337 - ], - [ - 122.485395, - -27.002337 - ], - [ - 122.485395, - -25 - ], - [ - 121.484227, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 121.484227, - -27.002337 - ], - [ - 121.484227, - -29.004674 - ], - [ - 122.485395, - -29.004674 - ], - [ - 122.485395, - -27.002337 - ], - [ - 121.484227, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 121.484227, - -29.004674 - ], - [ - 121.484227, - -31.00701 - ], - [ - 122.485395, - -31.00701 - ], - [ - 122.485395, - -29.004674 - ], - [ - 121.484227, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 121.484227, - -31.00701 - ], - [ - 121.484227, - -33.009347 - ], - [ - 122.485395, - -33.009347 - ], - [ - 122.485395, - -31.00701 - ], - [ - 121.484227, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 121.484227, - -33.009347 - ], - [ - 121.484227, - -35.011684 - ], - [ - 122.485395, - -35.011684 - ], - [ - 122.485395, - -33.009347 - ], - [ - 121.484227, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 122.485395, - -14.988316 - ], - [ - 122.485395, - -16.990653 - ], - [ - 123.486563, - -16.990653 - ], - [ - 123.486563, - -14.988316 - ], - [ - 122.485395, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 122.485395, - -16.990653 - ], - [ - 122.485395, - -18.99299 - ], - [ - 123.486563, - -18.99299 - ], - [ - 123.486563, - -16.990653 - ], - [ - 122.485395, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 122.485395, - -18.99299 - ], - [ - 122.485395, - -20.995326 - ], - [ - 123.486563, - -20.995326 - ], - [ - 123.486563, - -18.99299 - ], - [ - 122.485395, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 122.485395, - -20.995326 - ], - [ - 122.485395, - -22.997663 - ], - [ - 123.486563, - -22.997663 - ], - [ - 123.486563, - -20.995326 - ], - [ - 122.485395, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 122.485395, - -22.997663 - ], - [ - 122.485395, - -25 - ], - [ - 123.486563, - -25 - ], - [ - 123.486563, - -22.997663 - ], - [ - 122.485395, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 122.485395, - -25 - ], - [ - 122.485395, - -27.002337 - ], - [ - 123.486563, - -27.002337 - ], - [ - 123.486563, - -25 - ], - [ - 122.485395, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 122.485395, - -27.002337 - ], - [ - 122.485395, - -29.004674 - ], - [ - 123.486563, - -29.004674 - ], - [ - 123.486563, - -27.002337 - ], - [ - 122.485395, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 122.485395, - -29.004674 - ], - [ - 122.485395, - -31.00701 - ], - [ - 123.486563, - -31.00701 - ], - [ - 123.486563, - -29.004674 - ], - [ - 122.485395, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 122.485395, - -31.00701 - ], - [ - 122.485395, - -33.009347 - ], - [ - 123.486563, - -33.009347 - ], - [ - 123.486563, - -31.00701 - ], - [ - 122.485395, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 122.485395, - -33.009347 - ], - [ - 122.485395, - -35.011684 - ], - [ - 123.486563, - -35.011684 - ], - [ - 123.486563, - -33.009347 - ], - [ - 122.485395, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 123.486563, - -14.988316 - ], - [ - 123.486563, - -16.990653 - ], - [ - 124.487732, - -16.990653 - ], - [ - 124.487732, - -14.988316 - ], - [ - 123.486563, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 123.486563, - -16.990653 - ], - [ - 123.486563, - -18.99299 - ], - [ - 124.487732, - -18.99299 - ], - [ - 124.487732, - -16.990653 - ], - [ - 123.486563, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 123.486563, - -18.99299 - ], - [ - 123.486563, - -20.995326 - ], - [ - 124.487732, - -20.995326 - ], - [ - 124.487732, - -18.99299 - ], - [ - 123.486563, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 123.486563, - -20.995326 - ], - [ - 123.486563, - -22.997663 - ], - [ - 124.487732, - -22.997663 - ], - [ - 124.487732, - -20.995326 - ], - [ - 123.486563, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 123.486563, - -22.997663 - ], - [ - 123.486563, - -25 - ], - [ - 124.487732, - -25 - ], - [ - 124.487732, - -22.997663 - ], - [ - 123.486563, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 123.486563, - -25 - ], - [ - 123.486563, - -27.002337 - ], - [ - 124.487732, - -27.002337 - ], - [ - 124.487732, - -25 - ], - [ - 123.486563, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 123.486563, - -27.002337 - ], - [ - 123.486563, - -29.004674 - ], - [ - 124.487732, - -29.004674 - ], - [ - 124.487732, - -27.002337 - ], - [ - 123.486563, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 123.486563, - -29.004674 - ], - [ - 123.486563, - -31.00701 - ], - [ - 124.487732, - -31.00701 - ], - [ - 124.487732, - -29.004674 - ], - [ - 123.486563, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 123.486563, - -31.00701 - ], - [ - 123.486563, - -33.009347 - ], - [ - 124.487732, - -33.009347 - ], - [ - 124.487732, - -31.00701 - ], - [ - 123.486563, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 123.486563, - -33.009347 - ], - [ - 123.486563, - -35.011684 - ], - [ - 124.487732, - -35.011684 - ], - [ - 124.487732, - -33.009347 - ], - [ - 123.486563, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 124.487732, - -12.985979 - ], - [ - 124.487732, - -14.988316 - ], - [ - 125.4889, - -14.988316 - ], - [ - 125.4889, - -12.985979 - ], - [ - 124.487732, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 124.487732, - -14.988316 - ], - [ - 124.487732, - -16.990653 - ], - [ - 125.4889, - -16.990653 - ], - [ - 125.4889, - -14.988316 - ], - [ - 124.487732, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 124.487732, - -16.990653 - ], - [ - 124.487732, - -18.99299 - ], - [ - 125.4889, - -18.99299 - ], - [ - 125.4889, - -16.990653 - ], - [ - 124.487732, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 124.487732, - -18.99299 - ], - [ - 124.487732, - -20.995326 - ], - [ - 125.4889, - -20.995326 - ], - [ - 125.4889, - -18.99299 - ], - [ - 124.487732, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 124.487732, - -20.995326 - ], - [ - 124.487732, - -22.997663 - ], - [ - 125.4889, - -22.997663 - ], - [ - 125.4889, - -20.995326 - ], - [ - 124.487732, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 124.487732, - -22.997663 - ], - [ - 124.487732, - -25 - ], - [ - 125.4889, - -25 - ], - [ - 125.4889, - -22.997663 - ], - [ - 124.487732, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 124.487732, - -25 - ], - [ - 124.487732, - -27.002337 - ], - [ - 125.4889, - -27.002337 - ], - [ - 125.4889, - -25 - ], - [ - 124.487732, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 124.487732, - -27.002337 - ], - [ - 124.487732, - -29.004674 - ], - [ - 125.4889, - -29.004674 - ], - [ - 125.4889, - -27.002337 - ], - [ - 124.487732, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 124.487732, - -29.004674 - ], - [ - 124.487732, - -31.00701 - ], - [ - 125.4889, - -31.00701 - ], - [ - 125.4889, - -29.004674 - ], - [ - 124.487732, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 124.487732, - -31.00701 - ], - [ - 124.487732, - -33.009347 - ], - [ - 125.4889, - -33.009347 - ], - [ - 125.4889, - -31.00701 - ], - [ - 124.487732, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 124.487732, - -33.009347 - ], - [ - 124.487732, - -35.011684 - ], - [ - 125.4889, - -35.011684 - ], - [ - 125.4889, - -33.009347 - ], - [ - 124.487732, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 125.4889, - -12.985979 - ], - [ - 125.4889, - -14.988316 - ], - [ - 126.490069, - -14.988316 - ], - [ - 126.490069, - -12.985979 - ], - [ - 125.4889, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 125.4889, - -14.988316 - ], - [ - 125.4889, - -16.990653 - ], - [ - 126.490069, - -16.990653 - ], - [ - 126.490069, - -14.988316 - ], - [ - 125.4889, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 125.4889, - -16.990653 - ], - [ - 125.4889, - -18.99299 - ], - [ - 126.490069, - -18.99299 - ], - [ - 126.490069, - -16.990653 - ], - [ - 125.4889, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 125.4889, - -18.99299 - ], - [ - 125.4889, - -20.995326 - ], - [ - 126.490069, - -20.995326 - ], - [ - 126.490069, - -18.99299 - ], - [ - 125.4889, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 125.4889, - -20.995326 - ], - [ - 125.4889, - -22.997663 - ], - [ - 126.490069, - -22.997663 - ], - [ - 126.490069, - -20.995326 - ], - [ - 125.4889, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 125.4889, - -22.997663 - ], - [ - 125.4889, - -25 - ], - [ - 126.490069, - -25 - ], - [ - 126.490069, - -22.997663 - ], - [ - 125.4889, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 125.4889, - -25 - ], - [ - 125.4889, - -27.002337 - ], - [ - 126.490069, - -27.002337 - ], - [ - 126.490069, - -25 - ], - [ - 125.4889, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 125.4889, - -27.002337 - ], - [ - 125.4889, - -29.004674 - ], - [ - 126.490069, - -29.004674 - ], - [ - 126.490069, - -27.002337 - ], - [ - 125.4889, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 125.4889, - -29.004674 - ], - [ - 125.4889, - -31.00701 - ], - [ - 126.490069, - -31.00701 - ], - [ - 126.490069, - -29.004674 - ], - [ - 125.4889, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 125.4889, - -31.00701 - ], - [ - 125.4889, - -33.009347 - ], - [ - 126.490069, - -33.009347 - ], - [ - 126.490069, - -31.00701 - ], - [ - 125.4889, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 126.490069, - -12.985979 - ], - [ - 126.490069, - -14.988316 - ], - [ - 127.491237, - -14.988316 - ], - [ - 127.491237, - -12.985979 - ], - [ - 126.490069, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 126.490069, - -14.988316 - ], - [ - 126.490069, - -16.990653 - ], - [ - 127.491237, - -16.990653 - ], - [ - 127.491237, - -14.988316 - ], - [ - 126.490069, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 126.490069, - -16.990653 - ], - [ - 126.490069, - -18.99299 - ], - [ - 127.491237, - -18.99299 - ], - [ - 127.491237, - -16.990653 - ], - [ - 126.490069, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 126.490069, - -18.99299 - ], - [ - 126.490069, - -20.995326 - ], - [ - 127.491237, - -20.995326 - ], - [ - 127.491237, - -18.99299 - ], - [ - 126.490069, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 126.490069, - -20.995326 - ], - [ - 126.490069, - -22.997663 - ], - [ - 127.491237, - -22.997663 - ], - [ - 127.491237, - -20.995326 - ], - [ - 126.490069, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 126.490069, - -22.997663 - ], - [ - 126.490069, - -25 - ], - [ - 127.491237, - -25 - ], - [ - 127.491237, - -22.997663 - ], - [ - 126.490069, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 126.490069, - -25 - ], - [ - 126.490069, - -27.002337 - ], - [ - 127.491237, - -27.002337 - ], - [ - 127.491237, - -25 - ], - [ - 126.490069, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 126.490069, - -27.002337 - ], - [ - 126.490069, - -29.004674 - ], - [ - 127.491237, - -29.004674 - ], - [ - 127.491237, - -27.002337 - ], - [ - 126.490069, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 126.490069, - -29.004674 - ], - [ - 126.490069, - -31.00701 - ], - [ - 127.491237, - -31.00701 - ], - [ - 127.491237, - -29.004674 - ], - [ - 126.490069, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 126.490069, - -31.00701 - ], - [ - 126.490069, - -33.009347 - ], - [ - 127.491237, - -33.009347 - ], - [ - 127.491237, - -31.00701 - ], - [ - 126.490069, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 127.491237, - -12.985979 - ], - [ - 127.491237, - -14.988316 - ], - [ - 128.492405, - -14.988316 - ], - [ - 128.492405, - -12.985979 - ], - [ - 127.491237, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 127.491237, - -14.988316 - ], - [ - 127.491237, - -16.990653 - ], - [ - 128.492405, - -16.990653 - ], - [ - 128.492405, - -14.988316 - ], - [ - 127.491237, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 127.491237, - -16.990653 - ], - [ - 127.491237, - -18.99299 - ], - [ - 128.492405, - -18.99299 - ], - [ - 128.492405, - -16.990653 - ], - [ - 127.491237, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 127.491237, - -18.99299 - ], - [ - 127.491237, - -20.995326 - ], - [ - 128.492405, - -20.995326 - ], - [ - 128.492405, - -18.99299 - ], - [ - 127.491237, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 127.491237, - -20.995326 - ], - [ - 127.491237, - -22.997663 - ], - [ - 128.492405, - -22.997663 - ], - [ - 128.492405, - -20.995326 - ], - [ - 127.491237, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 127.491237, - -22.997663 - ], - [ - 127.491237, - -25 - ], - [ - 128.492405, - -25 - ], - [ - 128.492405, - -22.997663 - ], - [ - 127.491237, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 127.491237, - -25 - ], - [ - 127.491237, - -27.002337 - ], - [ - 128.492405, - -27.002337 - ], - [ - 128.492405, - -25 - ], - [ - 127.491237, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 127.491237, - -27.002337 - ], - [ - 127.491237, - -29.004674 - ], - [ - 128.492405, - -29.004674 - ], - [ - 128.492405, - -27.002337 - ], - [ - 127.491237, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 127.491237, - -29.004674 - ], - [ - 127.491237, - -31.00701 - ], - [ - 128.492405, - -31.00701 - ], - [ - 128.492405, - -29.004674 - ], - [ - 127.491237, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 127.491237, - -31.00701 - ], - [ - 127.491237, - -33.009347 - ], - [ - 128.492405, - -33.009347 - ], - [ - 128.492405, - -31.00701 - ], - [ - 127.491237, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 128.492405, - -12.985979 - ], - [ - 128.492405, - -14.988316 - ], - [ - 129.493574, - -14.988316 - ], - [ - 129.493574, - -12.985979 - ], - [ - 128.492405, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 128.492405, - -14.988316 - ], - [ - 128.492405, - -16.990653 - ], - [ - 129.493574, - -16.990653 - ], - [ - 129.493574, - -14.988316 - ], - [ - 128.492405, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 128.492405, - -16.990653 - ], - [ - 128.492405, - -18.99299 - ], - [ - 129.493574, - -18.99299 - ], - [ - 129.493574, - -16.990653 - ], - [ - 128.492405, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 128.492405, - -18.99299 - ], - [ - 128.492405, - -20.995326 - ], - [ - 129.493574, - -20.995326 - ], - [ - 129.493574, - -18.99299 - ], - [ - 128.492405, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 128.492405, - -20.995326 - ], - [ - 128.492405, - -22.997663 - ], - [ - 129.493574, - -22.997663 - ], - [ - 129.493574, - -20.995326 - ], - [ - 128.492405, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 128.492405, - -22.997663 - ], - [ - 128.492405, - -25 - ], - [ - 129.493574, - -25 - ], - [ - 129.493574, - -22.997663 - ], - [ - 128.492405, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 128.492405, - -25 - ], - [ - 128.492405, - -27.002337 - ], - [ - 129.493574, - -27.002337 - ], - [ - 129.493574, - -25 - ], - [ - 128.492405, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 128.492405, - -27.002337 - ], - [ - 128.492405, - -29.004674 - ], - [ - 129.493574, - -29.004674 - ], - [ - 129.493574, - -27.002337 - ], - [ - 128.492405, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 128.492405, - -29.004674 - ], - [ - 128.492405, - -31.00701 - ], - [ - 129.493574, - -31.00701 - ], - [ - 129.493574, - -29.004674 - ], - [ - 128.492405, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 128.492405, - -31.00701 - ], - [ - 128.492405, - -33.009347 - ], - [ - 129.493574, - -33.009347 - ], - [ - 129.493574, - -31.00701 - ], - [ - 128.492405, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 129.493574, - -10.983642 - ], - [ - 129.493574, - -12.985979 - ], - [ - 130.494742, - -12.985979 - ], - [ - 130.494742, - -10.983642 - ], - [ - 129.493574, - -10.983642 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 129.493574, - -12.985979 - ], - [ - 129.493574, - -14.988316 - ], - [ - 130.494742, - -14.988316 - ], - [ - 130.494742, - -12.985979 - ], - [ - 129.493574, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 129.493574, - -14.988316 - ], - [ - 129.493574, - -16.990653 - ], - [ - 130.494742, - -16.990653 - ], - [ - 130.494742, - -14.988316 - ], - [ - 129.493574, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 129.493574, - -16.990653 - ], - [ - 129.493574, - -18.99299 - ], - [ - 130.494742, - -18.99299 - ], - [ - 130.494742, - -16.990653 - ], - [ - 129.493574, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 129.493574, - -18.99299 - ], - [ - 129.493574, - -20.995326 - ], - [ - 130.494742, - -20.995326 - ], - [ - 130.494742, - -18.99299 - ], - [ - 129.493574, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 129.493574, - -20.995326 - ], - [ - 129.493574, - -22.997663 - ], - [ - 130.494742, - -22.997663 - ], - [ - 130.494742, - -20.995326 - ], - [ - 129.493574, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 129.493574, - -22.997663 - ], - [ - 129.493574, - -25 - ], - [ - 130.494742, - -25 - ], - [ - 130.494742, - -22.997663 - ], - [ - 129.493574, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 129.493574, - -25 - ], - [ - 129.493574, - -27.002337 - ], - [ - 130.494742, - -27.002337 - ], - [ - 130.494742, - -25 - ], - [ - 129.493574, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 129.493574, - -27.002337 - ], - [ - 129.493574, - -29.004674 - ], - [ - 130.494742, - -29.004674 - ], - [ - 130.494742, - -27.002337 - ], - [ - 129.493574, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 129.493574, - -29.004674 - ], - [ - 129.493574, - -31.00701 - ], - [ - 130.494742, - -31.00701 - ], - [ - 130.494742, - -29.004674 - ], - [ - 129.493574, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 129.493574, - -31.00701 - ], - [ - 129.493574, - -33.009347 - ], - [ - 130.494742, - -33.009347 - ], - [ - 130.494742, - -31.00701 - ], - [ - 129.493574, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 130.494742, - -10.983642 - ], - [ - 130.494742, - -12.985979 - ], - [ - 131.495911, - -12.985979 - ], - [ - 131.495911, - -10.983642 - ], - [ - 130.494742, - -10.983642 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 130.494742, - -12.985979 - ], - [ - 130.494742, - -14.988316 - ], - [ - 131.495911, - -14.988316 - ], - [ - 131.495911, - -12.985979 - ], - [ - 130.494742, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 130.494742, - -14.988316 - ], - [ - 130.494742, - -16.990653 - ], - [ - 131.495911, - -16.990653 - ], - [ - 131.495911, - -14.988316 - ], - [ - 130.494742, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 130.494742, - -16.990653 - ], - [ - 130.494742, - -18.99299 - ], - [ - 131.495911, - -18.99299 - ], - [ - 131.495911, - -16.990653 - ], - [ - 130.494742, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 130.494742, - -18.99299 - ], - [ - 130.494742, - -20.995326 - ], - [ - 131.495911, - -20.995326 - ], - [ - 131.495911, - -18.99299 - ], - [ - 130.494742, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 130.494742, - -20.995326 - ], - [ - 130.494742, - -22.997663 - ], - [ - 131.495911, - -22.997663 - ], - [ - 131.495911, - -20.995326 - ], - [ - 130.494742, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 130.494742, - -22.997663 - ], - [ - 130.494742, - -25 - ], - [ - 131.495911, - -25 - ], - [ - 131.495911, - -22.997663 - ], - [ - 130.494742, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 130.494742, - -25 - ], - [ - 130.494742, - -27.002337 - ], - [ - 131.495911, - -27.002337 - ], - [ - 131.495911, - -25 - ], - [ - 130.494742, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 130.494742, - -27.002337 - ], - [ - 130.494742, - -29.004674 - ], - [ - 131.495911, - -29.004674 - ], - [ - 131.495911, - -27.002337 - ], - [ - 130.494742, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 130.494742, - -29.004674 - ], - [ - 130.494742, - -31.00701 - ], - [ - 131.495911, - -31.00701 - ], - [ - 131.495911, - -29.004674 - ], - [ - 130.494742, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 130.494742, - -31.00701 - ], - [ - 130.494742, - -33.009347 - ], - [ - 131.495911, - -33.009347 - ], - [ - 131.495911, - -31.00701 - ], - [ - 130.494742, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 131.495911, - -10.983642 - ], - [ - 131.495911, - -12.985979 - ], - [ - 132.497079, - -12.985979 - ], - [ - 132.497079, - -10.983642 - ], - [ - 131.495911, - -10.983642 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 131.495911, - -12.985979 - ], - [ - 131.495911, - -14.988316 - ], - [ - 132.497079, - -14.988316 - ], - [ - 132.497079, - -12.985979 - ], - [ - 131.495911, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 131.495911, - -14.988316 - ], - [ - 131.495911, - -16.990653 - ], - [ - 132.497079, - -16.990653 - ], - [ - 132.497079, - -14.988316 - ], - [ - 131.495911, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 131.495911, - -16.990653 - ], - [ - 131.495911, - -18.99299 - ], - [ - 132.497079, - -18.99299 - ], - [ - 132.497079, - -16.990653 - ], - [ - 131.495911, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 131.495911, - -18.99299 - ], - [ - 131.495911, - -20.995326 - ], - [ - 132.497079, - -20.995326 - ], - [ - 132.497079, - -18.99299 - ], - [ - 131.495911, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 131.495911, - -20.995326 - ], - [ - 131.495911, - -22.997663 - ], - [ - 132.497079, - -22.997663 - ], - [ - 132.497079, - -20.995326 - ], - [ - 131.495911, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 131.495911, - -22.997663 - ], - [ - 131.495911, - -25 - ], - [ - 132.497079, - -25 - ], - [ - 132.497079, - -22.997663 - ], - [ - 131.495911, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 131.495911, - -25 - ], - [ - 131.495911, - -27.002337 - ], - [ - 132.497079, - -27.002337 - ], - [ - 132.497079, - -25 - ], - [ - 131.495911, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 131.495911, - -27.002337 - ], - [ - 131.495911, - -29.004674 - ], - [ - 132.497079, - -29.004674 - ], - [ - 132.497079, - -27.002337 - ], - [ - 131.495911, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 131.495911, - -29.004674 - ], - [ - 131.495911, - -31.00701 - ], - [ - 132.497079, - -31.00701 - ], - [ - 132.497079, - -29.004674 - ], - [ - 131.495911, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 131.495911, - -31.00701 - ], - [ - 131.495911, - -33.009347 - ], - [ - 132.497079, - -33.009347 - ], - [ - 132.497079, - -31.00701 - ], - [ - 131.495911, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 132.497079, - -10.983642 - ], - [ - 132.497079, - -12.985979 - ], - [ - 133.498247, - -12.985979 - ], - [ - 133.498247, - -10.983642 - ], - [ - 132.497079, - -10.983642 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 132.497079, - -12.985979 - ], - [ - 132.497079, - -14.988316 - ], - [ - 133.498247, - -14.988316 - ], - [ - 133.498247, - -12.985979 - ], - [ - 132.497079, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 132.497079, - -14.988316 - ], - [ - 132.497079, - -16.990653 - ], - [ - 133.498247, - -16.990653 - ], - [ - 133.498247, - -14.988316 - ], - [ - 132.497079, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 132.497079, - -16.990653 - ], - [ - 132.497079, - -18.99299 - ], - [ - 133.498247, - -18.99299 - ], - [ - 133.498247, - -16.990653 - ], - [ - 132.497079, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 132.497079, - -18.99299 - ], - [ - 132.497079, - -20.995326 - ], - [ - 133.498247, - -20.995326 - ], - [ - 133.498247, - -18.99299 - ], - [ - 132.497079, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 132.497079, - -20.995326 - ], - [ - 132.497079, - -22.997663 - ], - [ - 133.498247, - -22.997663 - ], - [ - 133.498247, - -20.995326 - ], - [ - 132.497079, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 132.497079, - -22.997663 - ], - [ - 132.497079, - -25 - ], - [ - 133.498247, - -25 - ], - [ - 133.498247, - -22.997663 - ], - [ - 132.497079, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 132.497079, - -25 - ], - [ - 132.497079, - -27.002337 - ], - [ - 133.498247, - -27.002337 - ], - [ - 133.498247, - -25 - ], - [ - 132.497079, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 132.497079, - -27.002337 - ], - [ - 132.497079, - -29.004674 - ], - [ - 133.498247, - -29.004674 - ], - [ - 133.498247, - -27.002337 - ], - [ - 132.497079, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 132.497079, - -29.004674 - ], - [ - 132.497079, - -31.00701 - ], - [ - 133.498247, - -31.00701 - ], - [ - 133.498247, - -29.004674 - ], - [ - 132.497079, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 132.497079, - -31.00701 - ], - [ - 132.497079, - -33.009347 - ], - [ - 133.498247, - -33.009347 - ], - [ - 133.498247, - -31.00701 - ], - [ - 132.497079, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 133.498247, - -10.983642 - ], - [ - 133.498247, - -12.985979 - ], - [ - 134.499416, - -12.985979 - ], - [ - 134.499416, - -10.983642 - ], - [ - 133.498247, - -10.983642 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 133.498247, - -12.985979 - ], - [ - 133.498247, - -14.988316 - ], - [ - 134.499416, - -14.988316 - ], - [ - 134.499416, - -12.985979 - ], - [ - 133.498247, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 133.498247, - -14.988316 - ], - [ - 133.498247, - -16.990653 - ], - [ - 134.499416, - -16.990653 - ], - [ - 134.499416, - -14.988316 - ], - [ - 133.498247, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 133.498247, - -16.990653 - ], - [ - 133.498247, - -18.99299 - ], - [ - 134.499416, - -18.99299 - ], - [ - 134.499416, - -16.990653 - ], - [ - 133.498247, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 133.498247, - -18.99299 - ], - [ - 133.498247, - -20.995326 - ], - [ - 134.499416, - -20.995326 - ], - [ - 134.499416, - -18.99299 - ], - [ - 133.498247, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 133.498247, - -20.995326 - ], - [ - 133.498247, - -22.997663 - ], - [ - 134.499416, - -22.997663 - ], - [ - 134.499416, - -20.995326 - ], - [ - 133.498247, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 133.498247, - -22.997663 - ], - [ - 133.498247, - -25 - ], - [ - 134.499416, - -25 - ], - [ - 134.499416, - -22.997663 - ], - [ - 133.498247, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 133.498247, - -25 - ], - [ - 133.498247, - -27.002337 - ], - [ - 134.499416, - -27.002337 - ], - [ - 134.499416, - -25 - ], - [ - 133.498247, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 133.498247, - -27.002337 - ], - [ - 133.498247, - -29.004674 - ], - [ - 134.499416, - -29.004674 - ], - [ - 134.499416, - -27.002337 - ], - [ - 133.498247, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 133.498247, - -29.004674 - ], - [ - 133.498247, - -31.00701 - ], - [ - 134.499416, - -31.00701 - ], - [ - 134.499416, - -29.004674 - ], - [ - 133.498247, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 133.498247, - -31.00701 - ], - [ - 133.498247, - -33.009347 - ], - [ - 134.499416, - -33.009347 - ], - [ - 134.499416, - -31.00701 - ], - [ - 133.498247, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 133.498247, - -33.009347 - ], - [ - 133.498247, - -35.011684 - ], - [ - 134.499416, - -35.011684 - ], - [ - 134.499416, - -33.009347 - ], - [ - 133.498247, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 134.499416, - -10.983642 - ], - [ - 134.499416, - -12.985979 - ], - [ - 135.500584, - -12.985979 - ], - [ - 135.500584, - -10.983642 - ], - [ - 134.499416, - -10.983642 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 134.499416, - -12.985979 - ], - [ - 134.499416, - -14.988316 - ], - [ - 135.500584, - -14.988316 - ], - [ - 135.500584, - -12.985979 - ], - [ - 134.499416, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 134.499416, - -14.988316 - ], - [ - 134.499416, - -16.990653 - ], - [ - 135.500584, - -16.990653 - ], - [ - 135.500584, - -14.988316 - ], - [ - 134.499416, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 134.499416, - -16.990653 - ], - [ - 134.499416, - -18.99299 - ], - [ - 135.500584, - -18.99299 - ], - [ - 135.500584, - -16.990653 - ], - [ - 134.499416, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 134.499416, - -18.99299 - ], - [ - 134.499416, - -20.995326 - ], - [ - 135.500584, - -20.995326 - ], - [ - 135.500584, - -18.99299 - ], - [ - 134.499416, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 134.499416, - -20.995326 - ], - [ - 134.499416, - -22.997663 - ], - [ - 135.500584, - -22.997663 - ], - [ - 135.500584, - -20.995326 - ], - [ - 134.499416, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 134.499416, - -22.997663 - ], - [ - 134.499416, - -25 - ], - [ - 135.500584, - -25 - ], - [ - 135.500584, - -22.997663 - ], - [ - 134.499416, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 134.499416, - -25 - ], - [ - 134.499416, - -27.002337 - ], - [ - 135.500584, - -27.002337 - ], - [ - 135.500584, - -25 - ], - [ - 134.499416, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 134.499416, - -27.002337 - ], - [ - 134.499416, - -29.004674 - ], - [ - 135.500584, - -29.004674 - ], - [ - 135.500584, - -27.002337 - ], - [ - 134.499416, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 134.499416, - -29.004674 - ], - [ - 134.499416, - -31.00701 - ], - [ - 135.500584, - -31.00701 - ], - [ - 135.500584, - -29.004674 - ], - [ - 134.499416, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 134.499416, - -31.00701 - ], - [ - 134.499416, - -33.009347 - ], - [ - 135.500584, - -33.009347 - ], - [ - 135.500584, - -31.00701 - ], - [ - 134.499416, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 134.499416, - -33.009347 - ], - [ - 134.499416, - -35.011684 - ], - [ - 135.500584, - -35.011684 - ], - [ - 135.500584, - -33.009347 - ], - [ - 134.499416, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 135.500584, - -10.983642 - ], - [ - 135.500584, - -12.985979 - ], - [ - 136.501753, - -12.985979 - ], - [ - 136.501753, - -10.983642 - ], - [ - 135.500584, - -10.983642 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 135.500584, - -12.985979 - ], - [ - 135.500584, - -14.988316 - ], - [ - 136.501753, - -14.988316 - ], - [ - 136.501753, - -12.985979 - ], - [ - 135.500584, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 135.500584, - -14.988316 - ], - [ - 135.500584, - -16.990653 - ], - [ - 136.501753, - -16.990653 - ], - [ - 136.501753, - -14.988316 - ], - [ - 135.500584, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 135.500584, - -16.990653 - ], - [ - 135.500584, - -18.99299 - ], - [ - 136.501753, - -18.99299 - ], - [ - 136.501753, - -16.990653 - ], - [ - 135.500584, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 135.500584, - -18.99299 - ], - [ - 135.500584, - -20.995326 - ], - [ - 136.501753, - -20.995326 - ], - [ - 136.501753, - -18.99299 - ], - [ - 135.500584, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 135.500584, - -20.995326 - ], - [ - 135.500584, - -22.997663 - ], - [ - 136.501753, - -22.997663 - ], - [ - 136.501753, - -20.995326 - ], - [ - 135.500584, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 135.500584, - -22.997663 - ], - [ - 135.500584, - -25 - ], - [ - 136.501753, - -25 - ], - [ - 136.501753, - -22.997663 - ], - [ - 135.500584, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 135.500584, - -25 - ], - [ - 135.500584, - -27.002337 - ], - [ - 136.501753, - -27.002337 - ], - [ - 136.501753, - -25 - ], - [ - 135.500584, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 135.500584, - -27.002337 - ], - [ - 135.500584, - -29.004674 - ], - [ - 136.501753, - -29.004674 - ], - [ - 136.501753, - -27.002337 - ], - [ - 135.500584, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 135.500584, - -29.004674 - ], - [ - 135.500584, - -31.00701 - ], - [ - 136.501753, - -31.00701 - ], - [ - 136.501753, - -29.004674 - ], - [ - 135.500584, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 135.500584, - -31.00701 - ], - [ - 135.500584, - -33.009347 - ], - [ - 136.501753, - -33.009347 - ], - [ - 136.501753, - -31.00701 - ], - [ - 135.500584, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 135.500584, - -33.009347 - ], - [ - 135.500584, - -35.011684 - ], - [ - 136.501753, - -35.011684 - ], - [ - 136.501753, - -33.009347 - ], - [ - 135.500584, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 136.501753, - -10.983642 - ], - [ - 136.501753, - -12.985979 - ], - [ - 137.502921, - -12.985979 - ], - [ - 137.502921, - -10.983642 - ], - [ - 136.501753, - -10.983642 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 136.501753, - -12.985979 - ], - [ - 136.501753, - -14.988316 - ], - [ - 137.502921, - -14.988316 - ], - [ - 137.502921, - -12.985979 - ], - [ - 136.501753, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 136.501753, - -14.988316 - ], - [ - 136.501753, - -16.990653 - ], - [ - 137.502921, - -16.990653 - ], - [ - 137.502921, - -14.988316 - ], - [ - 136.501753, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 136.501753, - -16.990653 - ], - [ - 136.501753, - -18.99299 - ], - [ - 137.502921, - -18.99299 - ], - [ - 137.502921, - -16.990653 - ], - [ - 136.501753, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 136.501753, - -18.99299 - ], - [ - 136.501753, - -20.995326 - ], - [ - 137.502921, - -20.995326 - ], - [ - 137.502921, - -18.99299 - ], - [ - 136.501753, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 136.501753, - -20.995326 - ], - [ - 136.501753, - -22.997663 - ], - [ - 137.502921, - -22.997663 - ], - [ - 137.502921, - -20.995326 - ], - [ - 136.501753, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 136.501753, - -22.997663 - ], - [ - 136.501753, - -25 - ], - [ - 137.502921, - -25 - ], - [ - 137.502921, - -22.997663 - ], - [ - 136.501753, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 136.501753, - -25 - ], - [ - 136.501753, - -27.002337 - ], - [ - 137.502921, - -27.002337 - ], - [ - 137.502921, - -25 - ], - [ - 136.501753, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 136.501753, - -27.002337 - ], - [ - 136.501753, - -29.004674 - ], - [ - 137.502921, - -29.004674 - ], - [ - 137.502921, - -27.002337 - ], - [ - 136.501753, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 136.501753, - -29.004674 - ], - [ - 136.501753, - -31.00701 - ], - [ - 137.502921, - -31.00701 - ], - [ - 137.502921, - -29.004674 - ], - [ - 136.501753, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 136.501753, - -31.00701 - ], - [ - 136.501753, - -33.009347 - ], - [ - 137.502921, - -33.009347 - ], - [ - 137.502921, - -31.00701 - ], - [ - 136.501753, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 136.501753, - -33.009347 - ], - [ - 136.501753, - -35.011684 - ], - [ - 137.502921, - -35.011684 - ], - [ - 137.502921, - -33.009347 - ], - [ - 136.501753, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 137.502921, - -14.988316 - ], - [ - 137.502921, - -16.990653 - ], - [ - 138.504089, - -16.990653 - ], - [ - 138.504089, - -14.988316 - ], - [ - 137.502921, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 137.502921, - -16.990653 - ], - [ - 137.502921, - -18.99299 - ], - [ - 138.504089, - -18.99299 - ], - [ - 138.504089, - -16.990653 - ], - [ - 137.502921, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 137.502921, - -18.99299 - ], - [ - 137.502921, - -20.995326 - ], - [ - 138.504089, - -20.995326 - ], - [ - 138.504089, - -18.99299 - ], - [ - 137.502921, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 137.502921, - -20.995326 - ], - [ - 137.502921, - -22.997663 - ], - [ - 138.504089, - -22.997663 - ], - [ - 138.504089, - -20.995326 - ], - [ - 137.502921, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 137.502921, - -22.997663 - ], - [ - 137.502921, - -25 - ], - [ - 138.504089, - -25 - ], - [ - 138.504089, - -22.997663 - ], - [ - 137.502921, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 137.502921, - -25 - ], - [ - 137.502921, - -27.002337 - ], - [ - 138.504089, - -27.002337 - ], - [ - 138.504089, - -25 - ], - [ - 137.502921, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 137.502921, - -27.002337 - ], - [ - 137.502921, - -29.004674 - ], - [ - 138.504089, - -29.004674 - ], - [ - 138.504089, - -27.002337 - ], - [ - 137.502921, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 137.502921, - -29.004674 - ], - [ - 137.502921, - -31.00701 - ], - [ - 138.504089, - -31.00701 - ], - [ - 138.504089, - -29.004674 - ], - [ - 137.502921, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 137.502921, - -31.00701 - ], - [ - 137.502921, - -33.009347 - ], - [ - 138.504089, - -33.009347 - ], - [ - 138.504089, - -31.00701 - ], - [ - 137.502921, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 137.502921, - -33.009347 - ], - [ - 137.502921, - -35.011684 - ], - [ - 138.504089, - -35.011684 - ], - [ - 138.504089, - -33.009347 - ], - [ - 137.502921, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 137.502921, - -35.011684 - ], - [ - 137.502921, - -37.014021 - ], - [ - 138.504089, - -37.014021 - ], - [ - 138.504089, - -35.011684 - ], - [ - 137.502921, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 138.504089, - -14.988316 - ], - [ - 138.504089, - -16.990653 - ], - [ - 139.505258, - -16.990653 - ], - [ - 139.505258, - -14.988316 - ], - [ - 138.504089, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 138.504089, - -16.990653 - ], - [ - 138.504089, - -18.99299 - ], - [ - 139.505258, - -18.99299 - ], - [ - 139.505258, - -16.990653 - ], - [ - 138.504089, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 138.504089, - -18.99299 - ], - [ - 138.504089, - -20.995326 - ], - [ - 139.505258, - -20.995326 - ], - [ - 139.505258, - -18.99299 - ], - [ - 138.504089, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 138.504089, - -20.995326 - ], - [ - 138.504089, - -22.997663 - ], - [ - 139.505258, - -22.997663 - ], - [ - 139.505258, - -20.995326 - ], - [ - 138.504089, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 138.504089, - -22.997663 - ], - [ - 138.504089, - -25 - ], - [ - 139.505258, - -25 - ], - [ - 139.505258, - -22.997663 - ], - [ - 138.504089, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 138.504089, - -25 - ], - [ - 138.504089, - -27.002337 - ], - [ - 139.505258, - -27.002337 - ], - [ - 139.505258, - -25 - ], - [ - 138.504089, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 138.504089, - -27.002337 - ], - [ - 138.504089, - -29.004674 - ], - [ - 139.505258, - -29.004674 - ], - [ - 139.505258, - -27.002337 - ], - [ - 138.504089, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 138.504089, - -29.004674 - ], - [ - 138.504089, - -31.00701 - ], - [ - 139.505258, - -31.00701 - ], - [ - 139.505258, - -29.004674 - ], - [ - 138.504089, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 138.504089, - -31.00701 - ], - [ - 138.504089, - -33.009347 - ], - [ - 139.505258, - -33.009347 - ], - [ - 139.505258, - -31.00701 - ], - [ - 138.504089, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 138.504089, - -33.009347 - ], - [ - 138.504089, - -35.011684 - ], - [ - 139.505258, - -35.011684 - ], - [ - 139.505258, - -33.009347 - ], - [ - 138.504089, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 138.504089, - -35.011684 - ], - [ - 138.504089, - -37.014021 - ], - [ - 139.505258, - -37.014021 - ], - [ - 139.505258, - -35.011684 - ], - [ - 138.504089, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 139.505258, - -14.988316 - ], - [ - 139.505258, - -16.990653 - ], - [ - 140.506426, - -16.990653 - ], - [ - 140.506426, - -14.988316 - ], - [ - 139.505258, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 139.505258, - -16.990653 - ], - [ - 139.505258, - -18.99299 - ], - [ - 140.506426, - -18.99299 - ], - [ - 140.506426, - -16.990653 - ], - [ - 139.505258, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 139.505258, - -18.99299 - ], - [ - 139.505258, - -20.995326 - ], - [ - 140.506426, - -20.995326 - ], - [ - 140.506426, - -18.99299 - ], - [ - 139.505258, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 139.505258, - -20.995326 - ], - [ - 139.505258, - -22.997663 - ], - [ - 140.506426, - -22.997663 - ], - [ - 140.506426, - -20.995326 - ], - [ - 139.505258, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 139.505258, - -22.997663 - ], - [ - 139.505258, - -25 - ], - [ - 140.506426, - -25 - ], - [ - 140.506426, - -22.997663 - ], - [ - 139.505258, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 139.505258, - -25 - ], - [ - 139.505258, - -27.002337 - ], - [ - 140.506426, - -27.002337 - ], - [ - 140.506426, - -25 - ], - [ - 139.505258, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 139.505258, - -27.002337 - ], - [ - 139.505258, - -29.004674 - ], - [ - 140.506426, - -29.004674 - ], - [ - 140.506426, - -27.002337 - ], - [ - 139.505258, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 139.505258, - -29.004674 - ], - [ - 139.505258, - -31.00701 - ], - [ - 140.506426, - -31.00701 - ], - [ - 140.506426, - -29.004674 - ], - [ - 139.505258, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 139.505258, - -31.00701 - ], - [ - 139.505258, - -33.009347 - ], - [ - 140.506426, - -33.009347 - ], - [ - 140.506426, - -31.00701 - ], - [ - 139.505258, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 139.505258, - -33.009347 - ], - [ - 139.505258, - -35.011684 - ], - [ - 140.506426, - -35.011684 - ], - [ - 140.506426, - -33.009347 - ], - [ - 139.505258, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 139.505258, - -35.011684 - ], - [ - 139.505258, - -37.014021 - ], - [ - 140.506426, - -37.014021 - ], - [ - 140.506426, - -35.011684 - ], - [ - 139.505258, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 139.505258, - -37.014021 - ], - [ - 139.505258, - -39.016358 - ], - [ - 140.506426, - -39.016358 - ], - [ - 140.506426, - -37.014021 - ], - [ - 139.505258, - -37.014021 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 140.506426, - -12.985979 - ], - [ - 140.506426, - -14.988316 - ], - [ - 141.507595, - -14.988316 - ], - [ - 141.507595, - -12.985979 - ], - [ - 140.506426, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 140.506426, - -14.988316 - ], - [ - 140.506426, - -16.990653 - ], - [ - 141.507595, - -16.990653 - ], - [ - 141.507595, - -14.988316 - ], - [ - 140.506426, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 140.506426, - -16.990653 - ], - [ - 140.506426, - -18.99299 - ], - [ - 141.507595, - -18.99299 - ], - [ - 141.507595, - -16.990653 - ], - [ - 140.506426, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 140.506426, - -18.99299 - ], - [ - 140.506426, - -20.995326 - ], - [ - 141.507595, - -20.995326 - ], - [ - 141.507595, - -18.99299 - ], - [ - 140.506426, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 140.506426, - -20.995326 - ], - [ - 140.506426, - -22.997663 - ], - [ - 141.507595, - -22.997663 - ], - [ - 141.507595, - -20.995326 - ], - [ - 140.506426, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 140.506426, - -22.997663 - ], - [ - 140.506426, - -25 - ], - [ - 141.507595, - -25 - ], - [ - 141.507595, - -22.997663 - ], - [ - 140.506426, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 140.506426, - -25 - ], - [ - 140.506426, - -27.002337 - ], - [ - 141.507595, - -27.002337 - ], - [ - 141.507595, - -25 - ], - [ - 140.506426, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 140.506426, - -27.002337 - ], - [ - 140.506426, - -29.004674 - ], - [ - 141.507595, - -29.004674 - ], - [ - 141.507595, - -27.002337 - ], - [ - 140.506426, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 140.506426, - -29.004674 - ], - [ - 140.506426, - -31.00701 - ], - [ - 141.507595, - -31.00701 - ], - [ - 141.507595, - -29.004674 - ], - [ - 140.506426, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 140.506426, - -31.00701 - ], - [ - 140.506426, - -33.009347 - ], - [ - 141.507595, - -33.009347 - ], - [ - 141.507595, - -31.00701 - ], - [ - 140.506426, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 140.506426, - -33.009347 - ], - [ - 140.506426, - -35.011684 - ], - [ - 141.507595, - -35.011684 - ], - [ - 141.507595, - -33.009347 - ], - [ - 140.506426, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 140.506426, - -35.011684 - ], - [ - 140.506426, - -37.014021 - ], - [ - 141.507595, - -37.014021 - ], - [ - 141.507595, - -35.011684 - ], - [ - 140.506426, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 140.506426, - -37.014021 - ], - [ - 140.506426, - -39.016358 - ], - [ - 141.507595, - -39.016358 - ], - [ - 141.507595, - -37.014021 - ], - [ - 140.506426, - -37.014021 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 141.507595, - -8.981306 - ], - [ - 141.507595, - -10.983642 - ], - [ - 142.508763, - -10.983642 - ], - [ - 142.508763, - -8.981306 - ], - [ - 141.507595, - -8.981306 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 141.507595, - -10.983642 - ], - [ - 141.507595, - -12.985979 - ], - [ - 142.508763, - -12.985979 - ], - [ - 142.508763, - -10.983642 - ], - [ - 141.507595, - -10.983642 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 141.507595, - -12.985979 - ], - [ - 141.507595, - -14.988316 - ], - [ - 142.508763, - -14.988316 - ], - [ - 142.508763, - -12.985979 - ], - [ - 141.507595, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 141.507595, - -14.988316 - ], - [ - 141.507595, - -16.990653 - ], - [ - 142.508763, - -16.990653 - ], - [ - 142.508763, - -14.988316 - ], - [ - 141.507595, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 141.507595, - -16.990653 - ], - [ - 141.507595, - -18.99299 - ], - [ - 142.508763, - -18.99299 - ], - [ - 142.508763, - -16.990653 - ], - [ - 141.507595, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 141.507595, - -18.99299 - ], - [ - 141.507595, - -20.995326 - ], - [ - 142.508763, - -20.995326 - ], - [ - 142.508763, - -18.99299 - ], - [ - 141.507595, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 141.507595, - -20.995326 - ], - [ - 141.507595, - -22.997663 - ], - [ - 142.508763, - -22.997663 - ], - [ - 142.508763, - -20.995326 - ], - [ - 141.507595, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 141.507595, - -22.997663 - ], - [ - 141.507595, - -25 - ], - [ - 142.508763, - -25 - ], - [ - 142.508763, - -22.997663 - ], - [ - 141.507595, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 141.507595, - -25 - ], - [ - 141.507595, - -27.002337 - ], - [ - 142.508763, - -27.002337 - ], - [ - 142.508763, - -25 - ], - [ - 141.507595, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 141.507595, - -27.002337 - ], - [ - 141.507595, - -29.004674 - ], - [ - 142.508763, - -29.004674 - ], - [ - 142.508763, - -27.002337 - ], - [ - 141.507595, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 141.507595, - -29.004674 - ], - [ - 141.507595, - -31.00701 - ], - [ - 142.508763, - -31.00701 - ], - [ - 142.508763, - -29.004674 - ], - [ - 141.507595, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 141.507595, - -31.00701 - ], - [ - 141.507595, - -33.009347 - ], - [ - 142.508763, - -33.009347 - ], - [ - 142.508763, - -31.00701 - ], - [ - 141.507595, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 141.507595, - -33.009347 - ], - [ - 141.507595, - -35.011684 - ], - [ - 142.508763, - -35.011684 - ], - [ - 142.508763, - -33.009347 - ], - [ - 141.507595, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 141.507595, - -35.011684 - ], - [ - 141.507595, - -37.014021 - ], - [ - 142.508763, - -37.014021 - ], - [ - 142.508763, - -35.011684 - ], - [ - 141.507595, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 141.507595, - -37.014021 - ], - [ - 141.507595, - -39.016358 - ], - [ - 142.508763, - -39.016358 - ], - [ - 142.508763, - -37.014021 - ], - [ - 141.507595, - -37.014021 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 142.508763, - -8.981306 - ], - [ - 142.508763, - -10.983642 - ], - [ - 143.509931, - -10.983642 - ], - [ - 143.509931, - -8.981306 - ], - [ - 142.508763, - -8.981306 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 142.508763, - -10.983642 - ], - [ - 142.508763, - -12.985979 - ], - [ - 143.509931, - -12.985979 - ], - [ - 143.509931, - -10.983642 - ], - [ - 142.508763, - -10.983642 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 142.508763, - -12.985979 - ], - [ - 142.508763, - -14.988316 - ], - [ - 143.509931, - -14.988316 - ], - [ - 143.509931, - -12.985979 - ], - [ - 142.508763, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 142.508763, - -14.988316 - ], - [ - 142.508763, - -16.990653 - ], - [ - 143.509931, - -16.990653 - ], - [ - 143.509931, - -14.988316 - ], - [ - 142.508763, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 142.508763, - -16.990653 - ], - [ - 142.508763, - -18.99299 - ], - [ - 143.509931, - -18.99299 - ], - [ - 143.509931, - -16.990653 - ], - [ - 142.508763, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 142.508763, - -18.99299 - ], - [ - 142.508763, - -20.995326 - ], - [ - 143.509931, - -20.995326 - ], - [ - 143.509931, - -18.99299 - ], - [ - 142.508763, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 142.508763, - -20.995326 - ], - [ - 142.508763, - -22.997663 - ], - [ - 143.509931, - -22.997663 - ], - [ - 143.509931, - -20.995326 - ], - [ - 142.508763, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 142.508763, - -22.997663 - ], - [ - 142.508763, - -25 - ], - [ - 143.509931, - -25 - ], - [ - 143.509931, - -22.997663 - ], - [ - 142.508763, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 142.508763, - -25 - ], - [ - 142.508763, - -27.002337 - ], - [ - 143.509931, - -27.002337 - ], - [ - 143.509931, - -25 - ], - [ - 142.508763, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 142.508763, - -27.002337 - ], - [ - 142.508763, - -29.004674 - ], - [ - 143.509931, - -29.004674 - ], - [ - 143.509931, - -27.002337 - ], - [ - 142.508763, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 142.508763, - -29.004674 - ], - [ - 142.508763, - -31.00701 - ], - [ - 143.509931, - -31.00701 - ], - [ - 143.509931, - -29.004674 - ], - [ - 142.508763, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 142.508763, - -31.00701 - ], - [ - 142.508763, - -33.009347 - ], - [ - 143.509931, - -33.009347 - ], - [ - 143.509931, - -31.00701 - ], - [ - 142.508763, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 142.508763, - -33.009347 - ], - [ - 142.508763, - -35.011684 - ], - [ - 143.509931, - -35.011684 - ], - [ - 143.509931, - -33.009347 - ], - [ - 142.508763, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 142.508763, - -35.011684 - ], - [ - 142.508763, - -37.014021 - ], - [ - 143.509931, - -37.014021 - ], - [ - 143.509931, - -35.011684 - ], - [ - 142.508763, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 142.508763, - -37.014021 - ], - [ - 142.508763, - -39.016358 - ], - [ - 143.509931, - -39.016358 - ], - [ - 143.509931, - -37.014021 - ], - [ - 142.508763, - -37.014021 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 143.509931, - -10.983642 - ], - [ - 143.509931, - -12.985979 - ], - [ - 144.5111, - -12.985979 - ], - [ - 144.5111, - -10.983642 - ], - [ - 143.509931, - -10.983642 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 143.509931, - -12.985979 - ], - [ - 143.509931, - -14.988316 - ], - [ - 144.5111, - -14.988316 - ], - [ - 144.5111, - -12.985979 - ], - [ - 143.509931, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 143.509931, - -14.988316 - ], - [ - 143.509931, - -16.990653 - ], - [ - 144.5111, - -16.990653 - ], - [ - 144.5111, - -14.988316 - ], - [ - 143.509931, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 143.509931, - -16.990653 - ], - [ - 143.509931, - -18.99299 - ], - [ - 144.5111, - -18.99299 - ], - [ - 144.5111, - -16.990653 - ], - [ - 143.509931, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 143.509931, - -18.99299 - ], - [ - 143.509931, - -20.995326 - ], - [ - 144.5111, - -20.995326 - ], - [ - 144.5111, - -18.99299 - ], - [ - 143.509931, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 143.509931, - -20.995326 - ], - [ - 143.509931, - -22.997663 - ], - [ - 144.5111, - -22.997663 - ], - [ - 144.5111, - -20.995326 - ], - [ - 143.509931, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 143.509931, - -22.997663 - ], - [ - 143.509931, - -25 - ], - [ - 144.5111, - -25 - ], - [ - 144.5111, - -22.997663 - ], - [ - 143.509931, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 143.509931, - -25 - ], - [ - 143.509931, - -27.002337 - ], - [ - 144.5111, - -27.002337 - ], - [ - 144.5111, - -25 - ], - [ - 143.509931, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 143.509931, - -27.002337 - ], - [ - 143.509931, - -29.004674 - ], - [ - 144.5111, - -29.004674 - ], - [ - 144.5111, - -27.002337 - ], - [ - 143.509931, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 143.509931, - -29.004674 - ], - [ - 143.509931, - -31.00701 - ], - [ - 144.5111, - -31.00701 - ], - [ - 144.5111, - -29.004674 - ], - [ - 143.509931, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 143.509931, - -31.00701 - ], - [ - 143.509931, - -33.009347 - ], - [ - 144.5111, - -33.009347 - ], - [ - 144.5111, - -31.00701 - ], - [ - 143.509931, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 143.509931, - -33.009347 - ], - [ - 143.509931, - -35.011684 - ], - [ - 144.5111, - -35.011684 - ], - [ - 144.5111, - -33.009347 - ], - [ - 143.509931, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 143.509931, - -35.011684 - ], - [ - 143.509931, - -37.014021 - ], - [ - 144.5111, - -37.014021 - ], - [ - 144.5111, - -35.011684 - ], - [ - 143.509931, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 143.509931, - -37.014021 - ], - [ - 143.509931, - -39.016358 - ], - [ - 144.5111, - -39.016358 - ], - [ - 144.5111, - -37.014021 - ], - [ - 143.509931, - -37.014021 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 144.5111, - -12.985979 - ], - [ - 144.5111, - -14.988316 - ], - [ - 145.512268, - -14.988316 - ], - [ - 145.512268, - -12.985979 - ], - [ - 144.5111, - -12.985979 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 144.5111, - -14.988316 - ], - [ - 144.5111, - -16.990653 - ], - [ - 145.512268, - -16.990653 - ], - [ - 145.512268, - -14.988316 - ], - [ - 144.5111, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 144.5111, - -16.990653 - ], - [ - 144.5111, - -18.99299 - ], - [ - 145.512268, - -18.99299 - ], - [ - 145.512268, - -16.990653 - ], - [ - 144.5111, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 144.5111, - -18.99299 - ], - [ - 144.5111, - -20.995326 - ], - [ - 145.512268, - -20.995326 - ], - [ - 145.512268, - -18.99299 - ], - [ - 144.5111, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 144.5111, - -20.995326 - ], - [ - 144.5111, - -22.997663 - ], - [ - 145.512268, - -22.997663 - ], - [ - 145.512268, - -20.995326 - ], - [ - 144.5111, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 144.5111, - -22.997663 - ], - [ - 144.5111, - -25 - ], - [ - 145.512268, - -25 - ], - [ - 145.512268, - -22.997663 - ], - [ - 144.5111, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 144.5111, - -25 - ], - [ - 144.5111, - -27.002337 - ], - [ - 145.512268, - -27.002337 - ], - [ - 145.512268, - -25 - ], - [ - 144.5111, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 144.5111, - -27.002337 - ], - [ - 144.5111, - -29.004674 - ], - [ - 145.512268, - -29.004674 - ], - [ - 145.512268, - -27.002337 - ], - [ - 144.5111, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 144.5111, - -29.004674 - ], - [ - 144.5111, - -31.00701 - ], - [ - 145.512268, - -31.00701 - ], - [ - 145.512268, - -29.004674 - ], - [ - 144.5111, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 144.5111, - -31.00701 - ], - [ - 144.5111, - -33.009347 - ], - [ - 145.512268, - -33.009347 - ], - [ - 145.512268, - -31.00701 - ], - [ - 144.5111, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 144.5111, - -33.009347 - ], - [ - 144.5111, - -35.011684 - ], - [ - 145.512268, - -35.011684 - ], - [ - 145.512268, - -33.009347 - ], - [ - 144.5111, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 144.5111, - -35.011684 - ], - [ - 144.5111, - -37.014021 - ], - [ - 145.512268, - -37.014021 - ], - [ - 145.512268, - -35.011684 - ], - [ - 144.5111, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 144.5111, - -37.014021 - ], - [ - 144.5111, - -39.016358 - ], - [ - 145.512268, - -39.016358 - ], - [ - 145.512268, - -37.014021 - ], - [ - 144.5111, - -37.014021 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 145.512268, - -14.988316 - ], - [ - 145.512268, - -16.990653 - ], - [ - 146.513437, - -16.990653 - ], - [ - 146.513437, - -14.988316 - ], - [ - 145.512268, - -14.988316 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 145.512268, - -16.990653 - ], - [ - 145.512268, - -18.99299 - ], - [ - 146.513437, - -18.99299 - ], - [ - 146.513437, - -16.990653 - ], - [ - 145.512268, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 145.512268, - -18.99299 - ], - [ - 145.512268, - -20.995326 - ], - [ - 146.513437, - -20.995326 - ], - [ - 146.513437, - -18.99299 - ], - [ - 145.512268, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 145.512268, - -20.995326 - ], - [ - 145.512268, - -22.997663 - ], - [ - 146.513437, - -22.997663 - ], - [ - 146.513437, - -20.995326 - ], - [ - 145.512268, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 145.512268, - -22.997663 - ], - [ - 145.512268, - -25 - ], - [ - 146.513437, - -25 - ], - [ - 146.513437, - -22.997663 - ], - [ - 145.512268, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 145.512268, - -25 - ], - [ - 145.512268, - -27.002337 - ], - [ - 146.513437, - -27.002337 - ], - [ - 146.513437, - -25 - ], - [ - 145.512268, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 145.512268, - -27.002337 - ], - [ - 145.512268, - -29.004674 - ], - [ - 146.513437, - -29.004674 - ], - [ - 146.513437, - -27.002337 - ], - [ - 145.512268, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 145.512268, - -29.004674 - ], - [ - 145.512268, - -31.00701 - ], - [ - 146.513437, - -31.00701 - ], - [ - 146.513437, - -29.004674 - ], - [ - 145.512268, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 145.512268, - -31.00701 - ], - [ - 145.512268, - -33.009347 - ], - [ - 146.513437, - -33.009347 - ], - [ - 146.513437, - -31.00701 - ], - [ - 145.512268, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 145.512268, - -33.009347 - ], - [ - 145.512268, - -35.011684 - ], - [ - 146.513437, - -35.011684 - ], - [ - 146.513437, - -33.009347 - ], - [ - 145.512268, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 145.512268, - -35.011684 - ], - [ - 145.512268, - -37.014021 - ], - [ - 146.513437, - -37.014021 - ], - [ - 146.513437, - -35.011684 - ], - [ - 145.512268, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 145.512268, - -37.014021 - ], - [ - 145.512268, - -39.016358 - ], - [ - 146.513437, - -39.016358 - ], - [ - 146.513437, - -37.014021 - ], - [ - 145.512268, - -37.014021 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 146.513437, - -16.990653 - ], - [ - 146.513437, - -18.99299 - ], - [ - 147.514605, - -18.99299 - ], - [ - 147.514605, - -16.990653 - ], - [ - 146.513437, - -16.990653 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 146.513437, - -18.99299 - ], - [ - 146.513437, - -20.995326 - ], - [ - 147.514605, - -20.995326 - ], - [ - 147.514605, - -18.99299 - ], - [ - 146.513437, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 146.513437, - -20.995326 - ], - [ - 146.513437, - -22.997663 - ], - [ - 147.514605, - -22.997663 - ], - [ - 147.514605, - -20.995326 - ], - [ - 146.513437, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 146.513437, - -22.997663 - ], - [ - 146.513437, - -25 - ], - [ - 147.514605, - -25 - ], - [ - 147.514605, - -22.997663 - ], - [ - 146.513437, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 146.513437, - -25 - ], - [ - 146.513437, - -27.002337 - ], - [ - 147.514605, - -27.002337 - ], - [ - 147.514605, - -25 - ], - [ - 146.513437, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 146.513437, - -27.002337 - ], - [ - 146.513437, - -29.004674 - ], - [ - 147.514605, - -29.004674 - ], - [ - 147.514605, - -27.002337 - ], - [ - 146.513437, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 146.513437, - -29.004674 - ], - [ - 146.513437, - -31.00701 - ], - [ - 147.514605, - -31.00701 - ], - [ - 147.514605, - -29.004674 - ], - [ - 146.513437, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 146.513437, - -31.00701 - ], - [ - 146.513437, - -33.009347 - ], - [ - 147.514605, - -33.009347 - ], - [ - 147.514605, - -31.00701 - ], - [ - 146.513437, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 146.513437, - -33.009347 - ], - [ - 146.513437, - -35.011684 - ], - [ - 147.514605, - -35.011684 - ], - [ - 147.514605, - -33.009347 - ], - [ - 146.513437, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 146.513437, - -35.011684 - ], - [ - 146.513437, - -37.014021 - ], - [ - 147.514605, - -37.014021 - ], - [ - 147.514605, - -35.011684 - ], - [ - 146.513437, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 146.513437, - -37.014021 - ], - [ - 146.513437, - -39.016358 - ], - [ - 147.514605, - -39.016358 - ], - [ - 147.514605, - -37.014021 - ], - [ - 146.513437, - -37.014021 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 147.514605, - -18.99299 - ], - [ - 147.514605, - -20.995326 - ], - [ - 148.515773, - -20.995326 - ], - [ - 148.515773, - -18.99299 - ], - [ - 147.514605, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 147.514605, - -20.995326 - ], - [ - 147.514605, - -22.997663 - ], - [ - 148.515773, - -22.997663 - ], - [ - 148.515773, - -20.995326 - ], - [ - 147.514605, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 147.514605, - -22.997663 - ], - [ - 147.514605, - -25 - ], - [ - 148.515773, - -25 - ], - [ - 148.515773, - -22.997663 - ], - [ - 147.514605, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 147.514605, - -25 - ], - [ - 147.514605, - -27.002337 - ], - [ - 148.515773, - -27.002337 - ], - [ - 148.515773, - -25 - ], - [ - 147.514605, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 147.514605, - -27.002337 - ], - [ - 147.514605, - -29.004674 - ], - [ - 148.515773, - -29.004674 - ], - [ - 148.515773, - -27.002337 - ], - [ - 147.514605, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 147.514605, - -29.004674 - ], - [ - 147.514605, - -31.00701 - ], - [ - 148.515773, - -31.00701 - ], - [ - 148.515773, - -29.004674 - ], - [ - 147.514605, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 147.514605, - -31.00701 - ], - [ - 147.514605, - -33.009347 - ], - [ - 148.515773, - -33.009347 - ], - [ - 148.515773, - -31.00701 - ], - [ - 147.514605, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 147.514605, - -33.009347 - ], - [ - 147.514605, - -35.011684 - ], - [ - 148.515773, - -35.011684 - ], - [ - 148.515773, - -33.009347 - ], - [ - 147.514605, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 147.514605, - -35.011684 - ], - [ - 147.514605, - -37.014021 - ], - [ - 148.515773, - -37.014021 - ], - [ - 148.515773, - -35.011684 - ], - [ - 147.514605, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 147.514605, - -37.014021 - ], - [ - 147.514605, - -39.016358 - ], - [ - 148.515773, - -39.016358 - ], - [ - 148.515773, - -37.014021 - ], - [ - 147.514605, - -37.014021 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 148.515773, - -18.99299 - ], - [ - 148.515773, - -20.995326 - ], - [ - 149.516942, - -20.995326 - ], - [ - 149.516942, - -18.99299 - ], - [ - 148.515773, - -18.99299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 148.515773, - -20.995326 - ], - [ - 148.515773, - -22.997663 - ], - [ - 149.516942, - -22.997663 - ], - [ - 149.516942, - -20.995326 - ], - [ - 148.515773, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 148.515773, - -22.997663 - ], - [ - 148.515773, - -25 - ], - [ - 149.516942, - -25 - ], - [ - 149.516942, - -22.997663 - ], - [ - 148.515773, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 148.515773, - -25 - ], - [ - 148.515773, - -27.002337 - ], - [ - 149.516942, - -27.002337 - ], - [ - 149.516942, - -25 - ], - [ - 148.515773, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 148.515773, - -27.002337 - ], - [ - 148.515773, - -29.004674 - ], - [ - 149.516942, - -29.004674 - ], - [ - 149.516942, - -27.002337 - ], - [ - 148.515773, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 148.515773, - -29.004674 - ], - [ - 148.515773, - -31.00701 - ], - [ - 149.516942, - -31.00701 - ], - [ - 149.516942, - -29.004674 - ], - [ - 148.515773, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 148.515773, - -31.00701 - ], - [ - 148.515773, - -33.009347 - ], - [ - 149.516942, - -33.009347 - ], - [ - 149.516942, - -31.00701 - ], - [ - 148.515773, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 148.515773, - -33.009347 - ], - [ - 148.515773, - -35.011684 - ], - [ - 149.516942, - -35.011684 - ], - [ - 149.516942, - -33.009347 - ], - [ - 148.515773, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 148.515773, - -35.011684 - ], - [ - 148.515773, - -37.014021 - ], - [ - 149.516942, - -37.014021 - ], - [ - 149.516942, - -35.011684 - ], - [ - 148.515773, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 148.515773, - -37.014021 - ], - [ - 148.515773, - -39.016358 - ], - [ - 149.516942, - -39.016358 - ], - [ - 149.516942, - -37.014021 - ], - [ - 148.515773, - -37.014021 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 149.516942, - -20.995326 - ], - [ - 149.516942, - -22.997663 - ], - [ - 150.51811, - -22.997663 - ], - [ - 150.51811, - -20.995326 - ], - [ - 149.516942, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 149.516942, - -22.997663 - ], - [ - 149.516942, - -25 - ], - [ - 150.51811, - -25 - ], - [ - 150.51811, - -22.997663 - ], - [ - 149.516942, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 149.516942, - -25 - ], - [ - 149.516942, - -27.002337 - ], - [ - 150.51811, - -27.002337 - ], - [ - 150.51811, - -25 - ], - [ - 149.516942, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 149.516942, - -27.002337 - ], - [ - 149.516942, - -29.004674 - ], - [ - 150.51811, - -29.004674 - ], - [ - 150.51811, - -27.002337 - ], - [ - 149.516942, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 149.516942, - -29.004674 - ], - [ - 149.516942, - -31.00701 - ], - [ - 150.51811, - -31.00701 - ], - [ - 150.51811, - -29.004674 - ], - [ - 149.516942, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 149.516942, - -31.00701 - ], - [ - 149.516942, - -33.009347 - ], - [ - 150.51811, - -33.009347 - ], - [ - 150.51811, - -31.00701 - ], - [ - 149.516942, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 149.516942, - -33.009347 - ], - [ - 149.516942, - -35.011684 - ], - [ - 150.51811, - -35.011684 - ], - [ - 150.51811, - -33.009347 - ], - [ - 149.516942, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 149.516942, - -35.011684 - ], - [ - 149.516942, - -37.014021 - ], - [ - 150.51811, - -37.014021 - ], - [ - 150.51811, - -35.011684 - ], - [ - 149.516942, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 149.516942, - -37.014021 - ], - [ - 149.516942, - -39.016358 - ], - [ - 150.51811, - -39.016358 - ], - [ - 150.51811, - -37.014021 - ], - [ - 149.516942, - -37.014021 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 150.51811, - -20.995326 - ], - [ - 150.51811, - -22.997663 - ], - [ - 151.519279, - -22.997663 - ], - [ - 151.519279, - -20.995326 - ], - [ - 150.51811, - -20.995326 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 150.51811, - -22.997663 - ], - [ - 150.51811, - -25 - ], - [ - 151.519279, - -25 - ], - [ - 151.519279, - -22.997663 - ], - [ - 150.51811, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 150.51811, - -25 - ], - [ - 150.51811, - -27.002337 - ], - [ - 151.519279, - -27.002337 - ], - [ - 151.519279, - -25 - ], - [ - 150.51811, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 150.51811, - -27.002337 - ], - [ - 150.51811, - -29.004674 - ], - [ - 151.519279, - -29.004674 - ], - [ - 151.519279, - -27.002337 - ], - [ - 150.51811, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 150.51811, - -29.004674 - ], - [ - 150.51811, - -31.00701 - ], - [ - 151.519279, - -31.00701 - ], - [ - 151.519279, - -29.004674 - ], - [ - 150.51811, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 150.51811, - -31.00701 - ], - [ - 150.51811, - -33.009347 - ], - [ - 151.519279, - -33.009347 - ], - [ - 151.519279, - -31.00701 - ], - [ - 150.51811, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 150.51811, - -33.009347 - ], - [ - 150.51811, - -35.011684 - ], - [ - 151.519279, - -35.011684 - ], - [ - 151.519279, - -33.009347 - ], - [ - 150.51811, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 150.51811, - -35.011684 - ], - [ - 150.51811, - -37.014021 - ], - [ - 151.519279, - -37.014021 - ], - [ - 151.519279, - -35.011684 - ], - [ - 150.51811, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 150.51811, - -37.014021 - ], - [ - 150.51811, - -39.016358 - ], - [ - 151.519279, - -39.016358 - ], - [ - 151.519279, - -37.014021 - ], - [ - 150.51811, - -37.014021 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 151.519279, - -22.997663 - ], - [ - 151.519279, - -25 - ], - [ - 152.520447, - -25 - ], - [ - 152.520447, - -22.997663 - ], - [ - 151.519279, - -22.997663 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 151.519279, - -25 - ], - [ - 151.519279, - -27.002337 - ], - [ - 152.520447, - -27.002337 - ], - [ - 152.520447, - -25 - ], - [ - 151.519279, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 151.519279, - -27.002337 - ], - [ - 151.519279, - -29.004674 - ], - [ - 152.520447, - -29.004674 - ], - [ - 152.520447, - -27.002337 - ], - [ - 151.519279, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 151.519279, - -29.004674 - ], - [ - 151.519279, - -31.00701 - ], - [ - 152.520447, - -31.00701 - ], - [ - 152.520447, - -29.004674 - ], - [ - 151.519279, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 151.519279, - -31.00701 - ], - [ - 151.519279, - -33.009347 - ], - [ - 152.520447, - -33.009347 - ], - [ - 152.520447, - -31.00701 - ], - [ - 151.519279, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 151.519279, - -33.009347 - ], - [ - 151.519279, - -35.011684 - ], - [ - 152.520447, - -35.011684 - ], - [ - 152.520447, - -33.009347 - ], - [ - 151.519279, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 151.519279, - -35.011684 - ], - [ - 151.519279, - -37.014021 - ], - [ - 152.520447, - -37.014021 - ], - [ - 152.520447, - -35.011684 - ], - [ - 151.519279, - -35.011684 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 152.520447, - -25 - ], - [ - 152.520447, - -27.002337 - ], - [ - 153.521615, - -27.002337 - ], - [ - 153.521615, - -25 - ], - [ - 152.520447, - -25 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 152.520447, - -27.002337 - ], - [ - 152.520447, - -29.004674 - ], - [ - 153.521615, - -29.004674 - ], - [ - 153.521615, - -27.002337 - ], - [ - 152.520447, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 152.520447, - -29.004674 - ], - [ - 152.520447, - -31.00701 - ], - [ - 153.521615, - -31.00701 - ], - [ - 153.521615, - -29.004674 - ], - [ - 152.520447, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 152.520447, - -31.00701 - ], - [ - 152.520447, - -33.009347 - ], - [ - 153.521615, - -33.009347 - ], - [ - 153.521615, - -31.00701 - ], - [ - 152.520447, - -31.00701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 152.520447, - -33.009347 - ], - [ - 152.520447, - -35.011684 - ], - [ - 153.521615, - -35.011684 - ], - [ - 153.521615, - -33.009347 - ], - [ - 152.520447, - -33.009347 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 153.521615, - -27.002337 - ], - [ - 153.521615, - -29.004674 - ], - [ - 154.522784, - -29.004674 - ], - [ - 154.522784, - -27.002337 - ], - [ - 153.521615, - -27.002337 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 153.521615, - -29.004674 - ], - [ - 153.521615, - -31.00701 - ], - [ - 154.522784, - -31.00701 - ], - [ - 154.522784, - -29.004674 - ], - [ - 153.521615, - -29.004674 - ] - ] - ] - } - }, - { - "type": "Feature", - "bbox": [ - 110, - 0, - 160, - -50 - ], - "properties": { - "stroke": "#F00", - "stroke-width": 6, - "fill-opacity": 0 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 110, - 0 - ], - [ - 160, - 0 - ], - [ - 160, - -50 - ], - [ - 110, - -50 - ], - [ - 110, - 0 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#00F", - "stroke-width": 6, - "fill-opacity": 0 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 115.13671875, - -33.7243396617476 - ], - [ - 116.3671875, - -35.02999636902566 - ], - [ - 118.828125, - -34.59704151614416 - ], - [ - 123.74999999999999, - -33.9433599465788 - ], - [ - 126.38671874999999, - -32.249974455863295 - ], - [ - 131.484375, - -31.12819929911196 - ], - [ - 135.35156249999997, - -34.30714385628803 - ], - [ - 139.04296875, - -35.24561909420681 - ], - [ - 140.2734375, - -37.78808138412045 - ], - [ - 146.6015625, - -38.8225909761771 - ], - [ - 150.64453125, - -37.43997405227057 - ], - [ - 152.40234375, - -33.504759069226075 - ], - [ - 154.072265625, - -28.690587654250685 - ], - [ - 153.017578125, - -25.641526373065755 - ], - [ - 146.513671875, - -18.646245142670598 - ], - [ - 142.20703125, - -10.055402736564224 - ], - [ - 140.537109375, - -17.224758206624628 - ], - [ - 135.439453125, - -14.859850400601037 - ], - [ - 137.197265625, - -11.953349393643416 - ], - [ - 131.30859375, - -11.178401873711772 - ], - [ - 129.0234375, - -14.434680215297268 - ], - [ - 125.595703125, - -14.179186142354169 - ], - [ - 120.9375, - -19.559790136497398 - ], - [ - 114.873046875, - -21.125497636606266 - ], - [ - 114.169921875, - -26.11598592533351 - ], - [ - 115.13671875, - -33.7243396617476 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-rewind/LICENSE b/packages/turf-rewind/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-rewind/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-rewind/README.md b/packages/turf-rewind/README.md deleted file mode 100644 index ef1ea2b760..0000000000 --- a/packages/turf-rewind/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# @turf/rewind - - - -## rewind - -Rewind [(Multi)LineString][1] or [(Multi)Polygon][2] outer ring counterclockwise and inner rings clockwise (Uses [Shoelace Formula][3]). - -**Parameters** - -- `geojson` **[GeoJSON][4]** input GeoJSON Polygon -- `options` **[Object][5]** Optional parameters (optional, default `{}`) - - `options.reverse` **[boolean][6]** enable reverse winding (optional, default `false`) - - `options.mutate` **[boolean][6]** allows GeoJSON input to be mutated (significant performance increase if true) (optional, default `false`) - -**Examples** - -```javascript -var polygon = turf.polygon([[[121, -29], [138, -29], [138, -18], [121, -18], [121, -29]]]); - -var rewind = turf.rewind(polygon); - -//addToMap -var addToMap = [rewind]; -``` - -Returns **[GeoJSON][4]** rewind Polygon - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[3]: http://en.wikipedia.org/wiki/Shoelace_formula - -[4]: https://tools.ietf.org/html/rfc7946#section-3 - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/rewind -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-rewind/index.d.ts b/packages/turf-rewind/index.d.ts deleted file mode 100644 index d81fe8829a..0000000000 --- a/packages/turf-rewind/index.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { AllGeoJSON } from '@turf/helpers'; - -/** - * http://turfjs.org/docs/#rewind - */ -export default function rewind( - geojson: T, - options?: { - reversed?: boolean, - mutate?: boolean - } -): T; diff --git a/packages/turf-rewind/index.js b/packages/turf-rewind/index.js deleted file mode 100644 index b269895f73..0000000000 --- a/packages/turf-rewind/index.js +++ /dev/null @@ -1,132 +0,0 @@ -import clone from '@turf/clone'; -import booleanClockwise from '@turf/boolean-clockwise'; -import { geomEach, featureEach } from '@turf/meta'; -import { getCoords } from '@turf/invariant'; -import { featureCollection, isObject } from '@turf/helpers'; - -/** - * Rewind {@link LineString|(Multi)LineString} or {@link Polygon|(Multi)Polygon} outer ring counterclockwise and inner rings clockwise (Uses {@link http://en.wikipedia.org/wiki/Shoelace_formula|Shoelace Formula}). - * - * @name rewind - * @param {GeoJSON} geojson input GeoJSON Polygon - * @param {Object} [options={}] Optional parameters - * @param {boolean} [options.reverse=false] enable reverse winding - * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) - * @returns {GeoJSON} rewind Polygon - * @example - * var polygon = turf.polygon([[[121, -29], [138, -29], [138, -18], [121, -18], [121, -29]]]); - * - * var rewind = turf.rewind(polygon); - * - * //addToMap - * var addToMap = [rewind]; - */ -function rewind(geojson, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var reverse = options.reverse || false; - var mutate = options.mutate || false; - - // validation - if (!geojson) throw new Error(' is required'); - if (typeof reverse !== 'boolean') throw new Error(' must be a boolean'); - if (typeof mutate !== 'boolean') throw new Error(' must be a boolean'); - - // prevent input mutation - if (mutate === false) geojson = clone(geojson); - - // Support Feature Collection or Geometry Collection - var results = []; - switch (geojson.type) { - case 'GeometryCollection': - geomEach(geojson, function (geometry) { - rewindFeature(geometry, reverse); - }); - return geojson; - case 'FeatureCollection': - featureEach(geojson, function (feature) { - featureEach(rewindFeature(feature, reverse), function (result) { - results.push(result); - }); - }); - return featureCollection(results); - } - // Support Feature or Geometry Objects - return rewindFeature(geojson, reverse); -} - -/** - * Rewind - * - * @private - * @param {Geometry|Feature} geojson Geometry or Feature - * @param {Boolean} [reverse=false] enable reverse winding - * @returns {Geometry|Feature} rewind Geometry or Feature - */ -function rewindFeature(geojson, reverse) { - var type = (geojson.type === 'Feature') ? geojson.geometry.type : geojson.type; - - // Support all GeoJSON Geometry Objects - switch (type) { - case 'GeometryCollection': - geomEach(geojson, function (geometry) { - rewindFeature(geometry, reverse); - }); - return geojson; - case 'LineString': - rewindLineString(getCoords(geojson), reverse); - return geojson; - case 'Polygon': - rewindPolygon(getCoords(geojson), reverse); - return geojson; - case 'MultiLineString': - getCoords(geojson).forEach(function (lineCoords) { - rewindLineString(lineCoords, reverse); - }); - return geojson; - case 'MultiPolygon': - getCoords(geojson).forEach(function (lineCoords) { - rewindPolygon(lineCoords, reverse); - }); - return geojson; - case 'Point': - case 'MultiPoint': - return geojson; - } -} - -/** - * Rewind LineString - outer ring clockwise - * - * @private - * @param {Array>} coords GeoJSON LineString geometry coordinates - * @param {Boolean} [reverse=false] enable reverse winding - * @returns {void} mutates coordinates - */ -function rewindLineString(coords, reverse) { - if (booleanClockwise(coords) === reverse) coords.reverse(); -} - -/** - * Rewind Polygon - outer ring counterclockwise and inner rings clockwise. - * - * @private - * @param {Array>>} coords GeoJSON Polygon geometry coordinates - * @param {Boolean} [reverse=false] enable reverse winding - * @returns {void} mutates coordinates - */ -function rewindPolygon(coords, reverse) { - // outer ring - if (booleanClockwise(coords[0]) !== reverse) { - coords[0].reverse(); - } - // inner rings - for (var i = 1; i < coords.length; i++) { - if (booleanClockwise(coords[i]) === reverse) { - coords[i].reverse(); - } - } -} - -export default rewind; diff --git a/packages/turf-rewind/package.json b/packages/turf-rewind/package.json deleted file mode 100644 index 0060f8bab4..0000000000 --- a/packages/turf-rewind/package.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "@turf/rewind", - "version": "5.1.5", - "description": "turf rewind module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "polygon", - "rewind" - ], - "author": "Turf Authors", - "contributors": [ - "Abel Vázquez Montoro <@AbelVM>", - "Tom MacWright <@tmcw>", - "Denis Carriere <@DenisCarriere>", - "Morgan Herlocker <@morganherlocker>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/boolean-clockwise": "^5.1.5", - "@turf/clone": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-rewind/test.js b/packages/turf-rewind/test.js deleted file mode 100644 index ff7fce58db..0000000000 --- a/packages/turf-rewind/test.js +++ /dev/null @@ -1,58 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import { polygon, lineString, featureCollection, geometryCollection } from '@turf/helpers'; -import rewind from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -let fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); -// fixtures = fixtures.filter(fixture => fixture.name === 'polygon-clockwise'); - -test('turf-rewind', t => { - for (const {filename, name, geojson} of fixtures) { - const {reverse} = geojson.properties || {}; - const results = rewind(geojson, reverse); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEqual(results, load.sync(directories.out + filename), name); - } - t.end(); -}); - -test('turf-buffer - Support Geometry Objects', t => { - const line = lineString([[11, 0], [22, 4], [31, 0], [31, 11]]); - const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); - const gc = geometryCollection([poly.geometry, line.geometry]); - const fc = featureCollection([poly, line]); - - t.assert(rewind(line.geometry), 'support LineString Geometry'); - t.assert(rewind(poly.geometry), 'support Polygon Geometry'); - t.assert(rewind(fc), 'support Feature Collection'); - t.assert(rewind(gc), 'support Geometry Collection'); - t.end(); -}); - -test('turf-buffer - Prevent Input Mutation', t => { - const line = lineString([[11, 0], [22, 4], [31, 0], [31, 11]]); - const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); - const beforePoly = JSON.parse(JSON.stringify(poly)); - const beforeLine = JSON.parse(JSON.stringify(line)); - rewind(poly); - rewind(line); - - t.deepEqual(poly, beforePoly, 'poly should not mutate'); - t.deepEqual(line, beforeLine, 'line should not mutate'); - t.end(); -}); diff --git a/packages/turf-rewind/types.ts b/packages/turf-rewind/types.ts deleted file mode 100644 index 92ca655614..0000000000 --- a/packages/turf-rewind/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { polygon, lineString, multiLineString, multiPolygon } from '@turf/helpers' -import rewind from './' - -const coords = [[121, -29], [138, -29], [138, -18], [121, -18], [121, -29]] -const poly = polygon([coords]) -const line = lineString(coords) -const multiPoly = multiPolygon([[coords], [coords]]) -const multiLine = multiLineString([coords, coords]) - -rewind(line) -rewind(poly) -rewind(multiPoly) -rewind(multiLine) -rewind(poly, {mutate: true}) -rewind(poly, {mutate: true, reversed: true}) diff --git a/packages/turf-rhumb-bearing/.gitignore b/packages/turf-rhumb-bearing/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-rhumb-bearing/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-rhumb-bearing/LICENSE b/packages/turf-rhumb-bearing/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-rhumb-bearing/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-rhumb-bearing/README.md b/packages/turf-rhumb-bearing/README.md deleted file mode 100644 index 35f850955a..0000000000 --- a/packages/turf-rhumb-bearing/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# @turf/rhumb-bearing - - - -## rhumbBearing - -Takes two [points][1] and finds the bearing angle between them along a Rhumb line -i.e. the angle measured in degrees start the north line (0 degrees) - -**Parameters** - -- `start` **[Coord][2]** starting Point -- `end` **[Coord][2]** ending Point -- `options` **[Object][3]?** Optional parameters - - `options.final` **[boolean][4]** calculates the final bearing if true (optional, default `false`) - -**Examples** - -```javascript -var point1 = turf.point([-75.343, 39.984], {"marker-color": "#F00"}); -var point2 = turf.point([-75.534, 39.123], {"marker-color": "#00F"}); - -var bearing = turf.rhumbBearing(point1, point2); - -//addToMap -var addToMap = [point1, point2]; -point1.properties.bearing = bearing; -point2.properties.bearing = bearing; -``` - -Returns **[number][5]** bearing from north in decimal degrees, between -180 and 180 degrees (positive clockwise) - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/rhumb-bearing -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-rhumb-bearing/bench.js b/packages/turf-rhumb-bearing/bench.js deleted file mode 100644 index 256b7990e7..0000000000 --- a/packages/turf-rhumb-bearing/bench.js +++ /dev/null @@ -1,20 +0,0 @@ -const { point } = require('@turf/helpers'); -const Benchmark = require('benchmark'); -const rhumbBearing = require('./').default; - -var start = point([-75.4, 39.4]); -var end = point([-75.534, 39.123]); - -/** - * Benchmark Results - * - * initial bearing x 1,108,233 ops/sec ±3.22% (86 runs sampled) - * final bearing x 1,144,822 ops/sec ±2.01% (88 runs sampled) - */ -var suite = new Benchmark.Suite('turf-rhumb-bearing'); -suite - .add('initial bearing', () => rhumbBearing(start, end)) - .add('final bearing', () => rhumbBearing(start, end, true)) - .on('cycle', e => console.log(String(e.target))) - .on('complete', () => {}) - .run(); diff --git a/packages/turf-rhumb-bearing/index.d.ts b/packages/turf-rhumb-bearing/index.d.ts deleted file mode 100644 index ae44400c62..0000000000 --- a/packages/turf-rhumb-bearing/index.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Coord } from "@turf/helpers"; -/** - * Takes two {@link Point|points} and finds the bearing angle between them along a Rhumb line - * i.e. the angle measured in degrees start the north line (0 degrees) - * - * @name rhumbBearing - * @param {Coord} start starting Point - * @param {Coord} end ending Point - * @param {Object} [options] Optional parameters - * @param {boolean} [options.final=false] calculates the final bearing if true - * @returns {number} bearing from north in decimal degrees, between -180 and 180 degrees (positive clockwise) - * @example - * var point1 = turf.point([-75.343, 39.984], {"marker-color": "#F00"}); - * var point2 = turf.point([-75.534, 39.123], {"marker-color": "#00F"}); - * - * var bearing = turf.rhumbBearing(point1, point2); - * - * //addToMap - * var addToMap = [point1, point2]; - * point1.properties.bearing = bearing; - * point2.properties.bearing = bearing; - */ -declare function rhumbBearing(start: Coord, end: Coord, options?: { - final?: boolean; -}): number; -export default rhumbBearing; diff --git a/packages/turf-rhumb-bearing/index.ts b/packages/turf-rhumb-bearing/index.ts deleted file mode 100644 index 8c653aff17..0000000000 --- a/packages/turf-rhumb-bearing/index.ts +++ /dev/null @@ -1,68 +0,0 @@ -// https://en.wikipedia.org/wiki/Rhumb_line -import { Coord, degreesToRadians, radiansToDegrees } from "@turf/helpers"; -import { getCoord } from "@turf/invariant"; - -/** - * Takes two {@link Point|points} and finds the bearing angle between them along a Rhumb line - * i.e. the angle measured in degrees start the north line (0 degrees) - * - * @name rhumbBearing - * @param {Coord} start starting Point - * @param {Coord} end ending Point - * @param {Object} [options] Optional parameters - * @param {boolean} [options.final=false] calculates the final bearing if true - * @returns {number} bearing from north in decimal degrees, between -180 and 180 degrees (positive clockwise) - * @example - * var point1 = turf.point([-75.343, 39.984], {"marker-color": "#F00"}); - * var point2 = turf.point([-75.534, 39.123], {"marker-color": "#00F"}); - * - * var bearing = turf.rhumbBearing(point1, point2); - * - * //addToMap - * var addToMap = [point1, point2]; - * point1.properties.bearing = bearing; - * point2.properties.bearing = bearing; - */ -function rhumbBearing(start: Coord, end: Coord, options: {final?: boolean} = {}): number { - let bear360; - if (options.final) { bear360 = calculateRhumbBearing(getCoord(end), getCoord(start)); - } else { bear360 = calculateRhumbBearing(getCoord(start), getCoord(end)); } - - const bear180 = (bear360 > 180) ? - (360 - bear360) : bear360; - - return bear180; -} - -/** - * Returns the bearing from ‘this’ point to destination point along a rhumb line. - * Adapted from Geodesy: https://github.com/chrisveness/geodesy/blob/master/latlon-spherical.js - * - * @private - * @param {Array} from - origin point. - * @param {Array} to - destination point. - * @returns {number} Bearing in degrees from north. - * @example - * var p1 = new LatLon(51.127, 1.338); - * var p2 = new LatLon(50.964, 1.853); - * var d = p1.rhumbBearingTo(p2); // 116.7 m - */ -function calculateRhumbBearing(from: number[], to: number[]) { - // φ => phi - // Δλ => deltaLambda - // Δψ => deltaPsi - // θ => theta - const phi1 = degreesToRadians(from[1]); - const phi2 = degreesToRadians(to[1]); - let deltaLambda = degreesToRadians((to[0] - from[0])); - // if deltaLambdaon over 180° take shorter rhumb line across the anti-meridian: - if (deltaLambda > Math.PI) { deltaLambda -= 2 * Math.PI; } - if (deltaLambda < -Math.PI) { deltaLambda += 2 * Math.PI; } - - const deltaPsi = Math.log(Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4)); - - const theta = Math.atan2(deltaLambda, deltaPsi); - - return (radiansToDegrees(theta) + 360) % 360; -} - -export default rhumbBearing; diff --git a/packages/turf-rhumb-bearing/package.json b/packages/turf-rhumb-bearing/package.json deleted file mode 100644 index 05d4dab2b5..0000000000 --- a/packages/turf-rhumb-bearing/package.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "name": "@turf/rhumb-bearing", - "version": "6.0.1", - "description": "turf rhumb-bearing module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "bearing", - "loxodrome", - "rhumb", - "rhumb line" - ], - "author": "Turf Authors", - "contributors": [ - "Chris Veness <@chrisveness>", - "Stefano Borghi <@stebogit>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/destination": "*", - "benchmark": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-rhumb-bearing/test.js b/packages/turf-rhumb-bearing/test.js deleted file mode 100644 index 35672c2a43..0000000000 --- a/packages/turf-rhumb-bearing/test.js +++ /dev/null @@ -1,44 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const test = require('tape'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { point } = require('@turf/helpers'); -const rhumbBearing = require('.').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -let fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('bearing', t => { - fixtures.forEach(fixture => { - const name = fixture.name; - const filename = fixture.filename; - const geojson = fixture.geojson; - - const start = geojson.features[0]; - const end = geojson.features[1]; - - const initialBearing = rhumbBearing(start, end); - const finalBearing = rhumbBearing(start, end, {final: true}); - - const result = { - 'initialBearing': initialBearing, - 'finalBearing': finalBearing - }; - if (process.env.REGEN) write.sync(directories.out + name + '.json', result); - t.deepEqual(load.sync(directories.out + name + '.json'), result, name); - }); - - t.throws(() => { rhumbBearing(point([12, -54]), 'point'); }, 'invalid point'); - t.end(); -}); diff --git a/packages/turf-rhumb-bearing/tsconfig.json b/packages/turf-rhumb-bearing/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-rhumb-bearing/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-rhumb-bearing/tslint.json b/packages/turf-rhumb-bearing/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-rhumb-bearing/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-rhumb-destination/.gitignore b/packages/turf-rhumb-destination/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-rhumb-destination/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-rhumb-destination/LICENSE b/packages/turf-rhumb-destination/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-rhumb-destination/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-rhumb-destination/README.md b/packages/turf-rhumb-destination/README.md deleted file mode 100644 index 2c12f61a05..0000000000 --- a/packages/turf-rhumb-destination/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# @turf/rhumb-destination - - - -## rhumbDestination - -Returns the destination [Point][1] having travelled the given distance along a Rhumb line from the -origin Point with the (varant) given bearing. - -**Parameters** - -- `origin` **[Coord][2]** starting point -- `distance` **[number][3]** distance from the starting point -- `bearing` **[number][3]** varant bearing angle ranging from -180 to 180 degrees from north -- `options` **[Object][4]** Optional parameters (optional, default `{}`) - - `options.units` **[string][5]** can be degrees, radians, miles, or kilometers (optional, default `'kilometers'`) - - `options.properties` **[Object][4]** translate properties to destination point (optional, default `{}`) - -**Examples** - -```javascript -var pt = turf.point([-75.343, 39.984], {"marker-color": "F00"}); -var distance = 50; -var bearing = 90; -var options = {units: 'miles'}; - -var destination = turf.rhumbDestination(pt, distance, bearing, options); - -//addToMap -var addToMap = [pt, destination] -destination.properties['marker-color'] = '#00F'; -``` - -Returns **[Feature][6]<[Point][7]>** Destination point. - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[6]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/rhumb-destination -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-rhumb-destination/index.ts b/packages/turf-rhumb-destination/index.ts deleted file mode 100644 index f01d3ccb53..0000000000 --- a/packages/turf-rhumb-destination/index.ts +++ /dev/null @@ -1,92 +0,0 @@ -// https://en.wikipedia.org/wiki/Rhumb_line -import { - convertLength, Coord, degreesToRadians, earthRadius, - Feature, point, Point, Properties, Units, -} from "@turf/helpers"; -import { getCoord } from "@turf/invariant"; - -/** - * Returns the destination {@link Point} having travelled the given distance along a Rhumb line from the - * origin Point with the (varant) given bearing. - * - * @name rhumbDestination - * @param {Coord} origin starting point - * @param {number} distance distance from the starting point - * @param {number} bearing varant bearing angle ranging from -180 to 180 degrees from north - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers - * @param {Object} [options.properties={}] translate properties to destination point - * @returns {Feature} Destination point. - * @example - * var pt = turf.point([-75.343, 39.984], {"marker-color": "F00"}); - * var distance = 50; - * var bearing = 90; - * var options = {units: 'miles'}; - * - * var destination = turf.rhumbDestination(pt, distance, bearing, options); - * - * //addToMap - * var addToMap = [pt, destination] - * destination.properties['marker-color'] = '#00F'; - */ -function rhumbDestination

(origin: Coord, distance: number, bearing: number, options: { - units?: Units, - properties?: P, -} = {}): Feature { - - const wasNegativeDistance = distance < 0; - let distanceInMeters = convertLength(Math.abs(distance), options.units, "meters"); - if (wasNegativeDistance) distanceInMeters = -Math.abs(distanceInMeters); - const coords = getCoord(origin); - const destination = calculateRhumbDestination(coords, distanceInMeters, bearing); - - // compensate the crossing of the 180th meridian (https://macwright.org/2016/09/26/the-180th-meridian.html) - // solution from https://github.com/mapbox/mapbox-gl-js/issues/3250#issuecomment-294887678 - destination[0] += (destination[0] - coords[0] > 180) ? -360 : (coords[0] - destination[0] > 180) ? 360 : 0; - return point(destination, options.properties); -} - -/** - * Returns the destination point having travelled along a rhumb line from origin point the given - * distance on the given bearing. - * Adapted from Geodesy: http://www.movable-type.co.uk/scripts/latlong.html#rhumblines - * - * @private - * @param {Array} origin - point - * @param {number} distance - Distance travelled, in same units as earth radius (default: metres). - * @param {number} bearing - Bearing in degrees from north. - * @param {number} [radius=6371e3] - (Mean) radius of earth (defaults to radius in metres). - * @returns {Array} Destination point. - */ -function calculateRhumbDestination(origin: number[], distance: number, bearing: number, radius?: number) { - // φ => phi - // λ => lambda - // ψ => psi - // Δ => Delta - // δ => delta - // θ => theta - - radius = (radius === undefined) ? earthRadius : Number(radius); - - const delta = distance / radius; // angular distance in radians - const lambda1 = origin[0] * Math.PI / 180; // to radians, but without normalize to 𝜋 - const phi1 = degreesToRadians(origin[1]); - const theta = degreesToRadians(bearing); - - const DeltaPhi = delta * Math.cos(theta); - let phi2 = phi1 + DeltaPhi; - - // check for some daft bugger going past the pole, normalise latitude if so - if (Math.abs(phi2) > Math.PI / 2) { phi2 = phi2 > 0 ? Math.PI - phi2 : -Math.PI - phi2; } - - const DeltaPsi = Math.log(Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4)); - // E-W course becomes ill-conditioned with 0/0 - const q = Math.abs(DeltaPsi) > 10e-12 ? DeltaPhi / DeltaPsi : Math.cos(phi1); - - const DeltaLambda = delta * Math.sin(theta) / q; - const lambda2 = lambda1 + DeltaLambda; - - return [((lambda2 * 180 / Math.PI) + 540) % 360 - 180, phi2 * 180 / Math.PI]; // normalise to −180..+180° -} - -export default rhumbDestination; diff --git a/packages/turf-rhumb-destination/package.json b/packages/turf-rhumb-destination/package.json deleted file mode 100644 index 655f6d4845..0000000000 --- a/packages/turf-rhumb-destination/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "@turf/rhumb-destination", - "version": "6.0.3", - "description": "turf rhumb-destination module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "distance", - "destination", - "bearing", - "loxodrome", - "rhumb", - "rhumb line", - "miles", - "km" - ], - "author": "Turf Authors", - "contributors": [ - "Chris Veness <@chrisveness>", - "Stefano Borghi <@stebogit>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/truncate": "*", - "@types/tape": "*", - "benchmark": "*", - "load-json-file": "*", - "tape": "*", - "tslint": "*", - "typescript": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-rhumb-destination/test.js b/packages/turf-rhumb-destination/test.js deleted file mode 100644 index 1ccf97ce50..0000000000 --- a/packages/turf-rhumb-destination/test.js +++ /dev/null @@ -1,65 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const test = require('tape'); -const write = require('write-json-file'); -const load = require('load-json-file'); -const truncate = require('@turf/truncate').default; -const { getCoords } = require('@turf/invariant'); -const { featureCollection, lineString, point } = require('@turf/helpers'); -const rhumbDestination = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-rhumb-destination', t => { - for (const {filename, name, geojson} of fixtures) { - let {bearing, dist, units} = geojson.properties || {}; - bearing = (bearing !== undefined) ? bearing : 180; - dist = (dist !== undefined) ? dist : 100; - - const destinationPoint = rhumbDestination(geojson, dist, bearing, {units: units}); - const line = truncate(lineString([getCoords(geojson), getCoords(destinationPoint)], {'stroke': '#F00', 'stroke-width': 4})); - geojson.properties['marker-color'] = '#F00'; - const result = featureCollection([line, geojson, destinationPoint]); - - if (process.env.REGEN) write.sync(directories.out + filename, result); - t.deepEqual(result, load.sync(directories.out + filename), name); - } - t.end(); -}); - -test('turf-rhumb-destintation -- throws error', t => { - const pt = point([12, -54]); - t.assert(rhumbDestination(pt, 0, 45).geometry.coordinates[0], '0 distance is valid'); - t.assert(rhumbDestination(pt, 100, 0).geometry.coordinates[0], '0 bearing is valid'); - // t.throws(() => rhumbDestination(pt, 100, 45, 'blah'), 'unknown option given to units'); - // t.throws(() => rhumbDestination(pt, null, 75), 'missing distance'); - // t.throws(() => rhumbDestination(pt, 'foo', 75), 'invalid distance - units param switched to distance'); - // t.throws(() => rhumbDestination('foo', 200, 75, {units: 'miles'}), 'invalid point'); - t.end(); -}); - -test('turf-rhumb-destintation -- add properties', t => { - const properties = {foo: 'bar'}; - const pt = point([12, -54], properties); - - t.deepEqual(rhumbDestination(pt, 0, 45, {properties}).properties, properties, 'add properties'); - t.end(); -}); - -test('turf-rhumb-destintation -- allows negative distance', t => { - const pt = point([12, -54]); - const out = rhumbDestination(pt, -100, 45); - t.deepEqual(out.geometry.coordinates, [10.90974456038191, -54.63591552764877]) - t.end(); -}); \ No newline at end of file diff --git a/packages/turf-rhumb-destination/tsconfig.json b/packages/turf-rhumb-destination/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-rhumb-destination/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-rhumb-destination/tslint.json b/packages/turf-rhumb-destination/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-rhumb-destination/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-rhumb-distance/.gitignore b/packages/turf-rhumb-distance/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-rhumb-distance/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-rhumb-distance/LICENSE b/packages/turf-rhumb-distance/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-rhumb-distance/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-rhumb-distance/README.md b/packages/turf-rhumb-distance/README.md deleted file mode 100644 index 6d0ad9f6f7..0000000000 --- a/packages/turf-rhumb-distance/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# @turf/rhumb-distance - - - -## rhumbDistance - -Calculates the distance along a rhumb line between two [points][1] in degrees, radians, -miles, or kilometers. - -**Parameters** - -- `from` **[Coord][2]** origin point -- `to` **[Coord][2]** destination point -- `options` **[Object][3]?** Optional parameters - - `options.units` **[string][4]** can be degrees, radians, miles, or kilometers (optional, default `"kilometers"`) - -**Examples** - -```javascript -var from = turf.point([-75.343, 39.984]); -var to = turf.point([-75.534, 39.123]); -var options = {units: 'miles'}; - -var distance = turf.rhumbDistance(from, to, options); - -//addToMap -var addToMap = [from, to]; -from.properties.distance = distance; -to.properties.distance = distance; -``` - -Returns **[number][5]** distance between the two points - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/rhumb-distance -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-rhumb-distance/bench.js b/packages/turf-rhumb-distance/bench.js deleted file mode 100644 index 0945f18be0..0000000000 --- a/packages/turf-rhumb-distance/bench.js +++ /dev/null @@ -1,18 +0,0 @@ -const { point } = require('@turf/helpers'); -const Benchmark = require('benchmark'); -const distance = require('./').default; - -const pt1 = point([-75.4, 39.4]); -const pt2 = point([-75.534, 39.123]); - -/** - * Benchmark Results - * - * turf-rhumb-distance x 1,721,401 ops/sec ±0.86% (89 runs sampled) - */ -const suite = new Benchmark.Suite('turf-rhumb-distance'); -suite - .add('turf-rhumb-distance', () => distance(pt1, pt2, 'miles')) - .on('cycle', e => console.log(String(e.target))) - .on('complete', () => {}) - .run(); diff --git a/packages/turf-rhumb-distance/index.ts b/packages/turf-rhumb-distance/index.ts deleted file mode 100644 index 93990789cf..0000000000 --- a/packages/turf-rhumb-distance/index.ts +++ /dev/null @@ -1,87 +0,0 @@ -// https://en.wikipedia.org/wiki/Rhumb_line -import { convertLength, Coord, earthRadius, Feature, Point, Units } from "@turf/helpers"; -import { getCoord } from "@turf/invariant"; - -/** - * Calculates the distance along a rhumb line between two {@link Point|points} in degrees, radians, - * miles, or kilometers. - * - * @name rhumbDistance - * @param {Coord} from origin point - * @param {Coord} to destination point - * @param {Object} [options] Optional parameters - * @param {string} [options.units="kilometers"] can be degrees, radians, miles, or kilometers - * @returns {number} distance between the two points - * @example - * var from = turf.point([-75.343, 39.984]); - * var to = turf.point([-75.534, 39.123]); - * var options = {units: 'miles'}; - * - * var distance = turf.rhumbDistance(from, to, options); - * - * //addToMap - * var addToMap = [from, to]; - * from.properties.distance = distance; - * to.properties.distance = distance; - */ -function rhumbDistance(from: Coord, to: Coord, options: { - units?: Units, -} = {}): number { - const origin = getCoord(from); - const destination = getCoord(to); - - // compensate the crossing of the 180th meridian (https://macwright.org/2016/09/26/the-180th-meridian.html) - // solution from https://github.com/mapbox/mapbox-gl-js/issues/3250#issuecomment-294887678 - destination[0] += (destination[0] - origin[0] > 180) ? -360 : (origin[0] - destination[0] > 180) ? 360 : 0; - const distanceInMeters = calculateRhumbDistance(origin, destination); - const distance = convertLength(distanceInMeters, "meters", options.units); - return distance; -} - -/** - * Returns the distance travelling from ‘this’ point to destination point along a rhumb line. - * Adapted from Geodesy: https://github.com/chrisveness/geodesy/blob/master/latlon-spherical.js - * - * @private - * @param {Array} origin point. - * @param {Array} destination point. - * @param {number} [radius=6371e3] - (Mean) radius of earth (defaults to radius in metres). - * @returns {number} Distance in km between this point and destination point (same units as radius). - * - * @example - * var p1 = new LatLon(51.127, 1.338); - * var p2 = new LatLon(50.964, 1.853); - * var d = p1.distanceTo(p2); // 40.31 km - */ -function calculateRhumbDistance(origin: number[], destination: number[], radius?: number) { - // φ => phi - // λ => lambda - // ψ => psi - // Δ => Delta - // δ => delta - // θ => theta - - radius = (radius === undefined) ? earthRadius : Number(radius); - // see www.edwilliams.org/avform.htm#Rhumb - - const R = radius; - const phi1 = origin[1] * Math.PI / 180; - const phi2 = destination[1] * Math.PI / 180; - const DeltaPhi = phi2 - phi1; - let DeltaLambda = Math.abs(destination[0] - origin[0]) * Math.PI / 180; - // if dLon over 180° take shorter rhumb line across the anti-meridian: - if (DeltaLambda > Math.PI) { DeltaLambda -= 2 * Math.PI; } - - // on Mercator projection, longitude distances shrink by latitude; q is the 'stretch factor' - // q becomes ill-conditioned along E-W line (0/0); use empirical tolerance to avoid it - const DeltaPsi = Math.log(Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4)); - const q = Math.abs(DeltaPsi) > 10e-12 ? DeltaPhi / DeltaPsi : Math.cos(phi1); - - // distance is pythagoras on 'stretched' Mercator projection - const delta = Math.sqrt(DeltaPhi * DeltaPhi + q * q * DeltaLambda * DeltaLambda); // angular distance in radians - const dist = delta * R; - - return dist; -} - -export default rhumbDistance; diff --git a/packages/turf-rhumb-distance/package.json b/packages/turf-rhumb-distance/package.json deleted file mode 100644 index 3c442c323f..0000000000 --- a/packages/turf-rhumb-distance/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "@turf/rhumb-distance", - "version": "6.0.1", - "description": "turf rhumb-distance module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "distance", - "rhumb line", - "rhumb", - "loxodrome", - "miles", - "km" - ], - "author": "Turf Authors", - "contributors": [ - "Chris Veness <@chrisveness>", - "Stefano Borghi <@stebogit>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/distance": "*", - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-rhumb-distance/test.js b/packages/turf-rhumb-distance/test.js deleted file mode 100644 index e485b6c344..0000000000 --- a/packages/turf-rhumb-distance/test.js +++ /dev/null @@ -1,52 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const test = require('tape'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const distance = require('@turf/distance').default; -const { point, round } = require('@turf/helpers'); -const rhumbDistance = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('rhumb-distance', t => { - fixtures.forEach(fixture => { - const name = fixture.name; - const geojson = fixture.geojson; - const pt1 = geojson.features[0]; - const pt2 = geojson.features[1]; - - const distances = { - miles: round(rhumbDistance(pt1, pt2, {units: 'miles'}), 6), - nauticalmiles: round(rhumbDistance(pt1, pt2, {units: 'nauticalmiles'}), 6), - kilometers: round(rhumbDistance(pt1, pt2, {units: 'kilometers'}), 6), - greatCircleDistance: round(distance(pt1, pt2, {units: 'kilometers'}), 6), - radians: round(rhumbDistance(pt1, pt2, {units: 'radians'}), 6), - degrees: round(rhumbDistance(pt1, pt2, {units: 'degrees'}), 6) - }; - - if (process.env.REGEN) write.sync(directories.out + name + '.json', distances); - t.deepEqual(distances, load.sync(directories.out + name + '.json'), name); - }); - - // Now fails due to approximation error - // TODO: to be added once earth radius is updated to 6371km - // t.ok(distances.kilometers > distances.greatCircleDistance, name + ' distance comparison'); - - t.throws(() => rhumbDistance(point([0, 0]), point([1, 1]), {units: 'foo'}), 'unknown option given to units'); - t.throws(() => rhumbDistance(null, point([1, 1])), 'null point'); - t.throws(() => rhumbDistance(point([1, 1]), 'point'), 'invalid point'); - - t.end(); -}); diff --git a/packages/turf-rhumb-distance/tsconfig.json b/packages/turf-rhumb-distance/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-rhumb-distance/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-rhumb-distance/tslint.json b/packages/turf-rhumb-distance/tslint.json deleted file mode 100644 index 32fa6e5e8d..0000000000 --- a/packages/turf-rhumb-distance/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-sample/LICENSE b/packages/turf-sample/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-sample/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-sample/README.md b/packages/turf-sample/README.md deleted file mode 100644 index 5df97790c3..0000000000 --- a/packages/turf-sample/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# @turf/sample - - - -## sample - -Takes a [FeatureCollection][1] and returns a FeatureCollection with given number of [features][2] at random. - -**Parameters** - -- `featurecollection` **[FeatureCollection][3]** set of input features -- `num` **[number][4]** number of features to select - -**Examples** - -```javascript -var points = turf.randomPoint(100, {bbox: [-80, 30, -60, 60]}); - -var sample = turf.sample(points, 5); - -//addToMap -var addToMap = [points, sample] -turf.featureEach(sample, function (currentFeature) { - currentFeature.properties['marker-size'] = 'large'; - currentFeature.properties['marker-color'] = '#000'; -}); -``` - -Returns **[FeatureCollection][3]** a FeatureCollection with `n` features - -[1]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/sample -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-sample/bench.js b/packages/turf-sample/bench.js deleted file mode 100644 index a4a52427e1..0000000000 --- a/packages/turf-sample/bench.js +++ /dev/null @@ -1,25 +0,0 @@ -import fs from 'fs'; -import Benchmark from 'benchmark'; -import { point, featureCollection } from '@turf/helpers'; -import sample from './'; - -var points = featureCollection( - [point(1,2, {team: 'Red Sox'}), - point(2,1, {team: 'Yankees'}), - point(3,1, {team: 'Nationals'}), - point(2,2, {team: 'Yankees'}), - point(2,3, {team: 'Red Sox'}), - point(4,2, {team: 'Yankees'})]); - -var suite = new Benchmark.Suite('turf-sample'); -suite - .add('turf-sample',function () { - sample(points, 4); - }) - .on('cycle', function (event) { - console.log(String(event.target)); - }) - .on('complete', function () { - - }) - .run(); \ No newline at end of file diff --git a/packages/turf-sample/index.js b/packages/turf-sample/index.js deleted file mode 100644 index 4d48e3b541..0000000000 --- a/packages/turf-sample/index.js +++ /dev/null @@ -1,43 +0,0 @@ -// http://stackoverflow.com/questions/11935175/sampling-a-random-subset-from-an-array -import { featureCollection } from '@turf/helpers'; - -/** - * Takes a {@link FeatureCollection} and returns a FeatureCollection with given number of {@link Feature|features} at random. - * - * @name sample - * @param {FeatureCollection} featurecollection set of input features - * @param {number} num number of features to select - * @returns {FeatureCollection} a FeatureCollection with `n` features - * @example - * var points = turf.randomPoint(100, {bbox: [-80, 30, -60, 60]}); - * - * var sample = turf.sample(points, 5); - * - * //addToMap - * var addToMap = [points, sample] - * turf.featureEach(sample, function (currentFeature) { - * currentFeature.properties['marker-size'] = 'large'; - * currentFeature.properties['marker-color'] = '#000'; - * }); - */ -function sample(featurecollection, num) { - if (!featurecollection) throw new Error('featurecollection is required'); - if (num === null || num === undefined) throw new Error('num is required'); - if (typeof num !== 'number') throw new Error('num must be a number'); - - var outFC = featureCollection(getRandomSubarray(featurecollection.features, num)); - return outFC; -} - -function getRandomSubarray(arr, size) { - var shuffled = arr.slice(0), i = arr.length, min = i - size, temp, index; - while (i-- > min) { - index = Math.floor((i + 1) * Math.random()); - temp = shuffled[index]; - shuffled[index] = shuffled[i]; - shuffled[i] = temp; - } - return shuffled.slice(min); -} - -export default sample; diff --git a/packages/turf-sample/package.json b/packages/turf-sample/package.json deleted file mode 100644 index 9eb8c0b966..0000000000 --- a/packages/turf-sample/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@turf/sample", - "version": "5.1.5", - "description": "turf sample module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "geojson", - "stats", - "sample", - "turf" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "rollup": "*", - "tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-sample/test.js b/packages/turf-sample/test.js deleted file mode 100644 index ace14fdfb3..0000000000 --- a/packages/turf-sample/test.js +++ /dev/null @@ -1,20 +0,0 @@ -import test from 'tape'; -import { point } from '@turf/helpers'; -import { featureCollection } from '@turf/helpers'; -import sample from '.'; - -test('remove', function (t) { - var points = featureCollection([ - point([1, 2], {team: 'Red Sox'}), - point([2, 1], {team: 'Yankees'}), - point([3, 1], {team: 'Nationals'}), - point([2, 2], {team: 'Yankees'}), - point([2, 3], {team: 'Red Sox'}), - point([4, 2], {team: 'Yankees'}) - ]); - - const results = sample(points, 4); - - t.equal(results.features.length, 4, 'should sample 4 features'); - t.end(); -}); diff --git a/packages/turf-sector/LICENSE b/packages/turf-sector/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-sector/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-sector/README.md b/packages/turf-sector/README.md deleted file mode 100644 index 52dfdd902b..0000000000 --- a/packages/turf-sector/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# @turf/sector - - - -## sector - -Creates a circular sector of a circle of given radius and center [Point][1], -between (clockwise) bearing1 and bearing2; 0 bearing is North of center point, positive clockwise. - -**Parameters** - -- `center` **[Coord][2]** center point -- `radius` **[number][3]** radius of the circle -- `bearing1` **[number][3]** angle, in decimal degrees, of the first radius of the sector -- `bearing2` **[number][3]** angle, in decimal degrees, of the second radius of the sector -- `options` **[Object][4]** Optional parameters (optional, default `{}`) - - `options.units` **[string][5]** miles, kilometers, degrees, or radians (optional, default `'kilometers'`) - - `options.steps` **[number][3]** number of steps (optional, default `64`) - - `options.properties` **Properties** Translate properties to Feature Polygon (optional, default `{}`) - -**Examples** - -```javascript -var center = turf.point([-75, 40]); -var radius = 5; -var bearing1 = 25; -var bearing2 = 45; - -var sector = turf.sector(center, radius, bearing1, bearing2); - -//addToMap -var addToMap = [center, sector]; -``` - -Returns **[Feature][6]<[Polygon][7]>** sector polygon - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[6]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/sector -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-sector/index.d.ts b/packages/turf-sector/index.d.ts deleted file mode 100644 index e340a2d2ac..0000000000 --- a/packages/turf-sector/index.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Feature, Polygon, Units, Coord, Properties } from '@turf/helpers'; - -/** - * http://turfjs.org/docs/#sector - */ -export default function sector( - center: Coord, - radius: number, - bearing1: number, - bearing2: number, - options?: { - steps?: number - units?: Units - properties?: Properties - } -): Feature; diff --git a/packages/turf-sector/index.js b/packages/turf-sector/index.js deleted file mode 100644 index 034ce176b4..0000000000 --- a/packages/turf-sector/index.js +++ /dev/null @@ -1,73 +0,0 @@ -import circle from '@turf/circle'; -import lineArc from '@turf/line-arc'; -import { coordEach } from '@turf/meta'; -import { polygon, isObject } from '@turf/helpers'; -import { getCoords } from '@turf/invariant'; - -/** - * Creates a circular sector of a circle of given radius and center {@link Point}, - * between (clockwise) bearing1 and bearing2; 0 bearing is North of center point, positive clockwise. - * - * @name sector - * @param {Coord} center center point - * @param {number} radius radius of the circle - * @param {number} bearing1 angle, in decimal degrees, of the first radius of the sector - * @param {number} bearing2 angle, in decimal degrees, of the second radius of the sector - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians - * @param {number} [options.steps=64] number of steps - * @param {Properties} [options.properties={}] Translate properties to Feature Polygon - * @returns {Feature} sector polygon - * @example - * var center = turf.point([-75, 40]); - * var radius = 5; - * var bearing1 = 25; - * var bearing2 = 45; - * - * var sector = turf.sector(center, radius, bearing1, bearing2); - * - * //addToMap - * var addToMap = [center, sector]; - */ -function sector(center, radius, bearing1, bearing2, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var properties = options.properties; - - // validation - if (!center) throw new Error('center is required'); - if (bearing1 === undefined || bearing1 === null) throw new Error('bearing1 is required'); - if (bearing2 === undefined || bearing2 === null) throw new Error('bearing2 is required'); - if (!radius) throw new Error('radius is required'); - if (typeof options !== 'object') throw new Error('options must be an object'); - - if (convertAngleTo360(bearing1) === convertAngleTo360(bearing2)) { - return circle(center, radius, options); - } - var coords = getCoords(center); - var arc = lineArc(center, radius, bearing1, bearing2, options); - var sliceCoords = [[coords]]; - coordEach(arc, function (currentCoords) { - sliceCoords[0].push(currentCoords); - }); - sliceCoords[0].push(coords); - - return polygon(sliceCoords, properties); -} - -/** - * Takes any angle in degrees - * and returns a valid angle between 0-360 degrees - * - * @private - * @param {number} alfa angle between -180-180 degrees - * @returns {number} angle between 0-360 degrees - */ -function convertAngleTo360(alfa) { - var beta = alfa % 360; - if (beta < 0) beta += 360; - return beta; -} - -export default sector; diff --git a/packages/turf-sector/package.json b/packages/turf-sector/package.json deleted file mode 100644 index a3dd76d95b..0000000000 --- a/packages/turf-sector/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "@turf/sector", - "version": "5.1.5", - "description": "turf sector module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gif" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/truncate": "6.x", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/circle": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/line-arc": "^5.1.5", - "@turf/meta": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-sector/test.js b/packages/turf-sector/test.js deleted file mode 100644 index 3a26e9f458..0000000000 --- a/packages/turf-sector/test.js +++ /dev/null @@ -1,44 +0,0 @@ -import test from 'tape'; -import fs from 'fs'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import truncate from '@turf/truncate'; -import { featureCollection } from '@turf/helpers'; -import sector from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-sector', t => { - for (const {filename, name, geojson} of fixtures) { - const {radius, bearing1, bearing2} = geojson.properties; - const sectored = colorize(truncate(sector(geojson, radius, bearing1, bearing2))); - const results = featureCollection([geojson, sectored]); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEquals(results, load.sync(directories.out + filename), name); - } - t.end(); -}); - -function colorize(feature, color = '#FF0', width = 10) { - feature.properties = { - 'stroke': '#000000', - 'stroke-width': width, - 'stroke-opacity': 1, - 'fill': color, - 'fill-opacity': 0.8 - }; - return feature; -} diff --git a/packages/turf-sector/types.ts b/packages/turf-sector/types.ts deleted file mode 100644 index b61918cec4..0000000000 --- a/packages/turf-sector/types.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { point } from '@turf/helpers'; -import sector from './'; - -const center = point([-75.343, 39.984]); -const units = 'kilometers'; -const bearing1 = 10; -const bearing2 = -30; -const radius = 5; -const steps = 10; - -sector(center, radius, bearing1, bearing2); -sector(center, radius, bearing1, bearing2, {steps}); -sector(center, radius, bearing1, bearing2, {steps, units}); \ No newline at end of file diff --git a/packages/turf-shortest-path/LICENSE b/packages/turf-shortest-path/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-shortest-path/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-shortest-path/README.md b/packages/turf-shortest-path/README.md deleted file mode 100644 index 2ddae087f1..0000000000 --- a/packages/turf-shortest-path/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# @turf/shortest-path - - - -## shortestPath - -Returns the shortest [path][1] from [start][2] to [end][2] without colliding with -any [Feature][3] in [ obstacles][4] - -**Parameters** - -- `start` **[Coord][5]** point -- `end` **[Coord][5]** point -- `options` **[Object][6]** optional parameters (optional, default `{}`) - - `options.obstacles` **([Geometry][7] \| [Feature][8] \| [FeatureCollection][9]<[Polygon][10]>)?** areas which path cannot travel - - `options.minDistance` **[number][11]?** minimum distance between shortest path and obstacles - - `options.units` **[string][12]** unit in which resolution & minimum distance will be expressed in; it can be degrees, radians, miles, kilometers, ... (optional, default `'kilometers'`) - - `options.resolution` **[number][11]** distance between matrix points on which the path will be calculated (optional, default `100`) - -**Examples** - -```javascript -var start = [-5, -6]; -var end = [9, -6]; -var options = { - obstacles: turf.polygon([[[0, -7], [5, -7], [5, -3], [0, -3], [0, -7]]]) -}; - -var path = turf.shortestPath(start, end, options); - -//addToMap -var addToMap = [start, end, options.obstacles, path]; -``` - -Returns **[Feature][8]<[LineString][13]>** shortest path between start and end - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: FeatureCollection - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1 - -[8]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[9]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[10]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[11]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[12]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[13]: https://tools.ietf.org/html/rfc7946#section-3.1.4 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/shortest-path -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-shortest-path/index.d.ts b/packages/turf-shortest-path/index.d.ts deleted file mode 100644 index a2a259c14f..0000000000 --- a/packages/turf-shortest-path/index.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Polygon, Feature, FeatureCollection, Coord, LineString, Units } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#shortestpath - */ -export default function shortestPath( - start: Coord, - end: Coord, - options?: { - obstacles?: Polygon | Feature | FeatureCollection, - minDistance?: number - units?: Units - resolution?: number - } -): Feature; diff --git a/packages/turf-shortest-path/index.js b/packages/turf-shortest-path/index.js deleted file mode 100644 index 1b108bc1e1..0000000000 --- a/packages/turf-shortest-path/index.js +++ /dev/null @@ -1,193 +0,0 @@ -import bbox from '@turf/bbox'; -import booleanPointInPolygon from '@turf/boolean-point-in-polygon'; -import distance from '@turf/distance'; -import scale from '@turf/transform-scale'; -import cleanCoords from '@turf/clean-coords'; -import bboxPolygon from '@turf/bbox-polygon'; -import { getCoord, getType, getGeom } from '@turf/invariant'; -import { point, isNumber, lineString, isObject, featureCollection, feature } from '@turf/helpers'; -import { Graph, astar } from './lib/javascript-astar'; - -/** - * Returns the shortest {@link LineString|path} from {@link Point|start} to {@link Point|end} without colliding with - * any {@link Feature} in {@link FeatureCollection| obstacles} - * - * @name shortestPath - * @param {Coord} start point - * @param {Coord} end point - * @param {Object} [options={}] optional parameters - * @param {Geometry|Feature|FeatureCollection} [options.obstacles] areas which path cannot travel - * @param {number} [options.minDistance] minimum distance between shortest path and obstacles - * @param {string} [options.units='kilometers'] unit in which resolution & minimum distance will be expressed in; it can be degrees, radians, miles, kilometers, ... - * @param {number} [options.resolution=100] distance between matrix points on which the path will be calculated - * @returns {Feature} shortest path between start and end - * @example - * var start = [-5, -6]; - * var end = [9, -6]; - * var options = { - * obstacles: turf.polygon([[[0, -7], [5, -7], [5, -3], [0, -3], [0, -7]]]) - * }; - * - * var path = turf.shortestPath(start, end, options); - * - * //addToMap - * var addToMap = [start, end, options.obstacles, path]; - */ -function shortestPath(start, end, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var resolution = options.resolution; - var minDistance = options.minDistance; - var obstacles = options.obstacles || featureCollection([]); - - // validation - if (!start) throw new Error('start is required'); - if (!end) throw new Error('end is required'); - if (resolution && !isNumber(resolution) || resolution <= 0) throw new Error('options.resolution must be a number, greater than 0'); - if (minDistance) throw new Error('options.minDistance is not yet implemented'); - - // Normalize Inputs - var startCoord = getCoord(start); - var endCoord = getCoord(end); - start = point(startCoord); - end = point(endCoord); - - // Handle obstacles - switch (getType(obstacles)) { - case 'FeatureCollection': - if (obstacles.features.length === 0) return lineString([startCoord, endCoord]); - break; - case 'Polygon': - obstacles = featureCollection([feature(getGeom(obstacles))]); - break; - default: - throw new Error('invalid obstacles'); - } - - // define path grid area - var collection = obstacles; - collection.features.push(start); - collection.features.push(end); - var box = bbox(scale(bboxPolygon(bbox(collection)), 1.15)); // extend 15% - if (!resolution) { - var width = distance([box[0], box[1]], [box[2], box[1]], options); - resolution = width / 100; - } - collection.features.pop(); - collection.features.pop(); - - var west = box[0]; - var south = box[1]; - var east = box[2]; - var north = box[3]; - - var xFraction = resolution / (distance([west, south], [east, south], options)); - var cellWidth = xFraction * (east - west); - var yFraction = resolution / (distance([west, south], [west, north], options)); - var cellHeight = yFraction * (north - south); - - var bboxHorizontalSide = (east - west); - var bboxVerticalSide = (north - south); - var columns = Math.floor(bboxHorizontalSide / cellWidth); - var rows = Math.floor(bboxVerticalSide / cellHeight); - // adjust origin of the grid - var deltaX = (bboxHorizontalSide - columns * cellWidth) / 2; - var deltaY = (bboxVerticalSide - rows * cellHeight) / 2; - - // loop through points only once to speed up process - // define matrix grid for A-star algorithm - var pointMatrix = []; - var matrix = []; - - var closestToStart = []; - var closestToEnd = []; - var minDistStart = Infinity; - var minDistEnd = Infinity; - var currentY = north - deltaY; - var r = 0; - while (currentY >= south) { - // var currentY = south + deltaY; - var matrixRow = []; - var pointMatrixRow = []; - var currentX = west + deltaX; - var c = 0; - while (currentX <= east) { - var pt = point([currentX, currentY]); - var isInsideObstacle = isInside(pt, obstacles); - // feed obstacles matrix - matrixRow.push(isInsideObstacle ? 0 : 1); // with javascript-astar - // matrixRow.push(isInsideObstacle ? 1 : 0); // with astar-andrea - // map point's coords - pointMatrixRow.push(currentX + '|' + currentY); - // set closest points - var distStart = distance(pt, start); - // if (distStart < minDistStart) { - if (!isInsideObstacle && distStart < minDistStart) { - minDistStart = distStart; - closestToStart = {x: c, y: r}; - } - var distEnd = distance(pt, end); - // if (distEnd < minDistEnd) { - if (!isInsideObstacle && distEnd < minDistEnd) { - minDistEnd = distEnd; - closestToEnd = {x: c, y: r}; - } - currentX += cellWidth; - c++; - } - matrix.push(matrixRow); - pointMatrix.push(pointMatrixRow); - currentY -= cellHeight; - r++; - } - - // find path on matrix grid - - // javascript-astar ---------------------- - var graph = new Graph(matrix, {diagonal: true}); - var startOnMatrix = graph.grid[closestToStart.y][closestToStart.x]; - var endOnMatrix = graph.grid[closestToEnd.y][closestToEnd.x]; - var result = astar.search(graph, startOnMatrix, endOnMatrix); - - var path = [startCoord]; - result.forEach(function (coord) { - var coords = pointMatrix[coord.x][coord.y].split('|'); - path.push([+coords[0], +coords[1]]); // make sure coords are numbers - }); - path.push(endCoord); - // --------------------------------------- - - - // astar-andrea ------------------------ - // var result = aStar(matrix, [closestToStart.x, closestToStart.y], [closestToEnd.x, closestToEnd.y], 'DiagonalFree'); - // var path = [start.geometry.coordinates]; - // result.forEach(function (coord) { - // var coords = pointMatrix[coord[1]][coord[0]].split('|'); - // path.push([+coords[0], +coords[1]]); // make sure coords are numbers - // }); - // path.push(end.geometry.coordinates); - // --------------------------------------- - - - return cleanCoords(lineString(path)); -} - -/** - * Checks if Point is inside any of the Polygons - * - * @private - * @param {Feature} pt to check - * @param {FeatureCollection} polygons features - * @returns {boolean} if inside or not - */ -function isInside(pt, polygons) { - for (var i = 0; i < polygons.features.length; i++) { - if (booleanPointInPolygon(pt, polygons.features[i])) { - return true; - } - } - return false; -} - -export default shortestPath; diff --git a/packages/turf-shortest-path/package.json b/packages/turf-shortest-path/package.json deleted file mode 100644 index 820dff39f0..0000000000 --- a/packages/turf-shortest-path/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "@turf/shortest-path", - "version": "5.1.5", - "description": "turf shortest-path module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "lib", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "shortest-path", - "path" - ], - "author": "Turf Authors", - "contributors": [ - "Stefano Borghi <@stebogit>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/truncate": "6.x", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/bbox-polygon": "6.x", - "@turf/boolean-point-in-polygon": "6.x", - "@turf/clean-coords": "^5.1.5", - "@turf/distance": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x", - "@turf/transform-scale": "^5.1.5" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-shortest-path/test.js b/packages/turf-shortest-path/test.js deleted file mode 100644 index d43ee9644d..0000000000 --- a/packages/turf-shortest-path/test.js +++ /dev/null @@ -1,54 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import truncate from '@turf/truncate'; -import { featureCollection, point } from '@turf/helpers'; -import { getCoord } from '@turf/invariant'; -import { featureEach } from '@turf/meta'; -import shortestPath from './'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('turf-shortest-path', t => { - for (const {filename, name, geojson} of fixtures) { - // First two features from Collection are Start & End Points - const start = geojson.features.shift(); - const end = geojson.features.shift(); - // Any remaining features from Collection are obstacles - const obstacles = geojson; - const options = geojson.properties; - options.obstacles = obstacles; - - const path = truncate(shortestPath(start, end, options)); - path.properties['stroke'] = '#F00'; - path.properties['stroke-width'] = 5; - - const results = featureCollection([]) - if (obstacles) { - featureEach(obstacles, obstacle => { - results.features.push(obstacle) - }) - } - results.features.push(point(getCoord(start), start.properties)); - results.features.push(point(getCoord(end), end.properties)); - results.features.push(path); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEqual(results, load.sync(directories.out + filename), name); - } - t.end(); -}); - diff --git a/packages/turf-shortest-path/test/out/bermuda-triangle.json b/packages/turf-shortest-path/test/out/bermuda-triangle.json deleted file mode 100644 index 0c64358127..0000000000 --- a/packages/turf-shortest-path/test/out/bermuda-triangle.json +++ /dev/null @@ -1,190 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -80.19, - 25.774 - ], - [ - -66.118, - 18.466 - ], - [ - -64.757, - 32.321 - ], - [ - -80.19, - 25.774 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "type": "start" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -60.925, - 22.335 - ] - } - }, - { - "type": "Feature", - "properties": { - "type": "end" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -79.991, - 29.965 - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "stroke-width": 5 - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - -60.925, - 22.335 - ], - [ - -61.112702, - 22.522046 - ], - [ - -62.450502, - 23.79623 - ], - [ - -62.450502, - 29.954789 - ], - [ - -64.680168, - 32.07843 - ], - [ - -64.903135, - 32.290794 - ], - [ - -65.126101, - 32.290794 - ], - [ - -65.349068, - 32.07843 - ], - [ - -65.795001, - 32.07843 - ], - [ - -66.017968, - 31.866066 - ], - [ - -66.240935, - 31.866066 - ], - [ - -66.463901, - 31.653702 - ], - [ - -66.686868, - 31.653702 - ], - [ - -66.909834, - 31.441337 - ], - [ - -67.132801, - 31.441337 - ], - [ - -67.355768, - 31.228973 - ], - [ - -67.801701, - 31.228973 - ], - [ - -68.024668, - 31.016609 - ], - [ - -68.247634, - 31.016609 - ], - [ - -68.470601, - 30.804245 - ], - [ - -68.693567, - 30.804245 - ], - [ - -68.916534, - 30.591881 - ], - [ - -69.139501, - 30.591881 - ], - [ - -69.362467, - 30.379517 - ], - [ - -69.808401, - 30.379517 - ], - [ - -70.031367, - 30.167153 - ], - [ - -70.254334, - 30.167153 - ], - [ - -70.4773, - 29.954789 - ], - [ - -80.064865, - 29.954789 - ], - [ - -79.991, - 29.965 - ] - ] - } - } - ] -} diff --git a/packages/turf-shortest-path/types.ts b/packages/turf-shortest-path/types.ts deleted file mode 100644 index 4f348b295e..0000000000 --- a/packages/turf-shortest-path/types.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { point, featureCollection, polygon } from '@turf/helpers' -import shortestPath from './' - -const start = point([-5, -6]); -const end = point([9, -6]); - -shortestPath(start.geometry, end.geometry.coordinates); -shortestPath(start, end); -shortestPath(start, end, { - obstacles: polygon([[[0, -7], [5, -7], [5, -3], [0, -3], [0, -7]]]) -}); -shortestPath(start, end, { - obstacles: featureCollection([polygon([[[0, -7], [5, -7], [5, -3], [0, -3], [0, -7]]])]) -}); -shortestPath(start, end, { - resolution: 1000 -}); diff --git a/packages/turf-simplify/LICENSE b/packages/turf-simplify/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-simplify/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-simplify/README.md b/packages/turf-simplify/README.md deleted file mode 100644 index 4c45e3e2e1..0000000000 --- a/packages/turf-simplify/README.md +++ /dev/null @@ -1,87 +0,0 @@ -# @turf/simplify - - - -## simplify - -Takes a [GeoJSON][1] object and returns a simplified version. Internally uses -[simplify-js][2] to perform simplification using the Ramer-Douglas-Peucker algorithm. - -**Parameters** - -- `geojson` **[GeoJSON][3]** object to be simplified -- `options` **[Object][4]** Optional parameters (optional, default `{}`) - - `options.tolerance` **[number][5]** simplification tolerance (optional, default `1`) - - `options.highQuality` **[boolean][6]** whether or not to spend more time to create a higher-quality simplification with a different algorithm (optional, default `false`) - - `options.mutate` **[boolean][6]** allows GeoJSON input to be mutated (significant performance increase if true) (optional, default `false`) - -**Examples** - -```javascript -var geojson = turf.polygon([[ - [-70.603637, -33.399918], - [-70.614624, -33.395332], - [-70.639343, -33.392466], - [-70.659942, -33.394759], - [-70.683975, -33.404504], - [-70.697021, -33.419406], - [-70.701141, -33.434306], - [-70.700454, -33.446339], - [-70.694274, -33.458369], - [-70.682601, -33.465816], - [-70.668869, -33.472117], - [-70.646209, -33.473835], - [-70.624923, -33.472117], - [-70.609817, -33.468107], - [-70.595397, -33.458369], - [-70.587158, -33.442901], - [-70.587158, -33.426283], - [-70.590591, -33.414248], - [-70.594711, -33.406224], - [-70.603637, -33.399918] -]]); -var options = {tolerance: 0.01, highQuality: false}; -var simplified = turf.simplify(geojson, options); - -//addToMap -var addToMap = [geojson, simplified] -``` - -Returns **[GeoJSON][3]** a simplified GeoJSON - -[1]: https://tools.ietf.org/html/rfc7946#section-3 - -[2]: http://mourner.github.io/simplify-js/ - -[3]: https://tools.ietf.org/html/rfc7946#section-3 - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/simplify -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-simplify/index.d.ts b/packages/turf-simplify/index.d.ts deleted file mode 100644 index 2b2b2bdb40..0000000000 --- a/packages/turf-simplify/index.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { AllGeoJSON } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#simplify - */ -export default function simplify( - geojson: T, - options?: { - tolerance?: number, - highQuality?: boolean, - mutate?: boolean - } -): T; diff --git a/packages/turf-simplify/index.js b/packages/turf-simplify/index.js deleted file mode 100644 index 6522b76ddc..0000000000 --- a/packages/turf-simplify/index.js +++ /dev/null @@ -1,175 +0,0 @@ -import cleanCoords from '@turf/clean-coords'; -import clone from '@turf/clone'; -import { geomEach } from '@turf/meta'; -import { isObject } from '@turf/helpers'; -import simplifyJS from './lib/simplify'; - -/** - * Takes a {@link GeoJSON} object and returns a simplified version. Internally uses - * [simplify-js](http://mourner.github.io/simplify-js/) to perform simplification using the Ramer-Douglas-Peucker algorithm. - * - * @name simplify - * @param {GeoJSON} geojson object to be simplified - * @param {Object} [options={}] Optional parameters - * @param {number} [options.tolerance=1] simplification tolerance - * @param {boolean} [options.highQuality=false] whether or not to spend more time to create a higher-quality simplification with a different algorithm - * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) - * @returns {GeoJSON} a simplified GeoJSON - * @example - * var geojson = turf.polygon([[ - * [-70.603637, -33.399918], - * [-70.614624, -33.395332], - * [-70.639343, -33.392466], - * [-70.659942, -33.394759], - * [-70.683975, -33.404504], - * [-70.697021, -33.419406], - * [-70.701141, -33.434306], - * [-70.700454, -33.446339], - * [-70.694274, -33.458369], - * [-70.682601, -33.465816], - * [-70.668869, -33.472117], - * [-70.646209, -33.473835], - * [-70.624923, -33.472117], - * [-70.609817, -33.468107], - * [-70.595397, -33.458369], - * [-70.587158, -33.442901], - * [-70.587158, -33.426283], - * [-70.590591, -33.414248], - * [-70.594711, -33.406224], - * [-70.603637, -33.399918] - * ]]); - * var options = {tolerance: 0.01, highQuality: false}; - * var simplified = turf.simplify(geojson, options); - * - * //addToMap - * var addToMap = [geojson, simplified] - */ -function simplify(geojson, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var tolerance = options.tolerance !== undefined ? options.tolerance : 1; - var highQuality = options.highQuality || false; - var mutate = options.mutate || false; - - if (!geojson) throw new Error('geojson is required'); - if (tolerance && tolerance < 0) throw new Error('invalid tolerance'); - - // Clone geojson to avoid side effects - if (mutate !== true) geojson = clone(geojson); - - geomEach(geojson, function (geom) { - simplifyGeom(geom, tolerance, highQuality); - }); - return geojson; -} - -/** - * Simplifies a feature's coordinates - * - * @private - * @param {Geometry} geometry to be simplified - * @param {number} [tolerance=1] simplification tolerance - * @param {boolean} [highQuality=false] whether or not to spend more time to create a higher-quality simplification with a different algorithm - * @returns {Geometry} output - */ -function simplifyGeom(geometry, tolerance, highQuality) { - var type = geometry.type; - - // "unsimplyfiable" geometry types - if (type === 'Point' || type === 'MultiPoint') return geometry; - - // Remove any extra coordinates - cleanCoords(geometry, true); - - var coordinates = geometry.coordinates; - switch (type) { - case 'LineString': - geometry['coordinates'] = simplifyLine(coordinates, tolerance, highQuality); - break; - case 'MultiLineString': - geometry['coordinates'] = coordinates.map(function (lines) { - return simplifyLine(lines, tolerance, highQuality); - }); - break; - case 'Polygon': - geometry['coordinates'] = simplifyPolygon(coordinates, tolerance, highQuality); - break; - case 'MultiPolygon': - geometry['coordinates'] = coordinates.map(function (rings) { - return simplifyPolygon(rings, tolerance, highQuality); - }); - } - return geometry; -} - - -/** - * Simplifies the coordinates of a LineString with simplify-js - * - * @private - * @param {Array} coordinates to be processed - * @param {number} tolerance simplification tolerance - * @param {boolean} highQuality whether or not to spend more time to create a higher-quality - * @returns {Array>} simplified coords - */ -function simplifyLine(coordinates, tolerance, highQuality) { - return simplifyJS(coordinates.map(function (coord) { - return {x: coord[0], y: coord[1], z: coord[2]}; - }), tolerance, highQuality).map(function (coords) { - return (coords.z) ? [coords.x, coords.y, coords.z] : [coords.x, coords.y]; - }); -} - - -/** - * Simplifies the coordinates of a Polygon with simplify-js - * - * @private - * @param {Array} coordinates to be processed - * @param {number} tolerance simplification tolerance - * @param {boolean} highQuality whether or not to spend more time to create a higher-quality - * @returns {Array>>} simplified coords - */ -function simplifyPolygon(coordinates, tolerance, highQuality) { - return coordinates.map(function (ring) { - var pts = ring.map(function (coord) { - return {x: coord[0], y: coord[1]}; - }); - if (pts.length < 4) { - throw new Error('invalid polygon'); - } - var simpleRing = simplifyJS(pts, tolerance, highQuality).map(function (coords) { - return [coords.x, coords.y]; - }); - //remove 1 percent of tolerance until enough points to make a triangle - while (!checkValidity(simpleRing)) { - tolerance -= tolerance * 0.01; - simpleRing = simplifyJS(pts, tolerance, highQuality).map(function (coords) { - return [coords.x, coords.y]; - }); - } - if ( - (simpleRing[simpleRing.length - 1][0] !== simpleRing[0][0]) || - (simpleRing[simpleRing.length - 1][1] !== simpleRing[0][1])) { - simpleRing.push(simpleRing[0]); - } - return simpleRing; - }); -} - - -/** - * Returns true if ring has at least 3 coordinates and its first coordinate is the same as its last - * - * @private - * @param {Array} ring coordinates to be checked - * @returns {boolean} true if valid - */ -function checkValidity(ring) { - if (ring.length < 3) return false; - //if the last point is the same as the first, it's not a triangle - return !(ring.length === 3 && ((ring[2][0] === ring[0][0]) && (ring[2][1] === ring[0][1]))); -} - -export default simplify; diff --git a/packages/turf-simplify/package.json b/packages/turf-simplify/package.json deleted file mode 100644 index dc71f58ee0..0000000000 --- a/packages/turf-simplify/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "@turf/simplify", - "version": "5.1.5", - "description": "turf simplify module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "lib", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis", - "simplify", - "Ramer-Douglas-Peucker", - "algorithm", - "peucker" - ], - "author": "Turf Authors", - "contributors": [ - "Vladimir Agafonkin <@mourner>", - "Stefano Borghi <@stebogit>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/truncate": "6.x", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/clean-coords": "^5.1.5", - "@turf/clone": "6.x", - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-simplify/test.js b/packages/turf-simplify/test.js deleted file mode 100644 index 070098ce60..0000000000 --- a/packages/turf-simplify/test.js +++ /dev/null @@ -1,86 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import truncate from '@turf/truncate'; -import { polygon, multiPolygon } from '@turf/helpers'; -import simplify from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -let fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); -// fixtures = fixtures.filter(({name}) => name.includes('#555')); - -test('simplify', t => { - for (const {filename, name, geojson} of fixtures) { - let {tolerance, highQuality} = geojson.properties || {}; - tolerance = tolerance || 0.01; - highQuality = highQuality || false; - - const simplified = truncate(simplify(geojson, { - tolerance: tolerance, - highQuality: highQuality - })); - - if (process.env.REGEN) write.sync(directories.out + filename, simplified); - t.deepEqual(simplified, load.sync(directories.out + filename), name); - } - - t.end(); -}); - - -test('simplify -- throw', t => { - const poly = polygon([[[0, 0], [2, 2], [2, 0], [0, 0]]]); - t.throws(() => simplify(null), /geojson is required/, 'missing geojson'); - t.throws(() => simplify(poly, {tolerance: -1}), /invalid tolerance/, 'negative tolerance'); - t.end(); -}); - - -test('simplify -- removes ID & BBox from properties', t => { - const properties = {foo: 'bar'}; - const id = 12345; - const bbox = [0, 0, 2, 2]; - const poly = polygon([[[0, 0], [2, 2], [2, 0], [0, 0]]], properties, {bbox, id}); - const simple = simplify(poly, {tolerance: 0.1}); - - t.equal(simple.id, id); - t.deepEqual(simple.bbox, bbox); - t.deepEqual(simple.properties, properties); - t.end(); -}); - - -test('simplify -- issue #555', t => { - // polygons from issue #555 - const poly1 = polygon([[[-75.693254, 45.431144], [-75.693335, 45.431109], [-75.693335, 45.431109], [-75.693254, 45.431144]]]); - const poly2 = polygon([[[-75.627178, 45.438106], [-75.627179, 45.438106], [-75.62718, 45.438106], [-75.627178, 45.438106]]]); - const poly3 = polygon([[[-75.684722, 45.410083], [-75.684641, 45.409989], [-75.684641, 45.409989], [-75.684722, 45.410083], [-75.684722, 45.410083]]]); - const poly4 = polygon([[[-75.885634, 45.272762], [-75.885482, 45.272641], [-75.885554, 45.272596], [-75.885534, 45.272581], [-75.885581, 45.272551], [-75.885703, 45.272647], [-75.885706, 45.272645], [-75.885709, 45.272647], [-75.885767, 45.272693], [-75.885759, 45.272698], [-75.885716, 45.272728], [-75.885716, 45.272728], [-75.885712, 45.272731], [-75.885712, 45.272731], [-75.885708, 45.272734], [-75.885684, 45.272749], [-75.885671, 45.272739], [-75.885634, 45.272762]], [[-75.885708, 45.27273], [-75.885708, 45.272729], [-75.885708, 45.272729], [-75.885708, 45.27273]]]); - const options = {tolerance: 0.000001, highQuality: true}; - - t.throws(() => simplify(poly1, options), /invalid polygon/); - t.throws(() => simplify(poly2, options), /invalid polygon/); - t.throws(() => simplify(poly3, options), /invalid polygon/); - t.throws(() => simplify(poly4, options), /invalid polygon/); - t.end(); -}); - -test('simplify -- issue #918', t => { - // simplify hangs on this input #918 - t.throws(() => simplify(multiPolygon([[[[0, 90], [0, 90], [0, 90], [0, 90], [0, 90], [0, 90], [0, 90], [0, 90], [0, 90], [0, 90], [0, 90]]]])), /invalid polygon/, 'invalid polygon'); - t.throws(() => simplify(multiPolygon([[[[0, 1], [0, 2], [0, 3], [0, 2.5], [0, 1]]]])), /invalid polygon/, 'invalid polygon'); - t.throws(() => simplify(multiPolygon([[[[0, 1], [0, 1], [1, 2], [0, 1]]]])), /invalid polygon/, 'invalid polygon'); - t.end(); -}); diff --git a/packages/turf-simplify/types.ts b/packages/turf-simplify/types.ts deleted file mode 100644 index 5d12b48689..0000000000 --- a/packages/turf-simplify/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {polygon, Feature, Polygon} from '@turf/helpers' -import simplify from './' - -const poly = polygon([[[0, 0], [10, 10], [20, 20], [0, 0]]]); - -// Output type is the same as Input type -const simple: Feature = simplify(poly); - -// Extra params -simplify(poly, {tolerance: 1}); -simplify(poly, {tolerance: 1, highQuality: true}); diff --git a/packages/turf-square-grid/.gitignore b/packages/turf-square-grid/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-square-grid/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-square-grid/LICENSE b/packages/turf-square-grid/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-square-grid/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-square-grid/README.md b/packages/turf-square-grid/README.md deleted file mode 100644 index 5825d70070..0000000000 --- a/packages/turf-square-grid/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# @turf/square-grid - - - -## squareGrid - -Creates a square grid from a bounding box, [Feature](https://tools.ietf.org/html/rfc7946#section-3.2) or [FeatureCollection](https://tools.ietf.org/html/rfc7946#section-3.3). - -**Parameters** - -- `bbox` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)>** extent in [minX, minY, maxX, maxY] order -- `cellSide` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** of each cell, in units -- `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Optional parameters (optional, default `{}`) - - `options.units` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** used in calculating cellSide, can be degrees, - radians, miles, or kilometers (optional, default `'kilometers'`) - - `options.mask` **[Feature](https://tools.ietf.org/html/rfc7946#section-3.2)<([Polygon](https://tools.ietf.org/html/rfc7946#section-3.1.6) \| [MultiPolygon](https://tools.ietf.org/html/rfc7946#section-3.1.7))>?** if passed a Polygon or MultiPolygon, - the grid Points will be created only inside it - - `options.properties` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** passed to each point of the grid (optional, default `{}`) - -**Examples** - -```javascript -var bbox = [-95, 30 ,-85, 40]; -var cellSide = 50; -var options = {units: 'miles'}; - -var squareGrid = turf.squareGrid(bbox, cellSide, options); - -//addToMap -var addToMap = [squareGrid] -``` - -Returns **[FeatureCollection](https://tools.ietf.org/html/rfc7946#section-3.3)<[Polygon](https://tools.ietf.org/html/rfc7946#section-3.1.6)>** grid a grid of polygons - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/square-grid -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-square-grid/index.d.ts b/packages/turf-square-grid/index.d.ts deleted file mode 100644 index 6df84574e3..0000000000 --- a/packages/turf-square-grid/index.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { FeatureCollection, Polygon, BBox, Units, Feature, MultiPolygon, Properties } from "@turf/helpers"; -/** - * Creates a square grid from a bounding box, {@link Feature} or {@link FeatureCollection}. - * - * @name squareGrid - * @param {Array} bbox extent in [minX, minY, maxX, maxY] order - * @param {number} cellSide of each cell, in units - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] used in calculating cellSide, can be degrees, - * radians, miles, or kilometers - * @param {Feature} [options.mask] if passed a Polygon or MultiPolygon, - * the grid Points will be created only inside it - * @param {Object} [options.properties={}] passed to each point of the grid - * @returns {FeatureCollection} grid a grid of polygons - * @example - * var bbox = [-95, 30 ,-85, 40]; - * var cellSide = 50; - * var options = {units: 'miles'}; - * - * var squareGrid = turf.squareGrid(bbox, cellSide, options); - * - * //addToMap - * var addToMap = [squareGrid] - */ -export default function squareGrid

(bbox: BBox, cellSide: number, options?: { - units?: Units; - properties?: P; - mask?: Feature | Polygon | MultiPolygon; -}): FeatureCollection; diff --git a/packages/turf-square-grid/index.ts b/packages/turf-square-grid/index.ts deleted file mode 100644 index ac47867203..0000000000 --- a/packages/turf-square-grid/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - FeatureCollection, Polygon, BBox, Units, Feature, MultiPolygon, Properties -} from "@turf/helpers"; - -import rectangleGrid from "@turf/rectangle-grid"; - -/** - * Creates a square grid from a bounding box, {@link Feature} or {@link FeatureCollection}. - * - * @name squareGrid - * @param {Array} bbox extent in [minX, minY, maxX, maxY] order - * @param {number} cellSide of each cell, in units - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] used in calculating cellSide, can be degrees, - * radians, miles, or kilometers - * @param {Feature} [options.mask] if passed a Polygon or MultiPolygon, - * the grid Points will be created only inside it - * @param {Object} [options.properties={}] passed to each point of the grid - * @returns {FeatureCollection} grid a grid of polygons - * @example - * var bbox = [-95, 30 ,-85, 40]; - * var cellSide = 50; - * var options = {units: 'miles'}; - * - * var squareGrid = turf.squareGrid(bbox, cellSide, options); - * - * //addToMap - * var addToMap = [squareGrid] - */ - -export default function squareGrid

(bbox: BBox, cellSide: number, options: { - units?: Units, - properties?: P, - mask?: Feature | Polygon | MultiPolygon, -} = {}): FeatureCollection { - return rectangleGrid(bbox, cellSide, cellSide, options); -} \ No newline at end of file diff --git a/packages/turf-square-grid/package.json b/packages/turf-square-grid/package.json deleted file mode 100644 index 3d4098c82b..0000000000 --- a/packages/turf-square-grid/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@turf/square-grid", - "version": "6.0.2", - "description": "turf square-grid module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "grid", - "regular", - "cartesian", - "grid" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/bbox-polygon": "*", - "@turf/truncate": "*", - "benchmark": "*", - "tape": "*", - "write-json-file": "*", - "typescript": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/rectangle-grid": "6.x", - "@turf/helpers": "6.x" - } -} diff --git a/packages/turf-square-grid/test.js b/packages/turf-square-grid/test.js deleted file mode 100644 index eedd63e2ed..0000000000 --- a/packages/turf-square-grid/test.js +++ /dev/null @@ -1,66 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const bboxPoly = require('@turf/bbox-polygon').default; -const truncate = require('@turf/truncate').default; -const squareGrid = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -let fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - json: load.sync(directories.in + filename) - }; -}); - -test('square-grid', t => { - for (const {name, json} of fixtures) { - const {bbox, cellSide, units, properties, mask} = json; - const options = { - mask, - units, - properties, - } - const result = truncate(squareGrid(bbox, cellSide, options)); - - // Add styled GeoJSON to the result - const poly = bboxPoly(bbox); - poly.properties = { - stroke: '#F00', - 'stroke-width': 6, - 'fill-opacity': 0 - }; - result.features.push(poly); - if (options.mask) { - options.mask.properties = { - "stroke": "#00F", - "stroke-width": 6, - "fill-opacity": 0 - }; - result.features.push(options.mask); - } - - if (process.env.REGEN) write.sync(directories.out + name + '.geojson', result); - t.deepEqual(result, load.sync(directories.out + name + '.geojson'), name); - } - t.end(); -}); - - -test('square-grid -- throw', t => { - const bbox = [0, 0, 1, 1]; - // t.throws(() => squareGrid(null, 0), /bbox is required/, 'missing bbox'); - // t.throws(() => squareGrid('string', 0), /bbox must be array/, 'invalid bbox'); - // t.throws(() => squareGrid([0, 2], 0), /bbox must contain 4 numbers/, 'invalid bbox'); - // t.throws(() => squareGrid(bbox, null), /cellSide is required/, 'missing cellSide'); - // t.throws(() => squareGrid(bbox, 'string'), /cellSide is invalid/, 'invalid cellSide'); - // t.throws(() => squareGrid(bbox, 1, 'string'), /options is invalid/, 'invalid options'); - t.end(); -}); diff --git a/packages/turf-square-grid/tsconfig.json b/packages/turf-square-grid/tsconfig.json deleted file mode 100644 index 230fe2dd4f..0000000000 --- a/packages/turf-square-grid/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -} \ No newline at end of file diff --git a/packages/turf-square-grid/tslint.json b/packages/turf-square-grid/tslint.json deleted file mode 100644 index 9dd5998b9c..0000000000 --- a/packages/turf-square-grid/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {"interface-name": false}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-square/LICENSE b/packages/turf-square/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-square/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-square/README.md b/packages/turf-square/README.md deleted file mode 100644 index 2f0b6e0cb4..0000000000 --- a/packages/turf-square/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# @turf/square - - - -## square - -Takes a bounding box and calculates the minimum square bounding box that -would contain the input. - -**Parameters** - -- `bbox` **[BBox][1]** extent in [west, south, east, north] order - -**Examples** - -```javascript -var bbox = [-20, -20, -15, 0]; -var squared = turf.square(bbox); - -//addToMap -var addToMap = [turf.bboxPolygon(bbox), turf.bboxPolygon(squared)] -``` - -Returns **[BBox][1]** a square surrounding `bbox` - -[1]: https://tools.ietf.org/html/rfc7946#section-5 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/square -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-square/index.d.ts b/packages/turf-square/index.d.ts deleted file mode 100644 index 208ce7bd2b..0000000000 --- a/packages/turf-square/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { BBox } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#square - */ -export default function (bbox: BBox): BBox; \ No newline at end of file diff --git a/packages/turf-square/index.js b/packages/turf-square/index.js deleted file mode 100644 index e45ac2ab2a..0000000000 --- a/packages/turf-square/index.js +++ /dev/null @@ -1,44 +0,0 @@ -import distance from '@turf/distance'; - -/** - * Takes a bounding box and calculates the minimum square bounding box that - * would contain the input. - * - * @name square - * @param {BBox} bbox extent in [west, south, east, north] order - * @returns {BBox} a square surrounding `bbox` - * @example - * var bbox = [-20, -20, -15, 0]; - * var squared = turf.square(bbox); - * - * //addToMap - * var addToMap = [turf.bboxPolygon(bbox), turf.bboxPolygon(squared)] - */ -function square(bbox) { - var west = bbox[0]; - var south = bbox[1]; - var east = bbox[2]; - var north = bbox[3]; - - var horizontalDistance = distance(bbox.slice(0, 2), [east, south]); - var verticalDistance = distance(bbox.slice(0, 2), [west, north]); - if (horizontalDistance >= verticalDistance) { - var verticalMidpoint = (south + north) / 2; - return [ - west, - verticalMidpoint - ((east - west) / 2), - east, - verticalMidpoint + ((east - west) / 2) - ]; - } else { - var horizontalMidpoint = (west + east) / 2; - return [ - horizontalMidpoint - ((north - south) / 2), - south, - horizontalMidpoint + ((north - south) / 2), - north - ]; - } -} - -export default square; diff --git a/packages/turf-square/package.json b/packages/turf-square/package.json deleted file mode 100644 index 2008586c09..0000000000 --- a/packages/turf-square/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "@turf/square", - "version": "5.1.5", - "description": "turf square module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gis", - "geojson", - "extent" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "rollup": "*", - "tape": "*" - }, - "dependencies": { - "@turf/distance": "6.x", - "@turf/helpers": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-standard-deviational-ellipse/LICENSE b/packages/turf-standard-deviational-ellipse/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-standard-deviational-ellipse/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-standard-deviational-ellipse/README.md b/packages/turf-standard-deviational-ellipse/README.md deleted file mode 100644 index 5f4aa84943..0000000000 --- a/packages/turf-standard-deviational-ellipse/README.md +++ /dev/null @@ -1,94 +0,0 @@ -# @turf/standard-deviational-ellipse - - - -## standardDeviationalEllipse - -Takes a [FeatureCollection][1] and returns a standard deviational ellipse, -also known as a “directional distribution.” The standard deviational ellipse -aims to show the direction and the distribution of a dataset by drawing -an ellipse that contains about one standard deviation’s worth (~ 70%) of the -data. - -This module mirrors the functionality of [Directional Distribution][2] -in ArcGIS and the [QGIS Standard Deviational Ellipse Plugin][3] - -**Bibliography** - -• Robert S. Yuill, “The Standard Deviational Ellipse; An Updated Tool for -Spatial Description,” _Geografiska Annaler_ 53, no. 1 (1971): 28–39, -doi:[10.2307/490885][4]. - -• Paul Hanly Furfey, “A Note on Lefever’s “Standard Deviational Ellipse,” -_American Journal of Sociology_ 33, no. 1 (1927): 94—98, -doi:[10.1086/214336][5]. - -**Parameters** - -- `points` **[FeatureCollection][6]<[Point][7]>** GeoJSON points -- `options` **[Object][8]** Optional parameters (optional, default `{}`) - - `options.weight` **[string][9]?** the property name used to weight the center - - `options.steps` **[number][10]** number of steps for the polygon (optional, default `64`) - - `options.properties` **[Object][8]** properties to pass to the resulting ellipse (optional, default `{}`) - -**Examples** - -```javascript -var bbox = [-74, 40.72, -73.98, 40.74]; -var points = turf.randomPoint(400, {bbox: bbox}); -var sdEllipse = turf.standardDeviationalEllipse(points); - -//addToMap -var addToMap = [points, sdEllipse]; -``` - -Returns **[Feature][11]<[Polygon][12]>** an elliptical Polygon that includes approximately 1 SD of the dataset within it. - -[1]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[2]: http://desktop.arcgis.com/en/arcmap/10.3/tools/spatial-statistics-toolbox/directional-distribution.htm - -[3]: http://arken.nmbu.no/~havatv/gis/qgisplugins/SDEllipse/ - -[4]: https://doi.org/10.2307/490885 - -[5]: https://doi.org/10.1086/214336 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[11]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[12]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/standard-deviational-ellipse -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-standard-deviational-ellipse/bench.js b/packages/turf-standard-deviational-ellipse/bench.js deleted file mode 100644 index d1b0a38d4d..0000000000 --- a/packages/turf-standard-deviational-ellipse/bench.js +++ /dev/null @@ -1,20 +0,0 @@ -import { randomPoint } from '@turf/random'; -import standardDeviationalEllipse from '.'; -import Benchmark from 'benchmark'; - -/** - * Benchmark Results - * - * turf-standard-deviational-ellipse - 150 points x 1,874 ops/sec ±5.89% (89 runs sampled) - * turf-standard-deviational-ellipse - 300 points x 1,092 ops/sec ±0.79% (93 runs sampled) - * turf-standard-deviational-ellipse - 600 points x 574 ops/sec ±1.14% (92 runs sampled) - */ -const suite = new Benchmark.Suite('turf-standard-deviational-ellipse'); -const properties = {bbox: [-10, -10, 10, 10]}; -suite - .add('turf-standard-deviational-ellipse - 150 points', () => standardDeviationalEllipse(randomPoint(150, properties))) - .add('turf-standard-deviational-ellipse - 300 points', () => standardDeviationalEllipse(randomPoint(300, properties))) - .add('turf-standard-deviational-ellipse - 600 points', () => standardDeviationalEllipse(randomPoint(600, properties))) - .on('cycle', e => console.log(String(e.target))) - .on('complete', () => {}) - .run(); diff --git a/packages/turf-standard-deviational-ellipse/index.d.ts b/packages/turf-standard-deviational-ellipse/index.d.ts deleted file mode 100644 index 365e43ee3b..0000000000 --- a/packages/turf-standard-deviational-ellipse/index.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { FeatureCollection, Feature, Position, Polygon, Properties, Point } from '@turf/helpers'; - -/** - * http://turfjs.org/docs/#standarddeviational-ellipse - */ - -export interface SDEProps { - meanCenterCoordinates: Position, - semiMajorAxis: number, - semiMinorAxis: number, - numberOfFeatures: number, - angle: number, - percentageWithinEllipse: number -} - -export interface StandardDeviationalEllipse extends Feature { - properties: { - standardDeviationalEllipse: SDEProps, - [key: string]: any - } -} - -export default function ( - points: FeatureCollection, - options?: { - properties?: Properties, - weight?: string, - steps?: number - } -): StandardDeviationalEllipse; diff --git a/packages/turf-standard-deviational-ellipse/index.js b/packages/turf-standard-deviational-ellipse/index.js deleted file mode 100644 index adbb517198..0000000000 --- a/packages/turf-standard-deviational-ellipse/index.js +++ /dev/null @@ -1,135 +0,0 @@ -import { coordAll, featureEach } from '@turf/meta'; -import { getCoords } from '@turf/invariant'; -import { featureCollection, isObject, isNumber } from '@turf/helpers'; -import centerMean from '@turf/center-mean'; -import pointsWithinPolygon from '@turf/points-within-polygon'; -import ellipse from '@turf/ellipse'; - -/** - * Takes a {@link FeatureCollection} and returns a standard deviational ellipse, - * also known as a “directional distribution.” The standard deviational ellipse - * aims to show the direction and the distribution of a dataset by drawing - * an ellipse that contains about one standard deviation’s worth (~ 70%) of the - * data. - * - * This module mirrors the functionality of [Directional Distribution](http://desktop.arcgis.com/en/arcmap/10.3/tools/spatial-statistics-toolbox/directional-distribution.htm) - * in ArcGIS and the [QGIS Standard Deviational Ellipse Plugin](http://arken.nmbu.no/~havatv/gis/qgisplugins/SDEllipse/) - * - * **Bibliography** - * - * • Robert S. Yuill, “The Standard Deviational Ellipse; An Updated Tool for - * Spatial Description,” _Geografiska Annaler_ 53, no. 1 (1971): 28–39, - * doi:{@link https://doi.org/10.2307/490885|10.2307/490885}. - * - * • Paul Hanly Furfey, “A Note on Lefever’s “Standard Deviational Ellipse,” - * _American Journal of Sociology_ 33, no. 1 (1927): 94—98, - * doi:{@link https://doi.org/10.1086/214336|10.1086/214336}. - * - * - * @name standardDeviationalEllipse - * @param {FeatureCollection} points GeoJSON points - * @param {Object} [options={}] Optional parameters - * @param {string} [options.weight] the property name used to weight the center - * @param {number} [options.steps=64] number of steps for the polygon - * @param {Object} [options.properties={}] properties to pass to the resulting ellipse - * @returns {Feature} an elliptical Polygon that includes approximately 1 SD of the dataset within it. - * @example - * - * var bbox = [-74, 40.72, -73.98, 40.74]; - * var points = turf.randomPoint(400, {bbox: bbox}); - * var sdEllipse = turf.standardDeviationalEllipse(points); - * - * //addToMap - * var addToMap = [points, sdEllipse]; - * - */ -function standardDeviationalEllipse(points, options) { - // Optional params - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var steps = options.steps || 64; - var weightTerm = options.weight; - var properties = options.properties || {}; - - // Validation: - if (!isNumber(steps)) throw new Error('steps must be a number'); - if (!isObject(properties)) throw new Error('properties must be a number'); - - // Calculate mean center & number of features: - var numberOfFeatures = coordAll(points).length; - var meanCenter = centerMean(points, {weight: weightTerm}); - - // Calculate angle of rotation: - // [X, Y] = mean center of all [x, y]. - // theta = arctan( (A + B) / C ) - // A = sum((x - X)^2) - sum((y - Y)^2) - // B = sqrt(A^2 + 4(sum((x - X)(y - Y))^2)) - // C = 2(sum((x - X)(y - Y))) - - var xDeviationSquaredSum = 0; - var yDeviationSquaredSum = 0; - var xyDeviationSum = 0; - - featureEach(points, function (point) { - var weight = point.properties[weightTerm] || 1; - var deviation = getDeviations(getCoords(point), getCoords(meanCenter)); - xDeviationSquaredSum += Math.pow(deviation.x, 2) * weight; - yDeviationSquaredSum += Math.pow(deviation.y, 2) * weight; - xyDeviationSum += deviation.x * deviation.y * weight; - }); - - var bigA = xDeviationSquaredSum - yDeviationSquaredSum; - var bigB = Math.sqrt(Math.pow(bigA, 2) + 4 * Math.pow(xyDeviationSum, 2)); - var bigC = 2 * xyDeviationSum; - var theta = Math.atan((bigA + bigB) / bigC); - var thetaDeg = theta * 180 / Math.PI; - - // Calculate axes: - // sigmaX = sqrt((1 / n - 2) * sum((((x - X) * cos(theta)) - ((y - Y) * sin(theta)))^2)) - // sigmaY = sqrt((1 / n - 2) * sum((((x - X) * sin(theta)) - ((y - Y) * cos(theta)))^2)) - var sigmaXsum = 0; - var sigmaYsum = 0; - var weightsum = 0; - featureEach(points, function (point) { - var weight = point.properties[weightTerm] || 1; - var deviation = getDeviations(getCoords(point), getCoords(meanCenter)); - sigmaXsum += Math.pow((deviation.x * Math.cos(theta)) - (deviation.y * Math.sin(theta)), 2) * weight; - sigmaYsum += Math.pow((deviation.x * Math.sin(theta)) + (deviation.y * Math.cos(theta)), 2) * weight; - weightsum += weight; - }); - - var sigmaX = Math.sqrt(2 * sigmaXsum / weightsum); - var sigmaY = Math.sqrt(2 * sigmaYsum / weightsum); - - var theEllipse = ellipse(meanCenter, sigmaX, sigmaY, {units: 'degrees', angle: thetaDeg, steps: steps, properties: properties}); - var pointsWithinEllipse = pointsWithinPolygon(points, featureCollection([theEllipse])); - var standardDeviationalEllipseProperties = { - meanCenterCoordinates: getCoords(meanCenter), - semiMajorAxis: sigmaX, - semiMinorAxis: sigmaY, - numberOfFeatures: numberOfFeatures, - angle: thetaDeg, - percentageWithinEllipse: 100 * coordAll(pointsWithinEllipse).length / numberOfFeatures - }; - theEllipse.properties.standardDeviationalEllipse = standardDeviationalEllipseProperties; - - return theEllipse; -} - -/** - * Get x_i - X and y_i - Y - * - * @private - * @param {Array} coordinates Array of [x_i, y_i] - * @param {Array} center Array of [X, Y] - * @returns {Object} { x: n, y: m } - */ -function getDeviations(coordinates, center) { - return { - x: coordinates[0] - center[0], - y: coordinates[1] - center[1] - }; -} - - -export default standardDeviationalEllipse; diff --git a/packages/turf-standard-deviational-ellipse/package.json b/packages/turf-standard-deviational-ellipse/package.json deleted file mode 100644 index a9bad1dbfb..0000000000 --- a/packages/turf-standard-deviational-ellipse/package.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "@turf/standard-deviational-ellipse", - "version": "5.1.5", - "description": "turf standard-deviational-ellipse module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "standard-deviational-ellipse", - "geostatistics", - "directional distribution" - ], - "author": "Turf Authors", - "contributors": [ - "Moacir P. de Sá Pereira <@muziejus>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/random": "6.x", - "@turf/truncate": "6.x", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/center-mean": "6.x", - "@turf/ellipse": "^5.1.5", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x", - "@turf/points-within-polygon": "^5.1.5" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-standard-deviational-ellipse/test.js b/packages/turf-standard-deviational-ellipse/test.js deleted file mode 100644 index d3c8909235..0000000000 --- a/packages/turf-standard-deviational-ellipse/test.js +++ /dev/null @@ -1,44 +0,0 @@ -import test from 'tape'; -import glob from 'glob'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import { featureCollection } from '@turf/helpers'; -import { featureEach } from '@turf/meta'; -import truncate from '@turf/truncate'; -import standardDeviationalEllipse from '.'; - -test('turf-standard-deviational-ellipse', t => { - glob.sync(path.join(__dirname, 'test', 'in', '*.json')).forEach(filepath => { - // Define params - const {name} = path.parse(filepath); - const geojson = load.sync(filepath); - const options = geojson.options; - // Optional: ESRI Polygon in GeoJSON test/in to compare results - const esriEllipse = geojson.esriEllipse; - - // Colorized results - const results = featureCollection([ - colorize(standardDeviationalEllipse(geojson, options)), - ]); - if (esriEllipse) results.features.unshift(colorize(esriEllipse, '#A00', '#A00', 0.5)) - - // Save to file - const out = filepath.replace(path.join('test', 'in'), path.join('test', 'out')); - if (process.env.REGEN) write.sync(out, results); - t.deepEqual(results, load.sync(out), name); - }); - t.end(); -}); - -function colorize (feature, stroke = '#0A0', fill = '#FFF', opacity = 0) { - const properties = { - fill, - stroke, - 'stroke-width': 3, - 'stroke-opacity': 1, - 'fill-opacity': opacity - }; - Object.assign(feature.properties, properties) - return feature -} \ No newline at end of file diff --git a/packages/turf-standard-deviational-ellipse/types.ts b/packages/turf-standard-deviational-ellipse/types.ts deleted file mode 100644 index 5dd84e35ca..0000000000 --- a/packages/turf-standard-deviational-ellipse/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { points } from '@turf/helpers' -import standardDeviatationalEllipse from './' - -const pts = points([ - [10, 10], - [0, 5] -]) -const stdEllipse = standardDeviatationalEllipse(pts) - -// Access custom properties -stdEllipse.properties.standardDeviationalEllipse.meanCenterCoordinates diff --git a/packages/turf-tag/LICENSE b/packages/turf-tag/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-tag/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-tag/README.md b/packages/turf-tag/README.md deleted file mode 100644 index c3b7e2f9c9..0000000000 --- a/packages/turf-tag/README.md +++ /dev/null @@ -1,82 +0,0 @@ -# @turf/tag - - - -## tag - -Takes a set of [points][1] and a set of [polygons][2] and performs a spatial join. - -**Parameters** - -- `points` **[FeatureCollection][3]<[Point][4]>** input points -- `polygons` **[FeatureCollection][3]<[Polygon][5]>** input polygons -- `field` **[string][6]** property in `polygons` to add to joined {} features -- `outField` **[string][6]** property in `points` in which to store joined property from `polygons` - -**Examples** - -```javascript -var pt1 = turf.point([-77, 44]); -var pt2 = turf.point([-77, 38]); -var poly1 = turf.polygon([[ - [-81, 41], - [-81, 47], - [-72, 47], - [-72, 41], - [-81, 41] -]], {pop: 3000}); -var poly2 = turf.polygon([[ - [-81, 35], - [-81, 41], - [-72, 41], - [-72, 35], - [-81, 35] -]], {pop: 1000}); - -var points = turf.featureCollection([pt1, pt2]); -var polygons = turf.featureCollection([poly1, poly2]); - -var tagged = turf.tag(points, polygons, 'pop', 'population'); - -//addToMap -var addToMap = [tagged, polygons] -``` - -Returns **[FeatureCollection][3]<[Point][4]>** points with `containingPolyId` property containing values from `polyId` - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/tag -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-tag/index.d.ts b/packages/turf-tag/index.d.ts deleted file mode 100644 index 3a7eeb4863..0000000000 --- a/packages/turf-tag/index.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { BBox, Point, FeatureCollection, Polygon } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#tag - */ -export default function tag( - points: FeatureCollection, - polygons: FeatureCollection, - field: string, - outField: string -): FeatureCollection; diff --git a/packages/turf-tag/index.js b/packages/turf-tag/index.js deleted file mode 100644 index e7f0fab183..0000000000 --- a/packages/turf-tag/index.js +++ /dev/null @@ -1,55 +0,0 @@ -import booleanPointInPolygon from '@turf/boolean-point-in-polygon'; -import clone from '@turf/clone'; -import { featureEach } from '@turf/meta'; - -/** - * Takes a set of {@link Point|points} and a set of {@link Polygon|polygons} and performs a spatial join. - * - * @name tag - * @param {FeatureCollection} points input points - * @param {FeatureCollection} polygons input polygons - * @param {string} field property in `polygons` to add to joined {} features - * @param {string} outField property in `points` in which to store joined property from `polygons` - * @returns {FeatureCollection} points with `containingPolyId` property containing values from `polyId` - * @example - * var pt1 = turf.point([-77, 44]); - * var pt2 = turf.point([-77, 38]); - * var poly1 = turf.polygon([[ - * [-81, 41], - * [-81, 47], - * [-72, 47], - * [-72, 41], - * [-81, 41] - * ]], {pop: 3000}); - * var poly2 = turf.polygon([[ - * [-81, 35], - * [-81, 41], - * [-72, 41], - * [-72, 35], - * [-81, 35] - * ]], {pop: 1000}); - * - * var points = turf.featureCollection([pt1, pt2]); - * var polygons = turf.featureCollection([poly1, poly2]); - * - * var tagged = turf.tag(points, polygons, 'pop', 'population'); - * - * //addToMap - * var addToMap = [tagged, polygons] - */ -function tag(points, polygons, field, outField) { - // prevent mutations - points = clone(points); - polygons = clone(polygons); - featureEach(points, function (pt) { - if (!pt.properties) pt.properties = {}; - featureEach(polygons, function (poly) { - if (pt.properties[outField] === undefined) { - if (booleanPointInPolygon(pt, poly)) pt.properties[outField] = poly.properties[field]; - } - }); - }); - return points; -} - -export default tag; diff --git a/packages/turf-tag/package.json b/packages/turf-tag/package.json deleted file mode 100644 index d0e678614d..0000000000 --- a/packages/turf-tag/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "@turf/tag", - "version": "5.1.5", - "description": "turf tag module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "geojson", - "turf", - "tag", - "polygon", - "featurecollection", - "point", - "data", - "analysis" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*" - }, - "dependencies": { - "@turf/boolean-point-in-polygon": "6.x", - "@turf/clone": "6.x", - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-tesselate/LICENSE b/packages/turf-tesselate/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-tesselate/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-tesselate/README.md b/packages/turf-tesselate/README.md deleted file mode 100644 index 3a3630f917..0000000000 --- a/packages/turf-tesselate/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# @turf/tesselate - - - -## tesselate - -Tesselates a [Feature<Polygon>][1] into a [FeatureCollection<Polygon>][2] of triangles -using [earcut][3]. - -**Parameters** - -- `poly` **[Feature][4]<[Polygon][5]>** the polygon to tesselate - -**Examples** - -```javascript -var poly = turf.polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); -var triangles = turf.tesselate(poly); - -//addToMap -var addToMap = [poly, triangles] -``` - -Returns **[FeatureCollection][6]<[Polygon][5]>** a geometrycollection feature - -[1]: Feature - -[2]: FeatureCollection - -[3]: https://github.com/mapbox/earcut - -[4]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[6]: https://tools.ietf.org/html/rfc7946#section-3.3 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/tesselate -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-tesselate/bench.js b/packages/turf-tesselate/bench.js deleted file mode 100644 index 3d19bdf536..0000000000 --- a/packages/turf-tesselate/bench.js +++ /dev/null @@ -1,16 +0,0 @@ -import Benchmark from 'benchmark'; -import { polygon } from '@turf/helpers'; -import tesselate from './'; - -var poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); - -/** - * Benchmark Results - * - */ -const suite = new Benchmark.Suite('turf-tesselate'); -suite - .add('polygon', () => turf.tesselate(poly)) - .on('cycle', e => console.log(String(e.target))) - .on('complete', () => {}) - .run(); diff --git a/packages/turf-tesselate/index.js b/packages/turf-tesselate/index.js deleted file mode 100644 index 5d54215fca..0000000000 --- a/packages/turf-tesselate/index.js +++ /dev/null @@ -1,76 +0,0 @@ -import earcut from 'earcut'; -import { polygon } from '@turf/helpers'; - -/** - * Tesselates a {@link Feature} into a {@link FeatureCollection} of triangles - * using [earcut](https://github.com/mapbox/earcut). - * - * @name tesselate - * @param {Feature} poly the polygon to tesselate - * @returns {FeatureCollection} a geometrycollection feature - * @example - * var poly = turf.polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); - * var triangles = turf.tesselate(poly); - * - * //addToMap - * var addToMap = [poly, triangles] - */ -function tesselate(poly) { - if (!poly.geometry || (poly.geometry.type !== 'Polygon' && poly.geometry.type !== 'MultiPolygon')) { - throw new Error('input must be a Polygon or MultiPolygon'); - } - - var fc = {type: 'FeatureCollection', features: []}; - - if (poly.geometry.type === 'Polygon') { - fc.features = processPolygon(poly.geometry.coordinates); - } else { - poly.geometry.coordinates.forEach(function (coordinates) { - fc.features = fc.features.concat(processPolygon(coordinates)); - }); - } - - return fc; -} - -function processPolygon(coordinates) { - var data = flattenCoords(coordinates); - var dim = 2; - var result = earcut(data.vertices, data.holes, dim); - - var features = []; - var vertices = []; - - result.forEach(function (vert, i) { - var index = result[i]; - vertices.push([data.vertices[index * dim], data.vertices[index * dim + 1]]); - }); - - for (var i = 0; i < vertices.length; i += 3) { - var coords = vertices.slice(i, i + 3); - coords.push(vertices[i]); - features.push(polygon([coords])); - } - - return features; -} - -function flattenCoords(data) { - var dim = data[0][0].length, - result = {vertices: [], holes: [], dimensions: dim}, - holeIndex = 0; - - for (var i = 0; i < data.length; i++) { - for (var j = 0; j < data[i].length; j++) { - for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]); - } - if (i > 0) { - holeIndex += data[i - 1].length; - result.holes.push(holeIndex); - } - } - - return result; -} - -export default tesselate; diff --git a/packages/turf-tesselate/package.json b/packages/turf-tesselate/package.json deleted file mode 100644 index 2c216e2054..0000000000 --- a/packages/turf-tesselate/package.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "name": "@turf/tesselate", - "version": "5.1.5", - "description": "turf tesselate module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "turfjs", - "tesselation", - "earcut", - "polygon", - "triangles" - ], - "author": "Turf Authors", - "contributors": [ - "Abel Vázquez <@AbelVM>", - "Morgan Herlocker <@morganherlocker>", - "Tom MacWright <@tmcw>", - "Vladimir Agafonkin <@mourner>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "rollup": "*", - "tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "earcut": "^2.0.0" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-tesselate/test.js b/packages/turf-tesselate/test.js deleted file mode 100644 index d49b220406..0000000000 --- a/packages/turf-tesselate/test.js +++ /dev/null @@ -1,32 +0,0 @@ -import test from 'tape'; -import tesselate from '.'; -import { featureCollection as featurecollection } from '@turf/helpers'; -import { point } from '@turf/helpers'; - -test('tesselate', function (t) { - var polygon = {type: 'Feature', id: 'USA-CA', properties: {fips: '06', name: 'California'}, geometry: {type: 'Polygon', coordinates: [[[-123.233256, 42.006186], [-122.378853, 42.011663], [-121.037003, 41.995232], [-120.001861, 41.995232], [-119.996384, 40.264519], [-120.001861, 38.999346], [-118.71478, 38.101128], [-117.498899, 37.21934], [-116.540435, 36.501861], [-115.85034, 35.970598], [-114.634459, 35.00118], [-114.634459, 34.87521], [-114.470151, 34.710902], [-114.333228, 34.448009], [-114.136058, 34.305608], [-114.256551, 34.174162], [-114.415382, 34.108438], [-114.535874, 33.933176], [-114.497536, 33.697668], [-114.524921, 33.54979], [-114.727567, 33.40739], [-114.661844, 33.034958], [-114.524921, 33.029481], [-114.470151, 32.843265], [-114.524921, 32.755634], [-114.72209, 32.717295], [-116.04751, 32.624187], [-117.126467, 32.536556], [-117.24696, 32.668003], [-117.252437, 32.876127], [-117.329114, 33.122589], [-117.471515, 33.297851], [-117.7837, 33.538836], [-118.183517, 33.763391], [-118.260194, 33.703145], [-118.413548, 33.741483], [-118.391641, 33.840068], [-118.566903, 34.042715], [-118.802411, 33.998899], [-119.218659, 34.146777], [-119.278905, 34.26727], [-119.558229, 34.415147], [-119.875891, 34.40967], [-120.138784, 34.475393], [-120.472878, 34.448009], [-120.64814, 34.579455], [-120.609801, 34.858779], [-120.670048, 34.902595], [-120.631709, 35.099764], [-120.894602, 35.247642], [-120.905556, 35.450289], [-121.004141, 35.461243], [-121.168449, 35.636505], [-121.283465, 35.674843], [-121.332757, 35.784382], [-121.716143, 36.195153], [-121.896882, 36.315645], [-121.935221, 36.638785], [-121.858544, 36.6114], [-121.787344, 36.803093], [-121.929744, 36.978355], [-122.105006, 36.956447], [-122.335038, 37.115279], [-122.417192, 37.241248], [-122.400761, 37.361741], [-122.515777, 37.520572], [-122.515777, 37.783465], [-122.329561, 37.783465], [-122.406238, 38.15042], [-122.488392, 38.112082], [-122.504823, 37.931343], [-122.701993, 37.893004], [-122.937501, 38.029928], [-122.97584, 38.265436], [-123.129194, 38.451652], [-123.331841, 38.566668], [-123.44138, 38.698114], [-123.737134, 38.95553], [-123.687842, 39.032208], [-123.824765, 39.366301], [-123.764519, 39.552517], [-123.85215, 39.831841], [-124.109566, 40.105688], [-124.361506, 40.259042], [-124.410798, 40.439781], [-124.158859, 40.877937], [-124.109566, 41.025814], [-124.158859, 41.14083], [-124.065751, 41.442061], [-124.147905, 41.715908], [-124.257444, 41.781632], [-124.213628, 42.000709], [-123.233256, 42.006186]]]}}; - - var triangles = tesselate(polygon); - - t.equal(triangles.type, 'FeatureCollection', 'Polygon returns a FeatureCollection'); - t.equal(triangles.features[0].geometry.type, 'Polygon', 'contains at least 1 triangle'); - t.equal(triangles.features[0].geometry.coordinates[0].length, 4, 'triangle is valid'); - - var multipolygon = { type: 'Feature', properties: { name: 'Michigan' }, geometry: { type: 'MultiPolygon', coordinates: [[[[-88.684434, 48.115785], [-88.675628, 48.120444], [-88.676395, 48.124876], [-88.674192, 48.127165], [-88.656915, 48.139225], [-88.614026, 48.154797], [-88.578413, 48.162370], [-88.547033, 48.174891], [-88.524753, 48.165291], [-88.501088, 48.168181], [-88.491961, 48.175466], [-88.482039, 48.179915], [-88.459735, 48.183807], [-88.447236, 48.182916], [-88.422601, 48.190975], [-88.418244, 48.180370], [-88.419875, 48.170731], [-88.427373, 48.166764], [-88.449502, 48.163312], [-88.459697, 48.158551], [-88.469573, 48.152879], [-88.485700, 48.137683], [-88.511902, 48.121699], [-88.566938, 48.093719], [-88.578053, 48.084373], [-88.578395, 48.078003], [-88.575869, 48.075166], [-88.573924, 48.068861], [-88.575048, 48.064154], [-88.579784, 48.058669], [-88.670073, 48.011446], [-88.718555, 47.995134], [-88.772357, 47.981126], [-88.791959, 47.978938], [-88.832063, 47.965213], [-88.852923, 47.965322], [-88.899184, 47.953300], [-88.918029, 47.945605], [-88.923573, 47.937976], [-88.962664, 47.923512], [-88.968903, 47.909474], [-88.968903, 47.901675], [-88.957985, 47.895436], [-88.942387, 47.895436], [-88.899698, 47.902445], [-88.898986, 47.900685], [-88.911665, 47.891344], [-88.998939, 47.867490], [-89.022736, 47.858532], [-89.044463, 47.855750], [-89.056412, 47.852598], [-89.107991, 47.835705], [-89.124134, 47.828616], [-89.157738, 47.824015], [-89.190170, 47.831603], [-89.192681, 47.833430], [-89.192207, 47.841060], [-89.201812, 47.850243], [-89.234533, 47.851718], [-89.235552, 47.853774], [-89.234535, 47.855373], [-89.228507, 47.858039], [-89.246774, 47.871016], [-89.250936, 47.870377], [-89.255202, 47.876102], [-89.247127, 47.888503], [-89.226327, 47.895438], [-89.220710, 47.900850], [-89.221332, 47.908069], [-89.214499, 47.913895], [-89.179154, 47.935030], [-89.095207, 47.967922], [-89.018303, 47.992525], [-88.994163, 48.002290], [-88.940886, 48.019590], [-88.931487, 48.021637], [-88.927529, 48.019615], [-88.915032, 48.020681], [-88.895069, 48.029059], [-88.896327, 48.031801], [-88.893701, 48.034770], [-88.835714, 48.056752], [-88.816084, 48.057006], [-88.810461, 48.055247], [-88.787556, 48.063035], [-88.772077, 48.070502], [-88.771830, 48.079457], [-88.764256, 48.085189], [-88.744458, 48.092769], [-88.728198, 48.101914], [-88.705586, 48.111013], [-88.695353, 48.110549], [-88.684434, 48.115785]]], [[[-85.566441, 45.760222], [-85.549560, 45.757266], [-85.543750, 45.751413], [-85.535620, 45.750394], [-85.525237, 45.750462], [-85.506133, 45.754715], [-85.501267, 45.754415], [-85.497656, 45.746246], [-85.503758, 45.742771], [-85.508818, 45.742358], [-85.510091, 45.742888], [-85.508522, 45.744991], [-85.509040, 45.748488], [-85.515145, 45.749451], [-85.520569, 45.744745], [-85.521911, 45.739419], [-85.520803, 45.737247], [-85.510895, 45.734414], [-85.498777, 45.726291], [-85.494154, 45.705378], [-85.494016, 45.698476], [-85.502800, 45.690998], [-85.506104, 45.681148], [-85.503767, 45.670472], [-85.500451, 45.664298], [-85.490252, 45.652122], [-85.487026, 45.621211], [-85.491347, 45.609665], [-85.509276, 45.596475], [-85.518038, 45.592912], [-85.526895, 45.591590], [-85.530273, 45.589253], [-85.534064, 45.578198], [-85.541129, 45.575045], [-85.561634, 45.572213], [-85.618049, 45.582647], [-85.622741, 45.586028], [-85.630016, 45.598166], [-85.619850, 45.624547], [-85.608653, 45.632008], [-85.604521, 45.639256], [-85.604951, 45.647599], [-85.609295, 45.658067], [-85.604881, 45.681932], [-85.600842, 45.688860], [-85.590769, 45.698051], [-85.583724, 45.700796], [-85.572309, 45.711449], [-85.565132, 45.730719], [-85.564774, 45.745462], [-85.567128, 45.750419], [-85.567781, 45.757655], [-85.566441, 45.760222]]], [[[-87.590208, 45.095264], [-87.591880, 45.094689], [-87.614897, 45.100064], [-87.621609, 45.102399], [-87.627640, 45.103328], [-87.628829, 45.104039], [-87.629571, 45.105324], [-87.631535, 45.106224], [-87.636110, 45.105918], [-87.648191, 45.106368], [-87.652512, 45.108633], [-87.657135, 45.107568], [-87.659952, 45.107512], [-87.661211, 45.108279], [-87.661296, 45.112566], [-87.667102, 45.118109], [-87.671000, 45.120069], [-87.672447, 45.121294], [-87.678209, 45.130084], [-87.678511, 45.131204], [-87.676024, 45.134089], [-87.675816, 45.135059], [-87.683902, 45.144135], [-87.688425, 45.147433], [-87.692375, 45.149505], [-87.695055, 45.150522], [-87.700618, 45.151188], [-87.703492, 45.152206], [-87.707391, 45.154679], [-87.708134, 45.156004], [-87.711322, 45.158946], [-87.717945, 45.161156], [-87.723121, 45.165141], [-87.724601, 45.167452], [-87.727768, 45.169596], [-87.730866, 45.170913], [-87.735135, 45.171538], [-87.736104, 45.172244], [-87.736509, 45.173389], [-87.735210, 45.177642], [-87.741805, 45.197051], [-87.741732, 45.198201], [-87.739492, 45.202126], [-87.736339, 45.204653], [-87.727960, 45.207956], [-87.726198, 45.209391], [-87.726175, 45.212640], [-87.727276, 45.216129], [-87.726952, 45.218949], [-87.722473, 45.223309], [-87.721354, 45.226847], [-87.721935, 45.228444], [-87.724920, 45.229977], [-87.725205, 45.231539], [-87.724156, 45.233236], [-87.718264, 45.238333], [-87.717051, 45.238743], [-87.713398, 45.238564], [-87.712184, 45.239014], [-87.711339, 45.239965], [-87.711480, 45.245224], [-87.709145, 45.254649], [-87.707779, 45.258343], [-87.709137, 45.260341], [-87.703053, 45.267041], [-87.698780, 45.269420], [-87.698456, 45.272072], [-87.699492, 45.276659], [-87.698248, 45.281512], [-87.693468, 45.287675], [-87.690364, 45.290270], [-87.687578, 45.296283], [-87.687498, 45.298055], [-87.679085, 45.305841], [-87.675328, 45.307907], [-87.667423, 45.316360], [-87.665243, 45.317115], [-87.663666, 45.318257], [-87.661500, 45.321386], [-87.662029, 45.326434], [-87.661603, 45.327608], [-87.659830, 45.329144], [-87.655775, 45.330847], [-87.648126, 45.339396], [-87.647454, 45.345232], [-87.647729, 45.350721], [-87.648476, 45.352243], [-87.650661, 45.353798], [-87.653568, 45.354204], [-87.656632, 45.358617], [-87.655807, 45.362706], [-87.656624, 45.367295], [-87.657349, 45.368752], [-87.673513, 45.376946], [-87.674403, 45.378065], [-87.674550, 45.381649], [-87.675017, 45.382454], [-87.682866, 45.384950], [-87.685934, 45.388711], [-87.690281, 45.389822], [-87.693956, 45.389893], [-87.699797, 45.387927], [-87.704337, 45.385462], [-87.706767, 45.383827], [-87.708329, 45.381218], [-87.718891, 45.377462], [-87.733409, 45.364432], [-87.737801, 45.359635], [-87.738352, 45.358243], [-87.750928, 45.355037], [-87.751626, 45.354169], [-87.751452, 45.351755], [-87.754104, 45.349442], [-87.762128, 45.348401], [-87.769172, 45.351195], [-87.771384, 45.351210], [-87.773901, 45.351226], [-87.783076, 45.349725], [-87.787967, 45.352612], [-87.790324, 45.353444], [-87.800464, 45.353608], [-87.810076, 45.351269], [-87.823028, 45.352650], [-87.823554, 45.351637], [-87.824855, 45.350713], [-87.826918, 45.350538], [-87.829775, 45.352005], [-87.832612, 45.352249], [-87.835303, 45.350980], [-87.836782, 45.346451], [-87.838141, 45.345101], [-87.848368, 45.340676], [-87.850133, 45.340435], [-87.851318, 45.341346], [-87.851475, 45.342335], [-87.849899, 45.344651], [-87.850418, 45.347492], [-87.852784, 45.349497], [-87.858617, 45.350378], [-87.860871, 45.351192], [-87.863489, 45.353020], [-87.864873, 45.354767], [-87.865274, 45.355969], [-87.865675, 45.358213], [-87.867037, 45.360137], [-87.868560, 45.360537], [-87.870243, 45.360617], [-87.871204, 45.360056], [-87.871285, 45.358614], [-87.871124, 45.357011], [-87.871685, 45.355729], [-87.873529, 45.354286], [-87.879835, 45.351490], [-87.881114, 45.351278], [-87.885170, 45.351736], [-87.886949, 45.353110], [-87.888052, 45.354697], [-87.887828, 45.358122], [-87.884855, 45.362792], [-87.876862, 45.368535], [-87.871485, 45.371546], [-87.871789, 45.373557], [-87.875692, 45.377052], [-87.875424, 45.379373], [-87.873568, 45.381357], [-87.870905, 45.383116], [-87.864677, 45.385232], [-87.859418, 45.388227], [-87.856830, 45.393106], [-87.859603, 45.396409], [-87.859773, 45.397278], [-87.859131, 45.398967], [-87.850969, 45.401925], [-87.849322, 45.403872], [-87.849668, 45.409518], [-87.850533, 45.411685], [-87.851810, 45.413103], [-87.856216, 45.416101], [-87.860432, 45.423504], [-87.860127, 45.429584], [-87.861950, 45.433072], [-87.861697, 45.434473], [-87.855298, 45.441379], [-87.847429, 45.444177], [-87.844815, 45.448411], [-87.836008, 45.450877], [-87.833042, 45.453596], [-87.832456, 45.455020], [-87.827430, 45.458076], [-87.821057, 45.459955], [-87.812976, 45.464159], [-87.812971, 45.466100], [-87.811469, 45.467991], [-87.805773, 45.473139], [-87.805873, 45.474380], [-87.807388, 45.477031], [-87.806891, 45.479092], [-87.798960, 45.485147], [-87.798362, 45.486564], [-87.797824, 45.491468], [-87.796409, 45.494679], [-87.793447, 45.498372], [-87.792769, 45.499967], [-87.793215, 45.505028], [-87.798794, 45.506287], [-87.802267, 45.514233], [-87.804203, 45.524676], [-87.804720, 45.531244], [-87.804528, 45.534373], [-87.803364, 45.537016], [-87.803390, 45.538272], [-87.807159, 45.543523], [-87.813737, 45.548616], [-87.818791, 45.552100], [-87.827215, 45.555620], [-87.832296, 45.558767], [-87.832968, 45.559461], [-87.833591, 45.562529], [-87.831689, 45.568035], [-87.829346, 45.568776], [-87.813745, 45.565175], [-87.806104, 45.562863], [-87.797536, 45.562124], [-87.792372, 45.563055], [-87.790874, 45.564096], [-87.788798, 45.565947], [-87.788326, 45.567941], [-87.787292, 45.574906], [-87.787534, 45.581376], [-87.786767, 45.582830], [-87.785647, 45.583960], [-87.781255, 45.585682], [-87.777199, 45.588499], [-87.776238, 45.597797], [-87.777671, 45.609204], [-87.780845, 45.614599], [-87.792016, 45.616756], [-87.795880, 45.618846], [-87.796179, 45.622074], [-87.796983, 45.623613], [-87.804481, 45.628933], [-87.810194, 45.638732], [-87.817277, 45.643926], [-87.821818, 45.645589], [-87.824102, 45.647138], [-87.824676, 45.653211], [-87.822693, 45.656077], [-87.822425, 45.658012], [-87.823672, 45.659817], [-87.823868, 45.661920], [-87.823164, 45.662732], [-87.803290, 45.666494], [-87.798903, 45.670140], [-87.795355, 45.671334], [-87.781623, 45.673280], [-87.781007, 45.673934], [-87.780737, 45.675458], [-87.780808, 45.680349], [-87.782226, 45.683053], [-87.787727, 45.687180], [-87.801880, 45.693862], [-87.804993, 45.695796], [-87.809075, 45.699717], [-87.809181, 45.700337], [-87.805076, 45.703556], [-87.805081, 45.704974], [-87.805867, 45.706841], [-87.810144, 45.710230], [-87.812338, 45.711303], [-87.831442, 45.714938], [-87.837343, 45.716919], [-87.855480, 45.726943], [-87.864320, 45.737139], [-87.863874, 45.742660], [-87.863050, 45.743090], [-87.864141, 45.745697], [-87.868111, 45.749477], [-87.873339, 45.750439], [-87.875813, 45.753888], [-87.879812, 45.754843], [-87.882261, 45.754779], [-87.891905, 45.754055], [-87.896032, 45.752285], [-87.898363, 45.752503], [-87.900005, 45.753497], [-87.901299, 45.756553], [-87.902707, 45.757932], [-87.904657, 45.759163], [-87.905873, 45.759364], [-87.907771, 45.759280], [-87.908933, 45.758297], [-87.921999, 45.756989], [-87.926611, 45.759590], [-87.929130, 45.760364], [-87.934585, 45.758094], [-87.944113, 45.757422], [-87.954459, 45.758414], [-87.959277, 45.757367], [-87.963452, 45.758220], [-87.964725, 45.759461], [-87.963996, 45.760794], [-87.966970, 45.764021], [-87.972451, 45.766319], [-87.976835, 45.767015], [-87.986429, 45.769596], [-87.989656, 45.772025], [-87.989829, 45.772945], [-87.985597, 45.774926], [-87.983392, 45.774696], [-87.981789, 45.775081], [-87.980870, 45.776977], [-87.982617, 45.782944], [-87.987942, 45.793075], [-87.989831, 45.794827], [-87.991447, 45.795393], [-87.995876, 45.795435], [-88.001593, 45.794091], [-88.007043, 45.792192], [-88.017588, 45.792455], [-88.023600, 45.790094], [-88.027228, 45.789190], [-88.031124, 45.789233], [-88.033568, 45.789816], [-88.039729, 45.789626], [-88.040221, 45.789236], [-88.040892, 45.786452], [-88.044697, 45.783718], [-88.048514, 45.782549], [-88.050634, 45.780972], [-88.072091, 45.780261], [-88.076375, 45.781606], [-88.078361, 45.784249], [-88.079764, 45.784950], [-88.088590, 45.784697], [-88.094047, 45.785658], [-88.099616, 45.790186], [-88.103247, 45.791361], [-88.106351, 45.797573], [-88.105518, 45.798839], [-88.105355, 45.800104], [-88.107506, 45.802668], [-88.109506, 45.803584], [-88.116024, 45.804079], [-88.129461, 45.809288], [-88.131834, 45.811312], [-88.136110, 45.819029], [-88.135067, 45.821694], [-88.133640, 45.823128], [-88.127808, 45.827173], [-88.122947, 45.829565], [-88.120723, 45.832995], [-88.114267, 45.837891], [-88.111726, 45.839196], [-88.109089, 45.839492], [-88.106622, 45.841072], [-88.098326, 45.850142], [-88.088825, 45.855860], [-88.087419, 45.857459], [-88.084985, 45.862443], [-88.082590, 45.864944], [-88.081641, 45.865087], [-88.077534, 45.863825], [-88.075146, 45.864832], [-88.073134, 45.871952], [-88.073944, 45.875593], [-88.081781, 45.880516], [-88.083965, 45.881186], [-88.095841, 45.880042], [-88.100218, 45.881205], [-88.101814, 45.883504], [-88.105447, 45.896593], [-88.105981, 45.897091], [-88.106136, 45.900811], [-88.105677, 45.904387], [-88.104576, 45.906847], [-88.101973, 45.910550], [-88.099172, 45.912362], [-88.095354, 45.913895], [-88.095409, 45.915175], [-88.096496, 45.917273], [-88.102908, 45.921869], [-88.104686, 45.922121], [-88.115346, 45.922211], [-88.118507, 45.921140], [-88.121864, 45.920750], [-88.126382, 45.921499], [-88.127594, 45.922414], [-88.127430, 45.923214], [-88.126122, 45.924639], [-88.127428, 45.926153], [-88.141001, 45.930608], [-88.145928, 45.933646], [-88.146419, 45.934194], [-88.146352, 45.935314], [-88.158704, 45.939064], [-88.163105, 45.939043], [-88.163959, 45.938340], [-88.170096, 45.939470], [-88.172628, 45.941015], [-88.175532, 45.944897], [-88.178008, 45.947111], [-88.189789, 45.952208], [-88.191991, 45.952740], [-88.196316, 45.953311], [-88.197627, 45.953082], [-88.202116, 45.949836], [-88.201852, 45.945173], [-88.209585, 45.944280], [-88.211158, 45.944531], [-88.215025, 45.946976], [-88.222167, 45.948513], [-88.223773, 45.948712], [-88.227988, 45.947688], [-88.233140, 45.947405], [-88.239672, 45.948982], [-88.242518, 45.950363], [-88.244452, 45.952142], [-88.245752, 45.954147], [-88.246579, 45.956597], [-88.245937, 45.958726], [-88.246307, 45.962983], [-88.249117, 45.963663], [-88.250133, 45.963572], [-88.250133, 45.963147], [-88.254816, 45.963538], [-88.256455, 45.962739], [-88.259343, 45.959494], [-88.268390, 45.957486], [-88.283335, 45.955091], [-88.292381, 45.951115], [-88.295264, 45.951253], [-88.296968, 45.953767], [-88.300965, 45.956168], [-88.309520, 45.959369], [-88.316894, 45.960969], [-88.320531, 45.959963], [-88.326003, 45.955300], [-88.326953, 45.955071], [-88.330296, 45.956625], [-88.327872, 45.958934], [-88.328333, 45.964054], [-88.330137, 45.965951], [-88.334628, 45.968808], [-88.380183, 45.991654], [-88.385234, 45.990239], [-88.384318, 45.988113], [-88.388847, 45.982675], [-88.395308, 45.980391], [-88.399046, 45.980278], [-88.402848, 45.981194], [-88.409864, 45.979688], [-88.411077, 45.979139], [-88.414849, 45.975483], [-88.416914, 45.975323], [-88.420356, 45.976764], [-88.423044, 45.978547], [-88.422322, 45.980170], [-88.423437, 45.981930], [-88.426125, 45.984102], [-88.434060, 45.986205], [-88.435798, 45.988125], [-88.439733, 45.990456], [-88.443078, 45.990685], [-88.448751, 45.989770], [-88.450325, 45.990181], [-88.454261, 45.993426], [-88.453868, 45.996169], [-88.454361, 45.997518], [-88.458658, 45.999391], [-88.465542, 46.000685], [-88.470855, 46.001004], [-88.474695, 45.998770], [-88.475152, 45.996598], [-88.474036, 45.994655], [-88.476002, 45.992826], [-88.478984, 45.991797], [-88.486755, 45.990949], [-88.492495, 45.992157], [-88.497417, 45.995149], [-88.498108, 45.996360], [-88.496897, 45.998281], [-88.496898, 45.999012], [-88.498765, 46.000393], [-88.500133, 46.000457], [-88.505946, 46.013385], [-88.506205, 46.017134], [-88.507188, 46.018300], [-88.509516, 46.019169], [-88.514601, 46.019926], [-88.523131, 46.019518], [-88.526673, 46.020822], [-88.532414, 46.021212], [-88.533825, 46.020915], [-88.533530, 46.019932], [-88.534876, 46.018104], [-88.539011, 46.014791], [-88.541078, 46.013763], [-88.550756, 46.012896], [-88.554987, 46.014977], [-88.565485, 46.015708], [-88.571553, 46.013811], [-88.572995, 46.011799], [-88.580670, 46.006975], [-88.589000, 46.005077], [-88.589755, 46.005602], [-88.592874, 46.011590], [-88.593302, 46.014447], [-88.593860, 46.015132], [-88.598093, 46.017623], [-88.601440, 46.017599], [-88.603965, 46.016181], [-88.607438, 46.010991], [-88.611466, 46.003332], [-88.611563, 45.998810], [-88.613063, 45.990627], [-88.614176, 45.988775], [-88.616405, 45.987700], [-88.623947, 45.988633], [-88.634055, 45.987999], [-88.634842, 45.987565], [-88.635598, 45.985119], [-88.637500, 45.984960], [-88.657760, 45.989287], [-88.661312, 45.988819], [-88.662902, 45.988730], [-88.663697, 45.989084], [-88.664802, 45.989835], [-88.664360, 45.991337], [-88.663609, 45.992397], [-88.663923, 45.993242], [-88.667464, 45.995048], [-88.671267, 45.999026], [-88.670939, 45.999957], [-88.670115, 45.999957], [-88.671458, 46.005104], [-88.674606, 46.010567], [-88.679132, 46.013538], [-88.691662, 46.015435], [-88.698716, 46.017903], [-88.704687, 46.018154], [-88.710328, 46.016303], [-88.713049, 46.012668], [-88.718397, 46.013284], [-88.721319, 46.018608], [-88.721125, 46.022013], [-88.724801, 46.024503], [-88.730675, 46.026535], [-88.739994, 46.027308], [-88.746422, 46.025798], [-88.752176, 46.023584], [-88.754033, 46.022460], [-88.756295, 46.020173], [-88.758618, 46.019542], [-88.760044, 46.019815], [-88.763767, 46.021943], [-88.765208, 46.022086], [-88.766156, 46.022149], [-88.767104, 46.021896], [-88.767610, 46.021643], [-88.768305, 46.021201], [-88.768692, 46.020571], [-88.769712, 46.018968], [-88.776187, 46.015931], [-88.779915, 46.015436], [-88.782104, 46.016558], [-88.783891, 46.020934], [-88.784007, 46.022984], [-88.783635, 46.024357], [-88.778734, 46.028875], [-88.778628, 46.031271], [-88.779221, 46.031869], [-88.784411, 46.032709], [-88.791796, 46.032057], [-88.796182, 46.033712], [-88.800670, 46.030036], [-88.796242, 46.026853], [-88.795790, 46.024864], [-88.796460, 46.023605], [-88.801761, 46.023737], [-88.811948, 46.021609], [-88.815629, 46.022320], [-88.815427, 46.022954], [-88.816489, 46.023924], [-88.820592, 46.026261], [-88.831544, 46.029620], [-88.835249, 46.030330], [-88.837991, 46.030176], [-88.840584, 46.031112], [-88.843903, 46.033050], [-88.847599, 46.037161], [-88.848464, 46.038858], [-88.850270, 46.040274], [-88.943279, 46.077943], [-88.948698, 46.080205], [-88.990807, 46.097298], [-89.091630, 46.138505], [-89.125136, 46.144531], [-89.161757, 46.151816], [-89.166887, 46.152868], [-89.194508, 46.157942], [-89.201283, 46.159426], [-89.203289, 46.160020], [-89.205657, 46.160408], [-89.218156, 46.162988], [-89.219964, 46.163319], [-89.276489, 46.174047], [-89.276883, 46.174116], [-89.495723, 46.216301], [-89.533801, 46.224119], [-89.638416, 46.243804], [-89.667617, 46.249797], [-89.764506, 46.268082], [-89.908196, 46.296037], [-89.909910, 46.296402], [-89.918798, 46.297741], [-90.120489, 46.336852], [-90.121248, 46.337217], [-90.121380, 46.338131], [-90.121084, 46.338656], [-90.119468, 46.339700], [-90.118791, 46.342253], [-90.119572, 46.344180], [-90.120198, 46.345066], [-90.120614, 46.346420], [-90.119729, 46.348504], [-90.117466, 46.349487], [-90.116741, 46.350652], [-90.116844, 46.355153], [-90.118827, 46.359241], [-90.119691, 46.359755], [-90.119757, 46.359748], [-90.120973, 46.359720], [-90.122287, 46.360139], [-90.122785, 46.361259], [-90.122757, 46.362621], [-90.122923, 46.363603], [-90.126517, 46.366889], [-90.131036, 46.369199], [-90.133871, 46.371828], [-90.134663, 46.374947], [-90.134656, 46.374979], [-90.132250, 46.381249], [-90.133966, 46.382118], [-90.135253, 46.382210], [-90.139410, 46.384999], [-90.144359, 46.390255], [-90.146816, 46.397205], [-90.148347, 46.399258], [-90.152936, 46.401293], [-90.157851, 46.409291], [-90.158972, 46.413769], [-90.158241, 46.420485], [-90.158603, 46.422656], [-90.163422, 46.434605], [-90.166526, 46.437576], [-90.166909, 46.439311], [-90.166919, 46.439851], [-90.174556, 46.439656], [-90.177860, 46.440548], [-90.179212, 46.453090], [-90.180336, 46.456746], [-90.189162, 46.459054], [-90.190749, 46.460173], [-90.193294, 46.463143], [-90.192005, 46.465611], [-90.189426, 46.467004], [-90.188633, 46.468101], [-90.188996, 46.469015], [-90.193394, 46.472487], [-90.201727, 46.476074], [-90.204009, 46.478175], [-90.211753, 46.490351], [-90.214843, 46.498181], [-90.214866, 46.499947], [-90.216594, 46.501759], [-90.220532, 46.503403], [-90.222351, 46.503380], [-90.228735, 46.501573], [-90.230324, 46.501732], [-90.231020, 46.503354], [-90.230921, 46.504656], [-90.229402, 46.507992], [-90.230363, 46.509705], [-90.231587, 46.509842], [-90.236283, 46.507121], [-90.243395, 46.505245], [-90.246043, 46.504832], [-90.248194, 46.505357], [-90.257160, 46.504716], [-90.258650, 46.503483], [-90.260504, 46.502822], [-90.263018, 46.502777], [-90.265269, 46.503829], [-90.265143, 46.505089], [-90.265143, 46.506222], [-90.266528, 46.507356], [-90.268480, 46.507167], [-90.270180, 46.507356], [-90.270684, 46.508237], [-90.270558, 46.509560], [-90.270432, 46.510756], [-90.270422, 46.511690], [-90.274721, 46.515416], [-90.271971, 46.519756], [-90.272599, 46.521127], [-90.277131, 46.524487], [-90.278356, 46.523847], [-90.278920, 46.522271], [-90.283423, 46.518868], [-90.285707, 46.518846], [-90.292854, 46.520972], [-90.294311, 46.519876], [-90.294411, 46.518848], [-90.298284, 46.517820], [-90.303546, 46.517432], [-90.306558, 46.518484], [-90.307716, 46.518392], [-90.312581, 46.517113], [-90.313839, 46.516199], [-90.313894, 46.516199], [-90.316983, 46.517319], [-90.317777, 46.521637], [-90.314434, 46.523784], [-90.311886, 46.528695], [-90.310329, 46.536852], [-90.310859, 46.539365], [-90.320428, 46.546287], [-90.324699, 46.545602], [-90.326686, 46.546150], [-90.328044, 46.548046], [-90.327548, 46.550262], [-90.331887, 46.553278], [-90.336921, 46.554076], [-90.344338, 46.552087], [-90.347514, 46.547083], [-90.349462, 46.538080], [-90.350121, 46.537337], [-90.351580, 46.537074], [-90.353534, 46.537553], [-90.355689, 46.540317], [-90.357014, 46.540591], [-90.357676, 46.540271], [-90.361600, 46.541434], [-90.369964, 46.540549], [-90.374461, 46.539212], [-90.387228, 46.533663], [-90.393320, 46.532615], [-90.395272, 46.533941], [-90.395568, 46.536317], [-90.398742, 46.542738], [-90.400041, 46.544384], [-90.400429, 46.544384], [-90.402019, 46.544384], [-90.405593, 46.547584], [-90.407775, 46.552246], [-90.414464, 46.557320], [-90.414596, 46.557320], [-90.415620, 46.563169], [-90.418136, 46.566094], [-90.348407, 46.600635], [-90.327626, 46.607744], [-90.306609, 46.602741], [-90.265294, 46.618516], [-90.237609, 46.624485], [-90.164026, 46.645515], [-90.100695, 46.655132], [-90.045420, 46.668272], [-90.028392, 46.674390], [-89.996034, 46.693225], [-89.985817, 46.703190], [-89.973803, 46.710322], [-89.957101, 46.716929], [-89.918466, 46.740324], [-89.892355, 46.763088], [-89.848652, 46.795711], [-89.831956, 46.804053], [-89.790663, 46.818469], [-89.720277, 46.830413], [-89.673375, 46.833229], [-89.660625, 46.831056], [-89.642255, 46.825340], [-89.634938, 46.819488], [-89.619329, 46.818890], [-89.569808, 46.831859], [-89.535683, 46.835878], [-89.513938, 46.841835], [-89.499080, 46.841621], [-89.491252, 46.838448], [-89.471540, 46.837359], [-89.437047, 46.839512], [-89.415154, 46.843983], [-89.372032, 46.857386], [-89.249143, 46.903326], [-89.227914, 46.912954], [-89.201511, 46.931149], [-89.168244, 46.965536], [-89.142595, 46.984859], [-89.128698, 46.992599], [-89.118339, 46.994220], [-89.113158, 46.989356], [-89.106277, 46.986480], [-89.086742, 46.985298], [-89.063103, 46.988522], [-89.039490, 46.999419], [-89.028930, 47.001140], [-89.022994, 46.995120], [-88.998417, 46.995314], [-88.987197, 46.997239], [-88.972802, 47.002096], [-88.959409, 47.008496], [-88.944045, 47.020129], [-88.924492, 47.042156], [-88.914189, 47.059246], [-88.903706, 47.086161], [-88.889140, 47.100575], [-88.855372, 47.114263], [-88.848176, 47.115065], [-88.814834, 47.141399], [-88.789813, 47.150925], [-88.778022, 47.150465], [-88.764351, 47.155762], [-88.729688, 47.185834], [-88.699660, 47.204831], [-88.672395, 47.219137], [-88.656359, 47.225624], [-88.640323, 47.226784], [-88.623579, 47.232352], [-88.609830, 47.238894], [-88.584912, 47.242361], [-88.573997, 47.245989], [-88.500780, 47.293503], [-88.477733, 47.313460], [-88.470484, 47.327653], [-88.459262, 47.339903], [-88.418673, 47.371188], [-88.389459, 47.384431], [-88.324083, 47.403542], [-88.303447, 47.412204], [-88.285195, 47.422392], [-88.239161, 47.429969], [-88.227446, 47.435093], [-88.218424, 47.441585], [-88.216977, 47.445493], [-88.217822, 47.448738], [-88.181820, 47.457657], [-88.150571, 47.460093], [-88.139651, 47.462693], [-88.085252, 47.468961], [-88.076388, 47.467752], [-88.049326, 47.469785], [-88.048226, 47.470008], [-88.048077, 47.474973], [-88.040291, 47.475999], [-87.978934, 47.479420], [-87.929269, 47.478737], [-87.902416, 47.477045], [-87.898036, 47.474872], [-87.816958, 47.471998], [-87.801184, 47.473301], [-87.756739, 47.460717], [-87.730804, 47.449112], [-87.715942, 47.439816], [-87.710471, 47.406200], [-87.712421, 47.401400], [-87.721274, 47.401032], [-87.742417, 47.405823], [-87.751380, 47.405066], [-87.759057, 47.403013], [-87.765019, 47.398652], [-87.800294, 47.392148], [-87.815371, 47.384790], [-87.827115, 47.386160], [-87.834822, 47.390478], [-87.848252, 47.394864], [-87.856700, 47.395387], [-87.882245, 47.395588], [-87.941613, 47.390073], [-87.957058, 47.387260], [-87.965063, 47.374430], [-87.965598, 47.368645], [-87.962567, 47.362543], [-87.954796, 47.356809], [-87.947397, 47.355461], [-87.938787, 47.346777], [-87.938250, 47.342299], [-87.943360, 47.335899], [-87.946352, 47.334254], [-87.958386, 47.334435], [-87.968604, 47.332582], [-87.989133, 47.322633], [-88.016478, 47.306275], [-88.054849, 47.298240], [-88.060090, 47.295796], [-88.071476, 47.286768], [-88.096851, 47.261351], [-88.108833, 47.259131], [-88.117456, 47.255174], [-88.131943, 47.239554], [-88.163059, 47.216278], [-88.194218, 47.209242], [-88.204849, 47.210498], [-88.212361, 47.209423], [-88.228987, 47.199042], [-88.236892, 47.189236], [-88.242006, 47.174767], [-88.242660, 47.158426], [-88.239470, 47.151137], [-88.236721, 47.149287], [-88.231797, 47.149609], [-88.232164, 47.145975], [-88.239895, 47.139436], [-88.247628, 47.135981], [-88.249571, 47.136231], [-88.250785, 47.140209], [-88.255303, 47.143640], [-88.262972, 47.145174], [-88.272017, 47.143511], [-88.281701, 47.138212], [-88.289040, 47.129689], [-88.289543, 47.126604], [-88.287870, 47.125374], [-88.287173, 47.120420], [-88.288347, 47.114547], [-88.297625, 47.098505], [-88.340052, 47.080494], [-88.346709, 47.079372], [-88.349952, 47.076377], [-88.353191, 47.069063], [-88.353952, 47.058047], [-88.359054, 47.039739], [-88.367624, 47.019213], [-88.373966, 47.012262], [-88.385606, 47.004522], [-88.404498, 46.983353], [-88.411145, 46.977984], [-88.443901, 46.972251], [-88.448570, 46.946769], [-88.455404, 46.923321], [-88.475859, 46.886042], [-88.477935, 46.850560], [-88.483748, 46.831727], [-88.482579, 46.826197], [-88.473342, 46.806226], [-88.462349, 46.786711], [-88.438427, 46.786714], [-88.433835, 46.793502], [-88.415225, 46.811715], [-88.381410, 46.838466], [-88.382204, 46.844477], [-88.382052, 46.845437], [-88.390135, 46.851595], [-88.404008, 46.848331], [-88.389727, 46.867100], [-88.372591, 46.872812], [-88.375855, 46.863428], [-88.369848, 46.857568], [-88.368767, 46.857313], [-88.360868, 46.856202], [-88.351940, 46.857028], [-88.310290, 46.889748], [-88.281244, 46.906632], [-88.261593, 46.915516], [-88.244437, 46.929612], [-88.167227, 46.958855], [-88.155374, 46.965069], [-88.143688, 46.966665], [-88.132876, 46.962204], [-88.150114, 46.943630], [-88.187522, 46.918999], [-88.175197, 46.904580], [-88.161913, 46.904941], [-88.126927, 46.909840], [-88.101315, 46.917207], [-88.081870, 46.920458], [-88.065192, 46.918563], [-88.032408, 46.908890], [-88.004298, 46.906982], [-87.986113, 46.905957], [-87.956000, 46.909051], [-87.900339, 46.909686], [-87.874538, 46.892578], [-87.846195, 46.883905], [-87.841228, 46.884363], [-87.827162, 46.889713], [-87.816794, 46.891154], [-87.813226, 46.888023], [-87.793194, 46.880822], [-87.782461, 46.879859], [-87.776930, 46.876726], [-87.776313, 46.872591], [-87.778752, 46.870422], [-87.776804, 46.866823], [-87.765989, 46.861316], [-87.755868, 46.860453], [-87.746646, 46.865427], [-87.741014, 46.865247], [-87.734870, 46.850120], [-87.736732, 46.847216], [-87.734325, 46.836955], [-87.731522, 46.831196], [-87.727358, 46.827656], [-87.713737, 46.825534], [-87.694590, 46.827182], [-87.685698, 46.832530], [-87.687930, 46.839159], [-87.687164, 46.841742], [-87.680668, 46.842496], [-87.674541, 46.836964], [-87.673177, 46.827593], [-87.674345, 46.824050], [-87.672015, 46.820415], [-87.662261, 46.815157], [-87.651510, 46.812411], [-87.641887, 46.813733], [-87.633300, 46.812107], [-87.628081, 46.805157], [-87.607988, 46.788408], [-87.595307, 46.782950], [-87.590767, 46.753009], [-87.582745, 46.730527], [-87.573203, 46.720471], [-87.523308, 46.688488], [-87.524444, 46.677586], [-87.503025, 46.647497], [-87.492860, 46.642561], [-87.467965, 46.635623], [-87.466537, 46.631555], [-87.467563, 46.626228], [-87.464108, 46.614811], [-87.451368, 46.605923], [-87.442612, 46.602776], [-87.411167, 46.601669], [-87.403275, 46.595215], [-87.383961, 46.593070], [-87.381649, 46.580059], [-87.392974, 46.572523], [-87.392828, 46.570852], [-87.382206, 46.553681], [-87.375613, 46.547140], [-87.390300, 46.542577], [-87.393985, 46.533183], [-87.389290, 46.524472], [-87.381349, 46.517292], [-87.366767, 46.507303], [-87.351071, 46.500749], [-87.310755, 46.492017], [-87.258732, 46.488255], [-87.202404, 46.490827], [-87.175065, 46.497548], [-87.127440, 46.494014], [-87.107559, 46.496124], [-87.098760, 46.503609], [-87.077279, 46.515339], [-87.046022, 46.519956], [-87.029892, 46.525599], [-87.017136, 46.533550], [-87.008724, 46.532723], [-86.976958, 46.526581], [-86.964534, 46.516549], [-86.962842, 46.509646], [-86.946980, 46.484567], [-86.946218, 46.479059], [-86.949526, 46.476315], [-86.947077, 46.472064], [-86.927725, 46.464566], [-86.903742, 46.466138], [-86.889094, 46.458499], [-86.883976, 46.450976], [-86.883919, 46.441514], [-86.875151, 46.437280], [-86.850111, 46.434114], [-86.837448, 46.434186], [-86.816026, 46.437892], [-86.810967, 46.449663], [-86.808817, 46.460611], [-86.803557, 46.466669], [-86.787905, 46.477729], [-86.768516, 46.479072], [-86.750157, 46.479109], [-86.735929, 46.475231], [-86.731096, 46.471760], [-86.730829, 46.468057], [-86.710573, 46.444908], [-86.703230, 46.439378], [-86.698139, 46.438624], [-86.686412, 46.454965], [-86.688816, 46.463152], [-86.686468, 46.471655], [-86.683819, 46.498079], [-86.696001, 46.503160], [-86.701929, 46.511571], [-86.709325, 46.543914], [-86.695645, 46.555026], [-86.678182, 46.561039], [-86.675764, 46.557061], [-86.670927, 46.556489], [-86.656479, 46.558453], [-86.652865, 46.560555], [-86.627380, 46.533710], [-86.629086, 46.518144], [-86.632109, 46.508865], [-86.634530, 46.504523], [-86.641088, 46.500438], [-86.645528, 46.492039], [-86.646393, 46.485776], [-86.636671, 46.478298], [-86.627441, 46.477540], [-86.620603, 46.483873], [-86.618061, 46.489452], [-86.612173, 46.493295], [-86.609393, 46.492976], [-86.606932, 46.478531], [-86.609039, 46.470239], [-86.586168, 46.463324], [-86.557731, 46.487434], [-86.524959, 46.505381], [-86.495054, 46.524874], [-86.484003, 46.535965], [-86.481956, 46.542709], [-86.469306, 46.551422], [-86.459930, 46.551928], [-86.444390, 46.548137], [-86.437167, 46.548960], [-86.390409, 46.563194], [-86.349890, 46.578035], [-86.188024, 46.654008], [-86.161681, 46.669475], [-86.138295, 46.672935], [-86.119862, 46.657256], [-86.112126, 46.655044], [-86.099843, 46.654615], [-86.074219, 46.657799], [-86.036969, 46.667627], [-85.995044, 46.673676], [-85.953670, 46.676869], [-85.924047, 46.684733], [-85.877908, 46.690914], [-85.841057, 46.688896], [-85.794923, 46.681083], [-85.750606, 46.677368], [-85.714415, 46.677156], [-85.668753, 46.680404], [-85.624573, 46.678862], [-85.587345, 46.674627], [-85.542517, 46.674263], [-85.509510, 46.675786], [-85.482096, 46.680432], [-85.369805, 46.713754], [-85.289846, 46.744644], [-85.256860, 46.753380], [-85.173042, 46.763634], [-85.063556, 46.757856], [-85.036286, 46.760435], [-85.009240, 46.769224], [-84.989497, 46.772403], [-84.964652, 46.772845], [-84.954009, 46.771362], [-84.951580, 46.769488], [-84.987539, 46.745483], [-85.007616, 46.728339], [-85.020159, 46.712463], [-85.027513, 46.697451], [-85.030078, 46.684769], [-85.028291, 46.675125], [-85.035504, 46.625021], [-85.037056, 46.600995], [-85.035476, 46.581547], [-85.031507, 46.568703], [-85.029594, 46.554419], [-85.027374, 46.553756], [-85.025491, 46.546397], [-85.027083, 46.543038], [-85.045534, 46.537694], [-85.052954, 46.532827], [-85.056133, 46.526520], [-85.054943, 46.514750], [-85.049847, 46.503963], [-85.033766, 46.487670], [-85.025598, 46.483028], [-85.015211, 46.479712], [-84.969464, 46.476290], [-84.955307, 46.480269], [-84.947269, 46.487399], [-84.937145, 46.489252], [-84.934432, 46.480315], [-84.921931, 46.469962], [-84.915184, 46.467515], [-84.893423, 46.465406], [-84.875070, 46.466781], [-84.861448, 46.469930], [-84.849767, 46.460245], [-84.843907, 46.448661], [-84.829491, 46.444071], [-84.800101, 46.446219], [-84.769151, 46.453523], [-84.723338, 46.468266], [-84.689672, 46.483923], [-84.678423, 46.487694], [-84.653880, 46.482250], [-84.631020, 46.484868], [-84.616489, 46.471870], [-84.607945, 46.456747], [-84.584167, 46.439410], [-84.573522, 46.427895], [-84.551496, 46.418522], [-84.503719, 46.439190], [-84.493401, 46.440313], [-84.479513, 46.432573], [-84.471848, 46.434289], [-84.462597, 46.440940], [-84.455527, 46.453897], [-84.455256, 46.462785], [-84.463322, 46.467435], [-84.445149, 46.489016], [-84.420274, 46.501077], [-84.394725, 46.499242], [-84.375040, 46.508669], [-84.373968, 46.509098], [-84.343599, 46.507713], [-84.337732, 46.505577], [-84.325371, 46.500021], [-84.293016, 46.492803], [-84.275814, 46.492821], [-84.265391, 46.494393], [-84.264266, 46.495055], [-84.254434, 46.500821], [-84.226131, 46.533920], [-84.193729, 46.539920], [-84.177428, 46.526920], [-84.166028, 46.526220], [-84.153027, 46.528320], [-84.146526, 46.531119], [-84.139426, 46.532219], [-84.128925, 46.530119], [-84.123325, 46.520919], [-84.117925, 46.517619], [-84.111225, 46.504119], [-84.125026, 46.470143], [-84.146172, 46.418520], [-84.138906, 46.372221], [-84.119122, 46.337014], [-84.106247, 46.321963], [-84.119629, 46.315013], [-84.115563, 46.268225], [-84.097766, 46.256512], [-84.108089, 46.241238], [-84.118175, 46.233968], [-84.125024, 46.232885], [-84.134652, 46.232140], [-84.145950, 46.224995], [-84.147150, 46.224184], [-84.149220, 46.223808], [-84.150725, 46.223808], [-84.151666, 46.224184], [-84.152042, 46.224937], [-84.152230, 46.226254], [-84.152499, 46.227875], [-84.159485, 46.233233], [-84.182732, 46.235450], [-84.219494, 46.231992], [-84.233117, 46.224037], [-84.249164, 46.206461], [-84.245233, 46.192571], [-84.247687, 46.179890], [-84.251424, 46.175888], [-84.221001, 46.163062], [-84.196669, 46.166150], [-84.177298, 46.183993], [-84.171640, 46.181731], [-84.125022, 46.180209], [-84.114941, 46.174114], [-84.113259, 46.168860], [-84.100126, 46.150770], [-84.095818, 46.147733], [-84.089309, 46.146432], [-84.060383, 46.146138], [-84.026536, 46.131648], [-84.031036, 46.123186], [-84.038696, 46.125620], [-84.051900, 46.119810], [-84.061329, 46.113482], [-84.069147, 46.103978], [-84.072398, 46.096690], [-84.071741, 46.092441], [-84.066257, 46.087438], [-84.051712, 46.079189], [-84.027861, 46.054784], [-84.006082, 46.044586], [-83.989526, 46.032823], [-83.963808, 46.027833], [-83.951410, 46.029042], [-83.943933, 46.031465], [-83.939012, 46.029226], [-83.935470, 46.020385], [-83.931175, 46.017871], [-83.908583, 46.011471], [-83.900535, 45.998918], [-83.896489, 45.989194], [-83.898594, 45.979530], [-83.901942, 45.972640], [-83.903923, 45.966210], [-83.916168, 45.955326], [-83.921257, 45.958075], [-83.952183, 45.965498], [-83.985141, 45.967133], [-83.996471, 45.961461], [-84.000033, 45.948452], [-84.017565, 45.959046], [-84.080071, 45.970822], [-84.090391, 45.967256], [-84.105370, 45.972948], [-84.107204, 45.977161], [-84.111174, 45.978675], [-84.140816, 45.975308], [-84.172250, 45.966072], [-84.178060, 45.969175], [-84.238174, 45.967595], [-84.254952, 45.956068], [-84.330021, 45.956247], [-84.353272, 45.941663], [-84.376429, 45.931962], [-84.428689, 45.958371], [-84.437633, 45.973750], [-84.443138, 45.977863], [-84.463128, 45.968925], [-84.480436, 45.977764], [-84.483062, 45.982242], [-84.482442, 45.985441], [-84.484009, 45.988250], [-84.507201, 45.991169], [-84.514123, 45.987242], [-84.514071, 45.971292], [-84.525052, 45.968578], [-84.532392, 45.969448], [-84.534422, 45.972762], [-84.534648, 45.978132], [-84.530444, 45.991385], [-84.533426, 46.005720], [-84.540995, 46.019501], [-84.544405, 46.022860], [-84.563891, 46.032459], [-84.581081, 46.031041], [-84.586592, 46.026584], [-84.609063, 46.026418], [-84.647609, 46.049704], [-84.656567, 46.052654], [-84.666710, 46.050486], [-84.675835, 46.046009], [-84.687322, 46.034880], [-84.692735, 46.027019], [-84.692700, 46.016963], [-84.686269, 45.979144], [-84.684368, 45.977499], [-84.685254, 45.973454], [-84.687712, 45.971260], [-84.703948, 45.970901], [-84.723039, 45.967279], [-84.730179, 45.961198], [-84.738849, 45.945792], [-84.739370, 45.941816], [-84.733041, 45.932837], [-84.718955, 45.927449], [-84.713614, 45.920366], [-84.713251, 45.916047], [-84.734002, 45.907026], [-84.721276, 45.873908], [-84.715481, 45.865934], [-84.701183, 45.853092], [-84.702295, 45.850464], [-84.706383, 45.848658], [-84.720836, 45.848107], [-84.722764, 45.846621], [-84.725734, 45.837045], [-84.746985, 45.835597], [-84.792763, 45.858691], [-84.831396, 45.872038], [-84.838472, 45.881512], [-84.837624, 45.889054], [-84.842243, 45.898194], [-84.852916, 45.900111], [-84.873254, 45.909815], [-84.879835, 45.915847], [-84.902913, 45.923673], [-84.917484, 45.930670], [-84.937134, 45.955949], [-84.973556, 45.986134], [-85.003597, 46.006130], [-85.013990, 46.010774], [-85.055581, 46.023148], [-85.088818, 46.028378], [-85.102899, 46.032488], [-85.130433, 46.046076], [-85.140835, 46.049601], [-85.152027, 46.050725], [-85.190630, 46.047622], [-85.197523, 46.044878], [-85.222511, 46.060689], [-85.266385, 46.065779], [-85.287693, 46.072276], [-85.316264, 46.086608], [-85.335911, 46.092595], [-85.356214, 46.092086], [-85.366622, 46.086778], [-85.381394, 46.082044], [-85.393832, 46.095465], [-85.412064, 46.101437], [-85.426916, 46.101964], [-85.441932, 46.095793], [-85.442293, 46.093941], [-85.440191, 46.092593], [-85.446990, 46.085164], [-85.480603, 46.096379], [-85.500100, 46.096940], [-85.512696, 46.094727], [-85.521570, 46.091257], [-85.540858, 46.079581], [-85.603785, 46.030363], [-85.617709, 46.008458], [-85.648581, 45.983695], [-85.654686, 45.973686], [-85.663966, 45.967013], [-85.697203, 45.960158], [-85.724246, 45.965409], [-85.743618, 45.965173], [-85.770938, 45.971349], [-85.790639, 45.977594], [-85.810442, 45.980087], [-85.817558, 45.979447], [-85.825819, 45.976292], [-85.832603, 45.967742], [-85.842404, 45.965247], [-85.861157, 45.968167], [-85.882442, 45.968620], [-85.893196, 45.967253], [-85.909100, 45.959074], [-85.922737, 45.948287], [-85.926213, 45.938093], [-85.926017, 45.932104], [-85.917238, 45.927782], [-85.910264, 45.922112], [-85.913769, 45.919439], [-85.920581, 45.920994], [-85.954063, 45.936629], [-85.998868, 45.950968], [-86.050956, 45.962205], [-86.072067, 45.965313], [-86.094753, 45.966704], [-86.123567, 45.964748], [-86.145714, 45.957372], [-86.150173, 45.954494], [-86.159415, 45.953765], [-86.196618, 45.963185], [-86.208255, 45.962978], [-86.220546, 45.958883], [-86.229060, 45.948570], [-86.233613, 45.945802], [-86.248008, 45.944849], [-86.254768, 45.948640], [-86.278007, 45.942057], [-86.315981, 45.915247], [-86.324232, 45.906080], [-86.332625, 45.851813], [-86.349134, 45.834160], [-86.355062, 45.805355], [-86.351658, 45.798132], [-86.363808, 45.790057], [-86.369918, 45.789254], [-86.395809, 45.789740], [-86.401656, 45.795412], [-86.415971, 45.793793], [-86.424828, 45.789747], [-86.428423, 45.785587], [-86.428946, 45.782524], [-86.427183, 45.779050], [-86.428294, 45.775620], [-86.431921, 45.767756], [-86.439661, 45.760669], [-86.455534, 45.756850], [-86.466039, 45.759741], [-86.479050, 45.757416], [-86.486028, 45.746608], [-86.496251, 45.749255], [-86.504216, 45.754230], [-86.514570, 45.752337], [-86.518281, 45.747688], [-86.523197, 45.736498], [-86.525166, 45.720797], [-86.533280, 45.710849], [-86.537258, 45.708361], [-86.541430, 45.708110], [-86.570627, 45.716412], [-86.580936, 45.711920], [-86.585847, 45.704922], [-86.584771, 45.682007], [-86.587528, 45.666456], [-86.593613, 45.665625], [-86.611306, 45.669733], [-86.620430, 45.667098], [-86.625132, 45.663819], [-86.627938, 45.659293], [-86.616972, 45.620581], [-86.604180, 45.606457], [-86.613803, 45.599583], [-86.616893, 45.606796], [-86.623870, 45.613262], [-86.633224, 45.618249], [-86.648439, 45.615992], [-86.666127, 45.621689], [-86.687208, 45.634253], [-86.688772, 45.639969], [-86.695275, 45.648175], [-86.708038, 45.649202], [-86.717828, 45.668106], [-86.718191, 45.677320], [-86.715781, 45.683949], [-86.705184, 45.690901], [-86.689102, 45.687862], [-86.676184, 45.691862], [-86.665677, 45.702217], [-86.665511, 45.709030], [-86.669263, 45.710860], [-86.671480, 45.720530], [-86.662762, 45.728964], [-86.647319, 45.732618], [-86.633138, 45.747654], [-86.634902, 45.763536], [-86.631018, 45.782019], [-86.617336, 45.783538], [-86.612137, 45.779356], [-86.597661, 45.775385], [-86.583391, 45.778242], [-86.576869, 45.788502], [-86.581071, 45.791802], [-86.581759, 45.794797], [-86.576858, 45.801473], [-86.571172, 45.805452], [-86.563392, 45.804469], [-86.557215, 45.808172], [-86.555547, 45.813499], [-86.559044, 45.822323], [-86.555186, 45.831696], [-86.549723, 45.836039], [-86.545602, 45.836495], [-86.538831, 45.840083], [-86.529208, 45.853043], [-86.528224, 45.856974], [-86.529573, 45.874974], [-86.532989, 45.882665], [-86.541464, 45.890234], [-86.553608, 45.896476], [-86.567719, 45.900500], [-86.583304, 45.898784], [-86.593184, 45.885110], [-86.603293, 45.876626], [-86.613536, 45.875982], [-86.625736, 45.868295], [-86.633168, 45.860068], [-86.632478, 45.843309], [-86.645998, 45.833888], [-86.721113, 45.845431], [-86.728520, 45.848759], [-86.742466, 45.864719], [-86.749638, 45.867796], [-86.758449, 45.867274], [-86.782080, 45.860195], [-86.784177, 45.854641], [-86.782259, 45.829950], [-86.777225, 45.827183], [-86.774612, 45.821696], [-86.773279, 45.811385], [-86.785722, 45.794517], [-86.805524, 45.791275], [-86.801476, 45.780027], [-86.821523, 45.770356], [-86.823743, 45.765486], [-86.820868, 45.760776], [-86.821814, 45.757164], [-86.838658, 45.741831], [-86.841818, 45.729051], [-86.838746, 45.722307], [-86.870392, 45.710087], [-86.876904, 45.711891], [-86.895342, 45.711464], [-86.904089, 45.709546], [-86.921060, 45.697868], [-86.944158, 45.695833], [-86.964275, 45.672761], [-86.966885, 45.675001], [-86.967315, 45.684923], [-86.969765, 45.691895], [-86.981349, 45.696463], [-86.984588, 45.705812], [-86.982413, 45.719873], [-86.977655, 45.728768], [-86.975224, 45.753130], [-86.981341, 45.766160], [-86.981624, 45.792221], [-86.988438, 45.810621], [-87.005080, 45.831718], [-87.018902, 45.838886], [-87.031435, 45.837238], [-87.039842, 45.834245], [-87.052043, 45.821879], [-87.057439, 45.812483], [-87.058844, 45.801510], [-87.058127, 45.779152], [-87.063975, 45.766510], [-87.064302, 45.758828], [-87.062406, 45.753296], [-87.055550, 45.751535], [-87.052908, 45.747983], [-87.057444, 45.736822], [-87.061721, 45.732821], [-87.070442, 45.718779], [-87.059533, 45.708497], [-87.095455, 45.701039], [-87.099401, 45.698614], [-87.099725, 45.695231], [-87.111638, 45.685905], [-87.129412, 45.681710], [-87.172241, 45.661788], [-87.196852, 45.636275], [-87.223647, 45.599338], [-87.234612, 45.588817], [-87.263488, 45.552032], [-87.288726, 45.501606], [-87.306122, 45.475513], [-87.319703, 45.464929], [-87.333147, 45.447208], [-87.334249, 45.442315], [-87.333240, 45.436897], [-87.329958, 45.431937], [-87.325834, 45.430040], [-87.327749, 45.425307], [-87.336152, 45.415360], [-87.350852, 45.407743], [-87.359512, 45.399829], [-87.364368, 45.388532], [-87.392500, 45.369028], [-87.399973, 45.349322], [-87.431684, 45.316383], [-87.437257, 45.305500], [-87.438908, 45.293405], [-87.465201, 45.273351], [-87.512336, 45.224252], [-87.548964, 45.191591], [-87.563417, 45.184070], [-87.585651, 45.166394], [-87.600796, 45.146842], [-87.609280, 45.132320], [-87.612019, 45.123377], [-87.610073, 45.114141], [-87.600120, 45.103011], [-87.590270, 45.096406], [-87.581969, 45.097206], [-87.590208, 45.095264]]], [[[-86.033174, 45.158420], [-86.005946, 45.155751], [-85.993194, 45.152805], [-85.989412, 45.151069], [-85.976803, 45.138363], [-85.976434, 45.120706], [-85.980433, 45.113046], [-85.984095, 45.087073], [-85.982799, 45.080787], [-85.977082, 45.072993], [-85.960590, 45.062223], [-85.959760, 45.058486], [-85.976883, 45.062660], [-85.997360, 45.055929], [-86.013073, 45.063774], [-86.019874, 45.071665], [-86.037129, 45.086576], [-86.052424, 45.095311], [-86.058653, 45.100776], [-86.060396, 45.104617], [-86.065016, 45.140266], [-86.059393, 45.152291], [-86.050473, 45.158418], [-86.044430, 45.159582], [-86.033174, 45.158420]]], [[[-86.093536, 45.007838], [-86.115699, 44.999093], [-86.133655, 44.996874], [-86.154824, 45.002394], [-86.156689, 45.010535], [-86.154557, 45.018102], [-86.141644, 45.040251], [-86.138095, 45.043038], [-86.117908, 45.048478], [-86.093166, 45.041492], [-86.079103, 45.030795], [-86.093451, 45.031660], [-86.097094, 45.030128], [-86.100315, 45.026240], [-86.101894, 45.022811], [-86.101214, 45.018101], [-86.093536, 45.007838]]], [[[-82.415937, 43.005555], [-82.422586, 43.000029], [-82.424206, 42.996938], [-82.424550, 42.993393], [-82.423086, 42.988728], [-82.420346, 42.984451], [-82.412965, 42.977041], [-82.416737, 42.966613], [-82.428603, 42.952001], [-82.447142, 42.937752], [-82.455027, 42.926866], [-82.464040, 42.901456], [-82.469912, 42.887459], [-82.470032, 42.881421], [-82.468220, 42.859107], [-82.468961, 42.852314], [-82.472681, 42.836784], [-82.478640, 42.825187], [-82.482045, 42.808629], [-82.481576, 42.805519], [-82.480394, 42.802272], [-82.471159, 42.784002], [-82.467394, 42.769298], [-82.467483, 42.761910], [-82.483604, 42.733624], [-82.483870, 42.717980], [-82.494491, 42.700823], [-82.510533, 42.665172], [-82.509935, 42.637294], [-82.518782, 42.613888], [-82.523337, 42.607486], [-82.548169, 42.591848], [-82.549717, 42.590338], [-82.554236, 42.583981], [-82.555938, 42.582425], [-82.569801, 42.573551], [-82.577380, 42.567078], [-82.579205, 42.565340], [-82.583996, 42.554041], [-82.589779, 42.550678], [-82.604686, 42.548592], [-82.607068, 42.548843], [-82.611059, 42.550419], [-82.616848, 42.554601], [-82.624907, 42.557229], [-82.633491, 42.557051], [-82.640916, 42.554973], [-82.642680, 42.554333], [-82.648776, 42.550401], [-82.661677, 42.541875], [-82.666596, 42.535084], [-82.679059, 42.522210], [-82.686417, 42.518597], [-82.685397, 42.528659], [-82.679522, 42.535520], [-82.670956, 42.537989], [-82.664335, 42.546244], [-82.680758, 42.557909], [-82.681036, 42.574695], [-82.688061, 42.588417], [-82.701152, 42.585991], [-82.711151, 42.590884], [-82.713042, 42.597904], [-82.700818, 42.606687], [-82.683482, 42.609433], [-82.681593, 42.618672], [-82.690124, 42.625033], [-82.689836, 42.627148], [-82.669103, 42.637225], [-82.645715, 42.631145], [-82.630922, 42.642110], [-82.626396, 42.647385], [-82.623043, 42.655951], [-82.623797, 42.665395], [-82.630851, 42.673341], [-82.635262, 42.675552], [-82.659781, 42.678618], [-82.674287, 42.687049], [-82.685500, 42.690036], [-82.700964, 42.689548], [-82.706135, 42.683578], [-82.726366, 42.682768], [-82.753317, 42.669732], [-82.765583, 42.655725], [-82.780817, 42.652232], [-82.792418, 42.655132], [-82.797318, 42.654032], [-82.813518, 42.640833], [-82.820118, 42.626333], [-82.819017, 42.616333], [-82.811017, 42.610933], [-82.789017, 42.603434], [-82.771844, 42.595517], [-82.769590, 42.593380], [-82.788612, 42.588501], [-82.788116, 42.582835], [-82.781514, 42.571634], [-82.782414, 42.564834], [-82.784514, 42.563634], [-82.789114, 42.568434], [-82.796715, 42.571034], [-82.821016, 42.570734], [-82.834216, 42.567849], [-82.845916, 42.560634], [-82.849316, 42.555734], [-82.851016, 42.548935], [-82.859316, 42.541935], [-82.874416, 42.523535], [-82.882316, 42.501035], [-82.883915, 42.471836], [-82.870347, 42.450888], [-82.886113, 42.408137], [-82.888413, 42.398237], [-82.894013, 42.389437], [-82.898413, 42.385437], [-82.915114, 42.378137], [-82.919114, 42.374437], [-82.928815, 42.359437], [-82.923970, 42.352068], [-82.945415, 42.347337], [-82.959416, 42.339638], [-82.988619, 42.332439], [-83.018320, 42.329739], [-83.064121, 42.317738], [-83.079721, 42.308638], [-83.096521, 42.290138], [-83.110922, 42.260638], [-83.128022, 42.238839], [-83.133923, 42.174740], [-83.121323, 42.125742], [-83.133511, 42.088143], [-83.157624, 42.085542], [-83.168759, 42.073601], [-83.188598, 42.066431], [-83.189115, 42.061853], [-83.186877, 42.061206], [-83.185526, 42.052243], [-83.188240, 42.031329], [-83.185858, 42.029451], [-83.170890, 42.022403], [-83.170890, 42.015185], [-83.193918, 41.997656], [-83.212479, 41.988720], [-83.216897, 41.988561], [-83.223354, 41.989191], [-83.228502, 41.987291], [-83.249204, 41.972402], [-83.257009, 41.959686], [-83.257292, 41.950745], [-83.253552, 41.944897], [-83.264550, 41.929086], [-83.270484, 41.939335], [-83.287130, 41.944397], [-83.295982, 41.944742], [-83.302904, 41.943073], [-83.315859, 41.935893], [-83.326024, 41.924961], [-83.333642, 41.907261], [-83.335961, 41.889721], [-83.341557, 41.879956], [-83.359467, 41.867849], [-83.366187, 41.865505], [-83.372445, 41.874477], [-83.381955, 41.870877], [-83.396220, 41.852965], [-83.409596, 41.830325], [-83.422316, 41.822278], [-83.434204, 41.818562], [-83.439612, 41.813162], [-83.441668, 41.808646], [-83.443364, 41.789118], [-83.437516, 41.769694], [-83.427308, 41.750214], [-83.424076, 41.740738], [-83.434360, 41.737058], [-83.451897, 41.734486], [-83.453832, 41.732647], [-83.497733, 41.731847], [-83.499733, 41.731647], [-83.503433, 41.731547], [-83.504334, 41.731547], [-83.585235, 41.729348], [-83.593835, 41.729148], [-83.595235, 41.729148], [-83.636636, 41.727849], [-83.639636, 41.727749], [-83.665937, 41.726949], [-83.685337, 41.726449], [-83.708937, 41.725150], [-83.763038, 41.723550], [-83.859541, 41.721250], [-83.880539, 41.720081], [-83.899764, 41.719961], [-83.998849, 41.716822], [-84.019373, 41.716668], [-84.134417, 41.712931], [-84.360546, 41.706621], [-84.396547, 41.705935], [-84.438067, 41.704903], [-84.749955, 41.698245], [-84.806082, 41.696089], [-84.806018, 41.707485], [-84.806042, 41.720544], [-84.806065, 41.732909], [-84.806074, 41.737603], [-84.806134, 41.743115], [-84.805883, 41.760216], [-84.818873, 41.760059], [-84.825196, 41.759990], [-84.932484, 41.759691], [-84.960860, 41.759438], [-84.961562, 41.759552], [-84.971551, 41.759527], [-84.972803, 41.759366], [-85.037817, 41.759801], [-85.039436, 41.759985], [-85.117267, 41.759700], [-85.123102, 41.759743], [-85.172230, 41.759618], [-85.196637, 41.759735], [-85.232835, 41.759839], [-85.272216, 41.759999], [-85.272951, 41.759911], [-85.273713, 41.759770], [-85.292099, 41.759962], [-85.298365, 41.760028], [-85.308140, 41.760097], [-85.318129, 41.759983], [-85.330623, 41.759982], [-85.350174, 41.759908], [-85.379133, 41.759875], [-85.427553, 41.759706], [-85.432471, 41.759684], [-85.515959, 41.759352], [-85.518251, 41.759513], [-85.607548, 41.759079], [-85.608312, 41.759193], [-85.622608, 41.759049], [-85.624987, 41.759093], [-85.632714, 41.759164], [-85.647683, 41.759125], [-85.650738, 41.759103], [-85.724534, 41.759085], [-85.749992, 41.759091], [-85.750469, 41.759090], [-85.775039, 41.759147], [-85.791363, 41.759051], [-85.872041, 41.759365], [-85.874997, 41.759341], [-85.888825, 41.759422], [-85.974901, 41.759849], [-85.974980, 41.759849], [-85.991302, 41.759949], [-86.041027, 41.760512], [-86.125060, 41.760576], [-86.125460, 41.760560], [-86.127844, 41.760592], [-86.217590, 41.760016], [-86.226070, 41.760016], [-86.265496, 41.760207], [-86.501773, 41.759553], [-86.519318, 41.759447], [-86.640044, 41.759671], [-86.641186, 41.759633], [-86.746521, 41.759982], [-86.748096, 41.759967], [-86.800611, 41.760251], [-86.800707, 41.760240], [-86.801578, 41.760240], [-86.804427, 41.760240], [-86.823628, 41.760240], [-86.824828, 41.760240], [-86.777227, 41.784740], [-86.717037, 41.819349], [-86.679355, 41.844793], [-86.619442, 41.893827], [-86.597899, 41.918291], [-86.582197, 41.942241], [-86.556421, 42.000042], [-86.501322, 42.084540], [-86.490122, 42.105139], [-86.485223, 42.118239], [-86.466262, 42.134406], [-86.404146, 42.196379], [-86.385179, 42.217279], [-86.356218, 42.254166], [-86.321803, 42.310743], [-86.297168, 42.358207], [-86.284448, 42.394563], [-86.284969, 42.401814], [-86.276878, 42.413317], [-86.261573, 42.443894], [-86.249710, 42.480212], [-86.240642, 42.540000], [-86.235280, 42.564958], [-86.228082, 42.583397], [-86.225613, 42.594765], [-86.229050, 42.637693], [-86.226638, 42.644922], [-86.216020, 42.664413], [-86.208654, 42.692090], [-86.206834, 42.719424], [-86.208309, 42.762789], [-86.210863, 42.783832], [-86.211815, 42.833236], [-86.210737, 42.859128], [-86.214138, 42.883555], [-86.216209, 42.919007], [-86.226305, 42.988284], [-86.232707, 43.015762], [-86.244277, 43.049681], [-86.250069, 43.057489], [-86.250517, 43.066993], [-86.254646, 43.083409], [-86.280756, 43.136015], [-86.316259, 43.195114], [-86.395750, 43.316225], [-86.407832, 43.338436], [-86.435124, 43.396702], [-86.448743, 43.432013], [-86.468747, 43.491963], [-86.479276, 43.515335], [-86.520205, 43.576718], [-86.529507, 43.593462], [-86.538497, 43.617501], [-86.540916, 43.633158], [-86.540787, 43.644593], [-86.538482, 43.658795], [-86.529179, 43.677889], [-86.510319, 43.698625], [-86.481854, 43.725135], [-86.461554, 43.746685], [-86.445123, 43.771564], [-86.437391, 43.789334], [-86.431043, 43.815975], [-86.431198, 43.840720], [-86.433915, 43.855608], [-86.445455, 43.889726], [-86.447915, 43.918089], [-86.463136, 43.970976], [-86.483331, 44.001179], [-86.501738, 44.021912], [-86.508827, 44.032755], [-86.514742, 44.047920], [-86.514702, 44.058119], [-86.508764, 44.067881], [-86.500453, 44.075607], [-86.446883, 44.105970], [-86.429871, 44.119782], [-86.421108, 44.129480], [-86.400645, 44.156848], [-86.380062, 44.189472], [-86.362847, 44.208113], [-86.351638, 44.229429], [-86.343793, 44.249608], [-86.327287, 44.263057], [-86.316025, 44.284210], [-86.300264, 44.308197], [-86.268710, 44.345324], [-86.251926, 44.400984], [-86.248083, 44.420946], [-86.248320, 44.434758], [-86.251843, 44.451632], [-86.251605, 44.465443], [-86.248914, 44.483004], [-86.243745, 44.488929], [-86.238743, 44.501682], [-86.223788, 44.549043], [-86.220697, 44.566742], [-86.225450, 44.594590], [-86.231828, 44.609107], [-86.253950, 44.648080], [-86.259029, 44.663654], [-86.256796, 44.686769], [-86.254996, 44.691935], [-86.248474, 44.699046], [-86.232482, 44.706050], [-86.172201, 44.720623], [-86.160268, 44.728189], [-86.121125, 44.727972], [-86.106182, 44.731088], [-86.089186, 44.741496], [-86.077933, 44.758234], [-86.073506, 44.769803], [-86.071746, 44.804717], [-86.065966, 44.821522], [-86.066031, 44.834852], [-86.071112, 44.865420], [-86.072468, 44.884788], [-86.070990, 44.895876], [-86.066745, 44.905685], [-86.058862, 44.911012], [-86.038332, 44.915696], [-86.031194, 44.907349], [-86.021513, 44.902774], [-86.009355, 44.899454], [-85.992535, 44.900026], [-85.980219, 44.906136], [-85.972824, 44.914781], [-85.967169, 44.929484], [-85.961603, 44.935567], [-85.952721, 44.940758], [-85.942099, 44.954317], [-85.938589, 44.964559], [-85.931600, 44.968788], [-85.915851, 44.968307], [-85.897626, 44.962014], [-85.891543, 44.957783], [-85.879934, 44.943305], [-85.869852, 44.939031], [-85.854304, 44.938147], [-85.836150, 44.940256], [-85.815451, 44.945631], [-85.807403, 44.949814], [-85.780439, 44.977932], [-85.778278, 44.983075], [-85.776207, 45.000574], [-85.771395, 45.015181], [-85.761943, 45.023454], [-85.746444, 45.051229], [-85.740836, 45.055575], [-85.712262, 45.065622], [-85.695715, 45.076461], [-85.681096, 45.092693], [-85.675671, 45.105540], [-85.674861, 45.116216], [-85.656024, 45.145788], [-85.618639, 45.186771], [-85.613174, 45.184624], [-85.611684, 45.181104], [-85.606963, 45.178477], [-85.593064, 45.178527], [-85.585986, 45.180381], [-85.564654, 45.192546], [-85.561809, 45.200524], [-85.551072, 45.210742], [-85.540497, 45.210169], [-85.526734, 45.189316], [-85.531461, 45.177247], [-85.536892, 45.173385], [-85.552179, 45.167352], [-85.561680, 45.158940], [-85.554083, 45.142568], [-85.558373, 45.133209], [-85.564612, 45.137498], [-85.564612, 45.147247], [-85.570178, 45.155145], [-85.573893, 45.155488], [-85.590434, 45.153175], [-85.599801, 45.149286], [-85.614319, 45.127562], [-85.609266, 45.113510], [-85.595029, 45.103962], [-85.597496, 45.094454], [-85.583198, 45.071304], [-85.573353, 45.068382], [-85.566066, 45.059201], [-85.566130, 45.043633], [-85.570160, 45.041278], [-85.573976, 45.043361], [-85.597181, 45.040547], [-85.599652, 45.021749], [-85.609123, 45.013103], [-85.621878, 45.004529], [-85.606588, 44.990662], [-85.604301, 44.990983], [-85.602356, 44.974272], [-85.602034, 44.926743], [-85.621403, 44.923123], [-85.625497, 44.921107], [-85.639842, 44.890255], [-85.645456, 44.883645], [-85.648932, 44.874010], [-85.652355, 44.849092], [-85.651435, 44.831624], [-85.641652, 44.810816], [-85.637000, 44.790078], [-85.640781, 44.775561], [-85.636097, 44.771329], [-85.627982, 44.767508], [-85.610776, 44.765160], [-85.599256, 44.765919], [-85.593571, 44.768783], [-85.590985, 44.783914], [-85.581717, 44.807784], [-85.545891, 44.864024], [-85.532931, 44.873190], [-85.530649, 44.889763], [-85.553509, 44.890924], [-85.559524, 44.888113], [-85.564509, 44.895246], [-85.539703, 44.916779], [-85.533553, 44.925762], [-85.520205, 44.960347], [-85.522100, 44.966727], [-85.520034, 44.973996], [-85.492600, 44.989834], [-85.475204, 44.991053], [-85.470462, 44.980745], [-85.464944, 44.961062], [-85.466650, 44.958844], [-85.472258, 44.959391], [-85.485740, 44.953626], [-85.491286, 44.927585], [-85.492490, 44.908220], [-85.488624, 44.901707], [-85.498007, 44.865451], [-85.502182, 44.855802], [-85.508617, 44.847872], [-85.519096, 44.845339], [-85.539924, 44.834166], [-85.555894, 44.818256], [-85.560231, 44.810072], [-85.560488, 44.789679], [-85.576566, 44.760208], [-85.571301, 44.755293], [-85.554326, 44.748744], [-85.538285, 44.746821], [-85.527216, 44.748235], [-85.504775, 44.768082], [-85.503935, 44.772951], [-85.505244, 44.781594], [-85.509251, 44.787334], [-85.499591, 44.803838], [-85.474796, 44.814959], [-85.462916, 44.825067], [-85.460445, 44.835667], [-85.425804, 44.881646], [-85.423003, 44.895019], [-85.406173, 44.911773], [-85.395800, 44.931018], [-85.378286, 44.998587], [-85.381654, 45.018407], [-85.380659, 45.046319], [-85.377586, 45.055713], [-85.366412, 45.069023], [-85.366908, 45.116938], [-85.372571, 45.126241], [-85.376948, 45.142881], [-85.380464, 45.180876], [-85.386726, 45.189497], [-85.388593, 45.235240], [-85.371593, 45.270834], [-85.355478, 45.282774], [-85.335016, 45.294027], [-85.323941, 45.303355], [-85.307646, 45.313140], [-85.294848, 45.316408], [-85.289568, 45.314052], [-85.273789, 45.315443], [-85.262996, 45.319507], [-85.255050, 45.325675], [-85.252193, 45.330863], [-85.235629, 45.339374], [-85.209673, 45.356937], [-85.196704, 45.360641], [-85.182471, 45.360824], [-85.143651, 45.370369], [-85.054805, 45.364091], [-85.043101, 45.361506], [-85.032813, 45.361251], [-85.022234, 45.366701], [-84.959119, 45.375973], [-84.915850, 45.393115], [-84.912537, 45.402828], [-84.912956, 45.409776], [-84.916165, 45.417639], [-84.922006, 45.421914], [-84.980953, 45.429382], [-84.990041, 45.427618], [-84.990785, 45.425264], [-84.983836, 45.420764], [-84.977116, 45.420035], [-84.978608, 45.418663], [-85.040936, 45.436701], [-85.069573, 45.459239], [-85.088386, 45.476928], [-85.109252, 45.521626], [-85.115479, 45.539406], [-85.119737, 45.569026], [-85.118637, 45.575175], [-85.111909, 45.585829], [-85.093525, 45.600121], [-85.079528, 45.617083], [-85.075686, 45.623688], [-85.074910, 45.629242], [-85.061488, 45.639505], [-85.015341, 45.651564], [-85.007026, 45.656360], [-85.001154, 45.661225], [-84.996336, 45.669685], [-84.992958, 45.679983], [-84.987847, 45.682997], [-84.975768, 45.683174], [-84.970950, 45.686334], [-84.943756, 45.710290], [-84.940526, 45.721832], [-84.942125, 45.728460], [-84.950840, 45.736893], [-84.982328, 45.751960], [-85.002914, 45.753940], [-85.048441, 45.760807], [-85.074563, 45.762182], [-85.077313, 45.765619], [-85.049129, 45.770431], [-85.030568, 45.769056], [-85.007410, 45.763168], [-84.995105, 45.759855], [-84.938312, 45.759892], [-84.924664, 45.756897], [-84.910398, 45.750010], [-84.866976, 45.752066], [-84.840981, 45.744751], [-84.806642, 45.746171], [-84.799558, 45.747130], [-84.788821, 45.752283], [-84.781373, 45.761080], [-84.779800, 45.769650], [-84.792337, 45.778497], [-84.793153, 45.780463], [-84.780313, 45.787224], [-84.772765, 45.789301], [-84.751571, 45.782733], [-84.742000, 45.784134], [-84.734065, 45.788205], [-84.726192, 45.786905], [-84.718904, 45.777599], [-84.715996, 45.766174], [-84.681967, 45.756197], [-84.679546, 45.749095], [-84.644822, 45.739990], [-84.604712, 45.721668], [-84.573631, 45.710381], [-84.555496, 45.702268], [-84.553311, 45.698566], [-84.538998, 45.690383], [-84.461680, 45.652404], [-84.442348, 45.654771], [-84.435415, 45.664106], [-84.427495, 45.669201], [-84.413642, 45.669427], [-84.400283, 45.663345], [-84.376403, 45.655565], [-84.329537, 45.664380], [-84.289685, 45.653296], [-84.270238, 45.644790], [-84.215268, 45.634767], [-84.196043, 45.621456], [-84.180514, 45.604639], [-84.157121, 45.585305], [-84.139462, 45.573714], [-84.128867, 45.562284], [-84.126532, 45.556616], [-84.126971, 45.542428], [-84.122309, 45.523788], [-84.116687, 45.513050], [-84.109238, 45.505171], [-84.095905, 45.497298], [-84.075792, 45.490537], [-84.056138, 45.489349], [-84.039958, 45.493733], [-84.036286, 45.496245], [-84.028813, 45.497225], [-84.009582, 45.495069], [-83.998350, 45.491158], [-83.978017, 45.494138], [-83.939261, 45.493189], [-83.909472, 45.485784], [-83.881813, 45.467907], [-83.858560, 45.446865], [-83.841543, 45.435287], [-83.806622, 45.419159], [-83.788777, 45.416415], [-83.773171, 45.417302], [-83.755569, 45.411034], [-83.737321, 45.410943], [-83.721815, 45.413304], [-83.697316, 45.396239], [-83.667934, 45.384675], [-83.643790, 45.371710], [-83.599273, 45.352561], [-83.570361, 45.347198], [-83.550268, 45.350832], [-83.546799, 45.352637], [-83.545729, 45.358397], [-83.538306, 45.358167], [-83.520258, 45.347239], [-83.514717, 45.346460], [-83.496704, 45.357536], [-83.488826, 45.355872], [-83.477794, 45.341891], [-83.445672, 45.310612], [-83.433040, 45.303688], [-83.425140, 45.296808], [-83.422389, 45.290775], [-83.401091, 45.279572], [-83.388274, 45.276916], [-83.385104, 45.274195], [-83.381743, 45.268983], [-83.388034, 45.254976], [-83.412569, 45.245807], [-83.412410, 45.238905], [-83.405914, 45.227157], [-83.384265, 45.203472], [-83.381647, 45.203357], [-83.368896, 45.182168], [-83.368046, 45.172478], [-83.363678, 45.166469], [-83.359895, 45.163020], [-83.348684, 45.161516], [-83.337822, 45.147120], [-83.316118, 45.141958], [-83.315924, 45.139992], [-83.319315, 45.137684], [-83.318442, 45.128930], [-83.307880, 45.099093], [-83.298275, 45.090483], [-83.290827, 45.069157], [-83.291346, 45.062597], [-83.280272, 45.045962], [-83.277037, 45.044767], [-83.271464, 45.038114], [-83.265896, 45.026844], [-83.271506, 45.023417], [-83.287974, 45.026462], [-83.302153, 45.032315], [-83.340257, 45.041545], [-83.357609, 45.050613], [-83.367470, 45.062268], [-83.399255, 45.070364], [-83.433798, 45.057616], [-83.442052, 45.051056], [-83.453363, 45.035331], [-83.454168, 45.031880], [-83.446342, 45.016655], [-83.435249, 45.011883], [-83.431254, 45.007998], [-83.435822, 45.000012], [-83.438948, 45.000011], [-83.450013, 44.990219], [-83.443718, 44.952247], [-83.438856, 44.940843], [-83.433032, 44.932890], [-83.425311, 44.926741], [-83.404596, 44.918761], [-83.398879, 44.906417], [-83.393960, 44.903056], [-83.352815, 44.886164], [-83.320503, 44.880571], [-83.312903, 44.884191], [-83.314966, 44.868380], [-83.321241, 44.852962], [-83.314429, 44.842220], [-83.300648, 44.829831], [-83.299736, 44.823359], [-83.290906, 44.807888], [-83.295718, 44.784516], [-83.288844, 44.765955], [-83.298287, 44.754907], [-83.297300, 44.746134], [-83.290665, 44.729265], [-83.284128, 44.721766], [-83.273393, 44.713901], [-83.276836, 44.689354], [-83.289442, 44.652968], [-83.307504, 44.629816], [-83.314517, 44.608725], [-83.315603, 44.595079], [-83.313649, 44.564588], [-83.308918, 44.548360], [-83.308471, 44.539902], [-83.318279, 44.514416], [-83.317610, 44.486058], [-83.326824, 44.444411], [-83.327171, 44.429234], [-83.324616, 44.415039], [-83.321553, 44.409119], [-83.321648, 44.404502], [-83.333757, 44.372486], [-83.335248, 44.357995], [-83.332533, 44.340464], [-83.336988, 44.332919], [-83.343738, 44.329763], [-83.352115, 44.332366], [-83.364312, 44.332590], [-83.373607, 44.327784], [-83.401822, 44.301831], [-83.414301, 44.294543], [-83.419236, 44.287800], [-83.425762, 44.272487], [-83.445176, 44.252823], [-83.465111, 44.245949], [-83.442731, 44.265361], [-83.445805, 44.273378], [-83.463049, 44.278838], [-83.479531, 44.280090], [-83.500392, 44.276610], [-83.508839, 44.273711], [-83.524817, 44.261558], [-83.537710, 44.248171], [-83.549096, 44.227282], [-83.552872, 44.210718], [-83.553834, 44.197956], [-83.567744, 44.155899], [-83.568915, 44.126734], [-83.567714, 44.119652], [-83.573071, 44.101298], [-83.588004, 44.086758], [-83.591361, 44.079237], [-83.590437, 44.069569], [-83.584090, 44.056748], [-83.601173, 44.054686], [-83.621078, 44.056186], [-83.650116, 44.052404], [-83.679654, 44.036365], [-83.687892, 44.020709], [-83.680108, 43.994196], [-83.743806, 43.991529], [-83.746779, 43.988807], [-83.763774, 43.985158], [-83.787863, 43.985279], [-83.829077, 43.989095], [-83.848276, 43.981594], [-83.854930, 43.977067], [-83.856128, 43.972632], [-83.869406, 43.960719], [-83.877694, 43.959235], [-83.885328, 43.946691], [-83.890145, 43.934672], [-83.890912, 43.923314], [-83.907388, 43.918062], [-83.916815, 43.899050], [-83.917875, 43.856509], [-83.926345, 43.787398], [-83.929375, 43.777091], [-83.945426, 43.759946], [-83.954792, 43.760932], [-83.956021, 43.759286], [-83.954347, 43.750647], [-83.939297, 43.715369], [-83.909479, 43.672622], [-83.897078, 43.664022], [-83.852076, 43.644922], [-83.844118, 43.652896], [-83.838160, 43.654384], [-83.814674, 43.643022], [-83.806774, 43.641221], [-83.778919, 43.630056], [-83.770693, 43.628691], [-83.769886, 43.634924], [-83.725793, 43.618691], [-83.703446, 43.597646], [-83.669795, 43.590790], [-83.666052, 43.591292], [-83.654192, 43.599290], [-83.618602, 43.628891], [-83.595579, 43.650249], [-83.563157, 43.684564], [-83.553707, 43.685432], [-83.549044, 43.693798], [-83.551470, 43.699901], [-83.540187, 43.708746], [-83.524837, 43.716948], [-83.515853, 43.718157], [-83.513461, 43.714607], [-83.506657, 43.710907], [-83.480070, 43.714636], [-83.470053, 43.723418], [-83.465080, 43.733843], [-83.459628, 43.740931], [-83.440171, 43.761694], [-83.438878, 43.767135], [-83.441591, 43.770175], [-83.446752, 43.771860], [-83.438311, 43.786846], [-83.426068, 43.799915], [-83.416378, 43.801034], [-83.411453, 43.805033], [-83.410663, 43.807730], [-83.428481, 43.817907], [-83.442917, 43.811033], [-83.471788, 43.789723], [-83.480725, 43.791786], [-83.448416, 43.861902], [-83.427794, 43.861215], [-83.425732, 43.849529], [-83.417483, 43.841967], [-83.404422, 43.841280], [-83.384487, 43.854340], [-83.358869, 43.857395], [-83.332270, 43.880522], [-83.331788, 43.893901], [-83.333532, 43.898520], [-83.340976, 43.904541], [-83.403047, 43.910709], [-83.400985, 43.916208], [-83.338067, 43.915687], [-83.318656, 43.917620], [-83.305690, 43.922489], [-83.282310, 43.938031], [-83.268980, 43.956132], [-83.261850, 43.969021], [-83.261530, 43.973525], [-83.227093, 43.981003], [-83.195688, 43.983137], [-83.180618, 43.982109], [-83.145407, 43.989441], [-83.134881, 43.993147], [-83.120659, 44.000950], [-83.107820, 44.003245], [-83.079297, 44.001079], [-83.066026, 44.003366], [-83.058741, 44.006224], [-83.046577, 44.015710], [-83.029868, 44.041175], [-83.024604, 44.045174], [-82.999283, 44.046510], [-82.990728, 44.048846], [-82.967439, 44.066138], [-82.958688, 44.065774], [-82.956658, 44.063306], [-82.947368, 44.062187], [-82.928884, 44.069389], [-82.915976, 44.070503], [-82.889831, 44.050952], [-82.875889, 44.045046], [-82.833103, 44.036851], [-82.793205, 44.023247], [-82.788298, 44.013712], [-82.783198, 44.009366], [-82.765018, 44.006845], [-82.746255, 43.996037], [-82.738992, 43.989506], [-82.728528, 43.972615], [-82.712235, 43.949610], [-82.709839, 43.948226], [-82.693505, 43.917980], [-82.678642, 43.883730], [-82.655450, 43.867883], [-82.643166, 43.852468], [-82.642899, 43.846419], [-82.647467, 43.844490], [-82.647784, 43.842684], [-82.644345, 43.837539], [-82.633641, 43.831224], [-82.617955, 43.768596], [-82.619079, 43.756088], [-82.617213, 43.746788], [-82.612224, 43.739771], [-82.604830, 43.678884], [-82.605783, 43.669489], [-82.600500, 43.602935], [-82.597911, 43.590016], [-82.593785, 43.581467], [-82.585654, 43.543969], [-82.565691, 43.502904], [-82.565505, 43.497063], [-82.553540, 43.464111], [-82.539517, 43.437539], [-82.538578, 43.431594], [-82.539930, 43.422378], [-82.535627, 43.368062], [-82.536794, 43.348510], [-82.530128, 43.333805], [-82.529416, 43.316243], [-82.532396, 43.305770], [-82.523086, 43.225361], [-82.519123, 43.212737], [-82.508881, 43.196748], [-82.501656, 43.161656], [-82.494194, 43.143736], [-82.490614, 43.118172], [-82.486042, 43.102486], [-82.471053, 43.087581], [-82.457221, 43.061285], [-82.422768, 43.007956], [-82.415937, 43.005555]]], [[[-83.436745, 44.021656], [-83.442245, 44.028530], [-83.441551, 44.038841], [-83.425743, 44.028530], [-83.436745, 44.021656]]], [[[-83.414047, 43.877026], [-83.427109, 43.877026], [-83.436729, 43.882526], [-83.432610, 43.885273], [-83.414047, 43.877026]]], [[[-87.600342, 47.407711], [-87.617531, 47.407711], [-87.629898, 47.415272], [-87.650520, 47.416649], [-87.623718, 47.426960], [-87.585907, 47.419399], [-87.600342, 47.407711]]], [[[-83.761154, 46.086082], [-83.784348, 46.090248], [-83.805168, 46.092033], [-83.821236, 46.091438], [-83.828964, 46.096790], [-83.828964, 46.102741], [-83.817070, 46.111069], [-83.803978, 46.109879], [-83.787323, 46.108093], [-83.774239, 46.097980], [-83.763527, 46.093815], [-83.758179, 46.090248], [-83.761154, 46.086082]]], [[[-83.973450, 46.065285], [-84.003006, 46.079033], [-84.012634, 46.087280], [-84.005760, 46.097591], [-83.987885, 46.103779], [-83.974136, 46.073532], [-83.973450, 46.065285]]], [[[-83.853355, 46.050987], [-83.858116, 46.055149], [-83.858116, 46.062885], [-83.858711, 46.067047], [-83.865845, 46.069427], [-83.871201, 46.075970], [-83.864059, 46.083702], [-83.852760, 46.085487], [-83.847404, 46.082516], [-83.840271, 46.071808], [-83.839081, 46.064072], [-83.846214, 46.051582], [-83.853355, 46.050987]]], [[[-83.749252, 46.034328], [-83.758774, 46.036114], [-83.763527, 46.043846], [-83.770180, 46.043228], [-83.773781, 46.051472], [-83.764122, 46.065857], [-83.749847, 46.065857], [-83.733192, 46.053364], [-83.732002, 46.048012], [-83.737358, 46.043846], [-83.743896, 46.035519], [-83.749252, 46.034328]]], [[[-84.638847, 45.955563], [-84.640915, 45.971375], [-84.639633, 45.977913], [-84.634041, 45.980309], [-84.613937, 45.973629], [-84.607750, 45.967918], [-84.608704, 45.964111], [-84.619171, 45.957447], [-84.638847, 45.955563]]], [[[-84.568253, 45.950787], [-84.582527, 45.958874], [-84.583954, 45.963634], [-84.579674, 45.968391], [-84.575386, 45.970299], [-84.563492, 45.967442], [-84.559212, 45.958401], [-84.564919, 45.951260], [-84.568253, 45.950787]]], [[[-83.561836, 45.912563], [-83.583054, 45.915920], [-83.632210, 45.932285], [-83.657661, 45.945461], [-83.687691, 45.935390], [-83.719429, 45.934078], [-83.732986, 45.937641], [-83.742775, 45.938004], [-83.766235, 45.935223], [-83.768852, 45.932068], [-83.786110, 45.933376], [-83.801041, 45.937580], [-83.803329, 45.943363], [-83.808144, 45.945694], [-83.822807, 45.943985], [-83.827568, 45.941235], [-83.835503, 45.941841], [-83.840866, 45.952724], [-83.846436, 45.953182], [-83.864861, 45.959465], [-83.881058, 45.968185], [-83.884827, 45.977165], [-83.873146, 45.993427], [-83.868233, 45.995075], [-83.845398, 46.025681], [-83.830147, 46.022324], [-83.818199, 46.002426], [-83.794052, 45.995800], [-83.776436, 46.004204], [-83.765274, 46.018364], [-83.765259, 46.024681], [-83.759369, 46.027191], [-83.746872, 46.024811], [-83.735573, 46.026596], [-83.727837, 46.034924], [-83.711777, 46.040279], [-83.692146, 46.039089], [-83.686195, 46.046227], [-83.679657, 46.057529], [-83.677872, 46.064667], [-83.682632, 46.071808], [-83.699883, 46.075375], [-83.719513, 46.081326], [-83.731407, 46.086678], [-83.723297, 46.093811], [-83.719788, 46.101032], [-83.703857, 46.103367], [-83.661163, 46.100258], [-83.634979, 46.103954], [-83.625557, 46.102211], [-83.615341, 46.095978], [-83.598610, 46.090084], [-83.581314, 46.089615], [-83.576088, 46.083511], [-83.572639, 46.074921], [-83.572571, 46.069897], [-83.565353, 46.061897], [-83.554062, 46.058884], [-83.547203, 46.047867], [-83.543365, 46.037197], [-83.540848, 46.021248], [-83.532913, 46.011330], [-83.494843, 45.999542], [-83.488350, 45.999542], [-83.480637, 45.996162], [-83.473946, 45.988560], [-83.473221, 45.984421], [-83.481766, 45.971874], [-83.488808, 45.968739], [-83.510620, 45.929325], [-83.517242, 45.923615], [-83.526344, 45.918636], [-83.561836, 45.912563]]], [[[-84.861969, 45.851276], [-84.881210, 45.860901], [-84.879150, 45.868462], [-84.861969, 45.860214], [-84.861969, 45.851276]]], [[[-84.617607, 45.844925], [-84.638428, 45.850872], [-84.650917, 45.859798], [-84.651512, 45.862770], [-84.645561, 45.874668], [-84.647346, 45.884186], [-84.644974, 45.885376], [-84.624153, 45.880020], [-84.602142, 45.852062], [-84.607491, 45.847900], [-84.617607, 45.844925]]], [[[-85.590889, 45.833141], [-85.595177, 45.835522], [-85.593811, 45.839809], [-85.581467, 45.841042], [-85.584709, 45.834095], [-85.590889, 45.833141]]], [[[-84.595001, 45.821129], [-84.609871, 45.825890], [-84.613441, 45.834217], [-84.612846, 45.836002], [-84.596786, 45.833622], [-84.589050, 45.827675], [-84.589645, 45.821724], [-84.595001, 45.821129]]], [[[-85.611832, 45.806015], [-85.617538, 45.810776], [-85.617538, 45.814106], [-85.612305, 45.816010], [-85.606598, 45.815060], [-85.603264, 45.813156], [-85.601837, 45.811253], [-85.611832, 45.806015]]], [[[-85.683296, 45.769455], [-85.690704, 45.769455], [-85.696259, 45.774391], [-85.691933, 45.777477], [-85.683296, 45.769455]]], [[[-85.377129, 45.769012], [-85.396172, 45.774723], [-85.394264, 45.778530], [-85.379036, 45.789951], [-85.379036, 45.802326], [-85.377129, 45.812794], [-85.370468, 45.818504], [-85.360954, 45.817554], [-85.353340, 45.806133], [-85.351433, 45.795662], [-85.359047, 45.776627], [-85.377129, 45.769012]]], [[[-85.462578, 45.765865], [-85.495575, 45.772739], [-85.507263, 45.778236], [-85.532013, 45.798172], [-85.529259, 45.818108], [-85.524445, 45.829792], [-85.496948, 45.822231], [-85.454330, 45.800236], [-85.450203, 45.796677], [-85.447830, 45.790134], [-85.450203, 45.776451], [-85.455559, 45.768719], [-85.462578, 45.765865]]], [[[-84.420113, 45.718815], [-84.431412, 45.724762], [-84.434387, 45.726547], [-84.442719, 45.726547], [-84.452827, 45.725952], [-84.472458, 45.731304], [-84.481384, 45.729523], [-84.500420, 45.736065], [-84.510529, 45.750340], [-84.512314, 45.755100], [-84.525406, 45.761047], [-84.558716, 45.793766], [-84.580727, 45.801498], [-84.588455, 45.807449], [-84.590240, 45.812801], [-84.589050, 45.816372], [-84.580727, 45.819939], [-84.571800, 45.819347], [-84.550385, 45.811016], [-84.525406, 45.808640], [-84.511124, 45.811611], [-84.504585, 45.811611], [-84.500420, 45.811016], [-84.490303, 45.804474], [-84.439148, 45.789604], [-84.433197, 45.787819], [-84.427841, 45.790195], [-84.423088, 45.792576], [-84.421303, 45.796146], [-84.423088, 45.805069], [-84.427246, 45.811611], [-84.418922, 45.811611], [-84.408211, 45.795551], [-84.402267, 45.787224], [-84.398697, 45.785439], [-84.390961, 45.785439], [-84.375496, 45.777706], [-84.357056, 45.772350], [-84.354080, 45.770565], [-84.354080, 45.767593], [-84.364197, 45.756290], [-84.371330, 45.746773], [-84.379662, 45.739635], [-84.390366, 45.734875], [-84.392151, 45.729523], [-84.399292, 45.722977], [-84.409996, 45.720005], [-84.420113, 45.718815]]], [[[-85.672188, 45.696632], [-85.696869, 45.697250], [-85.696259, 45.712063], [-85.695290, 45.724697], [-85.701813, 45.736130], [-85.688850, 45.747238], [-85.651863, 45.743141], [-85.649353, 45.722553], [-85.672188, 45.696632]]], [[[-85.843750, 45.690460], [-85.843750, 45.710209], [-85.835114, 45.711445], [-85.833260, 45.696632], [-85.843750, 45.690460]]], [[[-86.682877, 45.594818], [-86.691704, 45.595818], [-86.702019, 45.602692], [-86.712326, 45.610939], [-86.692390, 45.617126], [-86.677269, 45.613689], [-86.669022, 45.609566], [-86.665749, 45.606239], [-86.670982, 45.600529], [-86.682877, 45.594818]]], [[[-86.636894, 45.542053], [-86.648788, 45.543243], [-86.654144, 45.555737], [-86.661285, 45.574177], [-86.661285, 45.582504], [-86.658905, 45.586075], [-86.654739, 45.587856], [-86.644035, 45.585480], [-86.626190, 45.573582], [-86.620239, 45.562279], [-86.622025, 45.556332], [-86.630348, 45.546814], [-86.636894, 45.542053]]], [[[-86.660690, 45.520042], [-86.666641, 45.520042], [-86.669609, 45.524208], [-86.670204, 45.529560], [-86.667236, 45.531940], [-86.659500, 45.532536], [-86.656525, 45.525993], [-86.660690, 45.520042]]], [[[-86.715080, 45.497517], [-86.728142, 45.522949], [-86.723328, 45.520889], [-86.715767, 45.509201], [-86.715080, 45.497517]]], [[[-86.758385, 45.476204], [-86.782448, 45.487206], [-86.782448, 45.506451], [-86.774193, 45.511951], [-86.756325, 45.501640], [-86.758385, 45.476204]]], [[[-85.770958, 45.461353], [-85.792961, 45.481976], [-85.782646, 45.491596], [-85.770958, 45.487473], [-85.766838, 45.475788], [-85.770958, 45.461353]]], [[[-85.833519, 45.378174], [-85.873390, 45.421482], [-85.883011, 45.443478], [-85.858261, 45.440041], [-85.834892, 45.428356], [-85.825958, 45.404297], [-85.833519, 45.378174]]], [[[-83.322464, 45.186062], [-83.338272, 45.189499], [-83.334145, 45.199123], [-83.319710, 45.194313], [-83.322464, 45.186062]]], [[[-83.190582, 45.033356], [-83.229767, 45.039539], [-83.233894, 45.054665], [-83.231827, 45.058102], [-83.213959, 45.056728], [-83.201584, 45.046413], [-83.190582, 45.033356]]], [[[-85.582054, 44.859333], [-85.583755, 44.861454], [-85.581207, 44.869938], [-85.569328, 44.873333], [-85.569756, 44.863152], [-85.582054, 44.859333]]], [[[-83.829224, 43.662632], [-83.831284, 43.669506], [-83.821663, 43.677067], [-83.816162, 43.672943], [-83.816162, 43.666756], [-83.829224, 43.662632]]]] } }; - - var multiTriangles = tesselate(multipolygon); - - t.equal(multiTriangles.type, 'FeatureCollection', 'MultiPolygon returns a FeatureCollection'); - t.equal(multiTriangles.features[0].geometry.type, 'Polygon', 'contains at least 1 triangle'); - t.equal(multiTriangles.features[0].geometry.coordinates[0].length, 4, 'triangle is valid'); - - t.throws(function (err) { - tesselate(point([0, 0])); - }, /input must be a Polygon or MultiPolygon/); - - t.throws(function (err) { - tesselate(featurecollection([])); - }, /input must be a Polygon or MultiPolygon/); - - t.end(); -}); diff --git a/packages/turf-tin/.gitignore b/packages/turf-tin/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-tin/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-tin/LICENSE b/packages/turf-tin/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-tin/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-tin/README.md b/packages/turf-tin/README.md deleted file mode 100644 index 72a17858bc..0000000000 --- a/packages/turf-tin/README.md +++ /dev/null @@ -1,79 +0,0 @@ -# @turf/tin - - - -## tin - -Takes a set of [points][1] and creates a -[Triangulated Irregular Network][2], -or a TIN for short, returned as a collection of Polygons. These are often used -for developing elevation contour maps or stepped heat visualizations. - -If an optional z-value property is provided then it is added as properties called `a`, `b`, -and `c` representing its value at each of the points that represent the corners of the -triangle. - -**Parameters** - -- `points` **[FeatureCollection][3]<[Point][4]>** input points -- `z` **[String][5]?** name of the property from which to pull z values - This is optional: if not given, then there will be no extra data added to the derived triangles. - -**Examples** - -```javascript -// generate some random point data -var points = turf.randomPoint(30, {bbox: [50, 30, 70, 50]}); - -// add a random property to each point between 0 and 9 -for (var i = 0; i < points.features.length; i++) { - points.features[i].properties.z = ~~(Math.random() * 9); -} -var tin = turf.tin(points, 'z'); - -//addToMap -var addToMap = [tin, points] -for (var i = 0; i < tin.features.length; i++) { - var properties = tin.features[i].properties; - properties.fill = '#' + properties.a + properties.b + properties.c; -} -``` - -Returns **[FeatureCollection][3]<[Polygon][6]>** TIN output - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[2]: http://en.wikipedia.org/wiki/Triangulated_irregular_network - -[3]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/tin -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-tin/index.ts b/packages/turf-tin/index.ts deleted file mode 100644 index 493d7c4165..0000000000 --- a/packages/turf-tin/index.ts +++ /dev/null @@ -1,290 +0,0 @@ -// http://en.wikipedia.org/wiki/Delaunay_triangulation -// https://github.com/ironwallaby/delaunay -import { featureCollection, polygon } from "@turf/helpers"; -import { Feature, FeatureCollection, Point, Polygon } from "@turf/helpers"; - -export interface Pt { - x: number; - y: number; - z?: number; - __sentinel?: boolean; -} -export interface Vertice { - x: number; - y: number; -} - -/** - * Takes a set of {@link Point|points} and creates a - * [Triangulated Irregular Network](http://en.wikipedia.org/wiki/Triangulated_irregular_network), - * or a TIN for short, returned as a collection of Polygons. These are often used - * for developing elevation contour maps or stepped heat visualizations. - * - * If an optional z-value property is provided then it is added as properties called `a`, `b`, - * and `c` representing its value at each of the points that represent the corners of the - * triangle. - * - * @name tin - * @param {FeatureCollection} points input points - * @param {String} [z] name of the property from which to pull z values - * This is optional: if not given, then there will be no extra data added to the derived triangles. - * @returns {FeatureCollection} TIN output - * @example - * // generate some random point data - * var points = turf.randomPoint(30, {bbox: [50, 30, 70, 50]}); - * - * // add a random property to each point between 0 and 9 - * for (var i = 0; i < points.features.length; i++) { - * points.features[i].properties.z = ~~(Math.random() * 9); - * } - * var tin = turf.tin(points, 'z'); - * - * //addToMap - * var addToMap = [tin, points] - * for (var i = 0; i < tin.features.length; i++) { - * var properties = tin.features[i].properties; - * properties.fill = '#' + properties.a + properties.b + properties.c; - * } - */ -export default function tin( - points: FeatureCollection, - z?: string, -): FeatureCollection { - // break down points - let isPointZ = false; - return featureCollection(triangulate(points.features.map((p) => { - const point: Pt = { - x: p.geometry.coordinates[0], - y: p.geometry.coordinates[1], - }; - if (z) { - point.z = p.properties[z]; - } else if (p.geometry.coordinates.length === 3) { - isPointZ = true; - point.z = p.geometry.coordinates[2]; - } - return point; - })).map((triangle: any) => { - - const a = [triangle.a.x, triangle.a.y]; - const b = [triangle.b.x, triangle.b.y]; - const c = [triangle.c.x, triangle.c.y]; - let properties = {}; - - // Add z coordinates to triangle points if user passed - // them in that way otherwise add it as a property. - if (isPointZ) { - a.push(triangle.a.z); - b.push(triangle.b.z); - c.push(triangle.c.z); - } else { - properties = { - a: triangle.a.z, - b: triangle.b.z, - c: triangle.c.z, - }; - } - - return polygon([[a, b, c, a]], properties); - - })); -} - -class Triangle { - public a: Pt; - public b: Pt; - public c: Pt; - public x: number; - public y: number; - public r: number; - - constructor(a: Pt, b: Pt, c: Pt) { - this.a = a; - this.b = b; - this.c = c; - - const A = b.x - a.x; - const B = b.y - a.y; - const C = c.x - a.x; - const D = c.y - a.y; - const E = A * (a.x + b.x) + B * (a.y + b.y); - const F = C * (a.x + c.x) + D * (a.y + c.y); - const G = 2 * (A * (c.y - b.y) - B * (c.x - b.x)); - let dx; - let dy; - - // If the points of the triangle are collinear, then just find the - // extremes and use the midpoint as the center of the circumcircle. - this.x = (D * E - B * F) / G; - this.y = (A * F - C * E) / G; - dx = this.x - a.x; - dy = this.y - a.y; - this.r = dx * dx + dy * dy; - } -} - -function byX(a: Pt, b: Pt) { - return b.x - a.x; -} - -function dedup(edges: number[]) { - let j = edges.length; - let a; - let b; - let i; - let m; - let n; - - outer: - while (j) { - b = edges[--j]; - a = edges[--j]; - i = j; - while (i) { - n = edges[--i]; - m = edges[--i]; - if ((a === m && b === n) || (a === n && b === m)) { - edges.splice(j, 2); - edges.splice(i, 2); - j -= 2; - continue outer; - } - } - } -} - -function triangulate(vertices: Vertice[]) { - // Bail if there aren't enough vertices to form any triangles. - if (vertices.length < 3) { - return []; - } - - // Ensure the vertex array is in order of descending X coordinate - // (which is needed to ensure a subquadratic runtime), and then find - // the bounding box around the points. - vertices.sort(byX); - - let i = vertices.length - 1; - const xmin = vertices[i].x; - const xmax = vertices[0].x; - let ymin = vertices[i].y; - let ymax = ymin; - const epsilon = 1e-12; - - let a; - let b; - let c; - let A; - let B; - let G; - - while (i--) { - if (vertices[i].y < ymin) { - ymin = vertices[i].y; - } - if (vertices[i].y > ymax) { - ymax = vertices[i].y; - } - } - - // Find a supertriangle, which is a triangle that surrounds all the - // vertices. This is used like something of a sentinel value to remove - // cases in the main algorithm, and is removed before we return any - // results. - - // Once found, put it in the "open" list. (The "open" list is for - // triangles who may still need to be considered; the "closed" list is - // for triangles which do not.) - let dx = xmax - xmin; - let dy = ymax - ymin; - const dmax = (dx > dy) ? dx : dy; - const xmid = (xmax + xmin) * 0.5; - const ymid = (ymax + ymin) * 0.5; - const open = [ - new Triangle({ - __sentinel: true, - x: xmid - 20 * dmax, - y: ymid - dmax, - }, { - __sentinel: true, - x: xmid, - y: ymid + 20 * dmax, - }, { - __sentinel: true, - x: xmid + 20 * dmax, - y: ymid - dmax, - }, - )]; - const closed = []; - const edges: any = []; - let j; - - // Incrementally add each vertex to the mesh. - i = vertices.length; - while (i--) { - // For each open triangle, check to see if the current point is - // inside it's circumcircle. If it is, remove the triangle and add - // it's edges to an edge list. - edges.length = 0; - j = open.length; - while (j--) { - // If this point is to the right of this triangle's circumcircle, - // then this triangle should never get checked again. Remove it - // from the open list, add it to the closed list, and skip. - dx = vertices[i].x - open[j].x; - if (dx > 0 && dx * dx > open[j].r) { - closed.push(open[j]); - open.splice(j, 1); - continue; - } - - // If not, skip this triangle. - dy = vertices[i].y - open[j].y; - if (dx * dx + dy * dy > open[j].r) { - continue; - } - - // Remove the triangle and add it's edges to the edge list. - edges.push( - open[j].a, open[j].b, - open[j].b, open[j].c, - open[j].c, open[j].a, - ); - open.splice(j, 1); - } - - // Remove any doubled edges. - dedup(edges); - - // Add a new triangle for each edge. - j = edges.length; - while (j) { - b = edges[--j]; - a = edges[--j]; - c = vertices[i]; - // Avoid adding colinear triangles (which have error-prone - // circumcircles) - A = b.x - a.x; - B = b.y - a.y; - G = 2 * (A * (c.y - b.y) - B * (c.x - b.x)); - if (Math.abs(G) > epsilon) { - open.push(new Triangle(a, b, c)); - } - } - } - - // Copy any remaining open triangles to the closed list, and then - // remove any triangles that share a vertex with the supertriangle. - Array.prototype.push.apply(closed, open); - - i = closed.length; - while (i--) { - if (closed[i].a.__sentinel || - closed[i].b.__sentinel || - closed[i].c.__sentinel) { - closed.splice(i, 1); - } - } - - return closed; -} diff --git a/packages/turf-tin/package.json b/packages/turf-tin/package.json deleted file mode 100644 index d0711e451c..0000000000 --- a/packages/turf-tin/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "@turf/tin", - "version": "6.0.2", - "description": "turf tin module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "tin", - "triangulate" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "typescript": "*", - "tape": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x" - } -} diff --git a/packages/turf-tin/tsconfig.json b/packages/turf-tin/tsconfig.json deleted file mode 100644 index 91cffcbf55..0000000000 --- a/packages/turf-tin/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - }, - "files": [ - "index.ts" - ] -} \ No newline at end of file diff --git a/packages/turf-tin/tslint.json b/packages/turf-tin/tslint.json deleted file mode 100644 index 9dd5998b9c..0000000000 --- a/packages/turf-tin/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {"interface-name": false}, - "rulesDirectory": [] -} \ No newline at end of file diff --git a/packages/turf-tin/types.ts b/packages/turf-tin/types.ts deleted file mode 100644 index 85f4144740..0000000000 --- a/packages/turf-tin/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -import {featureCollection, point} from "@turf/helpers"; -import tin from "./"; - -const points = featureCollection([ - point([0, 0], {elevation: 20}), - point([10, 10], {elevation: 10}), - point([30, 30], {elevation: 50}), -]); -tin(points); -tin(points, "elevation"); diff --git a/packages/turf-transform-rotate/LICENSE b/packages/turf-transform-rotate/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-transform-rotate/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-transform-rotate/README.md b/packages/turf-transform-rotate/README.md deleted file mode 100644 index 02c96d26c7..0000000000 --- a/packages/turf-transform-rotate/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# @turf/transform-rotate - - - -## transformRotate - -Rotates any geojson Feature or Geometry of a specified angle, around its `centroid` or a given `pivot` point; -all rotations follow the right-hand rule: [https://en.wikipedia.org/wiki/Right-hand_rule][1] - -**Parameters** - -- `geojson` **[GeoJSON][2]** object to be rotated -- `angle` **[number][3]** of rotation (along the vertical axis), from North in decimal degrees, negative clockwise -- `options` **[Object][4]** Optional parameters (optional, default `{}`) - - `options.pivot` **[Coord][5]** point around which the rotation will be performed (optional, default `'centroid'`) - - `options.mutate` **[boolean][6]** allows GeoJSON input to be mutated (significant performance increase if true) (optional, default `false`) - -**Examples** - -```javascript -var poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]); -var options = {pivot: [0, 25]}; -var rotatedPoly = turf.transformRotate(poly, 10, options); - -//addToMap -var addToMap = [poly, rotatedPoly]; -rotatedPoly.properties = {stroke: '#F00', 'stroke-width': 4}; -``` - -Returns **[GeoJSON][2]** the rotated GeoJSON feature - -[1]: https://en.wikipedia.org/wiki/Right-hand_rule - -[2]: https://tools.ietf.org/html/rfc7946#section-3 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/transform-rotate -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-transform-rotate/index.d.ts b/packages/turf-transform-rotate/index.d.ts deleted file mode 100644 index a43c7140e3..0000000000 --- a/packages/turf-transform-rotate/index.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { AllGeoJSON, Coord } from '@turf/helpers'; - -/** - * http://turfjs.org/docs/#transformrotate - */ -export default function transformRotate( - geojson: T, - angle: number, - options?: { - pivot?: Coord, - mutate?: boolean - } -): T; \ No newline at end of file diff --git a/packages/turf-transform-rotate/index.js b/packages/turf-transform-rotate/index.js deleted file mode 100644 index f476729ff8..0000000000 --- a/packages/turf-transform-rotate/index.js +++ /dev/null @@ -1,62 +0,0 @@ -import centroid from '@turf/centroid'; -import rhumbBearing from '@turf/rhumb-bearing'; -import rhumbDistance from '@turf/rhumb-distance'; -import rhumbDestination from '@turf/rhumb-destination'; -import clone from '@turf/clone'; -import { coordEach } from '@turf/meta'; -import { getCoords } from '@turf/invariant'; -import { isObject } from '@turf/helpers'; - -/** - * Rotates any geojson Feature or Geometry of a specified angle, around its `centroid` or a given `pivot` point; - * all rotations follow the right-hand rule: https://en.wikipedia.org/wiki/Right-hand_rule - * - * @name transformRotate - * @param {GeoJSON} geojson object to be rotated - * @param {number} angle of rotation (along the vertical axis), from North in decimal degrees, negative clockwise - * @param {Object} [options={}] Optional parameters - * @param {Coord} [options.pivot='centroid'] point around which the rotation will be performed - * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) - * @returns {GeoJSON} the rotated GeoJSON feature - * @example - * var poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]); - * var options = {pivot: [0, 25]}; - * var rotatedPoly = turf.transformRotate(poly, 10, options); - * - * //addToMap - * var addToMap = [poly, rotatedPoly]; - * rotatedPoly.properties = {stroke: '#F00', 'stroke-width': 4}; - */ -function transformRotate(geojson, angle, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var pivot = options.pivot; - var mutate = options.mutate; - - // Input validation - if (!geojson) throw new Error('geojson is required'); - if (angle === undefined || angle === null || isNaN(angle)) throw new Error('angle is required'); - - // Shortcut no-rotation - if (angle === 0) return geojson; - - // Use centroid of GeoJSON if pivot is not provided - if (!pivot) pivot = centroid(geojson); - - // Clone geojson to avoid side effects - if (mutate === false || mutate === undefined) geojson = clone(geojson); - - // Rotate each coordinate - coordEach(geojson, function (pointCoords) { - var initialAngle = rhumbBearing(pivot, pointCoords); - var finalAngle = initialAngle + angle; - var distance = rhumbDistance(pivot, pointCoords); - var newCoords = getCoords(rhumbDestination(pivot, distance, finalAngle)); - pointCoords[0] = newCoords[0]; - pointCoords[1] = newCoords[1]; - }); - return geojson; -} - -export default transformRotate; diff --git a/packages/turf-transform-rotate/package.json b/packages/turf-transform-rotate/package.json deleted file mode 100644 index 14c32b7e05..0000000000 --- a/packages/turf-transform-rotate/package.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "name": "@turf/transform-rotate", - "version": "5.1.5", - "description": "turf transform-rotate module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "transform", - "transformation", - "rotate" - ], - "author": "Turf Authors", - "contributors": [ - "Stefano Borghi <@stebogit>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/truncate": "6.x", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/centroid": "6.x", - "@turf/clone": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x", - "@turf/rhumb-bearing": "6.x", - "@turf/rhumb-destination": "6.x", - "@turf/rhumb-distance": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-transform-rotate/test.js b/packages/turf-transform-rotate/test.js deleted file mode 100644 index 8b3ee7e616..0000000000 --- a/packages/turf-transform-rotate/test.js +++ /dev/null @@ -1,92 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import centroid from '@turf/centroid'; -import truncate from '@turf/truncate'; -import { getCoord } from '@turf/invariant'; -import { point, lineString, featureCollection, geometryCollection } from '@turf/helpers'; -import rotate from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('rotate', t => { - for (const {filename, name, geojson} of fixtures) { - const {angle, pivot} = geojson.properties || {}; - - const rotated = rotate(geojson, angle, {pivot: pivot}); - const result = featureCollection([colorize(truncate(rotated, {precision: 6, coordinates: 3})), geojson, makePivot(pivot, geojson)]); - - if (process.env.REGEN) write.sync(directories.out + filename, result); - t.deepEqual(result, load.sync(directories.out + filename), name); - } - - t.end(); -}); - -test('rotate -- throws', t => { - const line = lineString([[10, 10], [12, 15]]); - - t.throws(() => rotate(null, 100), /geojson is required/, 'missing geojson'); - t.throws(() => rotate(line, null), /angle is required/, 'missing angle'); - t.throws(() => rotate(line, 56, {pivot: 'notApoint'}), /coord must be GeoJSON Point or an Array of numbers/, 'coord must be GeoJSON Point or an Array of numbers'); - t.end(); -}); - -test('rotate -- mutated input', t => { - const line = lineString([[10, 10], [12, 15]]); - const lineBefore = JSON.parse(JSON.stringify(line)); - - rotate(line, 100); - t.deepEqual(line, lineBefore, 'input should NOT be mutated'); - - rotate(line, 100, {mutate: true}); - t.deepEqual(truncate(line, {precision: 1}), lineString([[8.6, 13.9], [13.3, 11.1]]), 'input should be mutated'); - t.end(); -}); - -test('rotate -- geometry support', t => { - const line = lineString([[10, 10], [12, 15]]); - const pt = point([10, 10]); - - t.assert(rotate(geometryCollection([line.geometry]), 100), 'geometryCollection support'); - t.assert(rotate(geometryCollection([line.geometry]).geometry, 100), 'geometryCollection support'); - t.assert(rotate(featureCollection([line]), 100), 'featureCollection support'); - t.assert(rotate(line.geometry, 100), 'geometry line support'); - t.assert(rotate(line.geometry, 100, {pivot: pt.geometry}), 'geometry pt support'); - t.assert(rotate(line.geometry, 100, {pivot: pt.geometry.coordinates}), 'pt coordinate support'); - t.end(); -}); - -// style result -function colorize(geojson) { - if (geojson.geometry.type === 'Point' || geojson.geometry.type === 'MultiPoint') { - geojson.properties['marker-color'] = '#F00'; - geojson.properties['marker-symbol'] = 'star'; - } else { - geojson.properties['stroke'] = '#F00'; - geojson.properties['stroke-width'] = 4; - } - return geojson; -} - -function makePivot(pivot, geojson) { - if (!pivot) { - const pt = centroid(geojson); - pt.properties['marker-symbol'] = 'circle'; - return pt; - } - return point(getCoord(pivot), {'marker-symbol': 'circle'}); -} diff --git a/packages/turf-transform-rotate/test/out/multiPolygon.geojson b/packages/turf-transform-rotate/test/out/multiPolygon.geojson deleted file mode 100644 index 6a7d8514f2..0000000000 --- a/packages/turf-transform-rotate/test/out/multiPolygon.geojson +++ /dev/null @@ -1,866 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "angle": -35, - "stroke": "#F00", - "stroke-width": 4 - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - -80.485744, - -34.568555 - ], - [ - -80.468814, - -34.573008 - ], - [ - -80.462576, - -34.585535 - ], - [ - -80.408333, - -34.597235 - ], - [ - -80.390418, - -34.591926 - ], - [ - -80.384938, - -34.575763 - ], - [ - -80.40874, - -34.541641 - ], - [ - -80.453415, - -34.515559 - ], - [ - -80.478938, - -34.531328 - ], - [ - -80.485744, - -34.568555 - ] - ] - ], - [ - [ - [ - -78.974587, - -33.514343 - ], - [ - -78.976214, - -33.524372 - ], - [ - -78.958788, - -33.535155 - ], - [ - -78.960075, - -33.554059 - ], - [ - -78.967126, - -33.560616 - ], - [ - -78.972747, - -33.560404 - ], - [ - -78.977186, - -33.565087 - ], - [ - -78.978392, - -33.573121 - ], - [ - -78.977548, - -33.576119 - ], - [ - -78.981677, - -33.581668 - ], - [ - -78.982741, - -33.594852 - ], - [ - -78.976924, - -33.595298 - ], - [ - -78.977091, - -33.599583 - ], - [ - -78.980604, - -33.599887 - ], - [ - -78.983469, - -33.606442 - ], - [ - -78.973548, - -33.607286 - ], - [ - -78.96818, - -33.605203 - ], - [ - -78.973577, - -33.602768 - ], - [ - -78.975826, - -33.60059 - ], - [ - -78.974282, - -33.594455 - ], - [ - -78.967173, - -33.58996 - ], - [ - -78.969058, - -33.583731 - ], - [ - -78.973668, - -33.582232 - ], - [ - -78.970214, - -33.572888 - ], - [ - -78.959394, - -33.575302 - ], - [ - -78.958636, - -33.571719 - ], - [ - -78.961644, - -33.569634 - ], - [ - -78.959735, - -33.562936 - ], - [ - -78.948719, - -33.565586 - ], - [ - -78.945293, - -33.558701 - ], - [ - -78.944539, - -33.544647 - ], - [ - -78.93732, - -33.540784 - ], - [ - -78.919418, - -33.555124 - ], - [ - -78.895603, - -33.535643 - ], - [ - -78.846877, - -33.529896 - ], - [ - -78.840902, - -33.515587 - ], - [ - -78.853259, - -33.512326 - ], - [ - -78.859467, - -33.50792 - ], - [ - -78.87837, - -33.501844 - ], - [ - -78.897775, - -33.512122 - ], - [ - -78.898307, - -33.516972 - ], - [ - -78.911621, - -33.520551 - ], - [ - -78.917832, - -33.512654 - ], - [ - -78.941291, - -33.51063 - ], - [ - -78.945395, - -33.506738 - ], - [ - -78.961241, - -33.508302 - ], - [ - -78.974587, - -33.514343 - ] - ] - ], - [ - [ - [ - -78.973142, - -33.622837 - ], - [ - -78.972867, - -33.628519 - ], - [ - -78.969185, - -33.628291 - ], - [ - -78.968926, - -33.626483 - ], - [ - -78.9666, - -33.626261 - ], - [ - -78.966234, - -33.628315 - ], - [ - -78.967225, - -33.628631 - ], - [ - -78.966887, - -33.630527 - ], - [ - -78.961603, - -33.631458 - ], - [ - -78.961694, - -33.633342 - ], - [ - -78.953376, - -33.633898 - ], - [ - -78.950313, - -33.631938 - ], - [ - -78.94848, - -33.632002 - ], - [ - -78.948093, - -33.633957 - ], - [ - -78.947271, - -33.631821 - ], - [ - -78.948515, - -33.630715 - ], - [ - -78.945846, - -33.630902 - ], - [ - -78.946218, - -33.629463 - ], - [ - -78.943479, - -33.627865 - ], - [ - -78.937431, - -33.626344 - ], - [ - -78.936954, - -33.625543 - ], - [ - -78.938485, - -33.625215 - ], - [ - -78.940853, - -33.625636 - ], - [ - -78.943339, - -33.626912 - ], - [ - -78.944126, - -33.625975 - ], - [ - -78.946487, - -33.62491 - ], - [ - -78.948538, - -33.626455 - ], - [ - -78.951861, - -33.625864 - ], - [ - -78.952949, - -33.626935 - ], - [ - -78.955352, - -33.626068 - ], - [ - -78.957045, - -33.626794 - ], - [ - -78.95706, - -33.625407 - ], - [ - -78.958633, - -33.625278 - ], - [ - -78.958873, - -33.623499 - ], - [ - -78.963525, - -33.620456 - ], - [ - -78.964782, - -33.620579 - ], - [ - -78.965491, - -33.623347 - ], - [ - -78.969376, - -33.623955 - ], - [ - -78.970831, - -33.622972 - ], - [ - -78.970733, - -33.622217 - ], - [ - -78.972047, - -33.622024 - ], - [ - -78.972236, - -33.622919 - ], - [ - -78.973142, - -33.622837 - ] - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "angle": -35 - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - -80.83740234375, - -33.75146241858857 - ], - [ - -80.8267593383789, - -33.76316538009658 - ], - [ - -80.83036422729492, - -33.77643631739436 - ], - [ - -80.79448699951172, - -33.81181543283183 - ], - [ - -80.77629089355469, - -33.8159515518711 - ], - [ - -80.76066970825195, - -33.805254282102595 - ], - [ - -80.75637817382812, - -33.76587681391894 - ], - [ - -80.77457427978516, - -33.723197462817026 - ], - [ - -80.80615997314453, - -33.724054113439884 - ], - [ - -80.83740234375, - -33.75146241858857 - ] - ] - ], - [ - [ - [ - -78.87805938720703, - -33.60575555447342 - ], - [ - -78.88629913330078, - -33.61318971884082 - ], - [ - -78.87943267822264, - -33.63034303571294 - ], - [ - -78.89350891113281, - -33.64520648119226 - ], - [ - -78.90380859375, - -33.64720713369291 - ], - [ - -78.90827178955078, - -33.64434904445886 - ], - [ - -78.9151382446289, - -33.64606390938584 - ], - [ - -78.92166137695312, - -33.65206566761678 - ], - [ - -78.92303466796875, - -33.65492350063952 - ], - [ - -78.93024444580078, - -33.65749546922024 - ], - [ - -78.94020080566406, - -33.66778257479216 - ], - [ - -78.93573760986328, - -33.67092561169521 - ], - [ - -78.93882751464844, - -33.674354248232504 - ], - [ - -78.94191741943358, - -33.67292566628718 - ], - [ - -78.94878387451172, - -33.67692563592954 - ], - [ - -78.94123077392578, - -33.682353868548184 - ], - [ - -78.93539428710938, - -33.68321092658006 - ], - [ - -78.93814086914062, - -33.678639851675534 - ], - [ - -78.93848419189453, - -33.675782806445994 - ], - [ - -78.93299102783203, - -33.671497060610534 - ], - [ - -78.92406463623047, - -33.671211336627486 - ], - [ - -78.92131805419922, - -33.6652109137176 - ], - [ - -78.92406463623047, - -33.66178191269289 - ], - [ - -78.914794921875, - -33.65578083204094 - ], - [ - -78.90758514404297, - -33.662924928220384 - ], - [ - -78.90449523925781, - -33.660353121928814 - ], - [ - -78.90552520751953, - -33.657209698729595 - ], - [ - -78.89934539794922, - -33.652637241813174 - ], - [ - -78.89213562011719, - -33.66006736092875 - ], - [ - -78.88458251953125, - -33.65606660727672 - ], - [ - -78.87428283691406, - -33.644920669896656 - ], - [ - -78.8656997680664, - -33.64520648119226 - ], - [ - -78.86089324951172, - -33.66549665763364 - ], - [ - -78.82793426513672, - -33.66092464108171 - ], - [ - -78.78398895263672, - -33.6794969467326 - ], - [ - -78.76922607421875, - -33.670639885813706 - ], - [ - -78.7771224975586, - -33.662067667998414 - ], - [ - -78.77918243408203, - -33.655495055856136 - ], - [ - -78.79051208496094, - -33.641490860339054 - ], - [ - -78.81351470947266, - -33.64063338660099 - ], - [ - -78.81729125976561, - -33.64434904445886 - ], - [ - -78.83068084716797, - -33.640919212129155 - ], - [ - -78.83033752441406, - -33.63148646875166 - ], - [ - -78.84819030761717, - -33.618621971969276 - ], - [ - -78.848876953125, - -33.61347563543629 - ], - [ - -78.86295318603516, - -33.6071852512562 - ], - [ - -78.87805938720703, - -33.60575555447342 - ] - ] - ], - [ - [ - [ - -78.95161628723145, - -33.69528025294664 - ], - [ - -78.95530700683594, - -33.70006466462807 - ], - [ - -78.9521312713623, - -33.70163560737423 - ], - [ - -78.9506721496582, - -33.700278885784996 - ], - [ - -78.94861221313477, - -33.701207171292374 - ], - [ - -78.94972801208496, - -33.70306371221516 - ], - [ - -78.95075798034668, - -33.70284949800254 - ], - [ - -78.95178794860838, - -33.7045631967461 - ], - [ - -78.9480972290039, - -33.70784769044128 - ], - [ - -78.94947052001952, - -33.70934709145684 - ], - [ - -78.94303321838379, - -33.71377374172037 - ], - [ - -78.93917083740234, - -33.71363095011231 - ], - [ - -78.93771171569824, - -33.71455909132016 - ], - [ - -78.93874168395996, - -33.7163439500602 - ], - [ - -78.93659591674805, - -33.714987460801574 - ], - [ - -78.93685340881348, - -33.7134881582668 - ], - [ - -78.93479347229004, - -33.714916066036416 - ], - [ - -78.93410682678223, - -33.71355955421924 - ], - [ - -78.93075942993164, - -33.71355955421924 - ], - [ - -78.92475128173828, - -33.715201644740844 - ], - [ - -78.92380714416502, - -33.714773276327996 - ], - [ - -78.92483711242676, - -33.71377374172037 - ], - [ - -78.92706871032715, - -33.712988384937574 - ], - [ - -78.92998695373535, - -33.712845592023534 - ], - [ - -78.92998695373535, - -33.71170324016297 - ], - [ - -78.93118858337402, - -33.70970408784028 - ], - [ - -78.93393516540527, - -33.70998968387856 - ], - [ - -78.93625259399414, - -33.70791909108323 - ], - [ - -78.9378833770752, - -33.708276093402596 - ], - [ - -78.93925666809082, - -33.7064196651371 - ], - [ - -78.9411449432373, - -33.706205459293635 - ], - [ - -78.94020080566406, - -33.70506301910626 - ], - [ - -78.94140243530273, - -33.704206178993886 - ], - [ - -78.94037246704102, - -33.70263528325574 - ], - [ - -78.94208908081055, - -33.69792242367998 - ], - [ - -78.94320487976074, - -33.69742255977288 - ], - [ - -78.94569396972656, - -33.699350590247136 - ], - [ - -78.94929885864258, - -33.69799383257217 - ], - [ - -78.94981384277342, - -33.69649423337286 - ], - [ - -78.9492130279541, - -33.695922950602935 - ], - [ - -78.95015716552734, - -33.69513743059241 - ], - [ - -78.95092964172363, - -33.69578012931697 - ], - [ - -78.95161628723145, - -33.69528025294664 - ] - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-symbol": "circle" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -79.10042352676392, - -33.68739048445928 - ] - } - } - ] -} diff --git a/packages/turf-transform-rotate/test/out/polygon-fiji.geojson b/packages/turf-transform-rotate/test/out/polygon-fiji.geojson deleted file mode 100644 index ee082af405..0000000000 --- a/packages/turf-transform-rotate/test/out/polygon-fiji.geojson +++ /dev/null @@ -1,218 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "angle": 90, - "stroke": "#F00", - "stroke-width": 4 - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - -180.440951, - -17.397697 - ], - [ - -180.319886, - -17.371599 - ], - [ - -180.248336, - -17.308562 - ], - [ - -180.314428, - -17.050603 - ], - [ - -180.622066, - -16.882061 - ], - [ - -180.748301, - -16.91354 - ], - [ - -180.699094, - -17.108087 - ], - [ - -180.440951, - -17.397697 - ] - ] - ], - [ - [ - [ - -180.17692, - -16.982292 - ], - [ - -179.74131, - -17.246094 - ], - [ - -179.681132, - -16.956292 - ], - [ - -179.726242, - -16.366019 - ], - [ - -180.194097, - -15.482049 - ], - [ - -180.517204, - -15.451473 - ], - [ - -180.757965, - -15.609927 - ], - [ - -180.758227, - -15.878007 - ], - [ - -180.643486, - -16.135412 - ], - [ - -180.599864, - -16.477159 - ], - [ - -180.550688, - -16.861058 - ], - [ - -180.17692, - -16.982292 - ] - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "angle": 90 - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - -179.6319580078125, - -16.762467717941593 - ], - [ - -179.659423828125, - -16.64671805097192 - ], - [ - -179.725341796875, - -16.578287608637478 - ], - [ - -179.99450683593747, - -16.641455036937753 - ], - [ - -180.1702880859375, - -16.935960102864705 - ], - [ - -180.1373291015625, - -17.056784609942543 - ], - [ - -179.93408203125, - -17.00951473208515 - ], - [ - -179.6319580078125, - -16.762467717941593 - ] - ] - ], - [ - [ - [ - -180.06591796875, - -16.509832826905836 - ], - [ - -179.79125976562497, - -16.093320185359257 - ], - [ - -180.0933837890625, - -16.0352548623504 - ], - [ - -180.7086181640625, - -16.0774858690887 - ], - [ - -181.63146972656247, - -16.525632239869275 - ], - [ - -181.6644287109375, - -16.836089974560213 - ], - [ - -181.4996337890625, - -17.06728740376787 - ], - [ - -181.219482421875, - -17.06728740376787 - ], - [ - -180.9503173828125, - -16.956978651248072 - ], - [ - -180.59326171875, - -16.914939206301646 - ], - [ - -180.1922607421875, - -16.867633616803836 - ], - [ - -180.06591796875, - -16.509832826905836 - ] - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-symbol": "circle" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -180.3680419921875, - -16.69276153221258 - ] - } - } - ] -} diff --git a/packages/turf-transform-rotate/test/out/polygon-resolute-bay.geojson b/packages/turf-transform-rotate/test/out/polygon-resolute-bay.geojson deleted file mode 100644 index 3d779539c3..0000000000 --- a/packages/turf-transform-rotate/test/out/polygon-resolute-bay.geojson +++ /dev/null @@ -1,234 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "angle": 45, - "stroke": "#F00", - "stroke-width": 4 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -93.830967, - 75.544684 - ], - [ - -94.948132, - 75.570652 - ], - [ - -96.031894, - 75.466838 - ], - [ - -96.482649, - 75.406146 - ], - [ - -96.461399, - 75.07792 - ], - [ - -96.252453, - 74.830912 - ], - [ - -95.944334, - 74.690772 - ], - [ - -95.249128, - 74.568077 - ], - [ - -94.660845, - 74.704565 - ], - [ - -94.251936, - 74.840942 - ], - [ - -93.552488, - 75.039784 - ], - [ - -93.373316, - 75.302095 - ], - [ - -93.325832, - 75.415353 - ], - [ - -93.508515, - 75.501265 - ], - [ - -93.830967, - 75.544684 - ] - ], - [ - [ - -94.372833, - 75.385527 - ], - [ - -95.24463, - 75.364941 - ], - [ - -95.816091, - 75.202451 - ], - [ - -95.590034, - 74.906165 - ], - [ - -95.156706, - 74.790553 - ], - [ - -94.220115, - 75.031293 - ], - [ - -94.091459, - 75.270188 - ], - [ - -94.372833, - 75.385527 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "angle": 45 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -95.174560546875, - 75.60953172351893 - ], - [ - -96.03149414062499, - 75.4282153667069 - ], - [ - -96.492919921875, - 75.16048677152294 - ], - [ - -96.6357421875, - 75.03617629075062 - ], - [ - -95.723876953125, - 74.80466599405533 - ], - [ - -94.910888671875, - 74.66582807452669 - ], - [ - -94.317626953125, - 74.62218784846145 - ], - [ - -93.49365234375, - 74.66292249033842 - ], - [ - -93.438720703125, - 74.86788912917916 - ], - [ - -93.515625, - 75.03901279805076 - ], - [ - -93.55957031249999, - 75.3060980061604 - ], - [ - -94.163818359375, - 75.52189820596192 - ], - [ - -94.449462890625, - 75.60953172351893 - ], - [ - -94.82299804687499, - 75.63681056594325 - ], - [ - -95.174560546875, - 75.60953172351893 - ] - ], - [ - [ - -95.108642578125, - 75.40054889588245 - ], - [ - -95.6634521484375, - 75.22926698530169 - ], - [ - -95.614013671875, - 75.01062406678055 - ], - [ - -94.647216796875, - 74.84061980605131 - ], - [ - -94.0264892578125, - 74.83774656082585 - ], - [ - -94.0155029296875, - 75.17876503868581 - ], - [ - -94.5867919921875, - 75.3700564253908 - ], - [ - -95.108642578125, - 75.40054889588245 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-symbol": "circle" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -94.81201171875, - 75.16734623421806 - ] - } - } - ] -} diff --git a/packages/turf-transform-rotate/types.ts b/packages/turf-transform-rotate/types.ts deleted file mode 100644 index 9610ef7ee0..0000000000 --- a/packages/turf-transform-rotate/types.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { polygon, point, Point, featureCollection, geometryCollection, Feature, Polygon, FeatureCollection } from '@turf/helpers'; -import rotate from './' - -const pt = point([15, 15]); -const poly = polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]); - -// Does not mutate Geometry type -const rotatedPoly: Feature = rotate(poly, 100, {pivot: pt}); -const rotatedFCPoly: FeatureCollection = rotate(featureCollection([poly]), 100, {pivot: pt}); - -// Different Geometry Inputs -rotate(poly, 100, {pivot: pt}); -rotate(poly, 100, {pivot: pt.geometry}); -rotate(poly.geometry, 100, {pivot: pt.geometry.coordinates}); -rotate(featureCollection([poly]), 100, {pivot: pt.geometry}); -rotate(featureCollection([poly, pt]), 100, {pivot: pt}); -rotate(geometryCollection([poly.geometry]).geometry, 100, {pivot: pt.geometry}); -rotate(geometryCollection([poly.geometry]), 100, {pivot: pt.geometry}); -rotate(geometryCollection([poly.geometry, pt.geometry]), 100, {pivot: pt}); - -// Allow mutating -rotate(poly, 100, {pivot: pt, mutate: true}); \ No newline at end of file diff --git a/packages/turf-transform-scale/LICENSE b/packages/turf-transform-scale/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-transform-scale/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-transform-scale/README.md b/packages/turf-transform-scale/README.md deleted file mode 100644 index aeee01aaa4..0000000000 --- a/packages/turf-transform-scale/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# @turf/transform-scale - - - -## transformScale - -Scale a GeoJSON from a given point by a factor of scaling (ex: factor=2 would make the GeoJSON 200% larger). -If a FeatureCollection is provided, the origin point will be calculated based on each individual Feature. - -**Parameters** - -- `geojson` **[GeoJSON][1]** GeoJSON to be scaled -- `factor` **[number][2]** of scaling, positive or negative values greater than 0 -- `options` **[Object][3]** Optional parameters (optional, default `{}`) - - `options.origin` **([string][4] \| [Coord][5])** Point from which the scaling will occur (string options: sw/se/nw/ne/center/centroid) (optional, default `'centroid'`) - - `options.mutate` **[boolean][6]** allows GeoJSON input to be mutated (significant performance increase if true) (optional, default `false`) - -**Examples** - -```javascript -var poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]); -var scaledPoly = turf.transformScale(poly, 3); - -//addToMap -var addToMap = [poly, scaledPoly]; -scaledPoly.properties = {stroke: '#F00', 'stroke-width': 4}; -``` - -Returns **[GeoJSON][1]** scaled GeoJSON - -[1]: https://tools.ietf.org/html/rfc7946#section-3 - -[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.1 - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/transform-scale -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-transform-scale/index.d.ts b/packages/turf-transform-scale/index.d.ts deleted file mode 100644 index aaffdde4aa..0000000000 --- a/packages/turf-transform-scale/index.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Corners, Coord, AllGeoJSON } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#transformscale - */ -export default function transformScale( - geojson: T, - factor: number, - options?: { - origin?: Corners | Coord, - mutate?: boolean - } -): T; diff --git a/packages/turf-transform-scale/index.js b/packages/turf-transform-scale/index.js deleted file mode 100644 index 7cf5609edd..0000000000 --- a/packages/turf-transform-scale/index.js +++ /dev/null @@ -1,142 +0,0 @@ -import clone from '@turf/clone'; -import center from '@turf/center'; -import centroid from '@turf/centroid'; -import turfBBox from '@turf/bbox'; -import rhumbBearing from '@turf/rhumb-bearing'; -import rhumbDistance from '@turf/rhumb-distance'; -import rhumbDestination from '@turf/rhumb-destination'; -import { coordEach, featureEach } from '@turf/meta'; -import { point, isObject } from '@turf/helpers'; -import { getCoord, getCoords, getType} from '@turf/invariant'; - -/** - * Scale a GeoJSON from a given point by a factor of scaling (ex: factor=2 would make the GeoJSON 200% larger). - * If a FeatureCollection is provided, the origin point will be calculated based on each individual Feature. - * - * @name transformScale - * @param {GeoJSON} geojson GeoJSON to be scaled - * @param {number} factor of scaling, positive or negative values greater than 0 - * @param {Object} [options={}] Optional parameters - * @param {string|Coord} [options.origin='centroid'] Point from which the scaling will occur (string options: sw/se/nw/ne/center/centroid) - * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) - * @returns {GeoJSON} scaled GeoJSON - * @example - * var poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]); - * var scaledPoly = turf.transformScale(poly, 3); - * - * //addToMap - * var addToMap = [poly, scaledPoly]; - * scaledPoly.properties = {stroke: '#F00', 'stroke-width': 4}; - */ -function transformScale(geojson, factor, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var origin = options.origin; - var mutate = options.mutate; - - // Input validation - if (!geojson) throw new Error('geojson required'); - if (typeof factor !== 'number' || factor === 0) throw new Error('invalid factor'); - var originIsPoint = Array.isArray(origin) || typeof origin === 'object'; - - // Clone geojson to avoid side effects - if (mutate !== true) geojson = clone(geojson); - - // Scale each Feature separately - if (geojson.type === 'FeatureCollection' && !originIsPoint) { - featureEach(geojson, function (feature, index) { - geojson.features[index] = scale(feature, factor, origin); - }); - return geojson; - } - // Scale Feature/Geometry - return scale(geojson, factor, origin); -} - -/** - * Scale Feature/Geometry - * - * @private - * @param {Feature|Geometry} feature GeoJSON Feature/Geometry - * @param {number} factor of scaling, positive or negative values greater than 0 - * @param {string|Coord} [origin="centroid"] Point from which the scaling will occur (string options: sw/se/nw/ne/center/centroid) - * @returns {Feature|Geometry} scaled GeoJSON Feature/Geometry - */ -function scale(feature, factor, origin) { - // Default params - var isPoint = getType(feature) === 'Point'; - origin = defineOrigin(feature, origin); - - // Shortcut no-scaling - if (factor === 1 || isPoint) return feature; - - // Scale each coordinate - coordEach(feature, function (coord) { - var originalDistance = rhumbDistance(origin, coord); - var bearing = rhumbBearing(origin, coord); - var newDistance = originalDistance * factor; - var newCoord = getCoords(rhumbDestination(origin, newDistance, bearing)); - coord[0] = newCoord[0]; - coord[1] = newCoord[1]; - if (coord.length === 3) coord[2] *= factor; - }); - - return feature; -} - -/** - * Define Origin - * - * @private - * @param {GeoJSON} geojson GeoJSON - * @param {string|Coord} origin sw/se/nw/ne/center/centroid - * @returns {Feature} Point origin - */ -function defineOrigin(geojson, origin) { - // Default params - if (origin === undefined || origin === null) origin = 'centroid'; - - // Input Coord - if (Array.isArray(origin) || typeof origin === 'object') return getCoord(origin); - - // Define BBox - var bbox = (geojson.bbox) ? geojson.bbox : turfBBox(geojson); - var west = bbox[0]; - var south = bbox[1]; - var east = bbox[2]; - var north = bbox[3]; - - switch (origin) { - case 'sw': - case 'southwest': - case 'westsouth': - case 'bottomleft': - return point([west, south]); - case 'se': - case 'southeast': - case 'eastsouth': - case 'bottomright': - return point([east, south]); - case 'nw': - case 'northwest': - case 'westnorth': - case 'topleft': - return point([west, north]); - case 'ne': - case 'northeast': - case 'eastnorth': - case 'topright': - return point([east, north]); - case 'center': - return center(geojson); - case undefined: - case null: - case 'centroid': - return centroid(geojson); - default: - throw new Error('invalid origin'); - } -} - -export default transformScale; diff --git a/packages/turf-transform-scale/package.json b/packages/turf-transform-scale/package.json deleted file mode 100644 index d8242e6de8..0000000000 --- a/packages/turf-transform-scale/package.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "name": "@turf/transform-scale", - "version": "5.1.5", - "description": "turf transform-scale module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "transform", - "transformation", - "scale", - "enlarge", - "contract", - "zoom-in", - "zoom-out" - ], - "author": "Turf Authors", - "contributors": [ - "Stefano Borghi <@stebogit>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/bbox-polygon": "6.x", - "@turf/hex-grid": "^5.1.5", - "@turf/truncate": "6.x", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/bbox": "6.x", - "@turf/center": "6.x", - "@turf/centroid": "6.x", - "@turf/clone": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x", - "@turf/rhumb-bearing": "6.x", - "@turf/rhumb-destination": "6.x", - "@turf/rhumb-distance": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-transform-scale/test.js b/packages/turf-transform-scale/test.js deleted file mode 100644 index 6fc03675fc..0000000000 --- a/packages/turf-transform-scale/test.js +++ /dev/null @@ -1,211 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import center from '@turf/center'; -import hexGrid from '@turf/hex-grid'; -import truncate from '@turf/truncate'; -import turfBBox from '@turf/bbox'; -import bboxPolygon from '@turf/bbox-polygon'; -import centroid from '@turf/centroid'; -import { featureEach } from '@turf/meta'; -import { getCoord } from '@turf/invariant'; -import { point, lineString, geometryCollection, featureCollection } from '@turf/helpers'; -import scale from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('scale', t => { - for (const {filename, name, geojson} of fixtures) { - let {factor, origin, mutate} = geojson.properties || {}; - factor = factor || 2; - - const scaled = scale(geojson, factor, { - origin: origin, - mutate: mutate - }); - const result = featureCollection([]); - featureEach(colorize(truncate(scaled, {precision: 6, coordinates: 3})), feature => result.features.push(feature)); - featureEach(geojson, feature => result.features.push(feature)); - featureEach(geojson, feature => result.features.push(markedOrigin(feature, origin))); - - if (process.env.REGEN) write.sync(directories.out + filename, result); - t.deepEqual(result, load.sync(directories.out + filename), name); - } - - t.end(); -}); - -test('scale -- throws', t => { - const line = lineString([[10, 10], [12, 15]]); - - t.throws(() => scale(null, 1.5), /geojson required/); - t.throws(() => scale(line, null), /invalid factor/); - t.throws(() => scale(line, 0), /invalid factor/); - t.throws(() => scale(line, 1.5, {origin: 'foobar'}), /invalid origin/); - t.throws(() => scale(line, 1.5, {origin: 2}), /invalid origin/); - - t.end(); -}); - -test('scale -- additional params', t => { - const line = lineString([[10, 10], [12, 15]]); - const bbox = [-180, -90, 180, 90]; - - t.assert(scale(line, 1.5, {origin: 'sw'})); - t.assert(scale(line, 1.5, {origin: 'se'})); - t.assert(scale(line, 1.5, {origin: 'nw'})); - t.assert(scale(line, 1.5, {origin: 'ne'})); - t.assert(scale(line, 1.5, {origin: 'center'})); - t.assert(scale(line, 1.5, {origin: 'centroid'})); - t.assert(scale(line, 1.5, {origin: null})); - line.bbox = bbox; - t.assert(scale(line, 1.5)); - t.end(); -}); - -test('scale -- bbox provided', t => { - const line = lineString([[10, 10], [12, 15]]); - line.bbox = [-180, -90, 180, 90]; - - t.assert(scale(line, 1.5)); - t.end(); -}); - -test('scale -- mutated input', t => { - const line = lineString([[10, 10], [12, 15]]); - const lineBefore = JSON.parse(JSON.stringify(line)); - - scale(line, 1.5); - t.deepEqual(line, lineBefore, 'mutate = undefined - input should NOT be mutated'); - scale(line, 1.5, {origin: 'centroid', mutate: false}); - t.deepEqual(line, lineBefore, 'mutate = false - input should NOT be mutated'); - scale(line, 1.5, {orgin: 'centroid', muate: 'nonBoolean'}); - t.deepEqual(line, lineBefore, 'non-boolean mutate - input should NOT be mutated'); - - scale(line, 1.5, {origin: 'centroid', mutate: true}); - t.deepEqual(truncate(line, {precision: 1}), lineString([[9.5, 8.8], [12.5, 16.2]]), 'mutate = true - input should be mutated'); - t.end(); -}); - -test('scale -- mutated FeatureCollection', t => { - const line = featureCollection([ - lineString([[10, 10], [12, 15]]), - lineString([[15, 15], [22, 35]]), - lineString([[30, 30], [42, 45]]) - ]); - const lineBefore = JSON.parse(JSON.stringify(line)); - scale(line, 1.5); - t.deepEqual(line, lineBefore, 'mutate = undefined - input should NOT be mutated'); - scale(line, 1.5, {origin: 'centroid', mutate: false}); - t.deepEqual(line, lineBefore, 'mutate = false - input should NOT be mutated'); - scale(line, 1.5, {origin: 'centroid', mutate: 'nonBoolean'}); - t.deepEqual(line, lineBefore, 'non-boolean mutate - input should NOT be mutated'); - t.end(); -}); - -test('scale -- Issue #895', t => { - const bbox = [-122.930, 45.385, -122.294, 45.772]; - const grid = hexGrid(bbox, 2, {units: 'miles'}); - featureEach(grid, (feature, index) => { - const factor = (index % 2 === 0) ? 0.4 : 0.6; - scale(feature, factor, {origin: 'centroid', mutate: true}); - }); - // Add styled GeoJSON to the result - const poly = bboxPolygon(bbox); - poly.properties = { - stroke: '#F00', - 'stroke-width': 6, - 'fill-opacity': 0 - }; - grid.features.push(poly); - const output = directories.out + 'issue-#895.geojson'; - if (process.env.REGEN) write.sync(output, grid); - t.deepEqual(grid, load.sync(output)); - t.end(); -}); - -test('scale -- geometry support', t => { - const pt = point([10, 10]); - const line = lineString([[10, 10], [12, 15]]); - - t.assert(scale(geometryCollection([line.geometry]), 1.5), 'geometryCollection support'); - t.assert(scale(geometryCollection([line.geometry]).geometry, 1.5), 'geometryCollection support'); - t.assert(scale(featureCollection([line]), 1.50), 'featureCollection support'); - t.assert(scale(line.geometry, 1.5), 'geometry line support'); - t.assert(scale(pt.geometry, 1.5), 'geometry point support'); - t.assert(scale(pt, 1.5), 'geometry point support'); - t.assert(scale(pt, 1.5, { origin: pt }), 'feature point support'); - t.assert(scale(pt, 1.5, { origin: pt.geometry }), 'geometry point support'); - t.assert(scale(pt, 1.5, { origin: pt.geometry.coordinates }), 'coordinate point support'); - - t.end(); -}); - -// style result -function colorize(geojson) { - featureEach(geojson, (feature, index) => { - if (feature.geometry.type === 'Point' || feature.geometry.type === 'MultiPoint') { - feature.properties['marker-color'] = '#F00'; - feature.properties['marker-symbol'] = 'star'; - } else { - feature.properties['stroke'] = '#F00'; - feature.properties['stroke-width'] = 4; - } - if (geojson.type === 'Feature') return feature; - geojson.features[index] = feature; - }); - return geojson; -} - -// define origin, as defined in transform-scale, and style it -function markedOrigin(geojson, origin, properties = {'marker-color': '#00F', 'marker-symbol': 'circle'}) { - // Input Geometry|Feature|Array - if (Array.isArray(origin) || typeof origin === 'object') return point(getCoord(origin), properties); - - // Define BBox - const [west, south, east, north] = (geojson.bbox) ? geojson.bbox : turfBBox(geojson); - - switch (origin) { - case 'sw': - case 'southwest': - case 'westsouth': - case 'bottomleft': - return point([west, south], properties); - case 'se': - case 'southeast': - case 'eastsouth': - case 'bottomright': - return point([east, south], properties); - case 'nw': - case 'northwest': - case 'westnorth': - case 'topleft': - return point([west, north], properties); - case 'ne': - case 'northeast': - case 'eastnorth': - case 'topright': - return point([east, north], properties); - case 'center': - var cr = center(geojson); - cr.properties = properties; - return cr; - default: - var cid = centroid(geojson); - cid.properties = properties; - return cid; - } -} diff --git a/packages/turf-transform-scale/test/out/feature-collection-polygon.geojson b/packages/turf-transform-scale/test/out/feature-collection-polygon.geojson deleted file mode 100644 index d956d9f0a5..0000000000 --- a/packages/turf-transform-scale/test/out/feature-collection-polygon.geojson +++ /dev/null @@ -1,909 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "fill": "#0F0", - "factor": 0.8, - "origin": "center", - "stroke": "#F00", - "stroke-width": 4 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -80.874748, - -33.734057 - ], - [ - -80.853468, - -33.757463 - ], - [ - -80.860682, - -33.784005 - ], - [ - -80.788922, - -33.854763 - ], - [ - -80.75252, - -33.863035 - ], - [ - -80.721274, - -33.841641 - ], - [ - -80.712709, - -33.762886 - ], - [ - -80.749113, - -33.677527 - ], - [ - -80.812268, - -33.679241 - ], - [ - -80.874748, - -33.734057 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "fill": "#00F", - "factor": 0.8, - "origin": "center", - "stroke": "#F00", - "stroke-width": 4 - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - -78.844571, - -33.533174 - ], - [ - -78.861041, - -33.548042 - ], - [ - -78.847307, - -33.582349 - ], - [ - -78.875449, - -33.612075 - ], - [ - -78.896044, - -33.616077 - ], - [ - -78.904969, - -33.610361 - ], - [ - -78.918699, - -33.61379 - ], - [ - -78.931743, - -33.625794 - ], - [ - -78.93449, - -33.63151 - ], - [ - -78.948908, - -33.636653 - ], - [ - -78.968822, - -33.657228 - ], - [ - -78.959897, - -33.663514 - ], - [ - -78.966077, - -33.670371 - ], - [ - -78.972257, - -33.667514 - ], - [ - -78.985991, - -33.675514 - ], - [ - -78.970887, - -33.68637 - ], - [ - -78.959214, - -33.688084 - ], - [ - -78.964706, - -33.678942 - ], - [ - -78.965391, - -33.673228 - ], - [ - -78.954404, - -33.664657 - ], - [ - -78.936552, - -33.664085 - ], - [ - -78.931058, - -33.652084 - ], - [ - -78.936551, - -33.645226 - ], - [ - -78.918013, - -33.633224 - ], - [ - -78.903595, - -33.647512 - ], - [ - -78.897416, - -33.642369 - ], - [ - -78.899476, - -33.636082 - ], - [ - -78.887118, - -33.626937 - ], - [ - -78.872699, - -33.641797 - ], - [ - -78.857596, - -33.633796 - ], - [ - -78.837004, - -33.611504 - ], - [ - -78.819841, - -33.612075 - ], - [ - -78.810218, - -33.652656 - ], - [ - -78.744309, - -33.643512 - ], - [ - -78.6564, - -33.680656 - ], - [ - -78.626889, - -33.662942 - ], - [ - -78.642694, - -33.645798 - ], - [ - -78.646824, - -33.632653 - ], - [ - -78.6695, - -33.604644 - ], - [ - -78.715496, - -33.602929 - ], - [ - -78.723043, - -33.610361 - ], - [ - -78.749821, - -33.603501 - ], - [ - -78.749143, - -33.584635 - ], - [ - -78.784848, - -33.558906 - ], - [ - -78.786225, - -33.548614 - ], - [ - -78.81437, - -33.536033 - ], - [ - -78.844571, - -33.533174 - ] - ] - ], - [ - [ - [ - -78.991664, - -33.712223 - ], - [ - -78.999049, - -33.721792 - ], - [ - -78.992697, - -33.724934 - ], - [ - -78.989778, - -33.72222 - ], - [ - -78.985658, - -33.724077 - ], - [ - -78.987891, - -33.72779 - ], - [ - -78.989951, - -33.727362 - ], - [ - -78.992012, - -33.730789 - ], - [ - -78.984631, - -33.737358 - ], - [ - -78.987378, - -33.740357 - ], - [ - -78.974503, - -33.74921 - ], - [ - -78.966777, - -33.748924 - ], - [ - -78.963858, - -33.750781 - ], - [ - -78.965919, - -33.75435 - ], - [ - -78.961626, - -33.751637 - ], - [ - -78.962141, - -33.748639 - ], - [ - -78.958021, - -33.751495 - ], - [ - -78.956647, - -33.748782 - ], - [ - -78.94995, - -33.748782 - ], - [ - -78.937932, - -33.752066 - ], - [ - -78.936043, - -33.751209 - ], - [ - -78.938103, - -33.74921 - ], - [ - -78.942567, - -33.747639 - ], - [ - -78.948405, - -33.747354 - ], - [ - -78.948405, - -33.745069 - ], - [ - -78.950808, - -33.741071 - ], - [ - -78.956302, - -33.741642 - ], - [ - -78.960937, - -33.737501 - ], - [ - -78.9642, - -33.738215 - ], - [ - -78.966946, - -33.734502 - ], - [ - -78.970723, - -33.734073 - ], - [ - -78.968834, - -33.731789 - ], - [ - -78.971238, - -33.730075 - ], - [ - -78.969177, - -33.726933 - ], - [ - -78.972609, - -33.717507 - ], - [ - -78.974841, - -33.716508 - ], - [ - -78.97982, - -33.720364 - ], - [ - -78.98703, - -33.71765 - ], - [ - -78.988059, - -33.714651 - ], - [ - -78.986857, - -33.713508 - ], - [ - -78.988746, - -33.711937 - ], - [ - -78.990291, - -33.713223 - ], - [ - -78.991664, - -33.712223 - ] - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "fill": "#0F0", - "factor": 0.8, - "origin": "center" - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -80.83740234375, - -33.75146241858857 - ], - [ - -80.8267593383789, - -33.76316538009658 - ], - [ - -80.83036422729492, - -33.77643631739436 - ], - [ - -80.79448699951172, - -33.81181543283183 - ], - [ - -80.77629089355469, - -33.8159515518711 - ], - [ - -80.76066970825195, - -33.805254282102595 - ], - [ - -80.75637817382812, - -33.76587681391894 - ], - [ - -80.77457427978516, - -33.723197462817026 - ], - [ - -80.80615997314453, - -33.724054113439884 - ], - [ - -80.83740234375, - -33.75146241858857 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "fill": "#00F", - "factor": 0.8, - "origin": "center" - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - -78.87805938720703, - -33.60575555447342 - ], - [ - -78.88629913330078, - -33.61318971884082 - ], - [ - -78.87943267822264, - -33.63034303571294 - ], - [ - -78.89350891113281, - -33.64520648119226 - ], - [ - -78.90380859375, - -33.64720713369291 - ], - [ - -78.90827178955078, - -33.64434904445886 - ], - [ - -78.9151382446289, - -33.64606390938584 - ], - [ - -78.92166137695312, - -33.65206566761678 - ], - [ - -78.92303466796875, - -33.65492350063952 - ], - [ - -78.93024444580078, - -33.65749546922024 - ], - [ - -78.94020080566406, - -33.66778257479216 - ], - [ - -78.93573760986328, - -33.67092561169521 - ], - [ - -78.93882751464844, - -33.674354248232504 - ], - [ - -78.94191741943358, - -33.67292566628718 - ], - [ - -78.94878387451172, - -33.67692563592954 - ], - [ - -78.94123077392578, - -33.682353868548184 - ], - [ - -78.93539428710938, - -33.68321092658006 - ], - [ - -78.93814086914062, - -33.678639851675534 - ], - [ - -78.93848419189453, - -33.675782806445994 - ], - [ - -78.93299102783203, - -33.671497060610534 - ], - [ - -78.92406463623047, - -33.671211336627486 - ], - [ - -78.92131805419922, - -33.6652109137176 - ], - [ - -78.92406463623047, - -33.66178191269289 - ], - [ - -78.914794921875, - -33.65578083204094 - ], - [ - -78.90758514404297, - -33.662924928220384 - ], - [ - -78.90449523925781, - -33.660353121928814 - ], - [ - -78.90552520751953, - -33.657209698729595 - ], - [ - -78.89934539794922, - -33.652637241813174 - ], - [ - -78.89213562011719, - -33.66006736092875 - ], - [ - -78.88458251953125, - -33.65606660727672 - ], - [ - -78.87428283691406, - -33.644920669896656 - ], - [ - -78.8656997680664, - -33.64520648119226 - ], - [ - -78.86089324951172, - -33.66549665763364 - ], - [ - -78.82793426513672, - -33.66092464108171 - ], - [ - -78.78398895263672, - -33.6794969467326 - ], - [ - -78.76922607421875, - -33.670639885813706 - ], - [ - -78.7771224975586, - -33.662067667998414 - ], - [ - -78.77918243408203, - -33.655495055856136 - ], - [ - -78.79051208496094, - -33.641490860339054 - ], - [ - -78.81351470947266, - -33.64063338660099 - ], - [ - -78.81729125976561, - -33.64434904445886 - ], - [ - -78.83068084716797, - -33.640919212129155 - ], - [ - -78.83033752441406, - -33.63148646875166 - ], - [ - -78.84819030761717, - -33.618621971969276 - ], - [ - -78.848876953125, - -33.61347563543629 - ], - [ - -78.86295318603516, - -33.6071852512562 - ], - [ - -78.87805938720703, - -33.60575555447342 - ] - ] - ], - [ - [ - [ - -78.95161628723145, - -33.69528025294664 - ], - [ - -78.95530700683594, - -33.70006466462807 - ], - [ - -78.9521312713623, - -33.70163560737423 - ], - [ - -78.9506721496582, - -33.700278885784996 - ], - [ - -78.94861221313477, - -33.701207171292374 - ], - [ - -78.94972801208496, - -33.70306371221516 - ], - [ - -78.95075798034668, - -33.70284949800254 - ], - [ - -78.95178794860838, - -33.7045631967461 - ], - [ - -78.9480972290039, - -33.70784769044128 - ], - [ - -78.94947052001952, - -33.70934709145684 - ], - [ - -78.94303321838379, - -33.71377374172037 - ], - [ - -78.93917083740234, - -33.71363095011231 - ], - [ - -78.93771171569824, - -33.71455909132016 - ], - [ - -78.93874168395996, - -33.7163439500602 - ], - [ - -78.93659591674805, - -33.714987460801574 - ], - [ - -78.93685340881348, - -33.7134881582668 - ], - [ - -78.93479347229004, - -33.714916066036416 - ], - [ - -78.93410682678223, - -33.71355955421924 - ], - [ - -78.93075942993164, - -33.71355955421924 - ], - [ - -78.92475128173828, - -33.715201644740844 - ], - [ - -78.92380714416502, - -33.714773276327996 - ], - [ - -78.92483711242676, - -33.71377374172037 - ], - [ - -78.92706871032715, - -33.712988384937574 - ], - [ - -78.92998695373535, - -33.712845592023534 - ], - [ - -78.92998695373535, - -33.71170324016297 - ], - [ - -78.93118858337402, - -33.70970408784028 - ], - [ - -78.93393516540527, - -33.70998968387856 - ], - [ - -78.93625259399414, - -33.70791909108323 - ], - [ - -78.9378833770752, - -33.708276093402596 - ], - [ - -78.93925666809082, - -33.7064196651371 - ], - [ - -78.9411449432373, - -33.706205459293635 - ], - [ - -78.94020080566406, - -33.70506301910626 - ], - [ - -78.94140243530273, - -33.704206178993886 - ], - [ - -78.94037246704102, - -33.70263528325574 - ], - [ - -78.94208908081055, - -33.69792242367998 - ], - [ - -78.94320487976074, - -33.69742255977288 - ], - [ - -78.94569396972656, - -33.699350590247136 - ], - [ - -78.94929885864258, - -33.69799383257217 - ], - [ - -78.94981384277342, - -33.69649423337286 - ], - [ - -78.9492130279541, - -33.695922950602935 - ], - [ - -78.95015716552734, - -33.69513743059241 - ], - [ - -78.95092964172363, - -33.69578012931697 - ], - [ - -78.95161628723145, - -33.69528025294664 - ] - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "marker-symbol": "circle" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -80.800048828125, - -33.76886761916494 - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "marker-symbol": "circle" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -78.91157627105713, - -33.67833746949198 - ] - } - } - ] -} diff --git a/packages/turf-transform-scale/test/out/issue-#895.geojson b/packages/turf-transform-scale/test/out/issue-#895.geojson deleted file mode 100644 index 779a3c7518..0000000000 --- a/packages/turf-transform-scale/test/out/issue-#895.geojson +++ /dev/null @@ -1,2347 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.84004903398898, - 45.42809052672104 - ], - [ - -122.84832102992823, - 45.438117824939646 - ], - [ - -122.8648612420343, - 45.438117824939646 - ], - [ - -122.87313386793556, - 45.42809052672104 - ], - [ - -122.86486407574824, - 45.41806322850245 - ], - [ - -122.8483194556427, - 45.41806322850245 - ], - [ - -122.84004903398898, - 45.42809052672104 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.8329594267147, - 45.47822701781402 - ], - [ - -122.84536702834623, - 45.49326796514193 - ], - [ - -122.8701784448819, - 45.49326796514193 - ], - [ - -122.8825866776346, - 45.47822701781402 - ], - [ - -122.87018128356033, - 45.46318607048614 - ], - [ - -122.84536545130265, - 45.46318607048614 - ], - [ - -122.8329594267147, - 45.47822701781402 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.84004903398898, - 45.52836350890701 - ], - [ - -122.84832103268968, - 45.538390807125616 - ], - [ - -122.86486123706368, - 45.538390807125616 - ], - [ - -122.87313386793556, - 45.52836350890701 - ], - [ - -122.864864080715, - 45.518336210688425 - ], - [ - -122.84831945288335, - 45.518336210688425 - ], - [ - -122.84004903398898, - 45.52836350890701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.8329594267147, - 45.5785 - ], - [ - -122.84536703111286, - 45.593540947327895 - ], - [ - -122.8701784399019, - 45.593540947327895 - ], - [ - -122.8825866776346, - 45.5785 - ], - [ - -122.87018128853526, - 45.5634590526721 - ], - [ - -122.84536544853881, - 45.5634590526721 - ], - [ - -122.8329594267147, - 45.5785 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.84004903398898, - 45.62863649109299 - ], - [ - -122.84832103546091, - 45.638663789311586 - ], - [ - -122.86486123207533, - 45.638663789311586 - ], - [ - -122.87313386793556, - 45.62863649109299 - ], - [ - -122.86486408569942, - 45.618609192874395 - ], - [ - -122.84831945011422, - 45.618609192874395 - ], - [ - -122.84004903398898, - 45.62863649109299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.8329594267147, - 45.678772982185976 - ], - [ - -122.84536703388943, - 45.693813929513865 - ], - [ - -122.87017843490406, - 45.693813929513865 - ], - [ - -122.8825866776346, - 45.678772982185976 - ], - [ - -122.87018129352805, - 45.66373203485807 - ], - [ - -122.84536544576497, - 45.66373203485807 - ], - [ - -122.8329594267147, - 45.678772982185976 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.84004903398898, - 45.728909473278954 - ], - [ - -122.84832103824215, - 45.73893677149755 - ], - [ - -122.86486122706918, - 45.73893677149755 - ], - [ - -122.87313386793556, - 45.728909473278954 - ], - [ - -122.86486409070176, - 45.71888217506035 - ], - [ - -122.84831944733514, - 45.71888217506035 - ], - [ - -122.84004903398898, - 45.728909473278954 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.77092536306486, - 45.45315877226752 - ], - [ - -122.7833329640062, - 45.46819971959543 - ], - [ - -122.80814438247427, - 45.46819971959543 - ], - [ - -122.82055261398472, - 45.45315877226752 - ], - [ - -122.80814721866943, - 45.43811782493964 - ], - [ - -122.78333138834222, - 45.43811782493964 - ], - [ - -122.77092536306486, - 45.45315877226752 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.77801497033909, - 45.50329526336053 - ], - [ - -122.78628696834852, - 45.513322561579116 - ], - [ - -122.80282717465809, - 45.513322561579116 - ], - [ - -122.81109980428573, - 45.50329526336053 - ], - [ - -122.80283001582177, - 45.49326796514193 - ], - [ - -122.78628538992422, - 45.49326796514193 - ], - [ - -122.77801497033909, - 45.50329526336053 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.77092536306486, - 45.553431754453506 - ], - [ - -122.78333296677039, - 45.5684727017814 - ], - [ - -122.8081443774987, - 45.5684727017814 - ], - [ - -122.82055261398472, - 45.553431754453506 - ], - [ - -122.80814722363999, - 45.53839080712561 - ], - [ - -122.78333138558082, - 45.53839080712561 - ], - [ - -122.77092536306486, - 45.553431754453506 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.77801497033909, - 45.603568245546484 - ], - [ - -122.7862869711173, - 45.61359554376509 - ], - [ - -122.80282716967429, - 45.61359554376509 - ], - [ - -122.81109980428573, - 45.603568245546484 - ], - [ - -122.80283002080182, - 45.593540947327895 - ], - [ - -122.78628538715759, - 45.593540947327895 - ], - [ - -122.77801497033909, - 45.603568245546484 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.77092536306486, - 45.65370473663947 - ], - [ - -122.78333296954452, - 45.66874568396738 - ], - [ - -122.8081443725053, - 45.66874568396738 - ], - [ - -122.82055261398472, - 45.65370473663947 - ], - [ - -122.80814722862829, - 45.638663789311586 - ], - [ - -122.78333138280948, - 45.638663789311586 - ], - [ - -122.77092536306486, - 45.65370473663947 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.77801497033909, - 45.70384122773247 - ], - [ - -122.78628697389604, - 45.713868525951064 - ], - [ - -122.80282716467252, - 45.713868525951064 - ], - [ - -122.81109980428573, - 45.70384122773247 - ], - [ - -122.80283002579966, - 45.69381392951387 - ], - [ - -122.78628538438102, - 45.69381392951387 - ], - [ - -122.77801497033909, - 45.70384122773247 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.70889129941503, - 45.42809052672104 - ], - [ - -122.72129889966686, - 45.44313147404894 - ], - [ - -122.74611032006555, - 45.44313147404894 - ], - [ - -122.75851855033488, - 45.42809052672104 - ], - [ - -122.74611315377973, - 45.41304957939315 - ], - [ - -122.72129732538122, - 45.41304957939315 - ], - [ - -122.70889129941503, - 45.42809052672104 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.71598090668931, - 45.47822701781403 - ], - [ - -122.72425290400804, - 45.48825431603263 - ], - [ - -122.74079311225148, - 45.48825431603263 - ], - [ - -122.7490657406359, - 45.47822701781403 - ], - [ - -122.74079595092974, - 45.46819971959544 - ], - [ - -122.72425132696458, - 45.46819971959544 - ], - [ - -122.71598090668931, - 45.47822701781403 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.70889129941503, - 45.528363508907006 - ], - [ - -122.7212989024286, - 45.54340445623491 - ], - [ - -122.74611031509443, - 45.54340445623491 - ], - [ - -122.75851855033488, - 45.528363508907006 - ], - [ - -122.74611315874586, - 45.513322561579116 - ], - [ - -122.72129732262226, - 45.513322561579116 - ], - [ - -122.70889129941503, - 45.528363508907006 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.71598090668931, - 45.5785 - ], - [ - -122.72425290677438, - 45.5885272982186 - ], - [ - -122.74079310727205, - 45.5885272982186 - ], - [ - -122.7490657406359, - 45.5785 - ], - [ - -122.74079595590536, - 45.5684727017814 - ], - [ - -122.72425132420034, - 45.5684727017814 - ], - [ - -122.71598090668931, - 45.5785 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.70889129941503, - 45.62863649109299 - ], - [ - -122.72129890520023, - 45.64367743842088 - ], - [ - -122.74611031010551, - 45.64367743842088 - ], - [ - -122.75851855033488, - 45.62863649109299 - ], - [ - -122.74611316372972, - 45.613595543765086 - ], - [ - -122.72129731985342, - 45.613595543765086 - ], - [ - -122.70889129941503, - 45.62863649109299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.71598090668931, - 45.678772982185976 - ], - [ - -122.72425290955061, - 45.68880028040457 - ], - [ - -122.74079310227484, - 45.68880028040457 - ], - [ - -122.7490657406359, - 45.678772982185976 - ], - [ - -122.74079596089871, - 45.66874568396738 - ], - [ - -122.72425132142621, - 45.66874568396738 - ], - [ - -122.71598090668931, - 45.678772982185976 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.70889129941503, - 45.728909473278954 - ], - [ - -122.7212989079818, - 45.74395042060685 - ], - [ - -122.74611030509874, - 45.74395042060685 - ], - [ - -122.75851855033488, - 45.728909473278954 - ], - [ - -122.74611316873148, - 45.71386852595106 - ], - [ - -122.72129731707469, - 45.71386852595106 - ], - [ - -122.70889129941503, - 45.728909473278954 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.65394684303942, - 45.45315877226753 - ], - [ - -122.66221883966813, - 45.46318607048614 - ], - [ - -122.67875904984373, - 45.46318607048614 - ], - [ - -122.68703167698607, - 45.45315877226753 - ], - [ - -122.67876188603873, - 45.44313147404894 - ], - [ - -122.6622172640042, - 45.44313147404894 - ], - [ - -122.65394684303942, - 45.45315877226753 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.6468572357652, - 45.50329526336053 - ], - [ - -122.65926483808738, - 45.51833621068842 - ], - [ - -122.68407625268901, - 45.51833621068842 - ], - [ - -122.69648448668505, - 45.50329526336053 - ], - [ - -122.6840790938528, - 45.48825431603263 - ], - [ - -122.65926325966308, - 45.48825431603263 - ], - [ - -122.6468572357652, - 45.50329526336053 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.65394684303942, - 45.553431754453506 - ], - [ - -122.66221884243197, - 45.5634590526721 - ], - [ - -122.67875904486874, - 45.5634590526721 - ], - [ - -122.68703167698607, - 45.553431754453506 - ], - [ - -122.67876189100991, - 45.54340445623491 - ], - [ - -122.66221726124246, - 45.54340445623491 - ], - [ - -122.65394684303942, - 45.553431754453506 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.6468572357652, - 45.603568245546484 - ], - [ - -122.65926484085657, - 45.61860919287439 - ], - [ - -122.68407624770458, - 45.61860919287439 - ], - [ - -122.69648448668505, - 45.603568245546484 - ], - [ - -122.68407909883229, - 45.588527298218594 - ], - [ - -122.65926325689668, - 45.588527298218594 - ], - [ - -122.6468572357652, - 45.603568245546484 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.65394684303942, - 45.653704736639476 - ], - [ - -122.66221884520576, - 45.66373203485808 - ], - [ - -122.67875903987596, - 45.66373203485808 - ], - [ - -122.68703167698607, - 45.653704736639476 - ], - [ - -122.67876189599883, - 45.64367743842088 - ], - [ - -122.66221725847083, - 45.64367743842088 - ], - [ - -122.65394684303942, - 45.653704736639476 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.6468572357652, - 45.70384122773246 - ], - [ - -122.65926484363558, - 45.718882175060365 - ], - [ - -122.68407624270225, - 45.718882175060365 - ], - [ - -122.69648448668505, - 45.70384122773246 - ], - [ - -122.68407910382956, - 45.68880028040458 - ], - [ - -122.65926325412045, - 45.68880028040458 - ], - [ - -122.6468572357652, - 45.70384122773246 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.59191277938953, - 45.42809052672104 - ], - [ - -122.60018477532878, - 45.438117824939646 - ], - [ - -122.61672498743485, - 45.438117824939646 - ], - [ - -122.62499761333618, - 45.42809052672104 - ], - [ - -122.61672782114886, - 45.41806322850245 - ], - [ - -122.60018320104325, - 45.41806322850245 - ], - [ - -122.59191277938953, - 45.42809052672104 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.5848231721153, - 45.47822701781402 - ], - [ - -122.59723077374679, - 45.49326796514193 - ], - [ - -122.62204219028246, - 45.49326796514193 - ], - [ - -122.63445042303516, - 45.47822701781402 - ], - [ - -122.62204502896088, - 45.46318607048614 - ], - [ - -122.59722919670321, - 45.46318607048614 - ], - [ - -122.5848231721153, - 45.47822701781402 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.59191277938953, - 45.52836350890701 - ], - [ - -122.60018477809024, - 45.538390807125616 - ], - [ - -122.61672498246423, - 45.538390807125616 - ], - [ - -122.62499761333618, - 45.52836350890701 - ], - [ - -122.6167278261156, - 45.518336210688425 - ], - [ - -122.60018319828396, - 45.518336210688425 - ], - [ - -122.59191277938953, - 45.52836350890701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.5848231721153, - 45.5785 - ], - [ - -122.59723077651347, - 45.593540947327895 - ], - [ - -122.62204218530246, - 45.593540947327895 - ], - [ - -122.63445042303516, - 45.5785 - ], - [ - -122.62204503393582, - 45.5634590526721 - ], - [ - -122.59722919393931, - 45.5634590526721 - ], - [ - -122.5848231721153, - 45.5785 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.59191277938953, - 45.62863649109299 - ], - [ - -122.60018478086153, - 45.638663789311586 - ], - [ - -122.61672497747594, - 45.638663789311586 - ], - [ - -122.62499761333618, - 45.62863649109299 - ], - [ - -122.61672783109998, - 45.618609192874395 - ], - [ - -122.60018319551477, - 45.618609192874395 - ], - [ - -122.59191277938953, - 45.62863649109299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.5848231721153, - 45.678772982185976 - ], - [ - -122.59723077929004, - 45.693813929513865 - ], - [ - -122.62204218030462, - 45.693813929513865 - ], - [ - -122.63445042303516, - 45.678772982185976 - ], - [ - -122.62204503892866, - 45.66373203485807 - ], - [ - -122.59722919116552, - 45.66373203485807 - ], - [ - -122.5848231721153, - 45.678772982185976 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.59191277938953, - 45.728909473278954 - ], - [ - -122.6001847836427, - 45.73893677149755 - ], - [ - -122.61672497246974, - 45.73893677149755 - ], - [ - -122.62499761333618, - 45.728909473278954 - ], - [ - -122.61672783610237, - 45.71888217506035 - ], - [ - -122.6001831927357, - 45.71888217506035 - ], - [ - -122.59191277938953, - 45.728909473278954 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.52278910846542, - 45.45315877226752 - ], - [ - -122.53519670940682, - 45.46819971959543 - ], - [ - -122.56000812787488, - 45.46819971959543 - ], - [ - -122.57241635938533, - 45.45315877226752 - ], - [ - -122.56001096407005, - 45.43811782493964 - ], - [ - -122.53519513374283, - 45.43811782493964 - ], - [ - -122.52278910846542, - 45.45315877226752 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.52987871573976, - 45.50329526336053 - ], - [ - -122.53815071374913, - 45.513322561579116 - ], - [ - -122.5546909200587, - 45.513322561579116 - ], - [ - -122.56296354968629, - 45.50329526336053 - ], - [ - -122.55469376122238, - 45.49326796514193 - ], - [ - -122.53814913532483, - 45.49326796514193 - ], - [ - -122.52987871573976, - 45.50329526336053 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.52278910846542, - 45.553431754453506 - ], - [ - -122.535196712171, - 45.5684727017814 - ], - [ - -122.56000812289926, - 45.5684727017814 - ], - [ - -122.57241635938533, - 45.553431754453506 - ], - [ - -122.5600109690406, - 45.53839080712561 - ], - [ - -122.53519513098138, - 45.53839080712561 - ], - [ - -122.52278910846542, - 45.553431754453506 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.52987871573976, - 45.603568245546484 - ], - [ - -122.53815071651792, - 45.61359554376509 - ], - [ - -122.55469091507484, - 45.61359554376509 - ], - [ - -122.56296354968629, - 45.603568245546484 - ], - [ - -122.55469376620238, - 45.593540947327895 - ], - [ - -122.53814913255815, - 45.593540947327895 - ], - [ - -122.52987871573976, - 45.603568245546484 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.52278910846542, - 45.65370473663947 - ], - [ - -122.53519671494507, - 45.66874568396738 - ], - [ - -122.56000811790591, - 45.66874568396738 - ], - [ - -122.57241635938533, - 45.65370473663947 - ], - [ - -122.56001097402896, - 45.638663789311586 - ], - [ - -122.53519512821015, - 45.638663789311586 - ], - [ - -122.52278910846542, - 45.65370473663947 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.52987871573976, - 45.70384122773247 - ], - [ - -122.53815071929665, - 45.713868525951064 - ], - [ - -122.55469091007313, - 45.713868525951064 - ], - [ - -122.56296354968629, - 45.70384122773247 - ], - [ - -122.55469377120028, - 45.69381392951387 - ], - [ - -122.53814912978157, - 45.69381392951387 - ], - [ - -122.52987871573976, - 45.70384122773247 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.46075504481558, - 45.42809052672104 - ], - [ - -122.47316264506742, - 45.44313147404894 - ], - [ - -122.49797406546617, - 45.44313147404894 - ], - [ - -122.5103822957355, - 45.42809052672104 - ], - [ - -122.49797689918034, - 45.41304957939315 - ], - [ - -122.47316107078177, - 45.41304957939315 - ], - [ - -122.46075504481558, - 45.42809052672104 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.46784465208987, - 45.47822701781403 - ], - [ - -122.4761166494086, - 45.48825431603263 - ], - [ - -122.49265685765204, - 45.48825431603263 - ], - [ - -122.50092948603645, - 45.47822701781403 - ], - [ - -122.49265969633029, - 45.46819971959544 - ], - [ - -122.47611507236513, - 45.46819971959544 - ], - [ - -122.46784465208987, - 45.47822701781403 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.46075504481558, - 45.528363508907006 - ], - [ - -122.47316264782916, - 45.54340445623491 - ], - [ - -122.49797406049504, - 45.54340445623491 - ], - [ - -122.5103822957355, - 45.528363508907006 - ], - [ - -122.49797690414647, - 45.513322561579116 - ], - [ - -122.47316106802282, - 45.513322561579116 - ], - [ - -122.46075504481558, - 45.528363508907006 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.46784465208987, - 45.5785 - ], - [ - -122.47611665217494, - 45.5885272982186 - ], - [ - -122.49265685267261, - 45.5885272982186 - ], - [ - -122.50092948603645, - 45.5785 - ], - [ - -122.49265970130591, - 45.5684727017814 - ], - [ - -122.4761150696009, - 45.5684727017814 - ], - [ - -122.46784465208987, - 45.5785 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.46075504481558, - 45.62863649109299 - ], - [ - -122.47316265060078, - 45.64367743842088 - ], - [ - -122.49797405550612, - 45.64367743842088 - ], - [ - -122.5103822957355, - 45.62863649109299 - ], - [ - -122.49797690913033, - 45.613595543765086 - ], - [ - -122.47316106525403, - 45.613595543765086 - ], - [ - -122.46075504481558, - 45.62863649109299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.46784465208987, - 45.678772982185976 - ], - [ - -122.47611665495117, - 45.68880028040457 - ], - [ - -122.49265684767539, - 45.68880028040457 - ], - [ - -122.50092948603645, - 45.678772982185976 - ], - [ - -122.49265970629926, - 45.66874568396738 - ], - [ - -122.47611506682682, - 45.66874568396738 - ], - [ - -122.46784465208987, - 45.678772982185976 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.46075504481558, - 45.728909473278954 - ], - [ - -122.47316265338236, - 45.74395042060685 - ], - [ - -122.4979740504993, - 45.74395042060685 - ], - [ - -122.5103822957355, - 45.728909473278954 - ], - [ - -122.49797691413204, - 45.71386852595106 - ], - [ - -122.47316106247524, - 45.71386852595106 - ], - [ - -122.46075504481558, - 45.728909473278954 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.40581058844003, - 45.45315877226753 - ], - [ - -122.41408258506868, - 45.46318607048614 - ], - [ - -122.43062279524429, - 45.46318607048614 - ], - [ - -122.43889542238662, - 45.45315877226753 - ], - [ - -122.43062563143928, - 45.44313147404894 - ], - [ - -122.41408100940475, - 45.44313147404894 - ], - [ - -122.40581058844003, - 45.45315877226753 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.39872098116575, - 45.50329526336053 - ], - [ - -122.41112858348794, - 45.51833621068842 - ], - [ - -122.43593999808957, - 45.51833621068842 - ], - [ - -122.4483482320856, - 45.50329526336053 - ], - [ - -122.43594283925341, - 45.48825431603263 - ], - [ - -122.41112700506363, - 45.48825431603263 - ], - [ - -122.39872098116575, - 45.50329526336053 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.40581058844003, - 45.553431754453506 - ], - [ - -122.41408258783258, - 45.5634590526721 - ], - [ - -122.4306227902693, - 45.5634590526721 - ], - [ - -122.43889542238662, - 45.553431754453506 - ], - [ - -122.43062563641047, - 45.54340445623491 - ], - [ - -122.41408100664302, - 45.54340445623491 - ], - [ - -122.40581058844003, - 45.553431754453506 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.39872098116575, - 45.603568245546484 - ], - [ - -122.41112858625706, - 45.61860919287439 - ], - [ - -122.43593999310514, - 45.61860919287439 - ], - [ - -122.4483482320856, - 45.603568245546484 - ], - [ - -122.43594284423284, - 45.588527298218594 - ], - [ - -122.41112700229729, - 45.588527298218594 - ], - [ - -122.39872098116575, - 45.603568245546484 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.40581058844003, - 45.653704736639476 - ], - [ - -122.41408259060631, - 45.66373203485808 - ], - [ - -122.43062278527646, - 45.66373203485808 - ], - [ - -122.43889542238662, - 45.653704736639476 - ], - [ - -122.43062564139939, - 45.64367743842088 - ], - [ - -122.41408100387139, - 45.64367743842088 - ], - [ - -122.40581058844003, - 45.653704736639476 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.39872098116575, - 45.70384122773246 - ], - [ - -122.4111285890362, - 45.718882175060365 - ], - [ - -122.43593998810275, - 45.718882175060365 - ], - [ - -122.4483482320856, - 45.70384122773246 - ], - [ - -122.43594284923006, - 45.68880028040458 - ], - [ - -122.411126999521, - 45.68880028040458 - ], - [ - -122.39872098116575, - 45.70384122773246 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.34377652479014, - 45.42809052672104 - ], - [ - -122.3520485207294, - 45.438117824939646 - ], - [ - -122.3685887328354, - 45.438117824939646 - ], - [ - -122.37686135873673, - 45.42809052672104 - ], - [ - -122.36859156654941, - 45.41806322850245 - ], - [ - -122.3520469464438, - 45.41806322850245 - ], - [ - -122.34377652479014, - 45.42809052672104 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.33668691751586, - 45.47822701781402 - ], - [ - -122.34909451914734, - 45.49326796514193 - ], - [ - -122.37390593568307, - 45.49326796514193 - ], - [ - -122.38631416843572, - 45.47822701781402 - ], - [ - -122.37390877436144, - 45.46318607048614 - ], - [ - -122.34909294210382, - 45.46318607048614 - ], - [ - -122.33668691751586, - 45.47822701781402 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.34377652479014, - 45.52836350890701 - ], - [ - -122.3520485234908, - 45.538390807125616 - ], - [ - -122.36858872786485, - 45.538390807125616 - ], - [ - -122.37686135873673, - 45.52836350890701 - ], - [ - -122.36859157151616, - 45.518336210688425 - ], - [ - -122.35204694368451, - 45.518336210688425 - ], - [ - -122.34377652479014, - 45.52836350890701 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.33668691751586, - 45.5785 - ], - [ - -122.34909452191403, - 45.593540947327895 - ], - [ - -122.37390593070302, - 45.593540947327895 - ], - [ - -122.38631416843572, - 45.5785 - ], - [ - -122.37390877933643, - 45.5634590526721 - ], - [ - -122.34909293933993, - 45.5634590526721 - ], - [ - -122.33668691751586, - 45.5785 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.34377652479014, - 45.62863649109299 - ], - [ - -122.35204852626208, - 45.638663789311586 - ], - [ - -122.3685887228765, - 45.638663789311586 - ], - [ - -122.37686135873673, - 45.62863649109299 - ], - [ - -122.36859157650059, - 45.618609192874395 - ], - [ - -122.35204694091539, - 45.618609192874395 - ], - [ - -122.34377652479014, - 45.62863649109299 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.33668691751586, - 45.678772982185976 - ], - [ - -122.3490945246906, - 45.693813929513865 - ], - [ - -122.37390592570523, - 45.693813929513865 - ], - [ - -122.38631416843572, - 45.678772982185976 - ], - [ - -122.37390878432922, - 45.66373203485807 - ], - [ - -122.3490929365662, - 45.66373203485807 - ], - [ - -122.33668691751586, - 45.678772982185976 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.34377652479014, - 45.728909473278954 - ], - [ - -122.35204852904332, - 45.73893677149755 - ], - [ - -122.3685887178703, - 45.73893677149755 - ], - [ - -122.37686135873673, - 45.728909473278954 - ], - [ - -122.36859158150293, - 45.71888217506035 - ], - [ - -122.35204693813631, - 45.71888217506035 - ], - [ - -122.34377652479014, - 45.728909473278954 - ] - ] - ] - } - }, - { - "type": "Feature", - "bbox": [ - -122.93, - 45.385, - -122.294, - 45.772 - ], - "properties": { - "stroke": "#F00", - "stroke-width": 6, - "fill-opacity": 0 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -122.93, - 45.385 - ], - [ - -122.294, - 45.385 - ], - [ - -122.294, - 45.772 - ], - [ - -122.93, - 45.772 - ], - [ - -122.93, - 45.385 - ] - ] - ] - } - } - ] -} diff --git a/packages/turf-transform-scale/test/out/polygon-fiji.geojson b/packages/turf-transform-scale/test/out/polygon-fiji.geojson deleted file mode 100644 index 5bd80cb6e8..0000000000 --- a/packages/turf-transform-scale/test/out/polygon-fiji.geojson +++ /dev/null @@ -1,216 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "stroke": "#F00", - "stroke-width": 4 - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - -178.895604, - -16.832174 - ], - [ - -178.950976, - -16.600675 - ], - [ - -179.083024, - -16.463814 - ], - [ - -179.621072, - -16.590149 - ], - [ - -179.972278, - -17.179159 - ], - [ - -179.906166, - -17.420808 - ], - [ - -179.499388, - -17.326268 - ], - [ - -178.895604, - -16.832174 - ] - ] - ], - [ - [ - [ - -179.76408, - -16.326904 - ], - [ - -179.216216, - -15.493879 - ], - [ - -179.81963, - -15.377748 - ], - [ - -181.048142, - -15.46221 - ], - [ - -182.893804, - -16.358503 - ], - [ - -182.961797, - -16.979418 - ], - [ - -182.633499, - -17.441813 - ], - [ - -182.072633, - -17.441813 - ], - [ - -181.533412, - -17.221196 - ], - [ - -180.818747, - -17.137117 - ], - [ - -180.016317, - -17.042506 - ], - [ - -179.76408, - -16.326904 - ] - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - -179.6319580078125, - -16.762467717941593 - ], - [ - -179.659423828125, - -16.64671805097192 - ], - [ - -179.725341796875, - -16.578287608637478 - ], - [ - -179.99450683593747, - -16.641455036937753 - ], - [ - -180.1702880859375, - -16.935960102864705 - ], - [ - -180.1373291015625, - -17.056784609942543 - ], - [ - -179.93408203125, - -17.00951473208515 - ], - [ - -179.6319580078125, - -16.762467717941593 - ] - ] - ], - [ - [ - [ - -180.06591796875, - -16.509832826905836 - ], - [ - -179.79125976562497, - -16.093320185359257 - ], - [ - -180.0933837890625, - -16.0352548623504 - ], - [ - -180.7086181640625, - -16.0774858690887 - ], - [ - -181.63146972656247, - -16.525632239869275 - ], - [ - -181.6644287109375, - -16.836089974560213 - ], - [ - -181.4996337890625, - -17.06728740376787 - ], - [ - -181.219482421875, - -17.06728740376787 - ], - [ - -180.9503173828125, - -16.956978651248072 - ], - [ - -180.59326171875, - -16.914939206301646 - ], - [ - -180.1922607421875, - -16.867633616803836 - ], - [ - -180.06591796875, - -16.509832826905836 - ] - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "marker-symbol": "circle" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -180.3680419921875, - -16.69276153221258 - ] - } - } - ] -} diff --git a/packages/turf-transform-scale/test/out/polygon-resolute-bay.geojson b/packages/turf-transform-scale/test/out/polygon-resolute-bay.geojson deleted file mode 100644 index 171ce1e85c..0000000000 --- a/packages/turf-transform-scale/test/out/polygon-resolute-bay.geojson +++ /dev/null @@ -1,235 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "factor": 2.5, - "stroke": "#F00", - "stroke-width": 4 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -95.739369, - 76.27281 - ], - [ - -97.901371, - 75.819519 - ], - [ - -99.012859, - 75.150198 - ], - [ - -99.342258, - 74.839421 - ], - [ - -97.052592, - 74.260646 - ], - [ - -95.05344, - 73.913551 - ], - [ - -93.607218, - 73.80445 - ], - [ - -91.593387, - 73.906287 - ], - [ - -91.427755, - 74.418703 - ], - [ - -91.591276, - 74.846513 - ], - [ - -91.659051, - 75.514226 - ], - [ - -93.161795, - 76.053726 - ], - [ - -93.884654, - 76.27281 - ], - [ - -94.840155, - 76.341007 - ], - [ - -95.739369, - 76.27281 - ] - ], - [ - [ - -95.562397, - 75.750353 - ], - [ - -96.947179, - 75.322148 - ], - [ - -96.801785, - 74.775541 - ], - [ - -94.406415, - 74.35053 - ], - [ - -92.878924, - 74.343347 - ], - [ - -92.819614, - 75.195893 - ], - [ - -94.243172, - 75.674122 - ], - [ - -95.562397, - 75.750353 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "factor": 2.5 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -95.174560546875, - 75.60953172351893 - ], - [ - -96.03149414062499, - 75.4282153667069 - ], - [ - -96.492919921875, - 75.16048677152294 - ], - [ - -96.6357421875, - 75.03617629075062 - ], - [ - -95.723876953125, - 74.80466599405533 - ], - [ - -94.910888671875, - 74.66582807452669 - ], - [ - -94.317626953125, - 74.62218784846145 - ], - [ - -93.49365234375, - 74.66292249033842 - ], - [ - -93.438720703125, - 74.86788912917916 - ], - [ - -93.515625, - 75.03901279805076 - ], - [ - -93.55957031249999, - 75.3060980061604 - ], - [ - -94.163818359375, - 75.52189820596192 - ], - [ - -94.449462890625, - 75.60953172351893 - ], - [ - -94.82299804687499, - 75.63681056594325 - ], - [ - -95.174560546875, - 75.60953172351893 - ] - ], - [ - [ - -95.108642578125, - 75.40054889588245 - ], - [ - -95.6634521484375, - 75.22926698530169 - ], - [ - -95.614013671875, - 75.01062406678055 - ], - [ - -94.647216796875, - 74.84061980605131 - ], - [ - -94.0264892578125, - 74.83774656082585 - ], - [ - -94.0155029296875, - 75.17876503868581 - ], - [ - -94.5867919921875, - 75.3700564253908 - ], - [ - -95.108642578125, - 75.40054889588245 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "marker-symbol": "circle" - }, - "geometry": { - "type": "Point", - "coordinates": [ - -94.81201171875, - 75.16734623421806 - ] - } - } - ] -} diff --git a/packages/turf-transform-scale/test/out/polygon.geojson b/packages/turf-transform-scale/test/out/polygon.geojson deleted file mode 100644 index 1450e6c43e..0000000000 --- a/packages/turf-transform-scale/test/out/polygon.geojson +++ /dev/null @@ -1,79 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "factor": 0.1, - "stroke": "#F00", - "stroke-width": 4 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 1.3495, - 29.675 - ], - [ - 1.700667, - 29.675 - ], - [ - 1.598959, - 29.975 - ], - [ - 1.3495, - 29.675 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "factor": 0.1 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - 0, - 29 - ], - [ - 3.5, - 29 - ], - [ - 2.5, - 32 - ], - [ - 0, - 29 - ] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "marker-symbol": "circle" - }, - "geometry": { - "type": "Point", - "coordinates": [ - 1.5, - 29.75 - ] - } - } - ] -} diff --git a/packages/turf-transform-scale/types.ts b/packages/turf-transform-scale/types.ts deleted file mode 100644 index 9d18f98a2e..0000000000 --- a/packages/turf-transform-scale/types.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { lineString, polygon, featureCollection, LineString, Feature, Polygon } from '@turf/helpers'; -import scale from './'; - -const line = lineString([[0, 0],[10, 29]]); -const poly = polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]); - -// Does not mutate Geometry type -const scaledPt: LineString = scale(line.geometry, 1.5); -const scaledPoly: Feature = scale(poly, 1.5); - -// Diferent Geometry inputs -scale(line.geometry, 1.5); -scale(poly.geometry, 1.5); -scale(featureCollection([poly]), 1.5); - -// All params -scale(poly, 1.5); -scale(poly, 1.5, {origin: [10, 10]}); -scale(poly, 1.5, {origin: 'ne', mutate: true}); diff --git a/packages/turf-transform-translate/LICENSE b/packages/turf-transform-translate/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-transform-translate/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-transform-translate/README.md b/packages/turf-transform-translate/README.md deleted file mode 100644 index a770996616..0000000000 --- a/packages/turf-transform-translate/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# @turf/transform-translate - - - -## transformTranslate - -Moves any geojson Feature or Geometry of a specified distance along a Rhumb Line -on the provided direction angle. - -**Parameters** - -- `geojson` **[GeoJSON][1]** object to be translated -- `distance` **[number][2]** length of the motion; negative values determine motion in opposite direction -- `direction` **[number][2]** of the motion; angle from North in decimal degrees, positive clockwise -- `options` **[Object][3]** Optional parameters (optional, default `{}`) - - `options.units` **[string][4]** in which `distance` will be express; miles, kilometers, degrees, or radians (optional, default `'kilometers'`) - - `options.zTranslation` **[number][2]** length of the vertical motion, same unit of distance (optional, default `0`) - - `options.mutate` **[boolean][5]** allows GeoJSON input to be mutated (significant performance increase if true) (optional, default `false`) - -**Examples** - -```javascript -var poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]); -var translatedPoly = turf.transformTranslate(poly, 100, 35); - -//addToMap -var addToMap = [poly, translatedPoly]; -translatedPoly.properties = {stroke: '#F00', 'stroke-width': 4}; -``` - -Returns **[GeoJSON][1]** the translated GeoJSON object - -[1]: https://tools.ietf.org/html/rfc7946#section-3 - -[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/transform-translate -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-transform-translate/index.d.ts b/packages/turf-transform-translate/index.d.ts deleted file mode 100644 index b2771319f2..0000000000 --- a/packages/turf-transform-translate/index.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { AllGeoJSON, Units } from '@turf/helpers' - -/** - * http://turfjs.org/docs/#transform-translate - */ -export default function transformTranslate( - geojson: T, - distance: number, - direction: number, - options?: { - units?: Units, - zTranslation?: number, - mutate?: boolean - } -): T; \ No newline at end of file diff --git a/packages/turf-transform-translate/index.js b/packages/turf-transform-translate/index.js deleted file mode 100644 index 4dce9133ce..0000000000 --- a/packages/turf-transform-translate/index.js +++ /dev/null @@ -1,66 +0,0 @@ -import { coordEach } from '@turf/meta'; -import { isObject } from '@turf/helpers'; -import { getCoords } from '@turf/invariant'; -import clone from '@turf/clone'; -import rhumbDestination from '@turf/rhumb-destination'; - -/** - * Moves any geojson Feature or Geometry of a specified distance along a Rhumb Line - * on the provided direction angle. - * - * @name transformTranslate - * @param {GeoJSON} geojson object to be translated - * @param {number} distance length of the motion; negative values determine motion in opposite direction - * @param {number} direction of the motion; angle from North in decimal degrees, positive clockwise - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] in which `distance` will be express; miles, kilometers, degrees, or radians - * @param {number} [options.zTranslation=0] length of the vertical motion, same unit of distance - * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) - * @returns {GeoJSON} the translated GeoJSON object - * @example - * var poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]); - * var translatedPoly = turf.transformTranslate(poly, 100, 35); - * - * //addToMap - * var addToMap = [poly, translatedPoly]; - * translatedPoly.properties = {stroke: '#F00', 'stroke-width': 4}; - */ -function transformTranslate(geojson, distance, direction, options) { - // Optional parameters - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var units = options.units; - var zTranslation = options.zTranslation; - var mutate = options.mutate; - - // Input validation - if (!geojson) throw new Error('geojson is required'); - if (distance === undefined || distance === null || isNaN(distance)) throw new Error('distance is required'); - if (zTranslation && typeof zTranslation !== 'number' && isNaN(zTranslation)) throw new Error('zTranslation is not a number'); - - // Shortcut no-motion - zTranslation = (zTranslation !== undefined) ? zTranslation : 0; - if (distance === 0 && zTranslation === 0) return geojson; - - if (direction === undefined || direction === null || isNaN(direction)) throw new Error('direction is required'); - - // Invert with negative distances - if (distance < 0) { - distance = -distance; - direction = -direction; - } - - // Clone geojson to avoid side effects - if (mutate === false || mutate === undefined) geojson = clone(geojson); - - // Translate each coordinate - coordEach(geojson, function (pointCoords) { - var newCoords = getCoords(rhumbDestination(pointCoords, distance, direction, {units: units})); - pointCoords[0] = newCoords[0]; - pointCoords[1] = newCoords[1]; - if (zTranslation && pointCoords.length === 3) pointCoords[2] += zTranslation; - }); - return geojson; -} - -export default transformTranslate; diff --git a/packages/turf-transform-translate/package.json b/packages/turf-transform-translate/package.json deleted file mode 100644 index c0632e85c6..0000000000 --- a/packages/turf-transform-translate/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "@turf/transform-translate", - "version": "5.1.5", - "description": "turf transform-translate module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "transform", - "transformation", - "translate", - "move", - "shift" - ], - "author": "Turf Authors", - "contributors": [ - "Stefano Borghi <@stebogit>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/truncate": "6.x", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/clone": "6.x", - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "@turf/meta": "6.x", - "@turf/rhumb-destination": "6.x" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-transform-translate/test.js b/packages/turf-transform-translate/test.js deleted file mode 100644 index 9bfb2ab7cb..0000000000 --- a/packages/turf-transform-translate/test.js +++ /dev/null @@ -1,82 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import truncate from '@turf/truncate'; -import { point, lineString, geometryCollection, featureCollection } from '@turf/helpers'; -import translate from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('translate', t => { - for (const {filename, name, geojson} of fixtures) { - let {distance, direction, units, zTranslation} = geojson.properties || {}; - - const translated = translate(geojson, distance, direction, {units, zTranslation}); - const result = featureCollection([colorize(truncate(translated, {precision: 6, coordiantes: 3})), geojson]); - - if (process.env.REGEN) write.sync(directories.out + filename, result); - t.deepEqual(result, load.sync(directories.out + filename), name); - } - - t.end(); -}); - -test('translate -- throws', t => { - const pt = point([-70.823364, -33.553984]); - - t.throws(() => translate(null, 100, -29), 'missing geojson'); - t.throws(() => translate(pt, null, 98), 'missing distance'); - t.throws(() => translate(pt, 23, null), 'missing direction'); - t.throws(() => translate(pt, 56, 57, {units: 'foo'}), 'invalid units'); - t.throws(() => translate(pt, 56, 57, {zTranslation: 'foo'}), 'invalid zTranslation'); - - t.end(); -}); - -test('rotate -- mutated input', t => { - const line = lineString([[10, 10], [12, 15]]); - const lineBefore = JSON.parse(JSON.stringify(line)); - - translate(line, 100, 50); - t.deepEqual(line, lineBefore, 'input should NOT be mutated'); - - translate(line, 100, 50, {units: 'kilometers', mutate: true}); - t.deepEqual(truncate(line, {precision: 1}), lineString([[10.7, 10.6], [12.7, 15.6]]), 'input should be mutated'); - t.end(); -}); - -test('rotate -- geometry support', t => { - const line = lineString([[10, 10], [12, 15]]); - t.assert(translate(geometryCollection([line.geometry]), 100, 50), 'geometryCollection support'); - t.assert(translate(geometryCollection([line.geometry]).geometry, 100, 50), 'geometryCollection support'); - t.assert(translate(featureCollection([line]), 100, 50), 'featureCollection support'); - t.assert(translate(line.geometry, 100, 50), 'geometry line support'); - t.assert(translate(line.geometry, 100, 50), 'geometry pt support'); - t.assert(translate(line, 0, 100), 'shortcut no-motion'); - t.end(); -}); - -// style result -function colorize(geojson) { - if (geojson.geometry.type === 'Point' || geojson.geometry.type === 'MultiPoint') { - geojson.properties['marker-color'] = '#F00'; - geojson.properties['marker-symbol'] = 'star'; - } else { - geojson.properties['stroke'] = '#F00'; - geojson.properties['stroke-width'] = 4; - } - return geojson; -} diff --git a/packages/turf-transform-translate/types.ts b/packages/turf-transform-translate/types.ts deleted file mode 100644 index ccaea04b7a..0000000000 --- a/packages/turf-transform-translate/types.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {point, polygon, featureCollection, Point, Feature, Polygon} from '@turf/helpers'; -import translate from './'; - -const pt = point([0, 0]); -const poly = polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]); - -// Does not mutate Geometry type -const translatedPt: Point = translate(pt.geometry, 100, 35); -const translatedPoly: Feature = translate(poly, 100, 35); - -// Diferent Geometry inputs -translate(pt.geometry, 100, 35); -translate(poly.geometry, 100, 35); -translate(featureCollection([poly]), 100, 35); - -// All params -translate(poly, 100, 35, {units: 'kilometers'}); -translate(poly, 100, 35, {units: 'kilometers', zTranslation: 10}); -translate(poly, 100, 35, {units: 'kilometers', zTranslation: 10, mutate: true}); diff --git a/packages/turf-triangle-grid/.gitignore b/packages/turf-triangle-grid/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-triangle-grid/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-triangle-grid/LICENSE b/packages/turf-triangle-grid/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-triangle-grid/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-triangle-grid/README.md b/packages/turf-triangle-grid/README.md deleted file mode 100644 index 4c302ad4eb..0000000000 --- a/packages/turf-triangle-grid/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# @turf/triangle-grid - - - -## triangleGrid - -Takes a bounding box and a cell depth and returns a set of triangular [polygons][1] in a grid. - -**Parameters** - -- `bbox` **[Array][2]<[number][3]>** extent in [minX, minY, maxX, maxY] order -- `cellSide` **[number][3]** dimension of each cell -- `options` **[Object][4]** Optional parameters (optional, default `{}`) - - `options.units` **[string][5]** used in calculating cellSide, can be degrees, radians, miles, or kilometers (optional, default `'kilometers'`) - - `options.mask` **[Feature][6]<[Polygon][7]>?** if passed a Polygon or MultiPolygon, the grid Points will be created only inside it - - `options.properties` **[Object][4]** passed to each point of the grid (optional, default `{}`) - -**Examples** - -```javascript -var bbox = [-95, 30 ,-85, 40]; -var cellSide = 50; -var options = {units: 'miles'}; - -var triangleGrid = turf.triangleGrid(bbox, cellSide, options); - -//addToMap -var addToMap = [triangleGrid]; -``` - -Returns **[FeatureCollection][8]<[Polygon][7]>** grid of polygons - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String - -[6]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[7]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[8]: https://tools.ietf.org/html/rfc7946#section-3.3 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/triangle-grid -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-triangle-grid/index.ts b/packages/turf-triangle-grid/index.ts deleted file mode 100644 index 76725b633d..0000000000 --- a/packages/turf-triangle-grid/index.ts +++ /dev/null @@ -1,132 +0,0 @@ -import distance from '@turf/distance'; -import intersect from '@turf/intersect'; -import { getType } from '@turf/invariant'; -import { - polygon, featureCollection, isObject, isNumber, - Units, BBox, Feature, Polygon, MultiPolygon, FeatureCollection, Properties -} from '@turf/helpers'; - -/** - * Takes a bounding box and a cell depth and returns a set of triangular {@link Polygon|polygons} in a grid. - * - * @name triangleGrid - * @param {Array} bbox extent in [minX, minY, maxX, maxY] order - * @param {number} cellSide dimension of each cell - * @param {Object} [options={}] Optional parameters - * @param {string} [options.units='kilometers'] used in calculating cellSide, can be degrees, radians, miles, or kilometers - * @param {Feature} [options.mask] if passed a Polygon or MultiPolygon, the grid Points will be created only inside it - * @param {Object} [options.properties={}] passed to each point of the grid - * @returns {FeatureCollection} grid of polygons - * @example - * var bbox = [-95, 30 ,-85, 40]; - * var cellSide = 50; - * var options = {units: 'miles'}; - * - * var triangleGrid = turf.triangleGrid(bbox, cellSide, options); - * - * //addToMap - * var addToMap = [triangleGrid]; - */ -function triangleGrid

(bbox: BBox, cellSide: number, options: { - units?: Units, - properties?: P, - mask?: Feature | Polygon -} = {}): FeatureCollection { - // Containers - var results = []; - - // Input Validation is being handled by Typescript - - // if (cellSide === null || cellSide === undefined) throw new Error('cellSide is required'); - // if (!isNumber(cellSide)) throw new Error('cellSide is invalid'); - // if (!bbox) throw new Error('bbox is required'); - // if (!Array.isArray(bbox)) throw new Error('bbox must be array'); - // if (bbox.length !== 4) throw new Error('bbox must contain 4 numbers'); - // if (mask && ['Polygon', 'MultiPolygon'].indexOf(getType(mask)) === -1) throw new Error('options.mask must be a (Multi)Polygon'); - - // Main - var xFraction = cellSide / (distance([bbox[0], bbox[1]], [bbox[2], bbox[1]], options)); - var cellWidth = xFraction * (bbox[2] - bbox[0]); - var yFraction = cellSide / (distance([bbox[0], bbox[1]], [bbox[0], bbox[3]], options)); - var cellHeight = yFraction * (bbox[3] - bbox[1]); - - var xi = 0; - var currentX = bbox[0]; - while (currentX <= bbox[2]) { - var yi = 0; - var currentY = bbox[1]; - while (currentY <= bbox[3]) { - var cellTriangle1 = null; - var cellTriangle2 = null; - - if (xi % 2 === 0 && yi % 2 === 0) { - cellTriangle1 = polygon([[ - [currentX, currentY], - [currentX, currentY + cellHeight], - [currentX + cellWidth, currentY], - [currentX, currentY] - ]], options.properties); - cellTriangle2 = polygon([[ - [currentX, currentY + cellHeight], - [currentX + cellWidth, currentY + cellHeight], - [currentX + cellWidth, currentY], - [currentX, currentY + cellHeight] - ]], options.properties); - } else if (xi % 2 === 0 && yi % 2 === 1) { - cellTriangle1 = polygon([[ - [currentX, currentY], - [currentX + cellWidth, currentY + cellHeight], - [currentX + cellWidth, currentY], - [currentX, currentY] - ]], options.properties); - cellTriangle2 = polygon([[ - [currentX, currentY], - [currentX, currentY + cellHeight], - [currentX + cellWidth, currentY + cellHeight], - [currentX, currentY] - ]], options.properties); - } else if (yi % 2 === 0 && xi % 2 === 1) { - cellTriangle1 = polygon([[ - [currentX, currentY], - [currentX, currentY + cellHeight], - [currentX + cellWidth, currentY + cellHeight], - [currentX, currentY] - ]], options.properties); - cellTriangle2 = polygon([[ - [currentX, currentY], - [currentX + cellWidth, currentY + cellHeight], - [currentX + cellWidth, currentY], - [currentX, currentY] - ]], options.properties); - } else if (yi % 2 === 1 && xi % 2 === 1) { - cellTriangle1 = polygon([[ - [currentX, currentY], - [currentX, currentY + cellHeight], - [currentX + cellWidth, currentY], - [currentX, currentY] - ]], options.properties); - cellTriangle2 = polygon([[ - [currentX, currentY + cellHeight], - [currentX + cellWidth, currentY + cellHeight], - [currentX + cellWidth, currentY], - [currentX, currentY + cellHeight] - ]], options.properties); - } - if (options.mask) { - if (intersect(options.mask, cellTriangle1)) results.push(cellTriangle1); - if (intersect(options.mask, cellTriangle2)) results.push(cellTriangle2); - } else { - results.push(cellTriangle1); - results.push(cellTriangle2); - } - - currentY += cellHeight; - yi++; - } - xi++; - currentX += cellWidth; - } - return featureCollection(results); -} - -export default triangleGrid; diff --git a/packages/turf-triangle-grid/package.json b/packages/turf-triangle-grid/package.json deleted file mode 100644 index 916f8cacb7..0000000000 --- a/packages/turf-triangle-grid/package.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "name": "@turf/triangle-grid", - "version": "6.0.1", - "description": "turf triangle-grid module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "triangle", - "grid", - "polygons", - "analysis", - "gis" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@turf/bbox-polygon": "*", - "@turf/truncate": "*", - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/distance": "6.x", - "@turf/helpers": "6.x", - "@turf/intersect": "6.x", - "@turf/invariant": "6.x" - } -} diff --git a/packages/turf-triangle-grid/test.js b/packages/turf-triangle-grid/test.js deleted file mode 100644 index 7939e0d68c..0000000000 --- a/packages/turf-triangle-grid/test.js +++ /dev/null @@ -1,63 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const bboxPoly = require('@turf/bbox-polygon').default; -const truncate = require('@turf/truncate').default; -const triangleGrid = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -let fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - json: load.sync(directories.in + filename) - }; -}); - -test('triangle-grid', t => { - for (const {name, json} of fixtures) { - const {bbox, cellSide} = json; - const options = json; - const result = truncate(triangleGrid(bbox, cellSide, options)); - - // Add styled GeoJSON to the result - const poly = bboxPoly(bbox); - poly.properties = { - stroke: '#F00', - 'stroke-width': 6, - 'fill-opacity': 0 - }; - result.features.push(poly); - if (options.mask) { - options.mask.properties = { - "stroke": "#00F", - "stroke-width": 6, - "fill-opacity": 0 - }; - result.features.push(options.mask); - } - - if (process.env.REGEN) write.sync(directories.out + name + '.geojson', result); - t.deepEqual(result, load.sync(directories.out + name + '.geojson'), name); - } - t.end(); -}); - - -test('square-grid -- throw', t => { - const bbox = [0, 0, 1, 1]; - // Types is managed by Typescript - // t.throws(() => triangleGrid(null, 0), /bbox is required/, 'missing bbox'); - // t.throws(() => triangleGrid('string', 0), /bbox must be array/, 'invalid bbox'); - // t.throws(() => triangleGrid([0, 2], 0), /bbox must contain 4 numbers/, 'invalid bbox'); - // t.throws(() => triangleGrid(bbox, null), /cellSide is required/, 'missing cellSide'); - // t.throws(() => triangleGrid(bbox, 'string'), /cellSide is invalid/, 'invalid cellSide'); - // t.throws(() => triangleGrid(bbox, 1, 'string'), /options is invalid/, 'invalid options'); - t.end(); -}); diff --git a/packages/turf-triangle-grid/types.ts b/packages/turf-triangle-grid/types.ts deleted file mode 100644 index 44918de465..0000000000 --- a/packages/turf-triangle-grid/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { BBox, Polygon, FeatureCollection } from '@turf/helpers' -import triangleGrid from './' - -const bbox: BBox = [ - -96.6357421875, - 31.12819929911196, - -84.9462890625, - 40.58058466412764 -] -const grid = triangleGrid(bbox, 50, {units: 'miles', properties: {'foo': 'bar'}}); -grid.features[0].properties.foo -// grid.features[0].properties.bar // [ts] Property 'bar' does not exist on type '{ 'foo': string; }'. diff --git a/packages/turf-truncate/.gitignore b/packages/turf-truncate/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-truncate/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-truncate/LICENSE b/packages/turf-truncate/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-truncate/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-truncate/README.md b/packages/turf-truncate/README.md deleted file mode 100644 index 656c24f8d5..0000000000 --- a/packages/turf-truncate/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# @turf/truncate - - - -## truncate - -Takes a GeoJSON Feature or FeatureCollection and truncates the precision of the geometry. - -**Parameters** - -- `geojson` **[GeoJSON][1]** any GeoJSON Feature, FeatureCollection, Geometry or GeometryCollection. -- `options` **[Object][2]** Optional parameters (optional, default `{}`) - - `options.precision` **[number][3]** coordinate decimal precision (optional, default `6`) - - `options.coordinates` **[number][3]** maximum number of coordinates (primarly used to remove z coordinates) (optional, default `3`) - - `options.mutate` **[boolean][4]** allows GeoJSON input to be mutated (significant performance increase if true) (optional, default `false`) - -**Examples** - -```javascript -var point = turf.point([ - 70.46923055566859, - 58.11088890802906, - 1508 -]); -var options = {precision: 3, coordinates: 2}; -var truncated = turf.truncate(point, options); -//=truncated.geometry.coordinates => [70.469, 58.111] - -//addToMap -var addToMap = [truncated]; -``` - -Returns **[GeoJSON][1]** layer with truncated geometry - -[1]: https://tools.ietf.org/html/rfc7946#section-3 - -[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/truncate -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-truncate/index.ts b/packages/turf-truncate/index.ts deleted file mode 100644 index c9d5fc8e59..0000000000 --- a/packages/turf-truncate/index.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { coordEach } from '@turf/meta'; -import { AllGeoJSON } from '@turf/helpers'; - -/** - * Takes a GeoJSON Feature or FeatureCollection and truncates the precision of the geometry. - * - * @name truncate - * @param {GeoJSON} geojson any GeoJSON Feature, FeatureCollection, Geometry or GeometryCollection. - * @param {Object} [options={}] Optional parameters - * @param {number} [options.precision=6] coordinate decimal precision - * @param {number} [options.coordinates=3] maximum number of coordinates (primarly used to remove z coordinates) - * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) - * @returns {GeoJSON} layer with truncated geometry - * @example - * var point = turf.point([ - * 70.46923055566859, - * 58.11088890802906, - * 1508 - * ]); - * var options = {precision: 3, coordinates: 2}; - * var truncated = turf.truncate(point, options); - * //=truncated.geometry.coordinates => [70.469, 58.111] - * - * //addToMap - * var addToMap = [truncated]; - */ -function truncate(geojson: T, options: { - precision?: number, - coordinates?: number, - mutate?: boolean -} = {}): T { - // Optional parameters - var precision = options.precision; - var coordinates = options.coordinates; - var mutate = options.mutate; - - // default params - precision = (precision === undefined || precision === null || isNaN(precision)) ? 6 : precision; - coordinates = (coordinates === undefined || coordinates === null || isNaN(coordinates)) ? 3 : coordinates; - - // validation - if (!geojson) throw new Error(' is required'); - if (typeof precision !== 'number') throw new Error(' must be a number'); - if (typeof coordinates !== 'number') throw new Error(' must be a number'); - - // prevent input mutation - if (mutate === false || mutate === undefined) geojson = JSON.parse(JSON.stringify(geojson)); - - var factor = Math.pow(10, precision); - - // Truncate Coordinates - coordEach(geojson, function (coords) { - truncateCoords(coords, factor, coordinates); - }); - return geojson; -} - -/** - * Truncate Coordinates - Mutates coordinates in place - * - * @private - * @param {Array} coords Geometry Coordinates - * @param {number} factor rounding factor for coordinate decimal precision - * @param {number} coordinates maximum number of coordinates (primarly used to remove z coordinates) - * @returns {Array} mutated coordinates - */ -function truncateCoords(coords, factor, coordinates) { - // Remove extra coordinates (usually elevation coordinates and more) - if (coords.length > coordinates) coords.splice(coordinates, coords.length); - - // Truncate coordinate decimals - for (var i = 0; i < coords.length; i++) { - coords[i] = Math.round(coords[i] * factor) / factor; - } - return coords; -} - -export default truncate; diff --git a/packages/turf-truncate/package.json b/packages/turf-truncate/package.json deleted file mode 100644 index 01426f11fe..0000000000 --- a/packages/turf-truncate/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@turf/truncate", - "version": "6.0.1", - "description": "turf truncate module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geojson", - "gis", - "truncate" - ], - "author": "Turf Authors", - "contributors": [ - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/meta": "6.x" - } -} diff --git a/packages/turf-truncate/test.js b/packages/turf-truncate/test.js deleted file mode 100644 index c33dfeb29a..0000000000 --- a/packages/turf-truncate/test.js +++ /dev/null @@ -1,55 +0,0 @@ -const fs = require('fs'); -const test = require('tape'); -const path = require('path'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const { point } = require('@turf/helpers'); -const truncate = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -let fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); -// fixtures = fixtures.filter(fixture => fixture.name === 'points'); - -test('turf-truncate', t => { - for (const {filename, name, geojson} of fixtures) { - const {precision, coordinates} = geojson.properties || {}; - const results = truncate(geojson, { - precision: precision, - coordinates: coordinates - }); - - if (process.env.REGEN) write.sync(directories.out + filename, results); - t.deepEqual(results, load.sync(directories.out + filename), name); - } - t.end(); -}); - -test('turf-truncate - precision & coordinates', t => { - t.deepEqual(truncate(point([50.1234567, 40.1234567]), {precision: 3}).geometry.coordinates, [50.123, 40.123], 'precision 3'); - t.deepEqual(truncate(point([50.1234567, 40.1234567]), {precision: 0}).geometry.coordinates, [50, 40], 'precision 0'); - t.deepEqual(truncate(point([50, 40, 1100]), {precision: 6}).geometry.coordinates, [50, 40, 1100], 'coordinates default to 3'); - t.deepEqual(truncate(point([50, 40, 1100]), {precision: 6, coordinates: 2}).geometry.coordinates, [50, 40], 'coordinates 2'); - t.end(); -}); - -test('turf-truncate - prevent input mutation', t => { - const pt = point([120.123, 40.123, 3000]); - const ptBefore = JSON.parse(JSON.stringify(pt)); - - truncate(pt, {precision: 0}); - t.deepEqual(ptBefore, pt, 'does not mutate input'); - - truncate(pt, {precision: 0, coordinates: 2, mutate: true}); - t.deepEqual(pt, point([120, 40]), 'does mutate input'); - t.end(); -}); diff --git a/packages/turf-truncate/types.ts b/packages/turf-truncate/types.ts deleted file mode 100644 index 02982c84e9..0000000000 --- a/packages/turf-truncate/types.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { featureCollection, point, lineString, geometryCollection } from '@turf/helpers' -import truncate from './' - -const pt = point([120.1234567, 40.1234567]) -const ptGeom = pt.geometry -const line = lineString([[20,80], [50, 40]]) -const lineGeom = line.geometry -const points = featureCollection([pt]) -const lines = featureCollection([line]) -const geomCollection = geometryCollection([ptGeom, lineGeom]) - -truncate(pt) -truncate(ptGeom) -truncate(line) -truncate(lineGeom) -truncate(lines) -truncate(points) -truncate(geomCollection) -truncate(pt, {precision: 6}) -truncate(pt, {precision: 3, coordinates: 2}) -truncate(pt, {precision: 3, coordinates: 2, mutate: false}) diff --git a/packages/turf-union/.gitignore b/packages/turf-union/.gitignore deleted file mode 100644 index 945ce43a90..0000000000 --- a/packages/turf-union/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/packages/turf-union/LICENSE b/packages/turf-union/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-union/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-union/README.md b/packages/turf-union/README.md deleted file mode 100644 index 6f88cc9237..0000000000 --- a/packages/turf-union/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# @turf/union - - - -## union - -Takes two [(Multi)Polygon(s)][1] and returns a combined polygon. If the input polygons are not contiguous, this function returns a [MultiPolygon][2] feature. - -**Parameters** - -- `polygon1` **[Feature][3]<([Polygon][4] \| [MultiPolygon][5])>** input Polygon feature -- `polygon2` **[Feature][3]<([Polygon][4] \| [MultiPolygon][5])>** Polygon feature to difference from polygon1 -- `options` **[Object][6]** Optional Parameters (optional, default `{}`) - - `options.properties` **[Object][6]** Translate Properties to output Feature (optional, default `{}`) - -**Examples** - -```javascript -var poly1 = turf.polygon([[ - [-82.574787, 35.594087], - [-82.574787, 35.615581], - [-82.545261, 35.615581], - [-82.545261, 35.594087], - [-82.574787, 35.594087] -]], {"fill": "#0f0"}); -var poly2 = turf.polygon([[ - [-82.560024, 35.585153], - [-82.560024, 35.602602], - [-82.52964, 35.602602], - [-82.52964, 35.585153], - [-82.560024, 35.585153] -]], {"fill": "#00f"}); - -var union = turf.union(poly1, poly2); - -//addToMap -var addToMap = [poly1, poly2, union]; -``` - -Returns **[Feature][3]<([Polygon][4] \| [MultiPolygon][5])>** a combined [Polygon][1] or [MultiPolygon][2] feature - -[1]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - -[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/union -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-union/index.ts b/packages/turf-union/index.ts deleted file mode 100644 index d694c1da47..0000000000 --- a/packages/turf-union/index.ts +++ /dev/null @@ -1,50 +0,0 @@ -import * as martinez from 'martinez-polygon-clipping'; -import { getGeom } from '@turf/invariant'; -import { multiPolygon, polygon } from '@turf/helpers'; -import { Feature, Polygon, MultiPolygon, Properties } from '@turf/helpers'; - -/** - * Takes two {@link (Multi)Polygon(s)} and returns a combined polygon. If the input polygons are not contiguous, this function returns a {@link MultiPolygon} feature. - * - * @name union - * @param {Feature} polygon1 input Polygon feature - * @param {Feature} polygon2 Polygon feature to difference from polygon1 - * @param {Object} [options={}] Optional Parameters - * @param {Object} [options.properties={}] Translate Properties to output Feature - * @returns {Feature<(Polygon|MultiPolygon)>} a combined {@link Polygon} or {@link MultiPolygon} feature - * @example - * var poly1 = turf.polygon([[ - * [-82.574787, 35.594087], - * [-82.574787, 35.615581], - * [-82.545261, 35.615581], - * [-82.545261, 35.594087], - * [-82.574787, 35.594087] - * ]], {"fill": "#0f0"}); - * var poly2 = turf.polygon([[ - * [-82.560024, 35.585153], - * [-82.560024, 35.602602], - * [-82.52964, 35.602602], - * [-82.52964, 35.585153], - * [-82.560024, 35.585153] - * ]], {"fill": "#00f"}); - * - * var union = turf.union(poly1, poly2); - * - * //addToMap - * var addToMap = [poly1, poly2, union]; - */ -function union

( - polygon1: Feature | Polygon | MultiPolygon, - polygon2: Feature | Polygon | MultiPolygon, - options: {properties?: P} = {} -): Feature { - const coords1 = getGeom(polygon1).coordinates; - const coords2 = getGeom(polygon2).coordinates; - - const unioned: any = martinez.union(coords1, coords2); - if (unioned.length === 0) return null; - if (unioned.length === 1) return polygon(unioned[0], options.properties); - else return multiPolygon(unioned, options.properties); -} - -export default union; diff --git a/packages/turf-union/package.json b/packages/turf-union/package.json deleted file mode 100644 index c1cf8cdd58..0000000000 --- a/packages/turf-union/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "@turf/union", - "version": "6.0.2", - "description": "turf union module", - "main": "index", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts" - ], - "scripts": { - "prepare": "tsc", - "pretest": "tsc", - "test": "node test.js", - "bench": "node bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "gif" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "benchmark": "*", - "glob": "*", - "load-json-file": "*", - "typescript": "*", - "tape": "*", - "write-json-file": "*", - "@turf/combine": "*", - "tslint": "*", - "@types/tape": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "martinez-polygon-clipping": "^0.4.3" - } -} diff --git a/packages/turf-union/test.js b/packages/turf-union/test.js deleted file mode 100644 index 4413dcd87a..0000000000 --- a/packages/turf-union/test.js +++ /dev/null @@ -1,36 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const test = require('tape'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const combine = require('@turf/combine').default; -const union = require('./').default; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return { - filename, - name: path.parse(filename).name, - geojson: load.sync(directories.in + filename) - }; -}); - -test('union', function (t) { - for (const {name, geojson, filename} of fixtures) { - let result = null; - if (geojson.features.length > 2) { - var last = geojson.features.pop(); - var multipoly = combine(geojson); - result = union(last, multipoly.features[0]); - } else { - result = union(geojson.features[0], geojson.features[1]); - } - if (process.env.REGEN) write.sync(directories.out + filename, result); - t.deepEqual(result, load.sync(directories.out + filename), name); - } - t.end(); -}); diff --git a/packages/turf-union/test/out/union1.geojson b/packages/turf-union/test/out/union1.geojson deleted file mode 100644 index 3f56c71a34..0000000000 --- a/packages/turf-union/test/out/union1.geojson +++ /dev/null @@ -1,47 +0,0 @@ -{ - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -80.15350341796875, - 32.82825010814964 - ], - [ - -80.00312805175781, - 32.69428812316933 - ], - [ - -79.92322780260464, - 32.73910022106017 - ], - [ - -79.80537414550781, - 32.7231762754146 - ], - [ - -79.81773376464844, - 32.923402043498875 - ], - [ - -79.92141723632812, - 32.953944317478246 - ], - [ - -79.94623496447946, - 32.89900638172028 - ], - [ - -80.09788513183594, - 32.927436533285565 - ], - [ - -80.15350341796875, - 32.82825010814964 - ] - ] - ] - } -} diff --git a/packages/turf-union/test/out/union2.geojson b/packages/turf-union/test/out/union2.geojson deleted file mode 100644 index b47de1d359..0000000000 --- a/packages/turf-union/test/out/union2.geojson +++ /dev/null @@ -1,87 +0,0 @@ -{ - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -80.14389038085938, - 32.8149783969858 - ], - [ - -80.07453918457031, - 32.85536439443039 - ], - [ - -80.00867471875296, - 32.846454942587876 - ], - [ - -80.02726389659408, - 32.92063024667495 - ], - [ - -79.98184204101562, - 32.90495631913751 - ], - [ - -79.99351501464844, - 32.84440429734253 - ], - [ - -80.00867471875296, - 32.846454942587876 - ], - [ - -79.99171138057724, - 32.77876713098757 - ], - [ - -80.00175476074217, - 32.732418508353746 - ], - [ - -79.93763756501369, - 32.741047214297545 - ], - [ - -79.80537414550781, - 32.7231762754146 - ], - [ - -79.81773376464844, - 32.923402043498875 - ], - [ - -79.91098503795921, - 32.95087128128811 - ], - [ - -79.95025634765625, - 32.97007559940924 - ], - [ - -79.95741485597671, - 32.93704020740794 - ], - [ - -80.03128051757812, - 32.936657533381286 - ], - [ - -80.02726389659408, - 32.92063024667495 - ], - [ - -80.10543823242188, - 32.94760622243483 - ], - [ - -80.14389038085938, - 32.8149783969858 - ] - ] - ] - } -} diff --git a/packages/turf-union/test/out/union3.geojson b/packages/turf-union/test/out/union3.geojson deleted file mode 100644 index f34b2b4e5f..0000000000 --- a/packages/turf-union/test/out/union3.geojson +++ /dev/null @@ -1,113 +0,0 @@ -{ - "type": "Feature", - "properties": {}, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [ - -80.15350341796875, - 32.82825010814964 - ], - [ - -80.00312805175781, - 32.69428812316933 - ], - [ - -79.92322780260464, - 32.73910022106017 - ], - [ - -79.93789672851562, - 32.74108223150125 - ], - [ - -79.93034362792969, - 32.76475877693074 - ], - [ - -79.97360229492188, - 32.76071688548088 - ], - [ - -79.97428894042969, - 32.83690450361482 - ], - [ - -79.94623496447946, - 32.89900638172028 - ], - [ - -80.09788513183594, - 32.927436533285565 - ], - [ - -80.15350341796875, - 32.82825010814964 - ] - ] - ], - [ - [ - [ - -79.94623496447946, - 32.89900638172028 - ], - [ - -79.88571166992188, - 32.887659962078956 - ], - [ - -79.89395141601562, - 32.75551989829049 - ], - [ - -79.92322780260464, - 32.73910022106017 - ], - [ - -79.87698786324371, - 32.73285245328464 - ], - [ - -79.88433837890625, - 32.687931474529464 - ], - [ - -79.79232788085938, - 32.679840539897484 - ], - [ - -79.63233947753906, - 32.804590457442565 - ], - [ - -79.64881896972656, - 32.915908931564864 - ], - [ - -79.78958129882812, - 32.913603231028915 - ], - [ - -79.81582464318822, - 32.89247428541929 - ], - [ - -79.81773376464844, - 32.923402043498875 - ], - [ - -79.92141723632812, - 32.953944317478246 - ], - [ - -79.94623496447946, - 32.89900638172028 - ] - ] - ] - ] - } -} diff --git a/packages/turf-union/types.ts b/packages/turf-union/types.ts deleted file mode 100644 index dd52154de7..0000000000 --- a/packages/turf-union/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { polygon } from '@turf/helpers'; -import union from './'; - -const poly1 = polygon([[[0, 0], [10, 10], [20, 20], [0, 0]]]); -const poly2 = polygon([[[20, 30], [10, 10], [20, 20], [20, 30]]]); -union(poly1, poly2); diff --git a/packages/turf-unkink-polygon/LICENSE b/packages/turf-unkink-polygon/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-unkink-polygon/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-unkink-polygon/README.md b/packages/turf-unkink-polygon/README.md deleted file mode 100644 index be13192729..0000000000 --- a/packages/turf-unkink-polygon/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# @turf/unkink-polygon - - - -## unkinkPolygon - -Takes a kinked polygon and returns a feature collection of polygons that have no kinks. -Uses [simplepolygon][1] internally. - -**Parameters** - -- `geojson` **([FeatureCollection][2] \| [Feature][3]<([Polygon][4] \| [MultiPolygon][5])>)** GeoJSON Polygon or MultiPolygon - -**Examples** - -```javascript -var poly = turf.polygon([[[0, 0], [2, 0], [0, 2], [2, 2], [0, 0]]]); - -var result = turf.unkinkPolygon(poly); - -//addToMap -var addToMap = [poly, result] -``` - -Returns **[FeatureCollection][2]<[Polygon][4]>** Unkinked polygons - -[1]: https://github.com/mclaeysb/simplepolygon - -[2]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[3]: https://tools.ietf.org/html/rfc7946#section-3.2 - -[4]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - -[5]: https://tools.ietf.org/html/rfc7946#section-3.1.7 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/unkink-polygon -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-unkink-polygon/index.d.ts b/packages/turf-unkink-polygon/index.d.ts deleted file mode 100644 index 010cd2c72d..0000000000 --- a/packages/turf-unkink-polygon/index.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Polygon, MultiPolygon, Feature, FeatureCollection } from '@turf/helpers'; - -/** - * http://turfjs.org/docs/#unkink-polygon - */ -export default function unkinkPolygon( - geojson: Feature | FeatureCollection | T -): FeatureCollection; diff --git a/packages/turf-unkink-polygon/index.js b/packages/turf-unkink-polygon/index.js deleted file mode 100644 index 9694237cab..0000000000 --- a/packages/turf-unkink-polygon/index.js +++ /dev/null @@ -1,31 +0,0 @@ -import { flattenEach, featureEach } from '@turf/meta'; -import { polygon, featureCollection } from '@turf/helpers'; -import simplepolygon from './lib/simplepolygon'; - -/** - * Takes a kinked polygon and returns a feature collection of polygons that have no kinks. - * Uses [simplepolygon](https://github.com/mclaeysb/simplepolygon) internally. - * - * @name unkinkPolygon - * @param {FeatureCollection|Feature} geojson GeoJSON Polygon or MultiPolygon - * @returns {FeatureCollection} Unkinked polygons - * @example - * var poly = turf.polygon([[[0, 0], [2, 0], [0, 2], [2, 2], [0, 0]]]); - * - * var result = turf.unkinkPolygon(poly); - * - * //addToMap - * var addToMap = [poly, result] - */ -function unkinkPolygon(geojson) { - var features = []; - flattenEach(geojson, function (feature) { - if (feature.geometry.type !== 'Polygon') return; - featureEach(simplepolygon(feature), function (poly) { - features.push(polygon(poly.geometry.coordinates, feature.properties)); - }); - }); - return featureCollection(features); -} - -export default unkinkPolygon; diff --git a/packages/turf-unkink-polygon/package.json b/packages/turf-unkink-polygon/package.json deleted file mode 100644 index 57d7005779..0000000000 --- a/packages/turf-unkink-polygon/package.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "name": "@turf/unkink-polygon", - "version": "5.1.5", - "description": "turf unkink-polygon module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "lib", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "kinks", - "unkink", - "polygon", - "self-intersection" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "@turf/kinks": "^5.1.5", - "benchmark": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/area": "6.x", - "@turf/boolean-point-in-polygon": "6.x", - "@turf/helpers": "6.x", - "@turf/meta": "6.x", - "rbush": "^2.0.1" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-unkink-polygon/test.js b/packages/turf-unkink-polygon/test.js deleted file mode 100644 index 548a52e73b..0000000000 --- a/packages/turf-unkink-polygon/test.js +++ /dev/null @@ -1,64 +0,0 @@ -import fs from 'fs'; -import path from 'path'; -import test from 'tape'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import { featureEach } from '@turf/meta'; -import { featureCollection } from '@turf/helpers'; -import kinks from '@turf/kinks'; -import unkinkPolygon from '.'; - -const directories = { - in: path.join(__dirname, 'test', 'in') + path.sep, - out: path.join(__dirname, 'test', 'out') + path.sep -}; - -const fixtures = fs.readdirSync(directories.in).map(filename => { - return {filename, geojson: load.sync(directories.in + filename)}; -}); - -test('unkink-polygon', t => { - for (const {filename, geojson} of fixtures) { - const unkinked = unkinkPolygon(geojson); - - // Detect if kinks exists - featureEach(unkinked, feature => { - // Throw Error when Issue #1094 is fixed - if (kinks(feature).features.length) t.skip(filename + ' has kinks') - }) - - // Style results - const results = colorize(unkinked); - if (process.env.REGEN) write.sync(directories.out + filename, unkinked); - - const expected = load.sync(directories.out + filename); - t.deepEquals(unkinked, expected, path.parse(filename).name); - } - t.end(); -}); - -test('unkink-polygon -- throws', t => { - var array = [1, 2, 3, 4, 5]; - for (const value in array) { - t.true(value !== 'isUnique', 'isUnique'); - t.true(value !== 'getUnique', 'getUnique'); - } - t.throws(() => Array.isUnique(), 'isUnique()'); - t.throws(() => Array.getUnique(), 'getUnique()'); - t.end(); -}); - -function colorize(features, colors = ['#F00', '#00F', '#0F0', '#F0F', '#FFF'], width = 6) { - const results = []; - featureEach(features, (feature, index) => { - const color = colors[index % colors.length]; - feature.properties = Object.assign({ - stroke: color, - fill: color, - 'stroke-width': width, - 'fill-opacity': 0.5 - }, feature.properties); - results.push(feature); - }); - return featureCollection(results); -} diff --git a/packages/turf-unkink-polygon/types.ts b/packages/turf-unkink-polygon/types.ts deleted file mode 100644 index 5503611220..0000000000 --- a/packages/turf-unkink-polygon/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { polygon, multiPolygon } from '@turf/helpers'; -import unkink from './'; - -const poly = polygon([[[20, 30], [10, 10], [20, 20], [20, 30]]]); -const multiPoly = multiPolygon([ - [[[20, 30], [10, 10], [20, 20], [20, 30]]], - [[[0, 0], [10, 10], [20, 20], [0, 0]]] -]); - -unkink(poly); -unkink(multiPoly); diff --git a/packages/turf-voronoi/LICENSE b/packages/turf-voronoi/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf-voronoi/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf-voronoi/README.md b/packages/turf-voronoi/README.md deleted file mode 100644 index a1d1676c52..0000000000 --- a/packages/turf-voronoi/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# @turf/voronoi - - - -## voronoi - -Takes a FeatureCollection of points, and a bounding box, and returns a FeatureCollection -of Voronoi polygons. - -The Voronoi algorithim used comes from the d3-voronoi package. - -**Parameters** - -- `points` **[FeatureCollection][1]<[Point][2]>** to find the Voronoi polygons around. -- `options` **[Object][3]** Optional parameters (optional, default `{}`) - - `options.bbox` **[Array][4]<[number][5]>** clipping rectangle, in [minX, minY, maxX, MaxY] order. (optional, default `[-180,-85,180,-85]`) - -**Examples** - -```javascript -var options = { - bbox: [-70, 40, -60, 60] -}; -var points = turf.randomPoint(100, options); -var voronoiPolygons = turf.voronoi(points, options); - -//addToMap -var addToMap = [voronoiPolygons, points]; -``` - -Returns **[FeatureCollection][1]<[Polygon][6]>** a set of polygons, one per input point. - -[1]: https://tools.ietf.org/html/rfc7946#section-3.3 - -[2]: https://tools.ietf.org/html/rfc7946#section-3.1.2 - -[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - -[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array - -[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number - -[6]: https://tools.ietf.org/html/rfc7946#section-3.1.6 - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/voronoi -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf-voronoi/index.d.ts b/packages/turf-voronoi/index.d.ts deleted file mode 100644 index ed756838d2..0000000000 --- a/packages/turf-voronoi/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { FeatureCollection, BBox, Point, Polygon } from '@turf/helpers'; - -/** - * http://turfjs.org/docs/#voronoi - */ -export default function voronoi( - points: FeatureCollection, - bbox: BBox -): FeatureCollection; diff --git a/packages/turf-voronoi/index.js b/packages/turf-voronoi/index.js deleted file mode 100644 index 2dcb6fc476..0000000000 --- a/packages/turf-voronoi/index.js +++ /dev/null @@ -1,59 +0,0 @@ -import { polygon, featureCollection, isObject } from '@turf/helpers'; -import { collectionOf } from '@turf/invariant'; -import * as d3voronoi from 'd3-voronoi'; - -/** - * @private - * @param {Array>} coords representing a polygon - * @returns {Feature} polygon - */ -function coordsToPolygon(coords) { - coords = coords.slice(); - coords.push(coords[0]); - return polygon([coords]); -} - -/** - * Takes a FeatureCollection of points, and a bounding box, and returns a FeatureCollection - * of Voronoi polygons. - * - * The Voronoi algorithim used comes from the d3-voronoi package. - * - * @name voronoi - * @param {FeatureCollection} points to find the Voronoi polygons around. - * @param {Object} [options={}] Optional parameters - * @param {number[]} [options.bbox=[-180, -85, 180, -85]] clipping rectangle, in [minX, minY, maxX, MaxY] order. - * @returns {FeatureCollection} a set of polygons, one per input point. - * @example - * var options = { - * bbox: [-70, 40, -60, 60] - * }; - * var points = turf.randomPoint(100, options); - * var voronoiPolygons = turf.voronoi(points, options); - * - * //addToMap - * var addToMap = [voronoiPolygons, points]; - */ -function voronoi(points, options) { - // Optional params - options = options || {}; - if (!isObject(options)) throw new Error('options is invalid'); - var bbox = options.bbox || [-180, -85, 180, 85]; - - // Input Validation - if (!points) throw new Error('points is required'); - if (!Array.isArray(bbox)) throw new Error('bbox is invalid'); - collectionOf(points, 'Point', 'points'); - - // Main - return featureCollection( - d3voronoi.voronoi() - .x(function (feature) { return feature.geometry.coordinates[0]; }) - .y(function (feature) { return feature.geometry.coordinates[1]; }) - .extent([[bbox[0], bbox[1]], [bbox[2], bbox[3]]]) - .polygons(points.features) - .map(coordsToPolygon) - ); -} - -export default voronoi; diff --git a/packages/turf-voronoi/package.json b/packages/turf-voronoi/package.json deleted file mode 100644 index 9a1c6a452e..0000000000 --- a/packages/turf-voronoi/package.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "@turf/voronoi", - "version": "5.1.5", - "description": "turf voronoi module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "geometry", - "voronoi", - "polygons", - "points" - ], - "author": "Turf Authors", - "contributors": [ - "Philippe Riviere <@Fil>", - "Mike Bostock <@mbostock>", - "Steve Bennett <@stevage1>", - "Denis Carriere <@DenisCarriere>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "glob": "*", - "load-json-file": "*", - "rollup": "*", - "tape": "*", - "write-json-file": "*" - }, - "dependencies": { - "@turf/helpers": "6.x", - "@turf/invariant": "6.x", - "d3-voronoi": "1.1.2" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} diff --git a/packages/turf-voronoi/test.js b/packages/turf-voronoi/test.js deleted file mode 100644 index e7ec4af21e..0000000000 --- a/packages/turf-voronoi/test.js +++ /dev/null @@ -1,20 +0,0 @@ -import fs from 'fs'; -import test from 'tape'; -import glob from 'glob'; -import path from 'path'; -import load from 'load-json-file'; -import write from 'write-json-file'; -import voronoi from '.'; - -test('turf-voronoi', t => { - glob.sync(path.join(__dirname, 'test', 'in', '*.json')).forEach(filepath => { - const {name} = path.parse(filepath); - const geojson = load.sync(filepath); - const results = voronoi(geojson, {bbox: geojson.bbox}); - - const out = filepath.replace(path.join('test', 'in'), path.join('test', 'out')) - if (process.env.REGEN) write.sync(out, results); - t.deepEqual(results, load.sync(out), name); - }); - t.end(); -}); diff --git a/packages/turf/.gitignore b/packages/turf/.gitignore deleted file mode 100644 index 5768bdaf52..0000000000 --- a/packages/turf/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -turf.js -turf.js.map -turf.mjs -turf.mjs.map -turf.min.js -turf.es.js -turf.es.js.map -turf.min.js.map -test.example.js -index.js \ No newline at end of file diff --git a/packages/turf/LICENSE b/packages/turf/LICENSE deleted file mode 100644 index 96ce51b76f..0000000000 --- a/packages/turf/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 TurfJS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/turf/README.md b/packages/turf/README.md deleted file mode 100644 index 8ad1d51b08..0000000000 --- a/packages/turf/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# @turf/turf - -# turf - -Turf is a modular geospatial analysis engine written in JavaScript. It performs geospatial -processing tasks with GeoJSON data and can be run on a server or in a browser. - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install @turf/turf -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/packages/turf/index.d.ts b/packages/turf/index.d.ts deleted file mode 100644 index 44d1f3c06d..0000000000 --- a/packages/turf/index.d.ts +++ /dev/null @@ -1,146 +0,0 @@ -/** - * Turf is a modular geospatial analysis engine written in JavaScript. It performs geospatial - * processing tasks with GeoJSON data and can be run on a server or in a browser. - * - * @module turf - * @summary Geospatial analysis for JavaScript - */ -export {default as isolines} from '@turf/isolines'; -export {default as convex} from '@turf/convex'; -export {default as pointsWithinPolygon} from '@turf/points-within-polygon'; -export {default as concave} from '@turf/concave'; -export {default as collect} from '@turf/collect'; -export {default as flip} from '@turf/flip'; -export {default as simplify} from '@turf/simplify'; -export {default as bezierSpline} from '@turf/bezier-spline'; -export {default as tag} from '@turf/tag'; -export {default as sample} from '@turf/sample'; -export {default as envelope} from '@turf/envelope'; -export {default as square} from '@turf/square'; -export {default as circle} from '@turf/circle'; -export {default as midpoint} from '@turf/midpoint'; -export {default as center} from '@turf/center'; -export {default as centerOfMass} from '@turf/center-of-mass'; -export {default as centroid} from '@turf/centroid'; -export {default as combine} from '@turf/combine'; -export {default as distance} from '@turf/distance'; -export {default as explode} from '@turf/explode'; -export {default as bbox} from '@turf/bbox'; -export {default as tesselate} from '@turf/tesselate'; -export {default as bboxPolygon} from '@turf/bbox-polygon'; -export {default as booleanPointInPolygon} from '@turf/boolean-point-in-polygon'; -export {default as nearestPoint} from '@turf/nearest-point'; -export {default as nearestPointOnLine} from '@turf/nearest-point-on-line'; -export {default as nearestPointToLine} from '@turf/nearest-point-to-line'; -export {default as planepoint} from '@turf/planepoint'; -export {default as tin} from '@turf/tin'; -export {default as bearing} from '@turf/bearing'; -export {default as destination} from '@turf/destination'; -export {default as kinks} from '@turf/kinks'; -export {default as pointOnFeature} from '@turf/point-on-feature'; -export {default as area} from '@turf/area'; -export {default as along} from '@turf/along'; -export {default as length} from '@turf/length'; -export {default as lineSlice} from '@turf/line-slice'; -export {default as lineSliceAlong} from '@turf/line-slice-along'; -export {default as pointGrid} from '@turf/point-grid'; -export {default as truncate} from '@turf/truncate'; -export {default as flatten} from '@turf/flatten'; -export {default as lineIntersect} from '@turf/line-intersect'; -export {default as lineChunk} from '@turf/line-chunk'; -export {default as unkinkPolygon} from '@turf/unkink-polygon'; -export {default as greatCircle} from '@turf/great-circle'; -export {default as lineSegment} from '@turf/line-segment'; -export {default as lineSplit} from '@turf/line-split'; -export {default as lineArc} from '@turf/line-arc'; -export {default as polygonToLine} from '@turf/polygon-to-line'; -export {default as lineToPolygon} from '@turf/line-to-polygon'; -export {default as bboxClip} from '@turf/bbox-clip'; -export {default as lineOverlap} from '@turf/line-overlap'; -export {default as sector} from '@turf/sector'; -export {default as rhumbBearing} from '@turf/rhumb-bearing'; -export {default as rhumbDistance} from '@turf/rhumb-distance'; -export {default as rhumbDestination} from '@turf/rhumb-destination'; -export {default as polygonTangents} from '@turf/polygon-tangents'; -export {default as rewind} from '@turf/rewind'; -export {default as isobands} from '@turf/isobands'; -export {default as transformRotate} from '@turf/transform-rotate'; -export {default as transformScale} from '@turf/transform-scale'; -export {default as transformTranslate} from '@turf/transform-translate'; -export {default as lineOffset} from '@turf/line-offset'; -export {default as polygonize} from '@turf/polygonize'; -export {default as booleanDisjoint} from '@turf/boolean-disjoint'; -export {default as booleanContains} from '@turf/boolean-contains'; -export {default as booleanCrosses} from '@turf/boolean-crosses'; -export {default as booleanClockwise} from '@turf/boolean-clockwise'; -export {default as booleanOverlap} from '@turf/boolean-overlap'; -export {default as booleanPointOnLine} from '@turf/boolean-point-on-line'; -export {default as booleanEqual} from '@turf/boolean-equal'; -export {default as booleanWithin} from '@turf/boolean-within'; -export {default as clone} from '@turf/clone'; -export {default as cleanCoords} from '@turf/clean-coords'; -export {default as clustersDbscan} from '@turf/clusters-dbscan'; -export {default as clustersKmeans} from '@turf/clusters-kmeans'; -export {default as pointToLineDistance} from '@turf/point-to-line-distance'; -export {default as booleanParallel} from '@turf/boolean-parallel'; -export {default as shortestPath} from '@turf/shortest-path'; -export {default as voronoi} from '@turf/voronoi'; -export {default as ellipse} from '@turf/ellipse'; -export {default as centerMean} from '@turf/center-mean'; -export {default as centerMedian} from '@turf/center-median'; -export {default as standardDeviationalEllipse} from '@turf/standard-deviational-ellipse'; -export {default as angle} from '@turf/angle'; -export {default as polygonSmooth} from '@turf/polygon-smooth'; -export {default as moranIndex} from '@turf/moran-index'; -export {default as distanceWeight} from '@turf/distance-weight'; -export * from '@turf/projection'; -export * from '@turf/random'; -export * from '@turf/clusters'; -export * from '@turf/helpers'; -export * from '@turf/invariant'; -export * from '@turf/meta'; -import * as projection from '@turf/projection'; -import * as random from '@turf/random'; -import * as clusters from '@turf/clusters'; -import * as helpers from '@turf/helpers'; -import * as invariant from '@turf/invariant'; -import * as meta from '@turf/meta'; -export {projection, random, clusters, helpers, invariant, meta}; - -// JSTS Modules -export {default as difference} from '@turf/difference'; -export {default as buffer} from '@turf/buffer'; -export {default as union} from '@turf/union'; -export {default as intersect} from '@turf/intersect'; - -// JSTS Sub-Models -export {default as dissolve} from '@turf/dissolve'; -export {default as hexGrid} from '@turf/hex-grid'; -export {default as mask} from '@turf/mask'; -export {default as squareGrid} from '@turf/square-grid'; -export {default as triangleGrid} from '@turf/triangle-grid'; -export {default as interpolate} from '@turf/interpolate'; - -// Renamed modules (Backwards compatitble with v4.0) -// https://github.com/Turfjs/turf/issues/860 -export {default as pointOnSurface} from '@turf/point-on-feature'; -export {default as polygonToLineString} from '@turf/polygon-to-line'; -export {default as lineStringToPolygon} from '@turf/line-to-polygon'; -export {default as inside} from '@turf/boolean-point-in-polygon'; -export {default as within} from '@turf/points-within-polygon'; -export {default as bezier} from '@turf/bezier-spline'; -export {default as nearest} from '@turf/nearest-point'; -export {default as pointOnLine} from '@turf/nearest-point-on-line'; -export {default as lineDistance} from '@turf/length'; - -// Renamed methods (Backwards compatitble with v4.0) -// https://github.com/Turfjs/turf/issues/860 -export { - radiansToDegrees as radians2degrees, - degreesToRadians as degrees2radians, - lengthToDegrees as distanceToDegrees, - lengthToRadians as distanceToRadians, - radiansToLength as radiansToDistance, - bearingToAzimuth as bearingToAngle, - convertLength as convertDistance -} from '@turf/helpers'; diff --git a/packages/turf/index.mjs b/packages/turf/index.mjs deleted file mode 100644 index 44d1f3c06d..0000000000 --- a/packages/turf/index.mjs +++ /dev/null @@ -1,146 +0,0 @@ -/** - * Turf is a modular geospatial analysis engine written in JavaScript. It performs geospatial - * processing tasks with GeoJSON data and can be run on a server or in a browser. - * - * @module turf - * @summary Geospatial analysis for JavaScript - */ -export {default as isolines} from '@turf/isolines'; -export {default as convex} from '@turf/convex'; -export {default as pointsWithinPolygon} from '@turf/points-within-polygon'; -export {default as concave} from '@turf/concave'; -export {default as collect} from '@turf/collect'; -export {default as flip} from '@turf/flip'; -export {default as simplify} from '@turf/simplify'; -export {default as bezierSpline} from '@turf/bezier-spline'; -export {default as tag} from '@turf/tag'; -export {default as sample} from '@turf/sample'; -export {default as envelope} from '@turf/envelope'; -export {default as square} from '@turf/square'; -export {default as circle} from '@turf/circle'; -export {default as midpoint} from '@turf/midpoint'; -export {default as center} from '@turf/center'; -export {default as centerOfMass} from '@turf/center-of-mass'; -export {default as centroid} from '@turf/centroid'; -export {default as combine} from '@turf/combine'; -export {default as distance} from '@turf/distance'; -export {default as explode} from '@turf/explode'; -export {default as bbox} from '@turf/bbox'; -export {default as tesselate} from '@turf/tesselate'; -export {default as bboxPolygon} from '@turf/bbox-polygon'; -export {default as booleanPointInPolygon} from '@turf/boolean-point-in-polygon'; -export {default as nearestPoint} from '@turf/nearest-point'; -export {default as nearestPointOnLine} from '@turf/nearest-point-on-line'; -export {default as nearestPointToLine} from '@turf/nearest-point-to-line'; -export {default as planepoint} from '@turf/planepoint'; -export {default as tin} from '@turf/tin'; -export {default as bearing} from '@turf/bearing'; -export {default as destination} from '@turf/destination'; -export {default as kinks} from '@turf/kinks'; -export {default as pointOnFeature} from '@turf/point-on-feature'; -export {default as area} from '@turf/area'; -export {default as along} from '@turf/along'; -export {default as length} from '@turf/length'; -export {default as lineSlice} from '@turf/line-slice'; -export {default as lineSliceAlong} from '@turf/line-slice-along'; -export {default as pointGrid} from '@turf/point-grid'; -export {default as truncate} from '@turf/truncate'; -export {default as flatten} from '@turf/flatten'; -export {default as lineIntersect} from '@turf/line-intersect'; -export {default as lineChunk} from '@turf/line-chunk'; -export {default as unkinkPolygon} from '@turf/unkink-polygon'; -export {default as greatCircle} from '@turf/great-circle'; -export {default as lineSegment} from '@turf/line-segment'; -export {default as lineSplit} from '@turf/line-split'; -export {default as lineArc} from '@turf/line-arc'; -export {default as polygonToLine} from '@turf/polygon-to-line'; -export {default as lineToPolygon} from '@turf/line-to-polygon'; -export {default as bboxClip} from '@turf/bbox-clip'; -export {default as lineOverlap} from '@turf/line-overlap'; -export {default as sector} from '@turf/sector'; -export {default as rhumbBearing} from '@turf/rhumb-bearing'; -export {default as rhumbDistance} from '@turf/rhumb-distance'; -export {default as rhumbDestination} from '@turf/rhumb-destination'; -export {default as polygonTangents} from '@turf/polygon-tangents'; -export {default as rewind} from '@turf/rewind'; -export {default as isobands} from '@turf/isobands'; -export {default as transformRotate} from '@turf/transform-rotate'; -export {default as transformScale} from '@turf/transform-scale'; -export {default as transformTranslate} from '@turf/transform-translate'; -export {default as lineOffset} from '@turf/line-offset'; -export {default as polygonize} from '@turf/polygonize'; -export {default as booleanDisjoint} from '@turf/boolean-disjoint'; -export {default as booleanContains} from '@turf/boolean-contains'; -export {default as booleanCrosses} from '@turf/boolean-crosses'; -export {default as booleanClockwise} from '@turf/boolean-clockwise'; -export {default as booleanOverlap} from '@turf/boolean-overlap'; -export {default as booleanPointOnLine} from '@turf/boolean-point-on-line'; -export {default as booleanEqual} from '@turf/boolean-equal'; -export {default as booleanWithin} from '@turf/boolean-within'; -export {default as clone} from '@turf/clone'; -export {default as cleanCoords} from '@turf/clean-coords'; -export {default as clustersDbscan} from '@turf/clusters-dbscan'; -export {default as clustersKmeans} from '@turf/clusters-kmeans'; -export {default as pointToLineDistance} from '@turf/point-to-line-distance'; -export {default as booleanParallel} from '@turf/boolean-parallel'; -export {default as shortestPath} from '@turf/shortest-path'; -export {default as voronoi} from '@turf/voronoi'; -export {default as ellipse} from '@turf/ellipse'; -export {default as centerMean} from '@turf/center-mean'; -export {default as centerMedian} from '@turf/center-median'; -export {default as standardDeviationalEllipse} from '@turf/standard-deviational-ellipse'; -export {default as angle} from '@turf/angle'; -export {default as polygonSmooth} from '@turf/polygon-smooth'; -export {default as moranIndex} from '@turf/moran-index'; -export {default as distanceWeight} from '@turf/distance-weight'; -export * from '@turf/projection'; -export * from '@turf/random'; -export * from '@turf/clusters'; -export * from '@turf/helpers'; -export * from '@turf/invariant'; -export * from '@turf/meta'; -import * as projection from '@turf/projection'; -import * as random from '@turf/random'; -import * as clusters from '@turf/clusters'; -import * as helpers from '@turf/helpers'; -import * as invariant from '@turf/invariant'; -import * as meta from '@turf/meta'; -export {projection, random, clusters, helpers, invariant, meta}; - -// JSTS Modules -export {default as difference} from '@turf/difference'; -export {default as buffer} from '@turf/buffer'; -export {default as union} from '@turf/union'; -export {default as intersect} from '@turf/intersect'; - -// JSTS Sub-Models -export {default as dissolve} from '@turf/dissolve'; -export {default as hexGrid} from '@turf/hex-grid'; -export {default as mask} from '@turf/mask'; -export {default as squareGrid} from '@turf/square-grid'; -export {default as triangleGrid} from '@turf/triangle-grid'; -export {default as interpolate} from '@turf/interpolate'; - -// Renamed modules (Backwards compatitble with v4.0) -// https://github.com/Turfjs/turf/issues/860 -export {default as pointOnSurface} from '@turf/point-on-feature'; -export {default as polygonToLineString} from '@turf/polygon-to-line'; -export {default as lineStringToPolygon} from '@turf/line-to-polygon'; -export {default as inside} from '@turf/boolean-point-in-polygon'; -export {default as within} from '@turf/points-within-polygon'; -export {default as bezier} from '@turf/bezier-spline'; -export {default as nearest} from '@turf/nearest-point'; -export {default as pointOnLine} from '@turf/nearest-point-on-line'; -export {default as lineDistance} from '@turf/length'; - -// Renamed methods (Backwards compatitble with v4.0) -// https://github.com/Turfjs/turf/issues/860 -export { - radiansToDegrees as radians2degrees, - degreesToRadians as degrees2radians, - lengthToDegrees as distanceToDegrees, - lengthToRadians as distanceToRadians, - radiansToLength as radiansToDistance, - bearingToAzimuth as bearingToAngle, - convertLength as convertDistance -} from '@turf/helpers'; diff --git a/packages/turf/package.json b/packages/turf/package.json deleted file mode 100644 index 8e80959c8d..0000000000 --- a/packages/turf/package.json +++ /dev/null @@ -1,177 +0,0 @@ -{ - "name": "@turf/turf", - "version": "6.0.0", - "description": "a JavaScript library for performing geospatial operations with GeoJSON", - "main": "turf", - "module": "turf.mjs", - "browser": "turf.min.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.mjs", - "index.d.ts", - "turf.js", - "turf.mjs", - "turf.min.js" - ], - "scripts": { - "prepare": "rollup -c rollup.config.js", - "pretest": "rollup -f cjs -o index.js index.mjs", - "test": "node test.js", - "posttest": "node test.example.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "gis", - "geo", - "geojs", - "geospatial", - "geography", - "geometry", - "map", - "contour", - "centroid", - "tin", - "extent", - "geojson", - "grid", - "polygon", - "line", - "point", - "area", - "analysis", - "statistics", - "stats", - "midpoint", - "plane", - "quantile", - "jenks", - "sample" - ], - "author": "Turf Authors", - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "camelcase": "*", - "documentation": "*", - "glob": "*", - "rollup": "*", - "rollup-plugin-buble": "*", - "rollup-plugin-commonjs": "*", - "rollup-plugin-node-resolve": "*", - "rollup-plugin-uglify": "*", - "tape": "*" - }, - "dependencies": { - "@turf/along": "6.x", - "@turf/angle": "6.x", - "@turf/area": "6.x", - "@turf/bbox": "6.x", - "@turf/bbox-clip": "6.x", - "@turf/bbox-polygon": "6.x", - "@turf/bearing": "6.x", - "@turf/bezier-spline": "6.x", - "@turf/boolean-clockwise": "6.x", - "@turf/boolean-contains": "6.x", - "@turf/boolean-crosses": "6.x", - "@turf/boolean-disjoint": "6.x", - "@turf/boolean-equal": "6.x", - "@turf/boolean-overlap": "6.x", - "@turf/boolean-parallel": "6.x", - "@turf/boolean-point-in-polygon": "6.x", - "@turf/boolean-point-on-line": "6.x", - "@turf/boolean-within": "6.x", - "@turf/buffer": "5.1.x", - "@turf/center": "6.x", - "@turf/center-mean": "6.x", - "@turf/center-median": "6.x", - "@turf/center-of-mass": "6.x", - "@turf/centroid": "6.x", - "@turf/circle": "6.x", - "@turf/clean-coords": "6.x", - "@turf/clone": "6.x", - "@turf/clusters": "6.x", - "@turf/clusters-dbscan": "6.x", - "@turf/clusters-kmeans": "6.x", - "@turf/collect": "6.x", - "@turf/combine": "6.x", - "@turf/concave": "6.x", - "@turf/convex": "6.x", - "@turf/destination": "6.x", - "@turf/difference": "5.1.x", - "@turf/dissolve": "5.1.x", - "@turf/distance": "6.x", - "@turf/distance-weight": "6.x", - "@turf/ellipse": "5.1.x", - "@turf/envelope": "5.1.x", - "@turf/explode": "5.1.x", - "@turf/flatten": "5.1.x", - "@turf/flip": "5.1.x", - "@turf/great-circle": "5.1.x", - "@turf/helpers": "6.x", - "@turf/hex-grid": "5.1.x", - "@turf/interpolate": "5.1.x", - "@turf/intersect": "6.x", - "@turf/invariant": "6.x", - "@turf/isobands": "5.1.x", - "@turf/isolines": "5.1.x", - "@turf/kinks": "5.1.x", - "@turf/length": "6.x", - "@turf/line-arc": "5.1.x", - "@turf/line-chunk": "5.1.x", - "@turf/line-intersect": "6.x", - "@turf/line-offset": "5.1.x", - "@turf/line-overlap": "5.1.x", - "@turf/line-segment": "6.x", - "@turf/line-slice": "5.1.x", - "@turf/line-slice-along": "5.1.x", - "@turf/line-split": "5.1.x", - "@turf/line-to-polygon": "6.x", - "@turf/mask": "5.1.x", - "@turf/meta": "6.x", - "@turf/midpoint": "5.1.x", - "@turf/moran-index": "6.x", - "@turf/nearest-point": "5.1.x", - "@turf/nearest-point-on-line": "5.1.x", - "@turf/nearest-point-to-line": "6.x", - "@turf/planepoint": "5.1.x", - "@turf/point-grid": "6.x", - "@turf/point-on-feature": "5.1.x", - "@turf/point-to-line-distance": "6.x", - "@turf/points-within-polygon": "5.1.x", - "@turf/polygon-smooth": "5.x", - "@turf/polygon-tangents": "5.1.x", - "@turf/polygon-to-line": "6.x", - "@turf/polygonize": "5.1.x", - "@turf/projection": "6.x", - "@turf/random": "6.x", - "@turf/rewind": "5.1.x", - "@turf/rhumb-bearing": "6.x", - "@turf/rhumb-destination": "6.x", - "@turf/rhumb-distance": "6.x", - "@turf/sample": "5.1.x", - "@turf/sector": "5.1.x", - "@turf/shortest-path": "5.1.x", - "@turf/simplify": "5.1.x", - "@turf/square": "5.1.x", - "@turf/square-grid": "5.1.x", - "@turf/standard-deviational-ellipse": "5.1.x", - "@turf/tag": "5.1.x", - "@turf/tesselate": "5.1.x", - "@turf/tin": "6.x", - "@turf/transform-rotate": "5.1.x", - "@turf/transform-scale": "5.1.x", - "@turf/transform-translate": "5.1.x", - "@turf/triangle-grid": "5.1.x", - "@turf/truncate": "6.x", - "@turf/union": "5.1.x", - "@turf/unkink-polygon": "5.1.x", - "@turf/voronoi": "5.1.x" - } -} diff --git a/packages/turf/rollup.config.js b/packages/turf/rollup.config.js deleted file mode 100644 index 11a07c4794..0000000000 --- a/packages/turf/rollup.config.js +++ /dev/null @@ -1,22 +0,0 @@ -import node from 'rollup-plugin-node-resolve' -import commonjs from 'rollup-plugin-commonjs' -import uglify from 'rollup-plugin-uglify' - -const pckg = require('./package') -const input = 'index.mjs' - -export default [{ - input, - output: [ - {file: pckg.main + '.js', format: 'umd', name: 'turf'}, - {file: pckg.module, format: 'es'}, - ], - plugins: [commonjs(), node()] -}, -{ - input, - output: [ - {file: pckg.browser, format: 'umd', name: 'turf'} - ], - plugins: [commonjs(), node(), uglify()] -}]; diff --git a/packages/turf/test.js b/packages/turf/test.js deleted file mode 100644 index b1eb6e97a9..0000000000 --- a/packages/turf/test.js +++ /dev/null @@ -1,364 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const glob = require('glob'); -const test = require('tape'); -const camelcase = require('camelcase'); -const documentation = require('documentation'); -const turf = require('./'); - -// Helpers -const directory = path.join(__dirname, '..'); -let modules = []; -for (const name of fs.readdirSync(directory)) { - if (!name.includes('turf')) continue; - const pckgPath = path.join(directory, name, 'package.json'); - const index = fs.readFileSync(path.join(directory, name, 'index.js'), 'utf8'); - const test = fs.readFileSync(path.join(directory, name, 'index.js'), 'utf8'); - - if (!fs.existsSync(pckgPath)) continue; - const pckg = JSON.parse(fs.readFileSync(pckgPath)); - modules.push({ - name, - pckg, - index, - test, - dir: path.join(directory, name), - dependencies: pckg.dependencies || {}, - devDependencies: pckg.devDependencies || {} - }); -} -// Exclude main Turf module -modules = modules.filter(({name}) => name !== 'turf'); - -test('turf -- required files', t => { - for (const {name, dir} of modules) { - for (const filename of ['test.js', 'index.js', 'index.d.ts', 'LICENSE', 'README.md']) { - // if (!fs.existsSync(path.join(dir, filename))) t.fail(`${name} ${filename} is required`); - } - // if (!fs.existsSync(path.join(dir, 'types.ts'))) t.fail(`${name} types.ts is required`); - } - t.skip('add "types.ts" to all packages'); - t.end(); -}); - -test('turf -- invalid dependencies', t => { - for (const {name, dependencies, devDependencies} of modules) { - for (const invalidDependency of ['load-json-file', 'write-json-file', 'tape', 'benchmark', 'glob', 'lerna', 'documentation', 'uglify-js']) { - if (dependencies[invalidDependency]) t.fail(`${name} ${invalidDependency} should be defined as devDependencies`); - } - if (devDependencies['eslint'] || devDependencies['eslint-config-mourner']) t.fail(`${name} eslint is handled at the root level`); - if (devDependencies['@turf/helpers']) t.fail(`${name} @turf/helpers should be located in Dependencies instead of DevDependencies`); - // if (devDependencies['mkdirp']) t.fail(`${name} tests should not have to create folders`); - } - t.skip('remove "mkdirp" from testing'); - t.end(); -}); - -test('turf -- * wildcard devDependencies', t => { - for (const {name, devDependencies} of modules) { - for (const dependency of Object.keys(devDependencies)) { - if (dependency.includes('@turf')) continue - if (dependency.includes('@std/esm')) continue - if (devDependencies[dependency] !== '*') t.fail(`${name} ${dependency} devDependencies must use *`); - } - } - t.end(); -}); - -test('turf -- strict version dependencies', t => { - for (const {name, dependencies} of modules) { - if (dependencies['jsts']) t.fail(name + ' jsts must use turf-jsts'); - if (dependencies['jsts-es']) t.fail(name + ' jsts-es must use turf-jsts'); - } - t.end(); -}); - -test('turf -- duplicate dependencies', t => { - for (const {name, dependencies, devDependencies} of modules) { - for (const dependency of Object.keys(dependencies)) { - if (devDependencies[dependency]) t.fail(`${name} ${dependency} is duplicated in devDependencies`); - } - } - t.end(); -}); - -test('turf -- check if files exists', t => { - for (const {name, dir, pckg} of modules) { - const {files} = pckg; - if (!files || !files.length) t.fail(`${name} (files) must be included in package.json`); - for (const file of files) { - // ignore Rollup bundle - if (file === 'main.js') continue; - if (file === 'main.es.js') continue; - if (file === 'index.d.ts') continue; - if (!fs.existsSync(path.join(dir, file))) t.fail(`${name} missing file ${file} in "files"`); - } - } - t.end(); -}); - -test('turf -- external files must be in the lib folder', t => { - for (const {name, pckg} of modules) { - const {files} = pckg; - for (const file of files) { - switch (file) { - case 'main.js': - case 'main.es.js': - case 'index.js': - case 'index.ts': - case 'index.mjs': - case 'index.d.ts': - case 'lib': - break; - default: - // t.fail(`${name} external files must be in the lib folder`) - } - } - } - t.end(); -}); - -test('turf -- MIT license', t => { - const text = fs.readFileSync(path.join(__dirname, 'LICENSE'), 'utf8'); - for (const {name, dir, pckg} of modules) { - const {license} = pckg; - if (license !== 'MIT') t.fail(`${name} (license) must be "MIT"`); - if (fs.readFileSync(path.join(dir, 'LICENSE'), 'utf8') !== text) t.fail(`${name} (LICENSE) is different from @turf/turf`); - } - t.end(); -}); - -test('turf -- contributors', t => { - for (const {name, pckg} of modules) { - for (const contributor of pckg.contributors || []) { - if (!contributor.match(/<@.+>/)) t.fail(`${name} ${contributor} (contributors) should use "Full Name <@GitHub>"`); - } - } - t.end(); -}); - -test('turf -- scoped package name', t => { - for (const {name, pckg} of modules) { - const expected = name.replace('turf-', '@turf/'); - if (pckg.name !== expected) t.fail(`${name} (name) must use ${expected} in package.json`); - } - t.end(); -}); - -test('turf -- pre-defined attributes in package.json', t => { - for (const {name, pckg} of modules) { - if (pckg.author !== 'Turf Authors') t.fail(name + ' (author) should be "Turf Authors"'); - // if (pckg.main !== 'main.js') t.skip(`${name} (main) must be "main.js" in package.json`); - // if (pckg.module !== 'main.es.js') t.skip(`${name} (module) must be "main.es.js" in package.json`); - if (pckg['jsnext:main']) t.fail(`${name} (jsnext:main) is no longer required in favor of using (module) in package.json`); - // if (pckg.types !== 'index.d.ts') t.fail(`${name} (types) must be "index.d.ts" in package.json`); - if (!pckg.bugs || pckg.bugs.url !== 'https://github.com/Turfjs/turf/issues') t.fail(`${name} (bugs.url) must be "https://github.com/Turfjs/turf/issues" in package.json`); - if (pckg.homepage !== 'https://github.com/Turfjs/turf') t.fail(`${name} (homepage) must be "https://github.com/Turfjs/turf" in package.json`); - } - t.end(); -}); - -test('turf -- parsing dependencies from index.js', t => { - for (const {name, dir, dependencies} of modules) { - const index = fs.readFileSync(path.join(dir, 'index.js'), 'utf8'); - - // Read Depedencies from index.js - const dependenciesUsed = new Set(); - for (const dependency of index.match(/(require\(|from )'[@/a-z-\d]+'/gi) || []) { - if (dependency.includes('jsts')) continue; - const dependencyName = dependency.split(/'/)[1]; - if (!dependencies[dependencyName]) t.skip(`${name} ${dependencyName} is missing from dependencies`); - if (dependenciesUsed.has(dependencyName)) t.skip(`${name} ${dependencyName} is duplicated in index.js`); - dependenciesUsed.add(dependencyName); - } - - // Read Dependencies from package.json - for (const dependencyName of Object.keys(dependencies)) { - // Ignore @turf/helpers since it could be used in Typescript definition - switch (dependencyName) { - case '@turf/helpers': - case '@turf/invariant': - case '@turf/meta': - case 'jsts': - case 'rbush': - case 'topojson-client': - case 'topojson-server': - continue; - } - if (!dependenciesUsed.has(dependencyName)) t.skip(`${name} ${dependencyName} is not required in index.js`); - } - } - t.end(); -}); - -// Test for missing modules -test('turf -- missing modules', t => { - const files = { - typescript: fs.readFileSync(path.join(__dirname, 'index.d.ts')), - modules: fs.readFileSync(path.join(__dirname, 'index.js')) - }; - - modules.forEach(({name}) => { - name = camelcase(name.replace('turf-', '')); - // name exception with linestring => lineString - name = name.replace('linestring', 'lineString').replace('Linestring', 'LineString'); - - // if (!files.typescript.includes(name)) t.skip(name + ' is missing from index.d.ts'); - if (!files.modules.includes(name)) t.skip(name + ' is missing from index.js'); - - switch (typeof turf[name]) { - case 'function': break; - case 'object': break; - case 'undefined': - t.skip(name + ' is missing from index.js'); - } - }); - t.end(); -}); - -const deprecated = { - modules: [ - '@turf/idw', - '@turf/line-distance', - '@turf/point-on-line', - '@turf/bezier', - '@turf/within', - '@turf/inside', - '@turf/nearest', - '@turf/polygon-to-linestring', - '@turf/linestring-to-polygon', - '@turf/point-on-surface' - ], - methods: [ - 'radians2degrees', - 'degrees2radians', - 'distanceToDegrees', - 'distanceToRadians', - 'radiansToDistance', - 'bearingToAngle', - 'convertDistance' - ] -} - -test('turf -- check for deprecated modules', t => { - for (const {name, dependencies, devDependencies} of modules) { - for (const dependency of [...Object.keys(dependencies), ...Object.keys(devDependencies)]) { - if (deprecated.modules.indexOf(dependency) !== -1) { - throw new Error(`${name} module has deprecated dependency ${dependency}`); - } - } - } - t.end(); -}); - -test('turf -- check for deprecated methods', t => { - for (const {name, index, test} of modules) { - // Exclude @turf/helpers from this test - if (name === 'turf-helpers') continue - for (const method of deprecated.methods) { - if ((test + index).match(method)) throw new Error(`${name} repo has deprecated method ${method}`); - } - } - t.end(); -}); - -// TurfJS v5.0 Typescript definition uses @turf/helpers -test('turf -- update to newer Typescript definitions', t => { - glob.sync(turfTypescriptPath).forEach(filepath => { - const typescript = fs.readFileSync(filepath, 'utf8'); - if (typescript.includes('reference types="geojson"')) t.skip(filepath + ' update Typescript definition v5.0'); - }); - t.end(); -}); - -// test('turf -- require() not allowed in favor of import', t => { -// for (const {name, index, test} of modules) { -// if ((index).includes('= require(')) throw new Error(`${name} module cannot use require(), use ES import instead`); -// } -// t.end(); -// }); - -/** - * ========================= - * Builds => test.example.js - * ========================= - * will be run as `posttest` - */ - -// File Paths -const testFilePath = path.join(__dirname, 'test.example.js'); -const turfModulesPath = path.join(__dirname, '..', 'turf-*', 'index.js'); -const turfTypescriptPath = path.join(__dirname, '..', 'turf-*', 'index.d.ts'); - -// Test Strings -const requireString = `const test = require('tape'); -const turf = require('./index'); -`; - -/** - * Generate Test String - * - * @param {Object} turfFunction Documentation function object - * @param {Object} example Documentation example object - * @returns {string} Test String - */ -function testString(turfFunction, example) { - const turfName = turfFunction.name; - const testFunctionName = turfName + 'Test'; - - // New modules will be excluded from tests - if (!turf[turfName]) return ` -test('turf-example-${turfName}', t => { - t.skip('${turfName}'); - t.end(); -}); -`; - // Specific moduels will exclude testing @example - switch (turfName) { - case 'isolines': - case 'isobands': - return ` - test('turf-example-${turfName}', t => { - t.skip('${turfName}'); - t.end(); - }); - `; - } - return ` -test('turf-example-${turfName}', t => { - const ${testFunctionName} = () => { - ${example.description} - } - ${testFunctionName}(); - t.pass('${turfName}'); - t.end(); -}); -`; -} - -// Iterate over each module and retrieve @example to build tests from them -glob(turfModulesPath, (err, files) => { - if (err) throw err; - - // Read each JSDocs from index.js files - documentation.build(files, {}).then(turfFunctions => { - if (err) throw err; - - // Write header of test.js - const writeableStream = fs.createWriteStream(testFilePath); - writeableStream.write(requireString); - writeableStream.on('error', err => { throw err; }); - - // Retrieve @example - turfFunctions.forEach(turfFunction => { - if (turfFunction.examples) { - - // Save to test.js - turfFunction.examples.forEach(example => { - writeableStream.write(testString(turfFunction, example)); - }); - } - }); - writeableStream.end(); - }); -}); diff --git a/rollup-plugins/typescript-export.js b/rollup-plugins/typescript-export.js deleted file mode 100644 index 2e3b2dfc34..0000000000 --- a/rollup-plugins/typescript-export.js +++ /dev/null @@ -1,12 +0,0 @@ -// https://github.com/Turfjs/turf/pull/986 -export default function () { - return { - name: 'typescript-export', - transformBundle(code) { - code = code.trim(); - const name = code.match(/module.exports = ([\w$]+);/); - if (name) code += `\nmodule.exports.default = ${name[1]};\n`; - return code; - } - }; -} diff --git a/rollup-plugins/valid-es5.js b/rollup-plugins/valid-es5.js deleted file mode 100644 index 88b53e08fb..0000000000 --- a/rollup-plugins/valid-es5.js +++ /dev/null @@ -1,24 +0,0 @@ -export default function () { - return { - name: 'valid-es5', - transformBundle(code) { - removeComments(code).match(/[\w\=\>]+/g).forEach(word => { - switch (word) { - case 'const': - case 'let': - case '=>': - throw new Error(word + ' is not valid ES5 syntax'); - } - }); - return code; - } - }; -} - -function removeComments(code) { - // Remove comments block comments - code = code.replace(/\/\*\*[\w\s*\.@{}|<>,=()[\];\/\-'`":]+\*\//g, ''); - // Remove inline comments - code = code.replace(/\/\/.+\n/g, '\n'); - return code; -} \ No newline at end of file diff --git a/rollup.config.js b/rollup.config.js index 34fd3c1666..f0776e8f1e 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,10 +1,25 @@ -import typescript from './rollup-plugins/typescript-export'; +import node from 'rollup-plugin-node-resolve' +import commonjs from 'rollup-plugin-commonjs' +import butternut from 'rollup-plugin-butternut' -export default { - input: 'index.js', +const pckg = require('./package') +const input = 'src/index.js' + +export default [{ + input, output: [ - {file: 'main.js', format: 'cjs'}, - {file: 'main.es.js', format: 'es'} + {file: pckg.main, format: 'umd', name: 'turf'}, + {file: 'dist/turf.es.js', format: 'es'} ], - plugins: [typescript()] -} + plugins: [node(), commonjs({ + include: 'node_modules/**' + })] + } + // { + // input, + // output: [ + // {file: pckg.browser, format: 'umd', name: 'turf'} + // ], + // plugins: [node(), commonjs(), butternut()] + // } +]; diff --git a/scripts/benchmarkModule.js b/scripts/benchmarkModule.js new file mode 100644 index 0000000000..8d842d1939 --- /dev/null +++ b/scripts/benchmarkModule.js @@ -0,0 +1,7 @@ +var path = require('path'); + +const turfModule = [process.argv[2]]; + +turfModule.forEach(function (dir) { + require(path.join(__dirname, '../src/', dir, 'bench.js')); //eslint-disable-line +}); diff --git a/scripts/checkTsProgress.js b/scripts/checkTsProgress.js deleted file mode 100644 index 560852821d..0000000000 --- a/scripts/checkTsProgress.js +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env node - -const path = require('path'); -const glob = require('glob'); -const fs = require('fs'); - -let count = 1; - -glob.sync(path.join(__dirname, '..', 'packages', 'turf-*')).forEach(pk => { - fs.stat(path.join(pk, 'index.ts'), function (err) { - if (err) { - console.log(count + '. ' + pk); - count++; - } - }); -}); diff --git a/scripts/create-new-module b/scripts/create-new-module index 24e62f59f0..56c9fac65f 100755 --- a/scripts/create-new-module +++ b/scripts/create-new-module @@ -23,7 +23,8 @@ const camelcaseName = camelcase(name); const decamelizeName = decamelize(name); // Create Folder -const folderPath = path.join(__dirname, '..', 'packages', `turf-${decamelizeName}`); +const folderPath = path.join(__dirname, '..', 'src', `${decamelizeName}`); + if (!fs.existsSync(folderPath)) { fs.mkdirSync(folderPath); fs.mkdirSync(path.join(folderPath, 'test')); @@ -47,68 +48,8 @@ export default function ${camelcaseName}(feature1, feature2) { }; `); -// Create package.json -fs.writeFileSync(path.join(folderPath, 'package.json'), `{ - "name": "@turf/${decamelizeName}", - "version": "5.0.0", - "description": "turf ${decamelizeName} module", - "main": "main.js", - "module": "main.es.js", - "types": "index.d.ts", - "files": [ - "index.js", - "index.d.ts", - "main.js", - "main.es.js" - ], - "scripts": { - "pretest": "rollup -c ../../rollup.config.js", - "test": "node -r @std/esm test.js", - "posttest": "node -r @std/esm ../../scripts/validate-es5-dependencies.js", - "bench": "node -r @std/esm bench.js", - "docs": "node ../../scripts/generate-readmes" - }, - "repository": { - "type": "git", - "url": "git://github.com/Turfjs/turf.git" - }, - "keywords": [ - "turf", - "${name}" - ], - "author": "Turf Authors", - "contributors": [ - "YOUR NAME <@GITHUB NAME>" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/Turfjs/turf/issues" - }, - "homepage": "https://github.com/Turfjs/turf", - "devDependencies": { - "@std/esm": "*", - "benchmark": "*", - "rollup": "*", - "write-json-file": "*", - "load-json-file": "*", - "tape": "*" - }, - "dependencies": { - "@turf/helpers": "*" - }, - "@std/esm": { - "esm": "js", - "cjs": true - } -} -`); - -// Create LICENSE -const license = path.join(__dirname, '..', 'packages', 'turf', 'LICENSE'); -fs.copySync(license, path.join(folderPath, 'LICENSE')); - // Create index.d.ts -fs.writeFileSync(path.join(folderPath, 'index.d.ts'), `import { Feature, GeometryObject } from '@turf/helpers' +fs.writeFileSync(path.join(folderPath, 'index.d.ts'), `import { Feature, GeometryObject } from '../helpers' /** * http://turfjs.org/docs/#${name.toLocaleLowerCase().replace('-', '')} @@ -132,7 +73,7 @@ import load from 'load-json-file'; * * */ -const suite = new Benchmark.Suite('turf-${decamelizeName}'); +const suite = new Benchmark.Suite('${decamelizeName}'); glob.sync(path.join(__dirname, 'test', 'in', '*.geojson')).forEach(filepath => { const {name} = path.parse(filepath); const geojson = load.sync(filepath); @@ -157,7 +98,7 @@ import load from 'load-json-file'; import write from 'write-json-file'; import ${camelcaseName} from '.'; -test('turf-${decamelizeName}', t => { +test('${decamelizeName}', t => { glob.sync(path.join(__dirname, 'test', 'in', '*.json')).forEach(filepath => { // Define params const {name} = path.parse(filepath); @@ -172,42 +113,3 @@ test('turf-${decamelizeName}', t => { t.end(); }); `); - - -// Create README.md -fs.writeFileSync(path.join(folderPath, 'README.md'), `# @turf/${decamelizeName} - -# ${camelcaseName} - - - -**Parameters** - - -**Examples** - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -\`\`\`sh -$ npm install @turf/${decamelizeName} -\`\`\` - -Or install the Turf module that includes it as a function: - -\`\`\`sh -$ npm install @turf/turf -\`\`\` -`); diff --git a/scripts/modifyIndex.js b/scripts/modifyIndex.js new file mode 100644 index 0000000000..ce27a212a9 --- /dev/null +++ b/scripts/modifyIndex.js @@ -0,0 +1,25 @@ +#!/usr/bin/env node +const fs = require('fs'); +const path = require('path'); +const glob = require('glob'); + +// Delete unused files +glob.sync(path.join(__dirname, '..', 'src', 'turf-*')).forEach(packagePath => { + + const filePath = path.join(packagePath, 'index.ts'); + + if (fs.existsSync(filePath)) { + var data = fs.readFileSync(filePath, 'utf-8'); + + var newValue = data.replace(/@turf\//g, '../'); + + if (newValue.includes('options')) { + newValue = newValue.replace(/options:([^)]*)/g, 'options'); + } + + newValue = newValue.replace(/:(?!.*\()([^,{]*)/g, ''); + + fs.writeFileSync(path.join(packagePath, 'index.js'), newValue, 'utf-8'); + } + +}); diff --git a/scripts/npm-publish-all b/scripts/npm-publish-all deleted file mode 100755 index 6fd47b8610..0000000000 --- a/scripts/npm-publish-all +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env node - -const path = require('path'); -const glob = require('glob'); -const {spawnSync} = require('child_process'); - -glob.sync(path.join(__dirname, '..', 'packages', 'turf-*', 'index.ts')).forEach(filepath => { - const {dir} = path.parse(filepath); - const log = spawnSync('npm', ['publish'], {encoding: 'utf8', cwd: dir}); - console.log(log.stdout.trim()); -}); - diff --git a/scripts/postfix.md b/scripts/postfix.md deleted file mode 100644 index 1a12decd20..0000000000 --- a/scripts/postfix.md +++ /dev/null @@ -1,25 +0,0 @@ - - - ---- - -This module is part of the [Turfjs project](http://turfjs.org/), an open source -module collection dedicated to geographic algorithms. It is maintained in the -[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create -PRs and issues. - -### Installation - -Install this module individually: - -```sh -$ npm install {module} -``` - -Or install the Turf module that includes it as a function: - -```sh -$ npm install @turf/turf -``` diff --git a/scripts/testModule.js b/scripts/testModule.js new file mode 100644 index 0000000000..a0b25f1ed6 --- /dev/null +++ b/scripts/testModule.js @@ -0,0 +1,10 @@ +var test = require('tape'); +var path = require('path'); + +test.createStream().pipe(process.stdout); + +const turfModule = [process.argv[2]]; + +turfModule.forEach(function (dir) { + require(path.join(__dirname, '../src/', dir, 'test.js')); //eslint-disable-line +}); diff --git a/scripts/update-dependencies b/scripts/update-dependencies deleted file mode 100755 index 3526e40eb9..0000000000 --- a/scripts/update-dependencies +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env node - -const load = require('load-json-file'); -const write = require('write-json-file'); -const path = require('path'); -const glob = require('glob'); - -// Update package.json -glob.sync(path.join(__dirname, '..', 'packages', 'turf-*', 'package.json')).forEach(packagePath => { - const pckg = load.sync(packagePath); - // pckg.dependencies = updateDependencies(pckg); - pckg.devDependencies = updateDevDependencies(pckg); - write.sync(packagePath, pckg, {indent: 2}); -}); - -function entries(obj) { - return Object.keys(obj || {}).map(key => [key, obj[key]]); -} - -function updateDependencies(pckg) { - const dependencies = {}; - new Map(entries(pckg.dependencies)) - .forEach((version, name) => { - // Update dependencies to Major releases - switch (name) { - case 'geojson-rbush': - dependencies[name] = '2.x'; - break; - case 'topojson-client': - case 'topojson-server': - dependencies[name] = '3.x'; - break; - case 'jsts': - case 'jsts-es': - case '@turf/point-on-surface': - case '@turf/line-distance': - case '@turf/inside': - case '@turf/point-on-line': - case '@turf/nearest': - throw new Error(`${pckg.name} module has invalid dependency ${name}`); - default: - dependencies[name] = version; - } - }); - // All modules will have helpers to handle the internal TypeScript definitions - if (pckg.name !== '@turf/helpers') dependencies['@turf/helpers'] = '^5.0.4'; - return dependencies; -} - -function updateDevDependencies(pckg) { - const devDependencies = {}; - const dev = new Map(entries(pckg.devDependencies)); - dev.delete('uglify-js'); - dev.delete('@turf/helpers'); - dev.delete('rollup-plugin-node-resolve'); - dev.delete('rollup-plugin-uglify'); - dev.delete('rollup-plugin-commonjs'); - dev.delete('rollup-plugin-buble'); - dev - .set('rollup', '*') - .set('tape', '*') - .set('@std/esm', '*') - .set('benchmark', '*').forEach((version, name) => { - devDependencies[name] = '*'; - }); - return devDependencies; -} diff --git a/scripts/update-typescript-configurations b/scripts/update-typescript-configurations deleted file mode 100755 index c9aa4fda9d..0000000000 --- a/scripts/update-typescript-configurations +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env node - -const fs = require('fs'); -const load = require('load-json-file'); -const write = require('write-json-file'); -const path = require('path'); -const glob = require('glob'); - -// Update Typescript Repos -glob.sync(path.join(__dirname, '..', 'packages', 'turf-*', 'index.ts')).forEach(filepath => { - const {dir} = path.parse(filepath); - const pckgPath = path.join(dir, 'package.json'); - const pckg = load.sync(pckgPath); - - const formatedPckg = { - name: pckg.name, - version: updateVersion(pckg.version), - description: pckg.description, - main: 'index', - types: 'index.d.ts', - files: updateFiles(pckg.files), - scripts: { - 'prepare': 'tsc', - 'pretest': 'tsc', - 'test': 'node test.js', - 'bench': 'node bench.js', - 'docs': 'node ../../scripts/generate-readmes' - }, - repository: pckg.repository, - keywords: pckg.keywords, - author: pckg.author, - contributors: pckg.contributors, - license: pckg.license, - bugs: pckg.bugs, - homepage: pckg.homepage, - devDependencies: updateDevDependencies(pckg), - dependencies: pckg.dependencies - }; - write.sync(pckgPath, formatedPckg, {indent: 2}); - - // Remove extra files - // To-Do - - // Add .gitignore - fs.writeFileSync(path.join(dir, '.gitignore'), 'index.js'); - - // Add Typescript configs - if (false) { - fs.writeFileSync(path.join(dir, 'tsconfig.json'), `{ - "compilerOptions": { - /* Basic Options */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "declaration": true, /* Generates corresponding '.d.ts' file. */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - - /* Module Resolution Options */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } -}`); - - fs.writeFileSync(path.join(dir, 'tslint.json'), `{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -}`); - } -}); - -function entries(obj) { - return Object.keys(obj || {}).map(key => [key, obj[key]]); -} - -/** - * @param {Array} files Files - * @returns {Array} Files - */ -function updateFiles(files) { - const newFiles = ['index.js', 'index.d.ts']; - if (files.includes('lib')) newFiles.push('lib'); - return newFiles; -} - -function updateDevDependencies(pckg) { - const devDependencies = {}; - const dev = new Map(entries(pckg.devDependencies)); - dev.delete('rollup'); - dev.delete('@std/esm'); - dev - .set('typescript', '*') - .set('tslint', '*') - .set('tape', '*') - .set('@types/tape', '*') - .set('benchmark', '*').forEach((version, name) => { - devDependencies[name] = '*'; - }); - return devDependencies; -} - -function updateVersion(version) { - let [major, minor, patch] = version.split('.'); - patch = Number(patch) + 1; - return `${major}.${minor}.${patch}`; -} diff --git a/scripts/validate-es5-dependencies.js b/scripts/validate-es5-dependencies.js deleted file mode 100644 index b6ac59ae64..0000000000 --- a/scripts/validate-es5-dependencies.js +++ /dev/null @@ -1,29 +0,0 @@ -import node from 'rollup-plugin-node-resolve'; -import uglify from 'rollup-plugin-uglify'; -import commonjs from 'rollup-plugin-commonjs'; -import {rollup} from 'rollup'; - -const input = 'index.js'; -const plugins = [commonjs(), node(), uglify()]; -const format = 'cjs'; - -rollup({input, plugins}) - .then(generate) - .catch(catchError); - -function generate(value) { - value.generate({format}) - .then(illegalSyntax) - .catch(catchError); -} - -function illegalSyntax({code}) { - if (code.includes('Object.assign(')) throw new Error('"Object.assign" syntax is invalid'); - if (code.includes('const ')) throw new Error('"const" syntax is invalid'); - if (code.includes('let ')) throw new Error('"let" syntax is invalid'); - if (code.includes('=> ')) throw new Error('"=>" syntax is invalid'); -} - -function catchError(e) { - throw new Error(e); -} diff --git a/src/along/bench.js b/src/along/bench.js new file mode 100644 index 0000000000..56df8308c6 --- /dev/null +++ b/src/along/bench.js @@ -0,0 +1,66 @@ +const fs = require('fs'); +const Benchmark = require('benchmark'); +const along = require('./').default; + +const line = { + type: "Feature", + properties: {}, + geometry: { + type: "LineString", + coordinates: [ + [ + -77.0316696166992, + 38.878605901789236 + ], + [ + -77.02960968017578, + 38.88194668656296 + ], + [ + -77.02033996582031, + 38.88408470638821 + ], + [ + -77.02566146850586, + 38.885821800123196 + ], + [ + -77.02188491821289, + 38.88956308852534 + ], + [ + -77.01982498168944, + 38.89236892551996 + ] + ] + } +}; + +const route = JSON.parse(fs.readFileSync(__dirname + '/test/fixtures/route.geojson')); + +const suite = new Benchmark.Suite('along'); +suite + .add('along',function () { + along(line, 1, 'miles'); + }) + .add('along#route 1 mile',function () { + along(route, 1, 'miles'); + }) + .add('along#route 10 miles',function () { + along(route, 10, 'miles'); + }) + .add('along#route 50 miles',function () { + along(route, 50, 'miles'); + }) + .add('along#route 100 miles',function () { + along(route, 100, 'miles'); + }) + .on('error', function (err) { + console.log(err) + }) + .on('cycle', function (event) { + console.log(String(event.target)); + }) + .on('complete', function () { + }) + .run(); diff --git a/src/along/index.d.ts b/src/along/index.d.ts new file mode 100644 index 0000000000..e069001c9b --- /dev/null +++ b/src/along/index.d.ts @@ -0,0 +1,22 @@ +import { Feature, LineString, Point, Units } from "../helpers"; +/** + * Takes a {@link LineString} and returns a {@link Point} at a specified distance along the line. + * + * @name along + * @param {Feature} line input line + * @param {number} distance distance along the line + * @param {Object} [options] Optional parameters + * @param {string} [options.units="kilometers"] can be degrees, radians, miles, or kilometers + * @returns {Feature} Point `distance` `units` along the line + * @example + * var line = turf.lineString([[-83, 30], [-84, 36], [-78, 41]]); + * var options = {units: 'miles'}; + * + * var along = turf.along(line, 200, options); + * + * //addToMap + * var addToMap = [along, line] + */ +export default function along(line: Feature | LineString, distance: number, options?: { + units?: Units; +}): Feature; diff --git a/src/along/index.js b/src/along/index.js new file mode 100644 index 0000000000..c8a8ad31f9 --- /dev/null +++ b/src/along/index.js @@ -0,0 +1,48 @@ +import rhumbBearing from '../rhumb-bearing'; +import rhumbDestination from '../rhumb-destination'; +import rhumbDistance from '../rhumb-distance'; +import { point, checkIfOptionsExist } from '../helpers'; +import { getGeom } from '../invariant'; + +/** + * Takes a {@link LineString} and returns a {@link Point} at a specified distance along the line. + * + * @name along + * @param {Feature} line input line + * @param {number} distance distance along the line + * @param {Object} [options] Optional parameters + * @param {string} [options.units="kilometers"] can be degrees, radians, miles, or kilometers + * @returns {Feature} Point `distance` `units` along the line + * @example + * var line = turf.lineString([[-83, 30], [-84, 36], [-78, 41]]); + * var options = {units: 'miles'}; + * + * var along = turf.along(line, 200, options); + * + * //addToMap + * var addToMap = [along, line] + */ +export default function along(line, distance, options) { + options = checkIfOptionsExist(options); + + const geom = getGeom(line); + const coords = geom.coordinates; + let travelled = 0; + for (let i = 0; i < coords.length; i++) { + if (distance >= travelled && i === coords.length - 1) { + break; + } else if (travelled >= distance) { + const overshot = distance - travelled; + if (!overshot) { + return point(coords[i]); + } else { + const direction = rhumbBearing(coords[i], coords[i - 1]) - 180; + const interpolated = rhumbDestination(coords[i], overshot, direction, options); + return interpolated; + } + } else { + travelled += rhumbDistance(coords[i], coords[i + 1], options); + } + } + return point(coords[coords.length - 1]); +} diff --git a/src/along/test.js b/src/along/test.js new file mode 100644 index 0000000000..c46c9e4c62 --- /dev/null +++ b/src/along/test.js @@ -0,0 +1,44 @@ +const path = require('path'); +const test = require('tape'); +const load = require('load-json-file'); +const { featureCollection } = require('../helpers'); +const isPointOnLine = require('../boolean-point-on-line').default; +const pointToLineDistance = require('../point-to-line-distance').default; + +const along = require('./').default; + +const line = load.sync(path.join(__dirname, 'test', 'fixtures', 'dc-line.geojson')); + +test('turf-along', t => { + const options = {units: 'miles'} + const pt1 = along(line, 1, options); + const pt2 = along(line.geometry, 1.2, options); + const pt3 = along(line, 1.4, options); + const pt4 = along(line.geometry, 1.6, options); + const pt5 = along(line, 1.8, options); + const pt6 = along(line.geometry, 2, options); + const pt7 = along(line, 100, options); + const pt8 = along(line.geometry, 0, options); + const fc = featureCollection([pt1, pt2, pt3, pt4, pt5, pt6, pt7, pt8]); + + fc.features.forEach((f, i) => { + t.ok(f); + t.equal(f.type, 'Feature'); + t.equal(f.geometry.type, 'Point'); + t.equal(pointToLineDistance(f, line, {units: 'centimeters'}) < 0.2, true) + }); + + t.end(); +}); + +test('turf-along-long', t => { + const fixtures = load.sync(path.join(__dirname, 'test', 'fixtures', 'long-line.geojson')); + const longLine = fixtures.features[0]; + const pointOnLongLine = fixtures.features[1]; + + const pt1 = along(longLine, 200, {units: 'miles'}); + t.deepEqual(pt1, pointOnLongLine); + t.equal(pointToLineDistance(pt1, longLine, {units: 'kilometers'}) < 1, true) + + t.end(); +}); \ No newline at end of file diff --git a/packages/turf-along/test/fixtures/dc-line.geojson b/src/along/test/fixtures/dc-line.geojson similarity index 100% rename from packages/turf-along/test/fixtures/dc-line.geojson rename to src/along/test/fixtures/dc-line.geojson diff --git a/src/along/test/fixtures/long-line.geojson b/src/along/test/fixtures/long-line.geojson new file mode 100644 index 0000000000..6cf723cbc4 --- /dev/null +++ b/src/along/test/fixtures/long-line.geojson @@ -0,0 +1,37 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -83, + 30 + ], + [ + -84, + 36 + ], + [ + -78, + 41 + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [ + -83.46932855288287, + 32.86680801741411 + ] + } + } + ] +} \ No newline at end of file diff --git a/packages/turf-angle/bench.js b/src/angle/bench.js similarity index 100% rename from packages/turf-angle/bench.js rename to src/angle/bench.js diff --git a/packages/turf-angle/diagrams/turf-angle.png b/src/angle/diagrams/turf-angle.png similarity index 100% rename from packages/turf-angle/diagrams/turf-angle.png rename to src/angle/diagrams/turf-angle.png diff --git a/packages/turf-angle/diagrams/turf-angle.svg b/src/angle/diagrams/turf-angle.svg similarity index 100% rename from packages/turf-angle/diagrams/turf-angle.svg rename to src/angle/diagrams/turf-angle.svg diff --git a/packages/turf-angle/index.d.ts b/src/angle/index.d.ts similarity index 100% rename from packages/turf-angle/index.d.ts rename to src/angle/index.d.ts diff --git a/src/angle/index.js b/src/angle/index.js new file mode 100644 index 0000000000..09028547d0 --- /dev/null +++ b/src/angle/index.js @@ -0,0 +1,44 @@ +import bearing from "../bearing"; +import { bearingToAzimuth, checkIfOptionsExist } from "../helpers"; +import rhumbBearing from "../rhumb-bearing"; + +/** + * Finds the angle formed by two adjacent segments defined by 3 points. The result will be the (positive clockwise) + * angle with origin on the `startPoint-midPoint` segment, or its explementary angle if required. + * + * @name angle + * @param {Coord} startPoint Start Point Coordinates + * @param {Coord} midPoint Mid Point Coordinates + * @param {Coord} endPoint End Point Coordinates + * @param {Object} [options={}] Optional parameters + * @param {boolean} [options.explementary=false] Returns the explementary angle instead (360 - angle) + * @param {boolean} [options.mercator=false] if calculations should be performed over Mercator or WGS84 projection + * @returns {number} Angle between the provided points, or its explementary. + * @example + * turf.angle([5, 5], [5, 6], [3, 4]); + * //=45 + */ +function angle(startPoint, midPoint, endPoint, options) { + options = checkIfOptionsExist(options); + + // Validation + if (!startPoint) { throw new Error("startPoint is required"); } + if (!midPoint) { throw new Error("midPoint is required"); } + if (!endPoint) { throw new Error("endPoint is required"); } + + // Rename to shorter variables + const A = startPoint; + const O = midPoint; + const B = endPoint; + + // Main + const azimuthAO = bearingToAzimuth((options.mercator !== true) ? bearing(A, O) : rhumbBearing(A, O)); + const azimuthBO = bearingToAzimuth((options.mercator !== true) ? bearing(B, O) : rhumbBearing(B, O)); + const angleAO = Math.abs(azimuthAO - azimuthBO); + + // Explementary angle + if (options.explementary === true) { return 360 - angleAO; } + return angleAO; +} + +export default angle; diff --git a/src/angle/test.js b/src/angle/test.js new file mode 100644 index 0000000000..8a45d28b18 --- /dev/null +++ b/src/angle/test.js @@ -0,0 +1,93 @@ +const test = require('tape'); +const path = require('path'); +const fs = require('fs'); +const glob = require('glob'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const sector = require('../sector').default; +const bearing = require('../bearing').default; +const truncate = require('../truncate').default; +const distance = require('../distance').default; +const { point, round, lineString, featureCollection } = require('../helpers'); +const angle = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-angle', t => { + for (const fixture of fixtures) { + const name = fixture.name; + const geojson = fixture.geojson; + const [start, mid, end] = geojson.features; + + // Results + const angleProperties = { + interiorAngle: round(angle(start, mid, end), 6), + interiorMercatorAngle: round(angle(start, mid, end, {mercator: true}), 6), + explementary: false, + fill: '#F00', + stroke: '#F00', + 'fill-opacity': 0.3 + }; + const angleExplementaryProperties = { + explementaryAngle: round(angle(start, mid, end, {explementary: true}), 6), + explementaryMercatorAngle: round(angle(start, mid, end, {explementary: true, mercator: true}), 6), + explementary: true, + fill: '#00F', + stroke: '#00F', + 'fill-opacity': 0.3 + }; + const results = featureCollection([ + truncate(sector(mid, distance(mid, start) / 3, bearing(mid, start), bearing(mid, end), {properties: angleProperties})), + truncate(sector(mid, distance(mid, start) / 2, bearing(mid, end), bearing(mid, start), {properties: angleExplementaryProperties})), + lineString([start.geometry.coordinates, mid.geometry.coordinates, end.geometry.coordinates], {'stroke-width': 4, stroke: '#222'}), + start, + mid, + end, + ]); + + // Save results + if (process.env.REGEN) write.sync(directories.out + name + '.json', results); + t.deepEqual(results, load.sync(directories.out + name + '.json'), name); + } + t.end(); +}); + +test('turf-angle -- simple', t => { + t.equal(round(angle([5, 5], [5, 6], [3, 4])), 45, '45 degrees'); + t.equal(round(angle([3, 4], [5, 6], [5, 5])), 45, '45 degrees -- inverse'); + t.equal(round(angle([3, 4], [5, 6], [5, 5], {explementary: true})), 360 - 45, 'explementary angle'); + t.end(); +}); + +test('turf-angle -- issues', t => { + const start = [167.72709868848324, -45.56543836343071]; + const mid = [167.7269698586315, -45.56691059720167]; + const end = [167.72687866352499, -45.566989345276355]; + const a = angle(start, mid, end); + + t.false(isNaN(a), 'result is not NaN'); + t.end(); +}); + +test('turf-angle -- throws', t => { + const pt1 = point([-10, -30]); + const pt2 = point([-11, -33]); + const pt3 = point([-12, -36]); + t.throws(() => angle(null, pt2, pt3), /startPoint is required/, 'startPoint is required'); + t.throws(() => angle(pt1, undefined, pt3), /midPoint is required/, 'midPoint is required'); + t.throws(() => angle(pt1, pt2), /endPoint is required/, 'endPoint is required'); + t.throws(() => angle(pt1, pt2, pt3, 'string'), /options is invalid/, 'invalid options'); + + t.end(); +}); diff --git a/packages/turf-angle/test/in/90-degrees.json b/src/angle/test/in/90-degrees.json similarity index 100% rename from packages/turf-angle/test/in/90-degrees.json rename to src/angle/test/in/90-degrees.json diff --git a/packages/turf-angle/test/in/acute-inverse.json b/src/angle/test/in/acute-inverse.json similarity index 100% rename from packages/turf-angle/test/in/acute-inverse.json rename to src/angle/test/in/acute-inverse.json diff --git a/packages/turf-angle/test/in/acute.json b/src/angle/test/in/acute.json similarity index 100% rename from packages/turf-angle/test/in/acute.json rename to src/angle/test/in/acute.json diff --git a/packages/turf-angle/test/in/obtuse-bigger.json b/src/angle/test/in/obtuse-bigger.json similarity index 100% rename from packages/turf-angle/test/in/obtuse-bigger.json rename to src/angle/test/in/obtuse-bigger.json diff --git a/packages/turf-angle/test/in/obtuse.json b/src/angle/test/in/obtuse.json similarity index 100% rename from packages/turf-angle/test/in/obtuse.json rename to src/angle/test/in/obtuse.json diff --git a/packages/turf-angle/test/out/90-degrees.json b/src/angle/test/out/90-degrees.json similarity index 100% rename from packages/turf-angle/test/out/90-degrees.json rename to src/angle/test/out/90-degrees.json diff --git a/packages/turf-angle/test/out/acute-inverse.json b/src/angle/test/out/acute-inverse.json similarity index 100% rename from packages/turf-angle/test/out/acute-inverse.json rename to src/angle/test/out/acute-inverse.json diff --git a/packages/turf-angle/test/out/acute.json b/src/angle/test/out/acute.json similarity index 100% rename from packages/turf-angle/test/out/acute.json rename to src/angle/test/out/acute.json diff --git a/packages/turf-angle/test/out/obtuse-bigger.json b/src/angle/test/out/obtuse-bigger.json similarity index 100% rename from packages/turf-angle/test/out/obtuse-bigger.json rename to src/angle/test/out/obtuse-bigger.json diff --git a/packages/turf-angle/test/out/obtuse.json b/src/angle/test/out/obtuse.json similarity index 100% rename from packages/turf-angle/test/out/obtuse.json rename to src/angle/test/out/obtuse.json diff --git a/packages/turf-area/bench.js b/src/area/bench.js similarity index 100% rename from packages/turf-area/bench.js rename to src/area/bench.js diff --git a/src/area/index.d.ts b/src/area/index.d.ts new file mode 100644 index 0000000000..a147b7ba38 --- /dev/null +++ b/src/area/index.d.ts @@ -0,0 +1,17 @@ +import { Feature, FeatureCollection, Geometry } from "../helpers"; +/** + * Takes one or more features and returns their area in square meters. + * + * @name area + * @param {GeoJSON} geojson input GeoJSON feature(s) + * @returns {number} area in square meters + * @example + * var polygon = turf.polygon([[[125, -15], [113, -22], [154, -27], [144, -15], [125, -15]]]); + * + * var area = turf.area(polygon); + * + * //addToMap + * var addToMap = [polygon] + * polygon.properties.area = area + */ +export default function area(geojson: Feature | FeatureCollection | Geometry): number; diff --git a/src/area/index.js b/src/area/index.js new file mode 100644 index 0000000000..00ec6f511b --- /dev/null +++ b/src/area/index.js @@ -0,0 +1,115 @@ +import { earthRadius } from '../helpers'; +import { geomReduce } from '../meta'; + +/** + * Takes one or more features and returns their area in square meters. + * + * @name area + * @param {GeoJSON} geojson input GeoJSON feature(s) + * @returns {number} area in square meters + * @example + * var polygon = turf.polygon([[[125, -15], [113, -22], [154, -27], [144, -15], [125, -15]]]); + * + * var area = turf.area(polygon); + * + * //addToMap + * var addToMap = [polygon] + * polygon.properties.area = area + */ +export default function area(geojson) { + return geomReduce(geojson, (value, geom) => { + return value + calculateArea(geom); + }, 0); +} + +/** + * Calculate Area + * + * @private + * @param {Geometry} geom GeoJSON Geometries + * @returns {number} area + */ +function calculateArea(geom) { + let total = 0; + let i; + switch (geom.type) { + case 'Polygon': + return polygonArea(geom.coordinates); + case 'MultiPolygon': + for (i = 0; i < geom.coordinates.length; i++) { + total += polygonArea(geom.coordinates[i]); + } + return total; + case 'Point': + case 'MultiPoint': + case 'LineString': + case 'MultiLineString': + return 0; + } + return 0; +} + +function polygonArea(coords) { + let total = 0; + if (coords && coords.length > 0) { + total += Math.abs(ringArea(coords[0])); + for (let i = 1; i < coords.length; i++) { + total -= Math.abs(ringArea(coords[i])); + } + } + return total; +} + +/** + * @private + * Calculate the approximate area of the polygon were it projected onto the earth. + * Note that this area will be positive if ring is oriented clockwise, otherwise it will be negative. + * + * Reference: + * Robert. G. Chamberlain and William H. Duquette, 'Some Algorithms for Polygons on a Sphere', + * JPL Publication 07-03, Jet Propulsion + * Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409 + * + * @param {Array>} coords Ring Coordinates + * @returns {number} The approximate signed geodesic area of the polygon in square meters. + */ +function ringArea(coords) { + let p1; + let p2; + let p3; + let lowerIndex; + let middleIndex; + let upperIndex; + let i; + let total = 0; + const coordsLength = coords.length; + + if (coordsLength > 2) { + for (i = 0; i < coordsLength; i++) { + if (i === coordsLength - 2) { // i = N-2 + lowerIndex = coordsLength - 2; + middleIndex = coordsLength - 1; + upperIndex = 0; + } else if (i === coordsLength - 1) { // i = N-1 + lowerIndex = coordsLength - 1; + middleIndex = 0; + upperIndex = 1; + } else { // i = 0 to N-3 + lowerIndex = i; + middleIndex = i + 1; + upperIndex = i + 2; + } + p1 = coords[lowerIndex]; + p2 = coords[middleIndex]; + p3 = coords[upperIndex]; + total += (rad(p3[0]) - rad(p1[0])) * Math.sin(rad(p2[1])); + } + + total = total * earthRadius * earthRadius / 2; + } + return total; +} + +function rad(num) { + return num * Math.PI / 180; +} diff --git a/packages/turf-area/test.js b/src/area/test.js similarity index 100% rename from packages/turf-area/test.js rename to src/area/test.js diff --git a/packages/turf-area/test/in/polygon.geojson b/src/area/test/in/polygon.geojson similarity index 100% rename from packages/turf-area/test/in/polygon.geojson rename to src/area/test/in/polygon.geojson diff --git a/src/area/test/out/polygon.json b/src/area/test/out/polygon.json new file mode 100644 index 0000000000..b45e8a6f88 --- /dev/null +++ b/src/area/test/out/polygon.json @@ -0,0 +1 @@ +7748891609977 diff --git a/packages/turf-bbox-clip/bench.js b/src/bbox-clip/bench.js similarity index 100% rename from packages/turf-bbox-clip/bench.js rename to src/bbox-clip/bench.js diff --git a/packages/turf-bbox-clip/index.d.ts b/src/bbox-clip/index.d.ts similarity index 100% rename from packages/turf-bbox-clip/index.d.ts rename to src/bbox-clip/index.d.ts diff --git a/src/bbox-clip/index.js b/src/bbox-clip/index.js new file mode 100644 index 0000000000..048726a73e --- /dev/null +++ b/src/bbox-clip/index.js @@ -0,0 +1,64 @@ +import { lineString, multiLineString, multiPolygon, polygon } from '../helpers'; +import { getGeom } from '../invariant'; +import { lineclip, polygonclip } from './lib/lineclip'; + +/** + * Takes a {@link Feature} and a bbox and clips the feature to the bbox using + * [lineclip](https://github.com/mapbox/lineclip). + * May result in degenerate edges when clipping Polygons. + * + * @name bboxClip + * @param {Feature} feature feature to clip to the bbox + * @param {BBox} bbox extent in [minX, minY, maxX, maxY] order + * @returns {Feature} clipped Feature + * @example + * var bbox = [0, 0, 10, 10]; + * var poly = turf.polygon([[[2, 2], [8, 4], [12, 8], [3, 7], [2, 2]]]); + * + * var clipped = turf.bboxClip(poly, bbox); + * + * //addToMap + * var addToMap = [bbox, poly, clipped] + */ +export default function bboxClip(feature, bbox) { + const geom = getGeom(feature); + const type = geom.type; + const properties = feature.type === 'Feature' ? feature.properties : {}; + let coords = geom.coordinates; + + switch (type) { + case 'LineString': + case 'MultiLineString': //eslint-disable-line + const lines = []; + if (type === 'LineString') { coords = [coords]; } + coords.forEach((line) => { + lineclip(line, bbox, lines); + }); + if (lines.length === 1) { return lineString(lines[0], properties); } + return multiLineString(lines, properties); + case 'Polygon': + return polygon(clipPolygon(coords, bbox), properties); + case 'MultiPolygon': + return multiPolygon(coords.map((poly) => { + return clipPolygon(poly, bbox); + }), properties); + default: + throw new Error('geometry ' + type + ' not supported'); + } +} + +function clipPolygon(rings, bbox) { + const outRings = []; + for (const ring of rings) { + const clipped = polygonclip(ring, bbox); + if (clipped.length > 0) { + if (clipped[0][0] !== clipped[clipped.length - 1][0] || clipped[0][1] !== clipped[clipped.length - 1][1]) { + clipped.push(clipped[0]); + } + if (clipped.length >= 4) { + outRings.push(clipped); + } + } + } + return outRings; +} diff --git a/packages/turf-bbox-clip/lib/lineclip.d.ts b/src/bbox-clip/lib/lineclip.d.ts similarity index 100% rename from packages/turf-bbox-clip/lib/lineclip.d.ts rename to src/bbox-clip/lib/lineclip.d.ts diff --git a/packages/turf-bbox-clip/lib/lineclip.js b/src/bbox-clip/lib/lineclip.js similarity index 93% rename from packages/turf-bbox-clip/lib/lineclip.js rename to src/bbox-clip/lib/lineclip.js index 33f7bb332c..a5664d46c1 100644 --- a/packages/turf-bbox-clip/lib/lineclip.js +++ b/src/bbox-clip/lib/lineclip.js @@ -1,16 +1,10 @@ 'use strict'; -module.exports = lineclip; -module.exports.default = lineclip; - -lineclip.polyline = lineclip; -lineclip.polygon = polygonclip; - // Cohen-Sutherland line clippign algorithm, adapted to efficiently // handle polylines rather than just segments -function lineclip(points, bbox, result) { +export function lineclip(points, bbox, result) { var len = points.length, codeA = bitCode(points[0], bbox), @@ -64,7 +58,7 @@ function lineclip(points, bbox, result) { // Sutherland-Hodgeman polygon clipping algorithm -function polygonclip(points, bbox) { +export function polygonclip(points, bbox) { var result, edge, prev, prevInside, i, p, inside; diff --git a/src/bbox-clip/test.js b/src/bbox-clip/test.js new file mode 100644 index 0000000000..ff0430d428 --- /dev/null +++ b/src/bbox-clip/test.js @@ -0,0 +1,59 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { point, feature, featureCollection } = require('../helpers'); +const turfBBox = require('../bbox').default; +const bboxClip = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-bbox-clip', t => { + for (const fixture of fixtures) { + const filename = fixture.filename; + const name = fixture.name; + const geojson = fixture.geojson; + const feature = geojson.features[0]; + const bbox = turfBBox(geojson.features[1]); + const clipped = bboxClip(feature, bbox); + const results = featureCollection([colorize(feature, '#080'), colorize(clipped, '#F00'), colorize(geojson.features[1], '#00F', 3)]); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEquals(results, load.sync(directories.out + filename), name); + } + t.end(); +}); + +test('turf-bbox-clip -- throws', t => { + t.throws(() => bboxClip(point([5, 10]), [-180, -90, 180, 90]), /geometry Point not supported/); + t.end(); +}); + +function colorize(feature, color, width) { + color = color || '#F00'; + width = width || 6; + feature.properties = { + stroke: color, + fill: color, + 'stroke-width': width, + 'fill-opacity': 0.1 + }; + return feature; +} + +test('turf-bbox-clip -- null geometries', t => { + t.throws(() => bboxClip(feature(null), [-180, -90, 180, 90]), 'coords must be GeoJSON Feature, Geometry Object or an Array'); + t.end(); +}); diff --git a/packages/turf-bbox-clip/test/in/linestring-single-line.geojson b/src/bbox-clip/test/in/linestring-single-line.geojson similarity index 100% rename from packages/turf-bbox-clip/test/in/linestring-single-line.geojson rename to src/bbox-clip/test/in/linestring-single-line.geojson diff --git a/packages/turf-bbox-clip/test/in/linestring.geojson b/src/bbox-clip/test/in/linestring.geojson similarity index 100% rename from packages/turf-bbox-clip/test/in/linestring.geojson rename to src/bbox-clip/test/in/linestring.geojson diff --git a/packages/turf-bbox-clip/test/in/multi-linestring.geojson b/src/bbox-clip/test/in/multi-linestring.geojson similarity index 100% rename from packages/turf-bbox-clip/test/in/multi-linestring.geojson rename to src/bbox-clip/test/in/multi-linestring.geojson diff --git a/packages/turf-bbox-clip/test/in/multi-polygon.geojson b/src/bbox-clip/test/in/multi-polygon.geojson similarity index 100% rename from packages/turf-bbox-clip/test/in/multi-polygon.geojson rename to src/bbox-clip/test/in/multi-polygon.geojson diff --git a/packages/turf-bbox-clip/test/in/polygon-crossing-hole.geojson b/src/bbox-clip/test/in/polygon-crossing-hole.geojson similarity index 100% rename from packages/turf-bbox-clip/test/in/polygon-crossing-hole.geojson rename to src/bbox-clip/test/in/polygon-crossing-hole.geojson diff --git a/packages/turf-bbox-clip/test/in/polygon-holes.geojson b/src/bbox-clip/test/in/polygon-holes.geojson similarity index 100% rename from packages/turf-bbox-clip/test/in/polygon-holes.geojson rename to src/bbox-clip/test/in/polygon-holes.geojson diff --git a/packages/turf-bbox-clip/test/in/polygon-point-intersection.geojson b/src/bbox-clip/test/in/polygon-point-intersection.geojson similarity index 100% rename from packages/turf-bbox-clip/test/in/polygon-point-intersection.geojson rename to src/bbox-clip/test/in/polygon-point-intersection.geojson diff --git a/packages/turf-bbox-clip/test/in/polygon.geojson b/src/bbox-clip/test/in/polygon.geojson similarity index 100% rename from packages/turf-bbox-clip/test/in/polygon.geojson rename to src/bbox-clip/test/in/polygon.geojson diff --git a/packages/turf-bbox-clip/test/out/linestring-single-line.geojson b/src/bbox-clip/test/out/linestring-single-line.geojson similarity index 100% rename from packages/turf-bbox-clip/test/out/linestring-single-line.geojson rename to src/bbox-clip/test/out/linestring-single-line.geojson diff --git a/packages/turf-bbox-clip/test/out/linestring.geojson b/src/bbox-clip/test/out/linestring.geojson similarity index 100% rename from packages/turf-bbox-clip/test/out/linestring.geojson rename to src/bbox-clip/test/out/linestring.geojson diff --git a/packages/turf-bbox-clip/test/out/multi-linestring.geojson b/src/bbox-clip/test/out/multi-linestring.geojson similarity index 100% rename from packages/turf-bbox-clip/test/out/multi-linestring.geojson rename to src/bbox-clip/test/out/multi-linestring.geojson diff --git a/packages/turf-bbox-clip/test/out/multi-polygon.geojson b/src/bbox-clip/test/out/multi-polygon.geojson similarity index 100% rename from packages/turf-bbox-clip/test/out/multi-polygon.geojson rename to src/bbox-clip/test/out/multi-polygon.geojson diff --git a/packages/turf-bbox-clip/test/out/polygon-crossing-hole.geojson b/src/bbox-clip/test/out/polygon-crossing-hole.geojson similarity index 100% rename from packages/turf-bbox-clip/test/out/polygon-crossing-hole.geojson rename to src/bbox-clip/test/out/polygon-crossing-hole.geojson diff --git a/packages/turf-bbox-clip/test/out/polygon-holes.geojson b/src/bbox-clip/test/out/polygon-holes.geojson similarity index 100% rename from packages/turf-bbox-clip/test/out/polygon-holes.geojson rename to src/bbox-clip/test/out/polygon-holes.geojson diff --git a/packages/turf-bbox-clip/test/out/polygon-point-intersection.geojson b/src/bbox-clip/test/out/polygon-point-intersection.geojson similarity index 100% rename from packages/turf-bbox-clip/test/out/polygon-point-intersection.geojson rename to src/bbox-clip/test/out/polygon-point-intersection.geojson diff --git a/packages/turf-bbox-clip/test/out/polygon.geojson b/src/bbox-clip/test/out/polygon.geojson similarity index 100% rename from packages/turf-bbox-clip/test/out/polygon.geojson rename to src/bbox-clip/test/out/polygon.geojson diff --git a/packages/turf-bbox-polygon/bench.js b/src/bbox-polygon/bench.js similarity index 100% rename from packages/turf-bbox-polygon/bench.js rename to src/bbox-polygon/bench.js diff --git a/packages/turf-bbox-polygon/index.d.ts b/src/bbox-polygon/index.d.ts similarity index 100% rename from packages/turf-bbox-polygon/index.d.ts rename to src/bbox-polygon/index.d.ts diff --git a/src/bbox-polygon/index.js b/src/bbox-polygon/index.js new file mode 100644 index 0000000000..14c0bf1d5a --- /dev/null +++ b/src/bbox-polygon/index.js @@ -0,0 +1,45 @@ +import { polygon, checkIfOptionsExist } from '../helpers'; + +/** + * Takes a bbox and returns an equivalent {@link Polygon|polygon}. + * + * @name bboxPolygon + * @param {BBox} bbox extent in [minX, minY, maxX, maxY] order + * @param {Object} [options={}] Optional parameters + * @param {Properties} [options.properties={}] Translate properties to Polygon + * @param {string|number} [options.id={}] Translate Id to Polygon + * @returns {Feature} a Polygon representation of the bounding box + * @example + * var bbox = [0, 0, 10, 10]; + * + * var poly = turf.bboxPolygon(bbox); + * + * //addToMap + * var addToMap = [poly] + */ +export default function bboxPolygon(bbox, options) { + options = checkIfOptionsExist(options); + + // Convert BBox positions to Numbers + // No performance loss for including Number() + // https://github.com/Turfjs/turf/issues/1119 + const west = Number(bbox[0]); + const south = Number(bbox[1]); + const east = Number(bbox[2]); + const north = Number(bbox[3]); + + if (bbox.length === 6) { throw new Error('@turf/bbox-polygon does not support BBox with 6 positions'); } + + const lowLeft = [west, south]; + const topLeft = [west, north]; + const topRight = [east, north]; + const lowRight = [east, south]; + + return polygon([[ + lowLeft, + lowRight, + topRight, + topLeft, + lowLeft, + ]], options.properties, {bbox, id: options.id}); +} diff --git a/packages/turf-bbox-polygon/test.js b/src/bbox-polygon/test.js similarity index 100% rename from packages/turf-bbox-polygon/test.js rename to src/bbox-polygon/test.js diff --git a/packages/turf-bbox/bench.js b/src/bbox/bench.js similarity index 100% rename from packages/turf-bbox/bench.js rename to src/bbox/bench.js diff --git a/packages/turf-bbox/index.d.ts b/src/bbox/index.d.ts similarity index 100% rename from packages/turf-bbox/index.d.ts rename to src/bbox/index.d.ts diff --git a/src/bbox/index.js b/src/bbox/index.js new file mode 100644 index 0000000000..1d910ddaa3 --- /dev/null +++ b/src/bbox/index.js @@ -0,0 +1,26 @@ +import { coordEach } from "../meta"; + +/** + * Takes a set of features, calculates the bbox of all input features, and returns a bounding box. + * + * @name bbox + * @param {GeoJSON} geojson any GeoJSON object + * @returns {BBox} bbox extent in [minX, minY, maxX, maxY] order + * @example + * var line = turf.lineString([[-74, 40], [-78, 42], [-82, 35]]); + * var bbox = turf.bbox(line); + * var bboxPolygon = turf.bboxPolygon(bbox); + * + * //addToMap + * var addToMap = [line, bboxPolygon] + */ +export default function bbox(geojson) { + const result = [Infinity, Infinity, -Infinity, -Infinity]; + coordEach(geojson, (coord) => { + if (result[0] > coord[0]) { result[0] = coord[0]; } + if (result[1] > coord[1]) { result[1] = coord[1]; } + if (result[2] < coord[0]) { result[2] = coord[0]; } + if (result[3] < coord[1]) { result[3] = coord[1]; } + }); + return result; +} diff --git a/src/bbox/test.js b/src/bbox/test.js new file mode 100644 index 0000000000..10e6b17ad8 --- /dev/null +++ b/src/bbox/test.js @@ -0,0 +1,63 @@ +const test = require('tape'); +const { + point, + polygon, + feature, + lineString, + multiPolygon, + multiLineString, + featureCollection } = require('../helpers') +const bbox = require('./').default; + +// Fixtures +const pt = point([102.0, 0.5]); +const line = lineString([[102.0, -10.0], [103.0, 1.0], [104.0, 0.0], [130.0, 4.0]]); +const poly = polygon([[[101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0], [101.0, 0.0]]]); +const multiLine = multiLineString([ + [[100.0, 0.0], [101.0, 1.0]], + [[102.0, 2.0], [103.0, 3.0]] +]); +const multiPoly = multiPolygon([ + [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]], + [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]] +]); +const fc = featureCollection([pt, line, poly, multiLine, multiPoly]); + +test('bbox', t => { + // FeatureCollection + const fcBBox = bbox(fc); + t.deepEqual(fcBBox, [100, -10, 130, 4], 'featureCollection'); + + // Point + const ptBBox = bbox(pt); + t.deepEqual(ptBBox, [102, 0.5, 102, 0.5], 'point'); + + // Line + const lineBBox = bbox(line); + t.deepEqual(lineBBox, [102, -10, 130, 4], 'lineString'); + + // Polygon + const polyExtent = bbox(poly); + t.deepEqual(polyExtent, [100, 0, 101, 1], 'polygon'); + + // MultiLineString + const multiLineBBox = bbox(multiLine); + t.deepEqual(multiLineBBox, [100, 0, 103, 3], 'multiLineString'); + + // MultiPolygon + const multiPolyBBox = bbox(multiPoly); + t.deepEqual(multiPolyBBox, [100, 0, 103, 3], 'multiPolygon'); + + + t.end(); +}); + +test('bbox -- throws', t => { + t.throws(() => bbox({}), /Unknown Geometry Type/, 'unknown geometry type error'); + t.end(); +}); + +test('bbox -- null geometries', t => { + t.deepEqual(bbox(feature(null)), [Infinity, Infinity, -Infinity, -Infinity]); + t.end(); +}); diff --git a/packages/turf-bearing/bench.js b/src/bearing/bench.js similarity index 100% rename from packages/turf-bearing/bench.js rename to src/bearing/bench.js diff --git a/packages/turf-bearing/index.d.ts b/src/bearing/index.d.ts similarity index 100% rename from packages/turf-bearing/index.d.ts rename to src/bearing/index.d.ts diff --git a/src/bearing/index.js b/src/bearing/index.js new file mode 100644 index 0000000000..1c88789c96 --- /dev/null +++ b/src/bearing/index.js @@ -0,0 +1,63 @@ +import { degreesToRadians, radiansToDegrees, isObject, checkIfOptionsExist } from '../helpers'; +import { getCoord } from '../invariant'; + +// http://en.wikipedia.org/wiki/Haversine_formula +// http://www.movable-type.co.uk/scripts/latlong.html + +/** + * Takes two {@link Point|points} and finds the geographic bearing between them, + * i.e. the angle measured in degrees from the north line (0 degrees) + * + * @name bearing + * @param {Coord} start starting Point + * @param {Coord} end ending Point + * @param {Object} [options={}] Optional parameters + * @param {boolean} [options.final=false] calculates the final bearing if true + * @returns {number} bearing in decimal degrees, between -180 and 180 degrees (positive clockwise) + * @example + * var point1 = turf.point([-75.343, 39.984]); + * var point2 = turf.point([-75.534, 39.123]); + * + * var bearing = turf.bearing(point1, point2); + * + * //addToMap + * var addToMap = [point1, point2] + * point1.properties['marker-color'] = '#f00' + * point2.properties['marker-color'] = '#0f0' + * point1.properties.bearing = bearing + */ +export default function bearing(start, end, options) { + + options = checkIfOptionsExist(options) + + // Reverse calculation + if (options.final === true) { return calculateFinalBearing(start, end); } + + const coordinates1 = getCoord(start); + const coordinates2 = getCoord(end); + + const lon1 = degreesToRadians(coordinates1[0]); + const lon2 = degreesToRadians(coordinates2[0]); + const lat1 = degreesToRadians(coordinates1[1]); + const lat2 = degreesToRadians(coordinates2[1]); + const a = Math.sin(lon2 - lon1) * Math.cos(lat2); + const b = Math.cos(lat1) * Math.sin(lat2) - + Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1); + + return radiansToDegrees(Math.atan2(a, b)); +} + +/** + * Calculates Final Bearing + * + * @private + * @param {Coord} start starting Point + * @param {Coord} end ending Point + * @returns {number} bearing + */ +function calculateFinalBearing(start, end) { + // Swap start & end + let bear = bearing(end, start); + bear = (bear + 180) % 360; + return bear; +} diff --git a/src/bearing/test.js b/src/bearing/test.js new file mode 100644 index 0000000000..90d59e5308 --- /dev/null +++ b/src/bearing/test.js @@ -0,0 +1,37 @@ +const path = require('path'); +const test = require('tape'); +const write = require('write-json-file'); +const destination = require('../destination').default; +const { point, lineString, featureCollection } = require('../helpers'); +const bearing = require('./').default; + +const out = path.join(__dirname, 'test', 'out') + path.sep; + +test('bearing', t => { + const start = point([-75, 45], {'marker-color': '#F00'}); + const end = point([20, 60], {'marker-color': '#00F'}); + + const initialBearing = bearing(start, end); + t.equal(initialBearing.toFixed(2), '37.75', 'initial bearing'); + + const finalBearing = bearing(start, end, {final: true}); + t.equal(finalBearing.toFixed(2), '120.01', 'final bearing'); + t.end(); + + if (process.env.REGEN) { + const initialDestination = destination(start, 1000, initialBearing); + const initialLine = lineString([start.geometry.coordinates, initialDestination.geometry.coordinates], { + 'stroke': '#F00', + 'stroke-width': 6 + }); + + const finalDestination = destination(end, 1000, finalBearing - 180); + const finalLine = lineString([end.geometry.coordinates, finalDestination.geometry.coordinates], { + 'stroke': '#00F', + 'stroke-width': 6 + }); + + const results = featureCollection([start, end, initialLine, finalLine]); + write.sync(out + 'results.geojson', results); + } +}); \ No newline at end of file diff --git a/packages/turf-bearing/test/out/results.geojson b/src/bearing/test/out/results.geojson similarity index 100% rename from packages/turf-bearing/test/out/results.geojson rename to src/bearing/test/out/results.geojson diff --git a/packages/turf-bezier-spline/bench.js b/src/bezier-spline/bench.js similarity index 100% rename from packages/turf-bezier-spline/bench.js rename to src/bezier-spline/bench.js diff --git a/packages/turf-bezier-spline/index.d.ts b/src/bezier-spline/index.d.ts similarity index 100% rename from packages/turf-bezier-spline/index.d.ts rename to src/bezier-spline/index.d.ts diff --git a/src/bezier-spline/index.js b/src/bezier-spline/index.js new file mode 100644 index 0000000000..9948bcad7d --- /dev/null +++ b/src/bezier-spline/index.js @@ -0,0 +1,60 @@ +import { lineString, checkIfOptionsExist } from '../helpers'; +import { getGeom } from '../invariant'; +import Spline from './lib/spline'; + +/** + * Takes a {@link LineString|line} and returns a curved version + * by applying a [Bezier spline](http://en.wikipedia.org/wiki/B%C3%A9zier_spline) + * algorithm. + * + * The bezier spline implementation is by [Leszek Rybicki](http://leszek.rybicki.cc/). + * + * @name bezierSpline + * @param {Feature} line input LineString + * @param {Object} [options={}] Optional parameters + * @param {Object} [options.properties={}] Translate properties to output + * @param {number} [options.resolution=10000] time in milliseconds between points + * @param {number} [options.sharpness=0.85] a measure of how curvy the path should be between splines + * @returns {Feature} curved line + * @example + * var line = turf.lineString([ + * [-76.091308, 18.427501], + * [-76.695556, 18.729501], + * [-76.552734, 19.40443], + * [-74.61914, 19.134789], + * [-73.652343, 20.07657], + * [-73.157958, 20.210656] + * ]); + * + * var curved = turf.bezierSpline(line); + * + * //addToMap + * var addToMap = [line, curved] + * curved.properties = { stroke: '#0F0' }; + */ +function bezier(line, options) { + options = checkIfOptionsExist(options); + // Optional params + const resolution = options.resolution || 10000; + const sharpness = options.sharpness || 0.85; + + const coords = []; + const points = getGeom(line).coordinates.map((pt) => { + return {x: pt[0], y: pt[1]}; + }); + const spline = new Spline({ + duration: resolution, + points, + sharpness, + }); + + for (let i = 0; i < spline.duration; i += 10) { + const pos = spline.pos(i); + if (Math.floor(i / 100) % 2 === 0) { + coords.push([pos.x, pos.y]); + } + } + return lineString(coords, options.properties); +} + +export default bezier; diff --git a/packages/turf-bezier-spline/lib/spline.d.ts b/src/bezier-spline/lib/spline.d.ts similarity index 100% rename from packages/turf-bezier-spline/lib/spline.d.ts rename to src/bezier-spline/lib/spline.d.ts diff --git a/packages/turf-bezier-spline/lib/spline.js b/src/bezier-spline/lib/spline.js similarity index 96% rename from packages/turf-bezier-spline/lib/spline.js rename to src/bezier-spline/lib/spline.js index fe4865e4f9..66167b36e9 100644 --- a/packages/turf-bezier-spline/lib/spline.js +++ b/src/bezier-spline/lib/spline.js @@ -1,5 +1,3 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); /** * BezierSpline * https://github.com/leszekr/bezier-spline-js @@ -46,7 +44,7 @@ var Spline = /** @class */ (function () { this.centers.push({ x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2, - z: (p1.z + p2.z) / 2, + z: (p1.z + p2.z) / 2 }); } this.controls.push([this.points[0], this.points[0]]); @@ -100,7 +98,7 @@ var Spline = /** @class */ (function () { angle: 180 * Math.atan2(p1.y - p2.y, p1.x - p2.x) / 3.14, speed: Math.sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y) + - (p2.z - p1.z) * (p2.z - p1.z)), + (p2.z - p1.z) * (p2.z - p1.z)) }; }; /** @@ -129,13 +127,13 @@ var Spline = /** @class */ (function () { }; return Spline; }()); -exports.default = Spline; +export default Spline; function bezier(t, p1, c1, c2, p2) { var b = B(t); var pos = { x: p2.x * b[0] + c2.x * b[1] + c1.x * b[2] + p1.x * b[3], y: p2.y * b[0] + c2.y * b[1] + c1.y * b[2] + p1.y * b[3], - z: p2.z * b[0] + c2.z * b[1] + c1.z * b[2] + p1.z * b[3], + z: p2.z * b[0] + c2.z * b[1] + c1.z * b[2] + p1.z * b[3] }; return pos; } diff --git a/src/bezier-spline/test.js b/src/bezier-spline/test.js new file mode 100644 index 0000000000..31864d29f3 --- /dev/null +++ b/src/bezier-spline/test.js @@ -0,0 +1,46 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { featureCollection } = require('../helpers'); +const bezierSpline = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-bezier-spline', t => { + fixtures.forEach(fixture => { + const filename = fixture.filename; + const name = fixture.name; + const geojson = fixture.geojson; + const spline = colorize(bezierSpline(geojson)); + const results = featureCollection([spline, geojson]); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEquals(results, load.sync(directories.out + filename), name); + }); + t.end(); +}); + +function colorize(feature, color, width) { + color = color || '#F00'; + width = width || 6; + feature.properties = { + stroke: color, + fill: color, + 'stroke-width': width, + 'fill-opacity': 0.1 + }; + return feature; +} diff --git a/packages/turf-bezier-spline/test/in/bezierIn.json b/src/bezier-spline/test/in/bezierIn.json similarity index 100% rename from packages/turf-bezier-spline/test/in/bezierIn.json rename to src/bezier-spline/test/in/bezierIn.json diff --git a/packages/turf-bezier-spline/test/in/issue-#1063.json b/src/bezier-spline/test/in/issue-#1063.json similarity index 100% rename from packages/turf-bezier-spline/test/in/issue-#1063.json rename to src/bezier-spline/test/in/issue-#1063.json diff --git a/packages/turf-bezier-spline/test/in/simple.json b/src/bezier-spline/test/in/simple.json similarity index 100% rename from packages/turf-bezier-spline/test/in/simple.json rename to src/bezier-spline/test/in/simple.json diff --git a/packages/turf-bezier-spline/test/out/bezierIn.json b/src/bezier-spline/test/out/bezierIn.json similarity index 100% rename from packages/turf-bezier-spline/test/out/bezierIn.json rename to src/bezier-spline/test/out/bezierIn.json diff --git a/packages/turf-bezier-spline/test/out/issue-#1063.json b/src/bezier-spline/test/out/issue-#1063.json similarity index 100% rename from packages/turf-bezier-spline/test/out/issue-#1063.json rename to src/bezier-spline/test/out/issue-#1063.json diff --git a/packages/turf-bezier-spline/test/out/simple.json b/src/bezier-spline/test/out/simple.json similarity index 100% rename from packages/turf-bezier-spline/test/out/simple.json rename to src/bezier-spline/test/out/simple.json diff --git a/packages/turf-boolean-clockwise/bench.js b/src/boolean-clockwise/bench.js old mode 100755 new mode 100644 similarity index 100% rename from packages/turf-boolean-clockwise/bench.js rename to src/boolean-clockwise/bench.js diff --git a/packages/turf-boolean-clockwise/index.d.ts b/src/boolean-clockwise/index.d.ts similarity index 100% rename from packages/turf-boolean-clockwise/index.d.ts rename to src/boolean-clockwise/index.d.ts diff --git a/src/boolean-clockwise/index.js b/src/boolean-clockwise/index.js new file mode 100644 index 0000000000..1daf689900 --- /dev/null +++ b/src/boolean-clockwise/index.js @@ -0,0 +1,32 @@ +import { getCoords } from '../invariant'; + +/** + * Takes a ring and return true or false whether or not the ring is clockwise or counter-clockwise. + * + * @name booleanClockwise + * @param {Feature|LineString|Array>} line to be evaluated + * @returns {boolean} true/false + * @example + * var clockwiseRing = turf.lineString([[0,0],[1,1],[1,0],[0,0]]); + * var counterClockwiseRing = turf.lineString([[0,0],[1,0],[1,1],[0,0]]); + * + * turf.booleanClockwise(clockwiseRing) + * //=true + * turf.booleanClockwise(counterClockwiseRing) + * //=false + */ +export default function booleanClockwise(line) { + const ring = getCoords(line); + let sum = 0; + let i = 1; + let prev; + let cur; + + while (i < ring.length) { + prev = cur || ring[0]; + cur = ring[i]; + sum += ((cur[0] - prev[0]) * (cur[1] + prev[1])); + i++; + } + return sum > 0; +} diff --git a/src/boolean-clockwise/test.js b/src/boolean-clockwise/test.js new file mode 100644 index 0000000000..856176041c --- /dev/null +++ b/src/boolean-clockwise/test.js @@ -0,0 +1,50 @@ +const glob = require('glob'); +const path = require('path'); +const test = require('tape'); +const load = require('load-json-file'); +const { point, lineString } = require('../helpers'); +const isClockwise = require('./').default; + +test('isClockwise#fixtures', t => { + // True Fixtures + glob.sync(path.join(__dirname, 'test', 'true', '*.geojson')).forEach(filepath => { + const name = path.parse(filepath).name; + const geojson = load.sync(filepath); + const feature = geojson.features[0]; + t.true(isClockwise(feature), '[true] ' + name); + }); + // False Fixtures + glob.sync(path.join(__dirname, 'test', 'false', '*.geojson')).forEach(filepath => { + const name = path.parse(filepath).name; + const geojson = load.sync(filepath); + const feature = geojson.features[0]; + t.false(isClockwise(feature), '[false] ' + name); + }); + t.end(); +}); + +test('isClockwise', t => { + const cwArray = [[0, 0], [1, 1], [1, 0], [0, 0]]; + const ccwArray = [[0, 0], [1, 0], [1, 1], [0, 0]]; + + t.equal(isClockwise(cwArray), true, '[true] clockwise array input'); + t.equal(isClockwise(ccwArray), false, '[false] counter-clockwise array input'); + + t.end(); +}); + +test('isClockwise -- Geometry types', t => { + const line = lineString([[0, 0], [1, 1], [1, 0], [0, 0]]); + + t.equal(isClockwise(line), true, 'Feature'); + t.equal(isClockwise(line.geometry), true, 'Geometry Object'); + + t.end(); +}); + +// test('isClockwise -- throws', t => { +// const pt = point([-10, -33]); +// t.throws(() => isClockwise(pt), 'feature geometry not supported'); + +// t.end(); +// }); diff --git a/packages/turf-boolean-clockwise/test/false/counter-clockwise-line.geojson b/src/boolean-clockwise/test/false/counter-clockwise-line.geojson similarity index 100% rename from packages/turf-boolean-clockwise/test/false/counter-clockwise-line.geojson rename to src/boolean-clockwise/test/false/counter-clockwise-line.geojson diff --git a/packages/turf-boolean-clockwise/test/true/clockwise-line.geojson b/src/boolean-clockwise/test/true/clockwise-line.geojson similarity index 100% rename from packages/turf-boolean-clockwise/test/true/clockwise-line.geojson rename to src/boolean-clockwise/test/true/clockwise-line.geojson diff --git a/packages/turf-boolean-concave/bench.js b/src/boolean-concave/bench.js similarity index 100% rename from packages/turf-boolean-concave/bench.js rename to src/boolean-concave/bench.js diff --git a/packages/turf-boolean-concave/index.d.ts b/src/boolean-concave/index.d.ts similarity index 100% rename from packages/turf-boolean-concave/index.d.ts rename to src/boolean-concave/index.d.ts diff --git a/src/boolean-concave/index.js b/src/boolean-concave/index.js new file mode 100644 index 0000000000..f358a14b6a --- /dev/null +++ b/src/boolean-concave/index.js @@ -0,0 +1,33 @@ +import { getGeom } from "../invariant"; + +/** + * Takes a polygon and return true or false as to whether it is concave or not. + * + * @name booleanConcave + * @param {Feature} polygon to be evaluated + * @returns {boolean} true/false + * @example + * var convexPolygon = turf.polygon([[[0,0],[0,1],[1,1],[1,0],[0,0]]]); + * + * turf.booleanConcave(convexPolygon) + * //=false + */ +export default function booleanConcave(polygon) { + // Taken from https://stackoverflow.com/a/1881201 & https://stackoverflow.com/a/25304159 + const coords = getGeom(polygon).coordinates; + if (coords[0].length <= 4) { return false; } + + let sign = false; + const n = coords[0].length - 1; + for (let i = 0; i < n; i++) { + const dx1 = coords[0][(i + 2) % n][0] - coords[0][(i + 1) % n][0]; + const dy1 = coords[0][(i + 2) % n][1] - coords[0][(i + 1) % n][1]; + const dx2 = coords[0][i][0] - coords[0][(i + 1) % n][0]; + const dy2 = coords[0][i][1] - coords[0][(i + 1) % n][1]; + const zcrossproduct = (dx1 * dy2) - (dy1 * dx2); + if (i === 0) { + sign = zcrossproduct > 0; + } else if (sign !== (zcrossproduct > 0)) { return true; } + } + return false; +} diff --git a/src/boolean-concave/test.js b/src/boolean-concave/test.js new file mode 100644 index 0000000000..b795d9c5ae --- /dev/null +++ b/src/boolean-concave/test.js @@ -0,0 +1,39 @@ +const glob = require('glob'); +const path = require('path'); +const test = require('tape'); +const load = require('load-json-file'); +const { polygon, point } = require('../helpers'); +const isConcave = require('./').default; + +test('isConcave#fixtures', t => { + // True Fixtures + glob.sync(path.join(__dirname, 'test', 'true', '*.geojson')).forEach(filepath => { + const name = path.parse(filepath).name; + const geojson = load.sync(filepath); + const feature = geojson.features[0]; + t.true(isConcave(feature), '[true] ' + name); + }); + // False Fixtures + glob.sync(path.join(__dirname, 'test', 'false', '*.geojson')).forEach(filepath => { + const name = path.parse(filepath).name; + const geojson = load.sync(filepath); + const feature = geojson.features[0]; + t.false(isConcave(feature), '[false] ' + name); + }); + t.end(); +}); + +test('isConcave -- Geometry types', t => { + const poly = polygon([[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]]); + + t.equal(isConcave(poly), false, 'Feature'); + t.equal(isConcave(poly.geometry), false, 'Geometry Object'); + + t.end(); +}); + +test('isConcave -- throws', t => { + const pt = point([-10, -33]); + // t.throws(() => isConcave(pt), 'feature geometry not supported'); + t.end(); +}); diff --git a/packages/turf-boolean-concave/test/false/3vertices.geojson b/src/boolean-concave/test/false/3vertices.geojson similarity index 100% rename from packages/turf-boolean-concave/test/false/3vertices.geojson rename to src/boolean-concave/test/false/3vertices.geojson diff --git a/packages/turf-boolean-concave/test/false/diamond.geojson b/src/boolean-concave/test/false/diamond.geojson similarity index 100% rename from packages/turf-boolean-concave/test/false/diamond.geojson rename to src/boolean-concave/test/false/diamond.geojson diff --git a/packages/turf-boolean-concave/test/false/square.geojson b/src/boolean-concave/test/false/square.geojson similarity index 100% rename from packages/turf-boolean-concave/test/false/square.geojson rename to src/boolean-concave/test/false/square.geojson diff --git a/packages/turf-boolean-concave/test/true/polygon.geojson b/src/boolean-concave/test/true/polygon.geojson similarity index 100% rename from packages/turf-boolean-concave/test/true/polygon.geojson rename to src/boolean-concave/test/true/polygon.geojson diff --git a/packages/turf-boolean-concave/test/true/polygon2.geojson b/src/boolean-concave/test/true/polygon2.geojson similarity index 100% rename from packages/turf-boolean-concave/test/true/polygon2.geojson rename to src/boolean-concave/test/true/polygon2.geojson diff --git a/packages/turf-boolean-contains/bench.js b/src/boolean-contains/bench.js similarity index 100% rename from packages/turf-boolean-contains/bench.js rename to src/boolean-contains/bench.js diff --git a/packages/turf-boolean-contains/diagrams/esri-contains.gif b/src/boolean-contains/diagrams/esri-contains.gif similarity index 100% rename from packages/turf-boolean-contains/diagrams/esri-contains.gif rename to src/boolean-contains/diagrams/esri-contains.gif diff --git a/packages/turf-boolean-contains/index.d.ts b/src/boolean-contains/index.d.ts similarity index 100% rename from packages/turf-boolean-contains/index.d.ts rename to src/boolean-contains/index.d.ts diff --git a/src/boolean-contains/index.js b/src/boolean-contains/index.js new file mode 100644 index 0000000000..c3530784a2 --- /dev/null +++ b/src/boolean-contains/index.js @@ -0,0 +1,254 @@ +import calcBbox from '../bbox'; +import booleanPointInPolygon from '../boolean-point-in-polygon'; +import booleanCrosses from '../boolean-crosses'; +import isPointOnLine from '../boolean-point-on-line'; +import { lineString } from '../helpers'; +import { getGeom } from '../invariant'; + +/** + * Boolean-contains returns True if the second geometry is completely contained by the first geometry. + * The interiors of both geometries must intersect and, the interior and boundary of the secondary (geometry b) + * must not intersect the exterior of the primary (geometry a). + * Boolean-contains returns the exact opposite result of the `@turf/boolean-within`. + * + * @name booleanContains + * @param {Geometry|Feature} feature1 GeoJSON Feature or Geometry + * @param {Geometry|Feature} feature2 GeoJSON Feature or Geometry + * @returns {boolean} true/false + * @example + * var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); + * var point = turf.point([1, 2]); + * + * turf.booleanContains(line, point); + * //=true + */ +export default function booleanContains(feature1, feature2) { + const geom1 = getGeom(feature1); + const geom2 = getGeom(feature2); + const type1 = geom1.type; + const type2 = geom2.type; + const coords1 = geom1.coordinates; + const coords2 = geom2.coordinates; + + switch (type1) { + case 'Point': + switch (type2) { + case 'Point': + return compareCoords(coords1, coords2); + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + case 'MultiPoint': + switch (type2) { + case 'Point': + return isPointInMultiPoint(geom1, geom2); + case 'MultiPoint': + return isMultiPointInMultiPoint(geom1, geom2); + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + case 'LineString': + switch (type2) { + case 'Point': + return isPointOnLine(geom2, geom1, {ignoreEndVertices: true}); + case 'LineString': + return isLineOnLine(geom1, geom2); + case 'MultiPoint': + return isMultiPointOnLine(geom1, geom2); + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + case 'Polygon': + switch (type2) { + case 'Point': + return booleanPointInPolygon(geom2, geom1, {ignoreBoundary: true}); + case 'LineString': + return isLineInPoly(geom1, geom2); + case 'Polygon': + return isPolyInPoly(geom1, geom2); + case 'MultiPoint': + return isMultiPointInPoly(geom1, geom2); + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + default: + throw new Error('feature1 ' + type1 + ' geometry not supported'); + } +} + +export function isPointInMultiPoint(multiPoint, pt) { + let i; + let output = false; + for (i = 0; i < multiPoint.coordinates.length; i++) { + if (compareCoords(multiPoint.coordinates[i], pt.coordinates)) { + output = true; + break; + } + } + return output; +} + +export function isMultiPointInMultiPoint(multiPoint1, multiPoint2) { + for (const coord2 of multiPoint2.coordinates) { + let matchFound = false; + for (const coord1 of multiPoint1.coordinates) { + if (compareCoords(coord2, coord1)) { + matchFound = true; + break; + } + } + if (!matchFound) { + return false; + } + } + return true; +} + +export function isMultiPointOnLine(lineString, multiPoint) { + let haveFoundInteriorPoint = false; + for (const coord of multiPoint.coordinates) { + if (isPointOnLine(coord, lineString, {ignoreEndVertices: true})) { + haveFoundInteriorPoint = true; + } + if (!isPointOnLine(coord, lineString)) { + return false; + } + } + if (haveFoundInteriorPoint) { + return true; + } + return false; +} + +export function isMultiPointInPoly(polygon, multiPoint) { + for (const coord of multiPoint.coordinates) { + if (!booleanPointInPolygon(coord, polygon, {ignoreBoundary: true})) { + return false; + } + } + return true; +} + +export function isLineOnLine(lineString1, lineString2) { + let haveFoundInteriorPoint = false; + for (const coords of lineString2.coordinates) { + if (isPointOnLine({type: 'Point', coordinates: coords}, lineString1, { ignoreEndVertices: true })) { + haveFoundInteriorPoint = true; + } + if (!isPointOnLine({type: 'Point', coordinates: coords}, lineString1, {ignoreEndVertices: false })) { + return false; + } + } + return haveFoundInteriorPoint; +} + +export function isLineInPoly(polygon, linestring) { + let i = 0; + + let pointInside = false; + let pointOutside = false; + + const polyBbox = calcBbox(polygon); + const lineBbox = calcBbox(linestring); + if (!doBBoxOverlap(polyBbox, lineBbox)) { + return false; + } + for (i; i < linestring.coordinates.length; i++) { + if (!booleanPointInPolygon({type: 'Point', coordinates: linestring.coordinates[i]}, polygon, { ignoreBoundary: false })) { + pointOutside = true; + break; + } + if (!pointInside) { + if (booleanPointInPolygon({type: 'Point', coordinates: linestring.coordinates[i]}, polygon, { ignoreBoundary: true })) { + pointInside = true; + } + if (!pointInside && i < linestring.coordinates.length - 1) { + const midPoint = getMidpoint(linestring.coordinates[i], linestring.coordinates[i + 1]); + if (booleanPointInPolygon({type: 'Point', coordinates: midPoint}, polygon, { ignoreBoundary: true })) { + pointInside = true; + } + } + } + } + if (pointOutside) return false; + + + if (booleanCrosses(extractPolygonBorderAsLineString(polygon), linestring)) + return false; + + return pointInside; +} + +/** + * Is Polygon2 in Polygon1 + * Only takes into account outer rings + * + * @private + * @param {Geometry|Feature} feature1 Polygon1 + * @param {Geometry|Feature} feature2 Polygon2 + * @returns {boolean} true/false + */ +export function isPolyInPoly(feature1, feature2) { + // Handle Nulls + if (feature1.type === 'Feature' && feature1.geometry === null) { return false; } + if (feature2.type === 'Feature' && feature2.geometry === null) { return false; } + + const poly1Bbox = calcBbox(feature1); + const poly2Bbox = calcBbox(feature2); + if (!doBBoxOverlap(poly1Bbox, poly2Bbox)) { + return false; + } + + const coords = getGeom(feature2).coordinates; + for (const ring of coords) { + for (const coord of ring) { + if (!booleanPointInPolygon(coord, feature1)) { + return false; + } + } + } + + // Check for boundary intersections + const feature1PolygonBorder = extractPolygonBorderAsLineString(feature1); + const feature2PolygonBorder = extractPolygonBorderAsLineString(feature2); + if (booleanCrosses(feature1PolygonBorder, feature2PolygonBorder)) { + // If borders overlap perfectly, then we say polygon a 'contains' b, although this is a hotly debated topic. + if (isLineOnLine(feature1PolygonBorder.geometry, feature2PolygonBorder.geometry)) + return true; + else + return false; + } + + return true; +} + +export function doBBoxOverlap(bbox1, bbox2) { + if (bbox1[0] > bbox2[0]) { return false; } + if (bbox1[2] < bbox2[2]) { return false; } + if (bbox1[1] > bbox2[1]) { return false; } + if (bbox1[3] < bbox2[3]) { return false; } + return true; +} + +/** + * compareCoords + * + * @private + * @param {Position} pair1 point [x,y] + * @param {Position} pair2 point [x,y] + * @returns {boolean} true/false if coord pairs match + */ +export function compareCoords(pair1, pair2) { + return pair1[0] === pair2[0] && pair1[1] === pair2[1]; +} + +export function getMidpoint(pair1, pair2) { + return [(pair1[0] + pair2[0]) / 2, (pair1[1] + pair2[1]) / 2]; +} + +function extractPolygonBorderAsLineString(feature) { + const coords = getGeom(feature).coordinates; + const outerRing = coords[0]; + + return lineString(outerRing); +} diff --git a/src/boolean-contains/test.js b/src/boolean-contains/test.js new file mode 100644 index 0000000000..edfed578e5 --- /dev/null +++ b/src/boolean-contains/test.js @@ -0,0 +1,44 @@ +const glob = require('glob'); +const path = require('path'); +const test = require('tape'); +const load = require('load-json-file'); +const { point } = require('../helpers'); +const booleanJSTS = require('boolean-jsts'); +const shapely = require('boolean-shapely'); +const contains = require('./').default; + +test('turf-boolean-contains', t => { + // True Fixtures + glob.sync(path.join(__dirname, 'test', 'true', '**', '*.geojson')).forEach(filepath => { + const name = path.parse(filepath).name; + const geojson = load.sync(filepath); + const feature1 = geojson.features[0]; + const feature2 = geojson.features[1]; + const result = contains(feature1, feature2); + + if (process.env.JSTS) t.true(booleanJSTS('contains', feature1, feature2), '[true] JSTS - ' + name); + if (process.env.SHAPELY) shapely.contains(feature1, feature2).then(result => t.true(result, '[true] shapely - ' + name)); + t.true(result, '[true] ' + name); + }); + // False Fixtures + glob.sync(path.join(__dirname, 'test', 'false', '**', '*.geojson')).forEach(filepath => { + const name = path.parse(filepath).name; + const geojson = load.sync(filepath); + const feature1 = geojson.features[0]; + const feature2 = geojson.features[1]; + const result = contains(feature1, feature2); + + if (process.env.JSTS) t.false(booleanJSTS('contains', feature1, feature2), '[false] JSTS - ' + name); + if (process.env.SHAPELY) shapely.contains(feature1, feature2).then(result => t.false(result, '[false] shapely - ' + name)); + t.false(result, '[false] ' + name); + }); + t.end(); +}); + +test('turf-boolean-contains -- Geometry Objects', t => { + const pt1 = point([0, 0]); + const pt2 = point([0, 0]); + + t.assert(contains(pt1.geometry, pt2.geometry)); + t.end(); +}); diff --git a/packages/turf-boolean-contains/test/false/LineString/LineString/LineIsNotContainedByLine.geojson b/src/boolean-contains/test/false/LineString/LineString/LineIsNotContainedByLine.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/LineString/LineString/LineIsNotContainedByLine.geojson rename to src/boolean-contains/test/false/LineString/LineString/LineIsNotContainedByLine.geojson diff --git a/packages/turf-boolean-contains/test/false/LineString/Polygon/LineIsNotContainedByPolygon.geojson b/src/boolean-contains/test/false/LineString/Polygon/LineIsNotContainedByPolygon.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/LineString/Polygon/LineIsNotContainedByPolygon.geojson rename to src/boolean-contains/test/false/LineString/Polygon/LineIsNotContainedByPolygon.geojson diff --git a/packages/turf-boolean-contains/test/false/LineString/Polygon/LineIsNotContainedByPolygonBoundary.geojson b/src/boolean-contains/test/false/LineString/Polygon/LineIsNotContainedByPolygonBoundary.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/LineString/Polygon/LineIsNotContainedByPolygonBoundary.geojson rename to src/boolean-contains/test/false/LineString/Polygon/LineIsNotContainedByPolygonBoundary.geojson diff --git a/src/boolean-contains/test/false/LineString/Polygon/issue-1467-LineIsNotContainedByUPolygon.geojson b/src/boolean-contains/test/false/LineString/Polygon/issue-1467-LineIsNotContainedByUPolygon.geojson new file mode 100644 index 0000000000..fad021560b --- /dev/null +++ b/src/boolean-contains/test/false/LineString/Polygon/issue-1467-LineIsNotContainedByUPolygon.geojson @@ -0,0 +1,34 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [[ + [0, 0], + [0, 2], + [1, 2], + [1, 1], + [2, 1], + [2, 2], + [3, 2], + [3, 0], + [0, 0] + ]] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [0.5, 1.5], + [2.5, 1.5] + ] + } + } + ] +} \ No newline at end of file diff --git a/packages/turf-boolean-contains/test/false/MultiPoint/LineString/MultiPointsIsNotContainedByLine.geojson b/src/boolean-contains/test/false/MultiPoint/LineString/MultiPointsIsNotContainedByLine.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/MultiPoint/LineString/MultiPointsIsNotContainedByLine.geojson rename to src/boolean-contains/test/false/MultiPoint/LineString/MultiPointsIsNotContainedByLine.geojson diff --git a/packages/turf-boolean-contains/test/false/MultiPoint/LineString/MultiPointsOnLineEndsIsNotContainedByLine.geojson b/src/boolean-contains/test/false/MultiPoint/LineString/MultiPointsOnLineEndsIsNotContainedByLine.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/MultiPoint/LineString/MultiPointsOnLineEndsIsNotContainedByLine.geojson rename to src/boolean-contains/test/false/MultiPoint/LineString/MultiPointsOnLineEndsIsNotContainedByLine.geojson diff --git a/packages/turf-boolean-contains/test/false/MultiPoint/MultiPoint/MultiPointIsNotContainedByMultiPoint.geojson b/src/boolean-contains/test/false/MultiPoint/MultiPoint/MultiPointIsNotContainedByMultiPoint.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/MultiPoint/MultiPoint/MultiPointIsNotContainedByMultiPoint.geojson rename to src/boolean-contains/test/false/MultiPoint/MultiPoint/MultiPointIsNotContainedByMultiPoint.geojson diff --git a/packages/turf-boolean-contains/test/false/MultiPoint/Polygon/MultiPointAllOnBoundaryIsNotContainedByPolygon.geojson b/src/boolean-contains/test/false/MultiPoint/Polygon/MultiPointAllOnBoundaryIsNotContainedByPolygon.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/MultiPoint/Polygon/MultiPointAllOnBoundaryIsNotContainedByPolygon.geojson rename to src/boolean-contains/test/false/MultiPoint/Polygon/MultiPointAllOnBoundaryIsNotContainedByPolygon.geojson diff --git a/packages/turf-boolean-contains/test/false/MultiPoint/Polygon/MultiPointIsNotContainedByPolygon.geojson b/src/boolean-contains/test/false/MultiPoint/Polygon/MultiPointIsNotContainedByPolygon.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/MultiPoint/Polygon/MultiPointIsNotContainedByPolygon.geojson rename to src/boolean-contains/test/false/MultiPoint/Polygon/MultiPointIsNotContainedByPolygon.geojson diff --git a/packages/turf-boolean-contains/test/false/Point/LineString/PointIsNotContainedByLine.geojson b/src/boolean-contains/test/false/Point/LineString/PointIsNotContainedByLine.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/Point/LineString/PointIsNotContainedByLine.geojson rename to src/boolean-contains/test/false/Point/LineString/PointIsNotContainedByLine.geojson diff --git a/packages/turf-boolean-contains/test/false/Point/LineString/PointIsNotContainedByLineBecauseOnEnd.geojson b/src/boolean-contains/test/false/Point/LineString/PointIsNotContainedByLineBecauseOnEnd.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/Point/LineString/PointIsNotContainedByLineBecauseOnEnd.geojson rename to src/boolean-contains/test/false/Point/LineString/PointIsNotContainedByLineBecauseOnEnd.geojson diff --git a/packages/turf-boolean-contains/test/false/Point/LineString/PointOnEndIsContainedByLinestring.geojson b/src/boolean-contains/test/false/Point/LineString/PointOnEndIsContainedByLinestring.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/Point/LineString/PointOnEndIsContainedByLinestring.geojson rename to src/boolean-contains/test/false/Point/LineString/PointOnEndIsContainedByLinestring.geojson diff --git a/packages/turf-boolean-contains/test/false/Point/MultiPoint/PointIsNotContainedBYMultiPoint.geojson b/src/boolean-contains/test/false/Point/MultiPoint/PointIsNotContainedBYMultiPoint.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/Point/MultiPoint/PointIsNotContainedBYMultiPoint.geojson rename to src/boolean-contains/test/false/Point/MultiPoint/PointIsNotContainedBYMultiPoint.geojson diff --git a/packages/turf-boolean-contains/test/false/Point/Polygon/PointIsNotContainedByPolygon.geojson b/src/boolean-contains/test/false/Point/Polygon/PointIsNotContainedByPolygon.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/Point/Polygon/PointIsNotContainedByPolygon.geojson rename to src/boolean-contains/test/false/Point/Polygon/PointIsNotContainedByPolygon.geojson diff --git a/packages/turf-boolean-contains/test/false/Point/Polygon/PointOnPolygonBoundary.geojson b/src/boolean-contains/test/false/Point/Polygon/PointOnPolygonBoundary.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/Point/Polygon/PointOnPolygonBoundary.geojson rename to src/boolean-contains/test/false/Point/Polygon/PointOnPolygonBoundary.geojson diff --git a/packages/turf-boolean-contains/test/false/Polygon/LineString/issue-#1201-false.geojson b/src/boolean-contains/test/false/Polygon/LineString/issue-#1201-false.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/Polygon/LineString/issue-#1201-false.geojson rename to src/boolean-contains/test/false/Polygon/LineString/issue-#1201-false.geojson diff --git a/src/boolean-contains/test/false/Polygon/Polygon/Issue-1467-polygon-polygon-border-crossing.geojson b/src/boolean-contains/test/false/Polygon/Polygon/Issue-1467-polygon-polygon-border-crossing.geojson new file mode 100644 index 0000000000..03d7b9e55a --- /dev/null +++ b/src/boolean-contains/test/false/Polygon/Polygon/Issue-1467-polygon-polygon-border-crossing.geojson @@ -0,0 +1,34 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [[ + [0, 0], + [0, 2], + [1, 2], + [1, 1], + [2, 1], + [2, 0], + [0, 0] + ]] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [[ + [0.1, 0.1], + [0.5, 1.9], + [1.9, 0.5], + [0.1, 0.1] + ]] + } + } + ] +} \ No newline at end of file diff --git a/packages/turf-boolean-contains/test/false/Polygon/Polygon/Polygon-Polygon.geojson b/src/boolean-contains/test/false/Polygon/Polygon/Polygon-Polygon.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/Polygon/Polygon/Polygon-Polygon.geojson rename to src/boolean-contains/test/false/Polygon/Polygon/Polygon-Polygon.geojson diff --git a/packages/turf-boolean-contains/test/false/Polygon/Polygon/Polygon-Polygon2.geojson b/src/boolean-contains/test/false/Polygon/Polygon/Polygon-Polygon2.geojson similarity index 100% rename from packages/turf-boolean-contains/test/false/Polygon/Polygon/Polygon-Polygon2.geojson rename to src/boolean-contains/test/false/Polygon/Polygon/Polygon-Polygon2.geojson diff --git a/packages/turf-boolean-contains/test/true/LineString/LineString/LineIsContainedByLine.geojson b/src/boolean-contains/test/true/LineString/LineString/LineIsContainedByLine.geojson similarity index 100% rename from packages/turf-boolean-contains/test/true/LineString/LineString/LineIsContainedByLine.geojson rename to src/boolean-contains/test/true/LineString/LineString/LineIsContainedByLine.geojson diff --git a/packages/turf-boolean-contains/test/true/LineString/LineString/LinesExactlySame.geojson b/src/boolean-contains/test/true/LineString/LineString/LinesExactlySame.geojson similarity index 100% rename from packages/turf-boolean-contains/test/true/LineString/LineString/LinesExactlySame.geojson rename to src/boolean-contains/test/true/LineString/LineString/LinesExactlySame.geojson diff --git a/packages/turf-boolean-contains/test/true/LineString/Polygon/LineIsContainedByPolygon.geojson b/src/boolean-contains/test/true/LineString/Polygon/LineIsContainedByPolygon.geojson similarity index 100% rename from packages/turf-boolean-contains/test/true/LineString/Polygon/LineIsContainedByPolygon.geojson rename to src/boolean-contains/test/true/LineString/Polygon/LineIsContainedByPolygon.geojson diff --git a/packages/turf-boolean-contains/test/true/LineString/Polygon/LineIsContainedByPolygonWithNoInternalVertices.geojson b/src/boolean-contains/test/true/LineString/Polygon/LineIsContainedByPolygonWithNoInternalVertices.geojson similarity index 100% rename from packages/turf-boolean-contains/test/true/LineString/Polygon/LineIsContainedByPolygonWithNoInternalVertices.geojson rename to src/boolean-contains/test/true/LineString/Polygon/LineIsContainedByPolygonWithNoInternalVertices.geojson diff --git a/packages/turf-boolean-contains/test/true/MultiPoint/LineString/MultipointsIsContainedByLine.geojson b/src/boolean-contains/test/true/MultiPoint/LineString/MultipointsIsContainedByLine.geojson similarity index 100% rename from packages/turf-boolean-contains/test/true/MultiPoint/LineString/MultipointsIsContainedByLine.geojson rename to src/boolean-contains/test/true/MultiPoint/LineString/MultipointsIsContainedByLine.geojson diff --git a/packages/turf-boolean-contains/test/true/MultiPoint/MultiPoint/MultiPointsContainedByMultiPoints.geojson b/src/boolean-contains/test/true/MultiPoint/MultiPoint/MultiPointsContainedByMultiPoints.geojson similarity index 100% rename from packages/turf-boolean-contains/test/true/MultiPoint/MultiPoint/MultiPointsContainedByMultiPoints.geojson rename to src/boolean-contains/test/true/MultiPoint/MultiPoint/MultiPointsContainedByMultiPoints.geojson diff --git a/packages/turf-boolean-contains/test/true/MultiPoint/MultiPoint/MultiPointsEqual.geojson b/src/boolean-contains/test/true/MultiPoint/MultiPoint/MultiPointsEqual.geojson similarity index 100% rename from packages/turf-boolean-contains/test/true/MultiPoint/MultiPoint/MultiPointsEqual.geojson rename to src/boolean-contains/test/true/MultiPoint/MultiPoint/MultiPointsEqual.geojson diff --git a/packages/turf-boolean-contains/test/true/MultiPoint/Polygon/MultiPointIsContainedByPolygonBoundary.geojson b/src/boolean-contains/test/true/MultiPoint/Polygon/MultiPointIsContainedByPolygonBoundary.geojson similarity index 100% rename from packages/turf-boolean-contains/test/true/MultiPoint/Polygon/MultiPointIsContainedByPolygonBoundary.geojson rename to src/boolean-contains/test/true/MultiPoint/Polygon/MultiPointIsContainedByPolygonBoundary.geojson diff --git a/packages/turf-boolean-contains/test/true/Point/LineString/PointIsContainedByLine.geojson b/src/boolean-contains/test/true/Point/LineString/PointIsContainedByLine.geojson similarity index 100% rename from packages/turf-boolean-contains/test/true/Point/LineString/PointIsContainedByLine.geojson rename to src/boolean-contains/test/true/Point/LineString/PointIsContainedByLine.geojson diff --git a/packages/turf-boolean-contains/test/true/Point/MultiPoint/PointIsContainedByMultiPoint.geojson b/src/boolean-contains/test/true/Point/MultiPoint/PointIsContainedByMultiPoint.geojson similarity index 100% rename from packages/turf-boolean-contains/test/true/Point/MultiPoint/PointIsContainedByMultiPoint.geojson rename to src/boolean-contains/test/true/Point/MultiPoint/PointIsContainedByMultiPoint.geojson diff --git a/packages/turf-boolean-contains/test/true/Point/Polygon/PointInsidePolygonBoundary.geojson b/src/boolean-contains/test/true/Point/Polygon/PointInsidePolygonBoundary.geojson similarity index 100% rename from packages/turf-boolean-contains/test/true/Point/Polygon/PointInsidePolygonBoundary.geojson rename to src/boolean-contains/test/true/Point/Polygon/PointInsidePolygonBoundary.geojson diff --git a/packages/turf-boolean-contains/test/true/Polygon/LineString/issue-#1201-true.geojson b/src/boolean-contains/test/true/Polygon/LineString/issue-#1201-true.geojson similarity index 100% rename from packages/turf-boolean-contains/test/true/Polygon/LineString/issue-#1201-true.geojson rename to src/boolean-contains/test/true/Polygon/LineString/issue-#1201-true.geojson diff --git a/packages/turf-boolean-contains/test/true/Polygon/Polygon/PolygonExactSameShape.geojson b/src/boolean-contains/test/true/Polygon/Polygon/PolygonExactSameShape.geojson similarity index 100% rename from packages/turf-boolean-contains/test/true/Polygon/Polygon/PolygonExactSameShape.geojson rename to src/boolean-contains/test/true/Polygon/Polygon/PolygonExactSameShape.geojson diff --git a/packages/turf-boolean-contains/test/true/Polygon/Polygon/PolygonIsContainedByPolygon.geojson b/src/boolean-contains/test/true/Polygon/Polygon/PolygonIsContainedByPolygon.geojson similarity index 100% rename from packages/turf-boolean-contains/test/true/Polygon/Polygon/PolygonIsContainedByPolygon.geojson rename to src/boolean-contains/test/true/Polygon/Polygon/PolygonIsContainedByPolygon.geojson diff --git a/packages/turf-boolean-crosses/bench.js b/src/boolean-crosses/bench.js similarity index 100% rename from packages/turf-boolean-crosses/bench.js rename to src/boolean-crosses/bench.js diff --git a/packages/turf-boolean-crosses/diagrams/esri-crosses.gif b/src/boolean-crosses/diagrams/esri-crosses.gif similarity index 100% rename from packages/turf-boolean-crosses/diagrams/esri-crosses.gif rename to src/boolean-crosses/diagrams/esri-crosses.gif diff --git a/src/boolean-crosses/index.js b/src/boolean-crosses/index.js new file mode 100644 index 0000000000..bc37132b25 --- /dev/null +++ b/src/boolean-crosses/index.js @@ -0,0 +1,176 @@ +import lineIntersect from '../line-intersect'; +import { polygonToLine } from '../polygon-to-line'; +import booleanPointInPolygon from '../boolean-point-in-polygon'; +import { getGeom } from '../invariant'; +import { point } from '../helpers'; + +/** + * Boolean-Crosses returns True if the intersection results in a geometry whose dimension is one less than + * the maximum dimension of the two source geometries and the intersection set is interior to + * both source geometries. + * + * Boolean-Crosses returns t (TRUE) for only multipoint/polygon, multipoint/linestring, linestring/linestring, linestring/polygon, and linestring/multipolygon comparisons. + * + * @name booleanCrosses + * @param {Geometry|Feature} feature1 GeoJSON Feature or Geometry + * @param {Geometry|Feature} feature2 GeoJSON Feature or Geometry + * @returns {boolean} true/false + * @example + * var line1 = turf.lineString([[-2, 2], [4, 2]]); + * var line2 = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); + * + * var cross = turf.booleanCrosses(line1, line2); + * //=true + */ +function booleanCrosses(feature1, feature2) { + var geom1 = getGeom(feature1); + var geom2 = getGeom(feature2); + var type1 = geom1.type; + var type2 = geom2.type; + + switch (type1) { + case 'MultiPoint': + switch (type2) { + case 'LineString': + return doMultiPointAndLineStringCross(geom1, geom2); + case 'Polygon': + return doesMultiPointCrossPoly(geom1, geom2); + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + case 'LineString': + switch (type2) { + case 'MultiPoint': // An inverse operation + return doMultiPointAndLineStringCross(geom2, geom1); + case 'LineString': + return doLineStringsCross(geom1, geom2); + case 'Polygon': + return doLineStringAndPolygonCross(geom1, geom2); + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + case 'Polygon': + switch (type2) { + case 'MultiPoint': // An inverse operation + return doesMultiPointCrossPoly(geom2, geom1); + case 'LineString': // An inverse operation + return doLineStringAndPolygonCross(geom2, geom1); + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + default: + throw new Error('feature1 ' + type1 + ' geometry not supported'); + } +} + +function doMultiPointAndLineStringCross(multiPoint, lineString) { + var foundIntPoint = false; + var foundExtPoint = false; + var pointLength = multiPoint.coordinates.length; + var i = 0; + while (i < pointLength && !foundIntPoint && !foundExtPoint) { + for (var i2 = 0; i2 < lineString.coordinates.length - 1; i2++) { + var incEndVertices = true; + if (i2 === 0 || i2 === lineString.coordinates.length - 2) { + incEndVertices = false; + } + if (isPointOnLineSegment(lineString.coordinates[i2], lineString.coordinates[i2 + 1], multiPoint.coordinates[i], incEndVertices)) { + foundIntPoint = true; + } else { + foundExtPoint = true; + } + } + i++; + } + return foundIntPoint && foundExtPoint; +} + +function doLineStringsCross(lineString1, lineString2) { + const intersections = lineIntersect(lineString1, lineString2); + + const endpoints = [ + lineString1.coordinates[0], lineString1.coordinates[lineString1.coordinates.length - 1], + lineString2.coordinates[0], lineString2.coordinates[lineString2.coordinates.length - 1] + ]; + + // A line that touches another line should not cross + const hasAnIntersectionWithoutEndpoints = intersections.features.some(function (feature) { + return !endpoints.some(compareCoords.bind(this, feature.geometry.coordinates)); + }); + + return hasAnIntersectionWithoutEndpoints; +} + +function doLineStringAndPolygonCross(lineString, polygon) { + const line = polygonToLine(polygon); + const doLinesIntersect = lineIntersect(lineString, line); + if (doLinesIntersect.features.length > 0) { + return true; + } + return false; +} + +function doesMultiPointCrossPoly(multiPoint, polygon) { + var foundIntPoint = false; + var foundExtPoint = false; + var pointLength = multiPoint.coordinates[0].length; + var i = 0; + while (i < pointLength && foundIntPoint && foundExtPoint) { + if (booleanPointInPolygon(point(multiPoint.coordinates[0][i]), polygon)) { + foundIntPoint = true; + } else { + foundExtPoint = true; + } + i++; + } + + return foundExtPoint && foundExtPoint; +} + +/** + * Is a point on a line segment + * Only takes into account outer rings + * See http://stackoverflow.com/a/4833823/1979085 + * + * @private + * @param {number[]} lineSegmentStart coord pair of start of line + * @param {number[]} lineSegmentEnd coord pair of end of line + * @param {number[]} pt coord pair of point to check + * @param {boolean} incEnd whether the point is allowed to fall on the line ends + * @returns {boolean} true/false + */ +function isPointOnLineSegment(lineSegmentStart, lineSegmentEnd, pt, incEnd) { + var dxc = pt[0] - lineSegmentStart[0]; + var dyc = pt[1] - lineSegmentStart[1]; + var dxl = lineSegmentEnd[0] - lineSegmentStart[0]; + var dyl = lineSegmentEnd[1] - lineSegmentStart[1]; + var cross = dxc * dyl - dyc * dxl; + if (cross !== 0) { + return false; + } + if (incEnd) { + if (Math.abs(dxl) >= Math.abs(dyl)) { + return dxl > 0 ? lineSegmentStart[0] <= pt[0] && pt[0] <= lineSegmentEnd[0] : lineSegmentEnd[0] <= pt[0] && pt[0] <= lineSegmentStart[0]; + } + return dyl > 0 ? lineSegmentStart[1] <= pt[1] && pt[1] <= lineSegmentEnd[1] : lineSegmentEnd[1] <= pt[1] && pt[1] <= lineSegmentStart[1]; + } else { + if (Math.abs(dxl) >= Math.abs(dyl)) { + return dxl > 0 ? lineSegmentStart[0] < pt[0] && pt[0] < lineSegmentEnd[0] : lineSegmentEnd[0] < pt[0] && pt[0] < lineSegmentStart[0]; + } + return dyl > 0 ? lineSegmentStart[1] < pt[1] && pt[1] < lineSegmentEnd[1] : lineSegmentEnd[1] < pt[1] && pt[1] < lineSegmentStart[1]; + } +} + +/** + * compareCoords + * + * @private + * @param {Position} pair1 point [x,y] + * @param {Position} pair2 point [x,y] + * @returns {boolean} true/false if coord pairs match + */ +export function compareCoords(pair1, pair2) { + return pair1[0] === pair2[0] && pair1[1] === pair2[1]; +} + +export default booleanCrosses; diff --git a/packages/turf-boolean-crosses/test.js b/src/boolean-crosses/test.js similarity index 100% rename from packages/turf-boolean-crosses/test.js rename to src/boolean-crosses/test.js diff --git a/packages/turf-boolean-crosses/test/false/LineString/LineString/LineDoesNotCrossButTouches.geojson b/src/boolean-crosses/test/false/LineString/LineString/LineDoesNotCrossButTouches.geojson similarity index 100% rename from packages/turf-boolean-crosses/test/false/LineString/LineString/LineDoesNotCrossButTouches.geojson rename to src/boolean-crosses/test/false/LineString/LineString/LineDoesNotCrossButTouches.geojson diff --git a/packages/turf-boolean-crosses/test/false/LineString/LineString/LineDoesNotCrossLine.geojson b/src/boolean-crosses/test/false/LineString/LineString/LineDoesNotCrossLine.geojson similarity index 100% rename from packages/turf-boolean-crosses/test/false/LineString/LineString/LineDoesNotCrossLine.geojson rename to src/boolean-crosses/test/false/LineString/LineString/LineDoesNotCrossLine.geojson diff --git a/packages/turf-boolean-crosses/test/false/LineString/Polygon/LineDoesNotCrossPolygon.geojson b/src/boolean-crosses/test/false/LineString/Polygon/LineDoesNotCrossPolygon.geojson similarity index 100% rename from packages/turf-boolean-crosses/test/false/LineString/Polygon/LineDoesNotCrossPolygon.geojson rename to src/boolean-crosses/test/false/LineString/Polygon/LineDoesNotCrossPolygon.geojson diff --git a/packages/turf-boolean-crosses/test/false/MultiPoint/LineString/MultiPointNotCrossLine.geojson b/src/boolean-crosses/test/false/MultiPoint/LineString/MultiPointNotCrossLine.geojson similarity index 100% rename from packages/turf-boolean-crosses/test/false/MultiPoint/LineString/MultiPointNotCrossLine.geojson rename to src/boolean-crosses/test/false/MultiPoint/LineString/MultiPointNotCrossLine.geojson diff --git a/packages/turf-boolean-crosses/test/false/MultiPoint/LineString/MultiPointNotCrossLineEnd.geojson b/src/boolean-crosses/test/false/MultiPoint/LineString/MultiPointNotCrossLineEnd.geojson similarity index 100% rename from packages/turf-boolean-crosses/test/false/MultiPoint/LineString/MultiPointNotCrossLineEnd.geojson rename to src/boolean-crosses/test/false/MultiPoint/LineString/MultiPointNotCrossLineEnd.geojson diff --git a/packages/turf-boolean-crosses/test/true/LineString/LineString/LineCrossesLine.geojson b/src/boolean-crosses/test/true/LineString/LineString/LineCrossesLine.geojson similarity index 100% rename from packages/turf-boolean-crosses/test/true/LineString/LineString/LineCrossesLine.geojson rename to src/boolean-crosses/test/true/LineString/LineString/LineCrossesLine.geojson diff --git a/src/boolean-crosses/test/true/LineString/LineString/ObliqueCrossing.geojson b/src/boolean-crosses/test/true/LineString/LineString/ObliqueCrossing.geojson new file mode 100644 index 0000000000..f57f358817 --- /dev/null +++ b/src/boolean-crosses/test/true/LineString/LineString/ObliqueCrossing.geojson @@ -0,0 +1,21 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [[0, 0], [2, 2]] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [[2, 0], [0, 2]] + } + } + ] +} \ No newline at end of file diff --git a/packages/turf-boolean-crosses/test/true/LineString/Polygon/LineCrossesPolygon.geojson b/src/boolean-crosses/test/true/LineString/Polygon/LineCrossesPolygon.geojson similarity index 100% rename from packages/turf-boolean-crosses/test/true/LineString/Polygon/LineCrossesPolygon.geojson rename to src/boolean-crosses/test/true/LineString/Polygon/LineCrossesPolygon.geojson diff --git a/packages/turf-boolean-crosses/test/true/LineString/Polygon/LineCrossesPolygonPartial.geojson b/src/boolean-crosses/test/true/LineString/Polygon/LineCrossesPolygonPartial.geojson similarity index 100% rename from packages/turf-boolean-crosses/test/true/LineString/Polygon/LineCrossesPolygonPartial.geojson rename to src/boolean-crosses/test/true/LineString/Polygon/LineCrossesPolygonPartial.geojson diff --git a/packages/turf-boolean-crosses/test/true/MultiPoint/LineString/MultiPointsCrossLine.geojson b/src/boolean-crosses/test/true/MultiPoint/LineString/MultiPointsCrossLine.geojson similarity index 100% rename from packages/turf-boolean-crosses/test/true/MultiPoint/LineString/MultiPointsCrossLine.geojson rename to src/boolean-crosses/test/true/MultiPoint/LineString/MultiPointsCrossLine.geojson diff --git a/packages/turf-boolean-disjoint/bench.js b/src/boolean-disjoint/bench.js similarity index 100% rename from packages/turf-boolean-disjoint/bench.js rename to src/boolean-disjoint/bench.js diff --git a/packages/turf-boolean-disjoint/diagrams/esri-disjoint.gif b/src/boolean-disjoint/diagrams/esri-disjoint.gif similarity index 100% rename from packages/turf-boolean-disjoint/diagrams/esri-disjoint.gif rename to src/boolean-disjoint/diagrams/esri-disjoint.gif diff --git a/packages/turf-boolean-disjoint/index.d.ts b/src/boolean-disjoint/index.d.ts similarity index 100% rename from packages/turf-boolean-disjoint/index.d.ts rename to src/boolean-disjoint/index.d.ts diff --git a/src/boolean-disjoint/index.js b/src/boolean-disjoint/index.js new file mode 100644 index 0000000000..5c4b0c0598 --- /dev/null +++ b/src/boolean-disjoint/index.js @@ -0,0 +1,169 @@ +import booleanPointInPolygon from '../boolean-point-in-polygon'; +import lineIntersect from '../line-intersect'; +import { flattenEach } from '../meta'; +import polygonToLine from '../polygon-to-line'; + +/** + * Boolean-disjoint returns (TRUE) if the intersection of the two geometries is an empty set. + * + * @name booleanDisjoint + * @param {Geometry|Feature} feature1 GeoJSON Feature or Geometry + * @param {Geometry|Feature} feature2 GeoJSON Feature or Geometry + * @returns {boolean} true/false + * @example + * var point = turf.point([2, 2]); + * var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); + * + * turf.booleanDisjoint(line, point); + * //=true + */ +function booleanDisjoint(feature1, feature2) { + let bool = true; + flattenEach(feature1, (flatten1) => { + flattenEach(feature2, (flatten2) => { + if (bool === false) { return false; } + bool = disjoint(flatten1.geometry, flatten2.geometry); + }); + }); + return bool; +} + +/** + * Disjoint operation for simple Geometries (Point/LineString/Polygon) + * + * @private + * @param {Geometry} geom1 GeoJSON Geometry + * @param {Geometry} geom2 GeoJSON Geometry + * @returns {boolean} true/false + */ +function disjoint(geom1, geom2) { + switch (geom1.type) { + case 'Point': + switch (geom2.type) { + case 'Point': + return !compareCoords(geom1.coordinates, geom2.coordinates); + case 'LineString': + return !isPointOnLine(geom2, geom1); + case 'Polygon': + return !booleanPointInPolygon(geom1, geom2); + } + /* istanbul ignore next */ + break; + case 'LineString': + switch (geom2.type) { + case 'Point': + return !isPointOnLine(geom1, geom2); + case 'LineString': + return !isLineOnLine(geom1, geom2); + case 'Polygon': + return !isLineInPoly(geom2, geom1); + } + /* istanbul ignore next */ + break; + case 'Polygon': + switch (geom2.type) { + case 'Point': + return !booleanPointInPolygon(geom2, geom1); + case 'LineString': + return !isLineInPoly(geom1, geom2); + case 'Polygon': + return !isPolyInPoly(geom2, geom1); + } + } + return false; +} + +// http://stackoverflow.com/a/11908158/1979085 +function isPointOnLine(lineString, pt) { + for (let i = 0; i < lineString.coordinates.length - 1; i++) { + if (isPointOnLineSegment(lineString.coordinates[i], lineString.coordinates[i + 1], pt.coordinates)) { + return true; + } + } + return false; +} + +function isLineOnLine(lineString1, lineString2) { + const doLinesIntersect = lineIntersect(lineString1, lineString2); + if (doLinesIntersect.features.length > 0) { + return true; + } + return false; +} + +function isLineInPoly(polygon, lineString) { + for (const coord of lineString.coordinates) { + if (booleanPointInPolygon(coord, polygon)) { + return true; + } + } + const doLinesIntersect = lineIntersect(lineString, polygonToLine(polygon)); + if (doLinesIntersect.features.length > 0) { + return true; + } + return false; +} + +/** + * Is Polygon (geom1) in Polygon (geom2) + * Only takes into account outer rings + * See http://stackoverflow.com/a/4833823/1979085 + * + * @private + * @param {Geometry|Feature} feature1 Polygon1 + * @param {Geometry|Feature} feature2 Polygon2 + * @returns {boolean} true/false + */ +function isPolyInPoly(feature1, feature2) { + for (const coord1 of feature1.coordinates[0]) { + if (booleanPointInPolygon(coord1, feature2)) { + return true; + } + } + for (const coord2 of feature2.coordinates[0]) { + if (booleanPointInPolygon(coord2, feature1)) { + return true; + } + } + const doLinesIntersect = lineIntersect(polygonToLine(feature1), polygonToLine(feature2)); + if (doLinesIntersect.features.length > 0) { + return true; + } + return false; +} + +function isPointOnLineSegment(lineSegmentStart, lineSegmentEnd, pt) { + const dxc = pt[0] - lineSegmentStart[0]; + const dyc = pt[1] - lineSegmentStart[1]; + const dxl = lineSegmentEnd[0] - lineSegmentStart[0]; + const dyl = lineSegmentEnd[1] - lineSegmentStart[1]; + const cross = dxc * dyl - dyc * dxl; + if (cross !== 0) { + return false; + } + if (Math.abs(dxl) >= Math.abs(dyl)) { + if (dxl > 0) { + return lineSegmentStart[0] <= pt[0] && pt[0] <= lineSegmentEnd[0]; + } else { + return lineSegmentEnd[0] <= pt[0] && pt[0] <= lineSegmentStart[0]; + } + } else if (dyl > 0) { + return lineSegmentStart[1] <= pt[1] && pt[1] <= lineSegmentEnd[1]; + } else { + return lineSegmentEnd[1] <= pt[1] && pt[1] <= lineSegmentStart[1]; + } +} + +/** + * compareCoords + * + * @private + * @param {Position} pair1 point [x,y] + * @param {Position} pair2 point [x,y] + * @returns {boolean} true/false if coord pairs match + */ +function compareCoords(pair1, pair2) { + return pair1[0] === pair2[0] && pair1[1] === pair2[1]; +} + +export default booleanDisjoint; diff --git a/packages/turf-boolean-disjoint/test.js b/src/boolean-disjoint/test.js similarity index 100% rename from packages/turf-boolean-disjoint/test.js rename to src/boolean-disjoint/test.js diff --git a/packages/turf-boolean-disjoint/test/false/LineString/LineString/LineString-LineString.geojson b/src/boolean-disjoint/test/false/LineString/LineString/LineString-LineString.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/LineString/LineString/LineString-LineString.geojson rename to src/boolean-disjoint/test/false/LineString/LineString/LineString-LineString.geojson diff --git a/packages/turf-boolean-disjoint/test/false/LineString/Point/LineString-Point-1.geojson b/src/boolean-disjoint/test/false/LineString/Point/LineString-Point-1.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/LineString/Point/LineString-Point-1.geojson rename to src/boolean-disjoint/test/false/LineString/Point/LineString-Point-1.geojson diff --git a/packages/turf-boolean-disjoint/test/false/LineString/Point/LineString-Point-2.geojson b/src/boolean-disjoint/test/false/LineString/Point/LineString-Point-2.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/LineString/Point/LineString-Point-2.geojson rename to src/boolean-disjoint/test/false/LineString/Point/LineString-Point-2.geojson diff --git a/packages/turf-boolean-disjoint/test/false/LineString/Polygon/LineString-In-Polygon.geojson b/src/boolean-disjoint/test/false/LineString/Polygon/LineString-In-Polygon.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/LineString/Polygon/LineString-In-Polygon.geojson rename to src/boolean-disjoint/test/false/LineString/Polygon/LineString-In-Polygon.geojson diff --git a/packages/turf-boolean-disjoint/test/false/LineString/Polygon/LineString-Polygon.geojson b/src/boolean-disjoint/test/false/LineString/Polygon/LineString-Polygon.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/LineString/Polygon/LineString-Polygon.geojson rename to src/boolean-disjoint/test/false/LineString/Polygon/LineString-Polygon.geojson diff --git a/packages/turf-boolean-disjoint/test/false/MultiPoint/LineString/MultiPoint-LineString.geojson b/src/boolean-disjoint/test/false/MultiPoint/LineString/MultiPoint-LineString.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/MultiPoint/LineString/MultiPoint-LineString.geojson rename to src/boolean-disjoint/test/false/MultiPoint/LineString/MultiPoint-LineString.geojson diff --git a/packages/turf-boolean-disjoint/test/false/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson b/src/boolean-disjoint/test/false/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson rename to src/boolean-disjoint/test/false/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson diff --git a/packages/turf-boolean-disjoint/test/false/MultiPoint/Polygon/MultiPoint-Polygon.geojson b/src/boolean-disjoint/test/false/MultiPoint/Polygon/MultiPoint-Polygon.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/MultiPoint/Polygon/MultiPoint-Polygon.geojson rename to src/boolean-disjoint/test/false/MultiPoint/Polygon/MultiPoint-Polygon.geojson diff --git a/packages/turf-boolean-disjoint/test/false/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson b/src/boolean-disjoint/test/false/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson rename to src/boolean-disjoint/test/false/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Point/LineString/Point-LineString-1.geojson b/src/boolean-disjoint/test/false/Point/LineString/Point-LineString-1.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Point/LineString/Point-LineString-1.geojson rename to src/boolean-disjoint/test/false/Point/LineString/Point-LineString-1.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Point/LineString/Point-LineString-2.geojson b/src/boolean-disjoint/test/false/Point/LineString/Point-LineString-2.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Point/LineString/Point-LineString-2.geojson rename to src/boolean-disjoint/test/false/Point/LineString/Point-LineString-2.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Point/LineString/Point-LineString-3.geojson b/src/boolean-disjoint/test/false/Point/LineString/Point-LineString-3.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Point/LineString/Point-LineString-3.geojson rename to src/boolean-disjoint/test/false/Point/LineString/Point-LineString-3.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Point/LineString/Point-LineString-4.geojson b/src/boolean-disjoint/test/false/Point/LineString/Point-LineString-4.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Point/LineString/Point-LineString-4.geojson rename to src/boolean-disjoint/test/false/Point/LineString/Point-LineString-4.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Point/MultiPoint/Point-MultiPoint.geojson b/src/boolean-disjoint/test/false/Point/MultiPoint/Point-MultiPoint.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Point/MultiPoint/Point-MultiPoint.geojson rename to src/boolean-disjoint/test/false/Point/MultiPoint/Point-MultiPoint.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Point/Point/Point-Point.geojson b/src/boolean-disjoint/test/false/Point/Point/Point-Point.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Point/Point/Point-Point.geojson rename to src/boolean-disjoint/test/false/Point/Point/Point-Point.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Point/Polygon/Point-Polygon-1.geojson b/src/boolean-disjoint/test/false/Point/Polygon/Point-Polygon-1.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Point/Polygon/Point-Polygon-1.geojson rename to src/boolean-disjoint/test/false/Point/Polygon/Point-Polygon-1.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Point/Polygon/Point-Polygon-2.geojson b/src/boolean-disjoint/test/false/Point/Polygon/Point-Polygon-2.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Point/Polygon/Point-Polygon-2.geojson rename to src/boolean-disjoint/test/false/Point/Polygon/Point-Polygon-2.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Polygon/LineString/Polygon-Containing-Linestring.geojson b/src/boolean-disjoint/test/false/Polygon/LineString/Polygon-Containing-Linestring.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Polygon/LineString/Polygon-Containing-Linestring.geojson rename to src/boolean-disjoint/test/false/Polygon/LineString/Polygon-Containing-Linestring.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Polygon/LineString/Polygon-LineString.geojson b/src/boolean-disjoint/test/false/Polygon/LineString/Polygon-LineString.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Polygon/LineString/Polygon-LineString.geojson rename to src/boolean-disjoint/test/false/Polygon/LineString/Polygon-LineString.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson b/src/boolean-disjoint/test/false/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson rename to src/boolean-disjoint/test/false/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Polygon/Point/Polygon-Point.geojson b/src/boolean-disjoint/test/false/Polygon/Point/Polygon-Point.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Polygon/Point/Polygon-Point.geojson rename to src/boolean-disjoint/test/false/Polygon/Point/Polygon-Point.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Polygon/Polygon/Large-Inside-Small.geojson b/src/boolean-disjoint/test/false/Polygon/Polygon/Large-Inside-Small.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Polygon/Polygon/Large-Inside-Small.geojson rename to src/boolean-disjoint/test/false/Polygon/Polygon/Large-Inside-Small.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Polygon/Polygon/Polygon-Polygon.geojson b/src/boolean-disjoint/test/false/Polygon/Polygon/Polygon-Polygon.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Polygon/Polygon/Polygon-Polygon.geojson rename to src/boolean-disjoint/test/false/Polygon/Polygon/Polygon-Polygon.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Polygon/Polygon/Small-Inside-Large.geojson b/src/boolean-disjoint/test/false/Polygon/Polygon/Small-Inside-Large.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Polygon/Polygon/Small-Inside-Large.geojson rename to src/boolean-disjoint/test/false/Polygon/Polygon/Small-Inside-Large.geojson diff --git a/packages/turf-boolean-disjoint/test/false/Polygon/Polygon/issue-1216.geojson b/src/boolean-disjoint/test/false/Polygon/Polygon/issue-1216.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/false/Polygon/Polygon/issue-1216.geojson rename to src/boolean-disjoint/test/false/Polygon/Polygon/issue-1216.geojson diff --git a/packages/turf-boolean-disjoint/test/true/LineString/LineString/LineString-LineString.geojson b/src/boolean-disjoint/test/true/LineString/LineString/LineString-LineString.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/LineString/LineString/LineString-LineString.geojson rename to src/boolean-disjoint/test/true/LineString/LineString/LineString-LineString.geojson diff --git a/packages/turf-boolean-disjoint/test/true/LineString/Point/LineString-Point.geojson b/src/boolean-disjoint/test/true/LineString/Point/LineString-Point.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/LineString/Point/LineString-Point.geojson rename to src/boolean-disjoint/test/true/LineString/Point/LineString-Point.geojson diff --git a/packages/turf-boolean-disjoint/test/true/LineString/Polygon/LineString-Polygon.geojson b/src/boolean-disjoint/test/true/LineString/Polygon/LineString-Polygon.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/LineString/Polygon/LineString-Polygon.geojson rename to src/boolean-disjoint/test/true/LineString/Polygon/LineString-Polygon.geojson diff --git a/packages/turf-boolean-disjoint/test/true/MultiPoint/LineString/MultiPoint-LineString.geojson b/src/boolean-disjoint/test/true/MultiPoint/LineString/MultiPoint-LineString.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/MultiPoint/LineString/MultiPoint-LineString.geojson rename to src/boolean-disjoint/test/true/MultiPoint/LineString/MultiPoint-LineString.geojson diff --git a/packages/turf-boolean-disjoint/test/true/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson b/src/boolean-disjoint/test/true/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson rename to src/boolean-disjoint/test/true/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson diff --git a/packages/turf-boolean-disjoint/test/true/MultiPoint/Point/MultiPoint-Point.geojson b/src/boolean-disjoint/test/true/MultiPoint/Point/MultiPoint-Point.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/MultiPoint/Point/MultiPoint-Point.geojson rename to src/boolean-disjoint/test/true/MultiPoint/Point/MultiPoint-Point.geojson diff --git a/packages/turf-boolean-disjoint/test/true/MultiPoint/Polygon/MultiPoint-Polygon.geojson b/src/boolean-disjoint/test/true/MultiPoint/Polygon/MultiPoint-Polygon.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/MultiPoint/Polygon/MultiPoint-Polygon.geojson rename to src/boolean-disjoint/test/true/MultiPoint/Polygon/MultiPoint-Polygon.geojson diff --git a/packages/turf-boolean-disjoint/test/true/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson b/src/boolean-disjoint/test/true/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson rename to src/boolean-disjoint/test/true/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson diff --git a/packages/turf-boolean-disjoint/test/true/Point/LineString/Point-LineString.geojson b/src/boolean-disjoint/test/true/Point/LineString/Point-LineString.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/Point/LineString/Point-LineString.geojson rename to src/boolean-disjoint/test/true/Point/LineString/Point-LineString.geojson diff --git a/packages/turf-boolean-disjoint/test/true/Point/MultiPoint/Point-Multipoint.geojson b/src/boolean-disjoint/test/true/Point/MultiPoint/Point-Multipoint.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/Point/MultiPoint/Point-Multipoint.geojson rename to src/boolean-disjoint/test/true/Point/MultiPoint/Point-Multipoint.geojson diff --git a/packages/turf-boolean-disjoint/test/true/Point/Point/Point-Point.geojson b/src/boolean-disjoint/test/true/Point/Point/Point-Point.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/Point/Point/Point-Point.geojson rename to src/boolean-disjoint/test/true/Point/Point/Point-Point.geojson diff --git a/packages/turf-boolean-disjoint/test/true/Point/Polygon/Point-Polygon.geojson b/src/boolean-disjoint/test/true/Point/Polygon/Point-Polygon.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/Point/Polygon/Point-Polygon.geojson rename to src/boolean-disjoint/test/true/Point/Polygon/Point-Polygon.geojson diff --git a/packages/turf-boolean-disjoint/test/true/Polygon/LineString/Polygon-LineString.geojson b/src/boolean-disjoint/test/true/Polygon/LineString/Polygon-LineString.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/Polygon/LineString/Polygon-LineString.geojson rename to src/boolean-disjoint/test/true/Polygon/LineString/Polygon-LineString.geojson diff --git a/packages/turf-boolean-disjoint/test/true/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson b/src/boolean-disjoint/test/true/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson rename to src/boolean-disjoint/test/true/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson diff --git a/packages/turf-boolean-disjoint/test/true/Polygon/Point/Polygon-Point.geojson b/src/boolean-disjoint/test/true/Polygon/Point/Polygon-Point.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/Polygon/Point/Polygon-Point.geojson rename to src/boolean-disjoint/test/true/Polygon/Point/Polygon-Point.geojson diff --git a/packages/turf-boolean-disjoint/test/true/Polygon/Polygon/Polygon-Polygon.geojson b/src/boolean-disjoint/test/true/Polygon/Polygon/Polygon-Polygon.geojson similarity index 100% rename from packages/turf-boolean-disjoint/test/true/Polygon/Polygon/Polygon-Polygon.geojson rename to src/boolean-disjoint/test/true/Polygon/Polygon/Polygon-Polygon.geojson diff --git a/packages/turf-boolean-equal/bench.js b/src/boolean-equal/bench.js similarity index 100% rename from packages/turf-boolean-equal/bench.js rename to src/boolean-equal/bench.js diff --git a/packages/turf-boolean-equal/diagrams/esri-equals.gif b/src/boolean-equal/diagrams/esri-equals.gif similarity index 100% rename from packages/turf-boolean-equal/diagrams/esri-equals.gif rename to src/boolean-equal/diagrams/esri-equals.gif diff --git a/src/boolean-equal/index.js b/src/boolean-equal/index.js new file mode 100644 index 0000000000..df2021d188 --- /dev/null +++ b/src/boolean-equal/index.js @@ -0,0 +1,122 @@ +import cleanCoords from '../clean-coords'; +import { getGeom } from '../invariant'; +import { lineString } from '../helpers'; + +/** + * Determine whether two geometries of the same type have identical X,Y coordinate values. + * See http://edndoc.esri.com/arcsde/9.0/general_topics/understand_spatial_relations.htm + * + * @name booleanEqual + * @param {Geometry|Feature} feature1 GeoJSON input + * @param {Geometry|Feature} feature2 GeoJSON input + * @returns {boolean} true if the objects are equal, false otherwise + * @example + * var pt1 = turf.point([0, 0]); + * var pt2 = turf.point([0, 0]); + * var pt3 = turf.point([1, 1]); + * + * turf.booleanEqual(pt1, pt2); + * //= true + * turf.booleanEqual(pt2, pt3); + * //= false + */ +function booleanEqual(feature1, feature2) { + const type1 = getGeom(feature1); + const type2 = getGeom(feature2); + if (type1.type !== type2.type) return false; + + if (type1.type === 'Point') return compareCoords(type1.coordinates, type2.coordinates); + if (type1.type === 'MultiPoint') return compareLine(type1.coordinates, type2.coordinates); + + + if (type1.type === 'LineString') return compareLine(type1.coordinates, type2.coordinates, type1.type); + + if (type1.type === 'Polygon') { + + // If we have a different number of holes & outside rings + if (type1.coordinates[0].length !== type2.coordinates[0].length) return false; + + for (let i = 0; i < type1.coordinates.length; i++) { + if (!compareLine(type1.coordinates[i], type2.coordinates[i], type1.type)) return false; + } + return true; + } + +} + +export default booleanEqual; + + +function compareCoords(pair1, pair2) { + if (pair1[0] !== pair2[0] || pair1[1] !== pair2[1]) return false; + return true; +} + +function compareLine(line1Coords, line2Coords, type) { + if (line1Coords.length !== line2Coords.length) { + line1Coords = cleanLine(line1Coords); + line2Coords = cleanLine(line2Coords); + if (line1Coords.length !== line2Coords.length) return false; + } + + if (type === 'LineString' && !compareCoords(line1Coords[0], line2Coords[0])) { + if (checkIfLineGoesOppositeWay(line1Coords, line2Coords)) { + return compareLineBackwards(line1Coords, line2Coords); + } + } else if (type === 'Polygon' && !compareCoords(line1Coords[1], line2Coords[1])) { + let doesMatchExist = findCoordIndexMatch(line1Coords[1], line2Coords); + if (doesMatchExist > -1) { + const doPolysGoSameWay = checkPolysGoSameWay(line1Coords, line2Coords, doesMatchExist); + if (!doPolysGoSameWay) { + line2Coords = line2Coords.reverse(); + doesMatchExist = findCoordIndexMatch(line1Coords[1], line2Coords); + } + line2Coords = rejigPolygon(line2Coords, doesMatchExist); + } + + } + + for (let i = 1; i < line1Coords.length; i++) { + if (!compareCoords(line1Coords[i], line2Coords[i])) return false; + } + return true; +} + +function findCoordIndexMatch(line1Coord, line2Coords) { + for (let i = 0; i < line2Coords.length; i++) { + if (compareCoords(line1Coord, line2Coords[i])) { + return i; + } + } + return -1; +} + +function rejigPolygon(coords, index) { + const oldCoords = coords.splice(0, index - 1); + coords.pop(); + coords = coords.concat(oldCoords); + coords.push(coords[0]); + return coords; +} + +function cleanLine(line) { + return cleanCoords(lineString(line)).geometry.coordinates; +} + +function checkIfLineGoesOppositeWay(line1Coords, line2Coords) { + return compareCoords(line1Coords[0], line2Coords[line2Coords.length - 1]); +} + +function checkPolysGoSameWay(line1Coords, line2Coords, matchIndex) { + return compareCoords(line1Coords[2], line2Coords[matchIndex + 1]); +} + +function compareLineBackwards(line1Coords, line2Coords) { + line2Coords = line2Coords.reverse(); + for (let i = 0; i < line1Coords.length; i++) { + if (!compareCoords(line1Coords[i], line2Coords[i])) { + return false; + } + } + return true; +} diff --git a/src/boolean-equal/test.js b/src/boolean-equal/test.js new file mode 100644 index 0000000000..8ab1906e13 --- /dev/null +++ b/src/boolean-equal/test.js @@ -0,0 +1,55 @@ +const glob = require('glob'); +const path = require('path'); +const test = require('tape'); +const load = require('load-json-file'); +const shapely = require('boolean-shapely'); +const { point, lineString, polygon } = require('../helpers'); +const equal = require('./').default; + +test('turf-boolean-equal', t => { + // True Fixtures + glob.sync(path.join(__dirname, 'test', 'true', '**', '*.geojson')).forEach(filepath => { + const name = path.parse(filepath).name; + const geojson = load.sync(filepath); + const feature1 = geojson.features[0]; + const feature2 = geojson.features[1]; + const result = equal(feature1, feature2); + + if (process.env.SHAPELY) shapely.equals(feature1, feature2).then(result => t.true(result, '[true] shapely - ' + name)); + t.true(result, '[true] ' + name); + }); + // False Fixtures + glob.sync(path.join(__dirname, 'test', 'false', '**', '*.geojson')).forEach(filepath => { + const name = path.parse(filepath).name; + const geojson = load.sync(filepath); + const feature1 = geojson.features[0]; + const feature2 = geojson.features[1]; + const result = equal(feature1, feature2); + + if (process.env.SHAPELY) shapely.equals(feature1, feature2).then(result => t.false(result, '[false] shapely - ' + name)); + t.false(result, '[false] ' + name); + }); + t.end(); +}); + +const pt = point([9, 50]); +const line1 = lineString([[7, 50], [8, 50], [9, 50]]); +const line2 = lineString([[7, 50], [8, 50], [9, 50]]); +const poly1 = polygon([[[8.5, 50], [9.5, 50], [9.5, 49], [8.5, 49], [8.5, 50]]]); +const poly2 = polygon([[[8.5, 50], [9.5, 50], [9.5, 49], [8.5, 49], [8.5, 50]]]); +const poly3 = polygon([[[10, 50], [10.5, 50], [10.5, 49], [10, 49], [10, 50]]]); + +test('turf-boolean-equal -- geometries', t => { + t.true(equal(line1.geometry, line2.geometry), '[true] LineString geometry'); + t.true(equal(poly1.geometry, poly2.geometry), '[true] Polygon geometry'); + t.false(equal(poly1.geometry, poly3.geometry), '[false] Polygon geometry'); + t.false(equal(pt, line1), '[false] different types'); + t.end(); +}); + + +test('turf-boolean-equal -- throws', t => { + // t.throws(() => equal(null, line1), /feature1 is required/, 'missing feature1'); + // t.throws(() => equal(line1, null), /feature2 is required/, 'missing feature2'); + t.end(); +}); diff --git a/packages/turf-boolean-equal/test/false/linear-rings.geojson b/src/boolean-equal/test/false/linear-rings.geojson similarity index 100% rename from packages/turf-boolean-equal/test/false/linear-rings.geojson rename to src/boolean-equal/test/false/linear-rings.geojson diff --git a/packages/turf-boolean-equal/test/false/lines.geojson b/src/boolean-equal/test/false/lines.geojson similarity index 100% rename from packages/turf-boolean-equal/test/false/lines.geojson rename to src/boolean-equal/test/false/lines.geojson diff --git a/packages/turf-boolean-equal/test/false/multipoints.geojson b/src/boolean-equal/test/false/multipoints.geojson similarity index 100% rename from packages/turf-boolean-equal/test/false/multipoints.geojson rename to src/boolean-equal/test/false/multipoints.geojson diff --git a/packages/turf-boolean-equal/test/false/points.geojson b/src/boolean-equal/test/false/points.geojson similarity index 100% rename from packages/turf-boolean-equal/test/false/points.geojson rename to src/boolean-equal/test/false/points.geojson diff --git a/packages/turf-boolean-equal/test/false/polygons.geojson b/src/boolean-equal/test/false/polygons.geojson similarity index 100% rename from packages/turf-boolean-equal/test/false/polygons.geojson rename to src/boolean-equal/test/false/polygons.geojson diff --git a/packages/turf-boolean-equal/test/true/different-initials-poly.geojson b/src/boolean-equal/test/true/different-initials-poly.geojson similarity index 100% rename from packages/turf-boolean-equal/test/true/different-initials-poly.geojson rename to src/boolean-equal/test/true/different-initials-poly.geojson diff --git a/packages/turf-boolean-equal/test/true/linear-rings.geojson b/src/boolean-equal/test/true/linear-rings.geojson similarity index 100% rename from packages/turf-boolean-equal/test/true/linear-rings.geojson rename to src/boolean-equal/test/true/linear-rings.geojson diff --git a/packages/turf-boolean-equal/test/true/lines-extra-vertices.geojson b/src/boolean-equal/test/true/lines-extra-vertices.geojson similarity index 100% rename from packages/turf-boolean-equal/test/true/lines-extra-vertices.geojson rename to src/boolean-equal/test/true/lines-extra-vertices.geojson diff --git a/packages/turf-boolean-equal/test/true/lines-reverse.geojson b/src/boolean-equal/test/true/lines-reverse.geojson similarity index 100% rename from packages/turf-boolean-equal/test/true/lines-reverse.geojson rename to src/boolean-equal/test/true/lines-reverse.geojson diff --git a/packages/turf-boolean-equal/test/true/lines.geojson b/src/boolean-equal/test/true/lines.geojson similarity index 100% rename from packages/turf-boolean-equal/test/true/lines.geojson rename to src/boolean-equal/test/true/lines.geojson diff --git a/packages/turf-boolean-equal/test/true/multipoints.geojson b/src/boolean-equal/test/true/multipoints.geojson similarity index 100% rename from packages/turf-boolean-equal/test/true/multipoints.geojson rename to src/boolean-equal/test/true/multipoints.geojson diff --git a/packages/turf-boolean-equal/test/true/points.geojson b/src/boolean-equal/test/true/points.geojson similarity index 100% rename from packages/turf-boolean-equal/test/true/points.geojson rename to src/boolean-equal/test/true/points.geojson diff --git a/packages/turf-boolean-equal/test/true/polygons.geojson b/src/boolean-equal/test/true/polygons.geojson similarity index 100% rename from packages/turf-boolean-equal/test/true/polygons.geojson rename to src/boolean-equal/test/true/polygons.geojson diff --git a/packages/turf-boolean-equal/test/true/reverse-lines.geojson b/src/boolean-equal/test/true/reverse-lines.geojson similarity index 100% rename from packages/turf-boolean-equal/test/true/reverse-lines.geojson rename to src/boolean-equal/test/true/reverse-lines.geojson diff --git a/packages/turf-boolean-equal/test/true/reverse-polygons.geojson b/src/boolean-equal/test/true/reverse-polygons.geojson similarity index 100% rename from packages/turf-boolean-equal/test/true/reverse-polygons.geojson rename to src/boolean-equal/test/true/reverse-polygons.geojson diff --git a/packages/turf-boolean-intersects/bench.js b/src/boolean-intersects/bench.js similarity index 100% rename from packages/turf-boolean-intersects/bench.js rename to src/boolean-intersects/bench.js diff --git a/packages/turf-boolean-intersects/index.d.ts b/src/boolean-intersects/index.d.ts similarity index 100% rename from packages/turf-boolean-intersects/index.d.ts rename to src/boolean-intersects/index.d.ts diff --git a/src/boolean-intersects/index.js b/src/boolean-intersects/index.js new file mode 100644 index 0000000000..a223e5043e --- /dev/null +++ b/src/boolean-intersects/index.js @@ -0,0 +1,27 @@ +import booleanDisjoint from '../boolean-disjoint'; +import { flattenEach } from '../meta'; + +/** + * Boolean-intersects returns (TRUE) two geometries spatially intersect, by that we mean that one does not completely contain another. + * + * @name booleanIntersects + * @param {Geometry|Feature} feature1 GeoJSON Feature or Geometry + * @param {Geometry|Feature} feature2 GeoJSON Feature or Geometry + * @returns {boolean} true/false + * @example + * var point = turf.point([2, 2]); + * var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); + * + * turf.booleanIntersects(line, point); + * //=true + */ +export default function booleanIntersects(feature1, feature2) { + let bool = false; + flattenEach(feature1, (flatten1) => { + flattenEach(feature2, (flatten2) => { + if (bool === true) { return true; } + bool = !booleanDisjoint(flatten1.geometry, flatten2.geometry); + }); + }); + return bool; +} diff --git a/packages/turf-boolean-intersects/test.js b/src/boolean-intersects/test.js similarity index 100% rename from packages/turf-boolean-intersects/test.js rename to src/boolean-intersects/test.js diff --git a/packages/turf-boolean-intersects/test/false/LineString/LineString/LineString-LineString.geojson b/src/boolean-intersects/test/false/LineString/LineString/LineString-LineString.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/LineString/LineString/LineString-LineString.geojson rename to src/boolean-intersects/test/false/LineString/LineString/LineString-LineString.geojson diff --git a/packages/turf-boolean-intersects/test/false/LineString/Point/LineString-Point.geojson b/src/boolean-intersects/test/false/LineString/Point/LineString-Point.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/LineString/Point/LineString-Point.geojson rename to src/boolean-intersects/test/false/LineString/Point/LineString-Point.geojson diff --git a/packages/turf-boolean-intersects/test/false/LineString/Polygon/LineString-Polygon.geojson b/src/boolean-intersects/test/false/LineString/Polygon/LineString-Polygon.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/LineString/Polygon/LineString-Polygon.geojson rename to src/boolean-intersects/test/false/LineString/Polygon/LineString-Polygon.geojson diff --git a/packages/turf-boolean-intersects/test/false/MultiPoint/LineString/MultiPoint-LineString.geojson b/src/boolean-intersects/test/false/MultiPoint/LineString/MultiPoint-LineString.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/MultiPoint/LineString/MultiPoint-LineString.geojson rename to src/boolean-intersects/test/false/MultiPoint/LineString/MultiPoint-LineString.geojson diff --git a/packages/turf-boolean-intersects/test/false/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson b/src/boolean-intersects/test/false/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson rename to src/boolean-intersects/test/false/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson diff --git a/packages/turf-boolean-intersects/test/false/MultiPoint/Point/MultiPoint-Point.geojson b/src/boolean-intersects/test/false/MultiPoint/Point/MultiPoint-Point.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/MultiPoint/Point/MultiPoint-Point.geojson rename to src/boolean-intersects/test/false/MultiPoint/Point/MultiPoint-Point.geojson diff --git a/packages/turf-boolean-intersects/test/false/MultiPoint/Polygon/MultiPoint-Polygon.geojson b/src/boolean-intersects/test/false/MultiPoint/Polygon/MultiPoint-Polygon.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/MultiPoint/Polygon/MultiPoint-Polygon.geojson rename to src/boolean-intersects/test/false/MultiPoint/Polygon/MultiPoint-Polygon.geojson diff --git a/packages/turf-boolean-intersects/test/false/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson b/src/boolean-intersects/test/false/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson rename to src/boolean-intersects/test/false/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson diff --git a/packages/turf-boolean-intersects/test/false/Point/LineString/Point-LineString.geojson b/src/boolean-intersects/test/false/Point/LineString/Point-LineString.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/Point/LineString/Point-LineString.geojson rename to src/boolean-intersects/test/false/Point/LineString/Point-LineString.geojson diff --git a/packages/turf-boolean-intersects/test/false/Point/MultiPoint/Point-Multipoint.geojson b/src/boolean-intersects/test/false/Point/MultiPoint/Point-Multipoint.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/Point/MultiPoint/Point-Multipoint.geojson rename to src/boolean-intersects/test/false/Point/MultiPoint/Point-Multipoint.geojson diff --git a/packages/turf-boolean-intersects/test/false/Point/Point/Point-Point.geojson b/src/boolean-intersects/test/false/Point/Point/Point-Point.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/Point/Point/Point-Point.geojson rename to src/boolean-intersects/test/false/Point/Point/Point-Point.geojson diff --git a/packages/turf-boolean-intersects/test/false/Point/Polygon/Point-Polygon.geojson b/src/boolean-intersects/test/false/Point/Polygon/Point-Polygon.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/Point/Polygon/Point-Polygon.geojson rename to src/boolean-intersects/test/false/Point/Polygon/Point-Polygon.geojson diff --git a/packages/turf-boolean-intersects/test/false/Polygon/LineString/Polygon-LineString.geojson b/src/boolean-intersects/test/false/Polygon/LineString/Polygon-LineString.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/Polygon/LineString/Polygon-LineString.geojson rename to src/boolean-intersects/test/false/Polygon/LineString/Polygon-LineString.geojson diff --git a/packages/turf-boolean-intersects/test/false/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson b/src/boolean-intersects/test/false/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson rename to src/boolean-intersects/test/false/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson diff --git a/packages/turf-boolean-intersects/test/false/Polygon/Point/Polygon-Point.geojson b/src/boolean-intersects/test/false/Polygon/Point/Polygon-Point.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/Polygon/Point/Polygon-Point.geojson rename to src/boolean-intersects/test/false/Polygon/Point/Polygon-Point.geojson diff --git a/packages/turf-boolean-intersects/test/false/Polygon/Polygon/Polygon-Polygon.geojson b/src/boolean-intersects/test/false/Polygon/Polygon/Polygon-Polygon.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/false/Polygon/Polygon/Polygon-Polygon.geojson rename to src/boolean-intersects/test/false/Polygon/Polygon/Polygon-Polygon.geojson diff --git a/packages/turf-boolean-intersects/test/true/LineString/LineString/LineString-LineString.geojson b/src/boolean-intersects/test/true/LineString/LineString/LineString-LineString.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/LineString/LineString/LineString-LineString.geojson rename to src/boolean-intersects/test/true/LineString/LineString/LineString-LineString.geojson diff --git a/packages/turf-boolean-intersects/test/true/LineString/Point/LineString-Point-1.geojson b/src/boolean-intersects/test/true/LineString/Point/LineString-Point-1.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/LineString/Point/LineString-Point-1.geojson rename to src/boolean-intersects/test/true/LineString/Point/LineString-Point-1.geojson diff --git a/packages/turf-boolean-intersects/test/true/LineString/Point/LineString-Point-2.geojson b/src/boolean-intersects/test/true/LineString/Point/LineString-Point-2.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/LineString/Point/LineString-Point-2.geojson rename to src/boolean-intersects/test/true/LineString/Point/LineString-Point-2.geojson diff --git a/packages/turf-boolean-intersects/test/true/LineString/Polygon/LineString-In-Polygon.geojson b/src/boolean-intersects/test/true/LineString/Polygon/LineString-In-Polygon.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/LineString/Polygon/LineString-In-Polygon.geojson rename to src/boolean-intersects/test/true/LineString/Polygon/LineString-In-Polygon.geojson diff --git a/packages/turf-boolean-intersects/test/true/LineString/Polygon/LineString-Polygon.geojson b/src/boolean-intersects/test/true/LineString/Polygon/LineString-Polygon.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/LineString/Polygon/LineString-Polygon.geojson rename to src/boolean-intersects/test/true/LineString/Polygon/LineString-Polygon.geojson diff --git a/packages/turf-boolean-intersects/test/true/MultiPoint/LineString/MultiPoint-LineString.geojson b/src/boolean-intersects/test/true/MultiPoint/LineString/MultiPoint-LineString.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/MultiPoint/LineString/MultiPoint-LineString.geojson rename to src/boolean-intersects/test/true/MultiPoint/LineString/MultiPoint-LineString.geojson diff --git a/packages/turf-boolean-intersects/test/true/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson b/src/boolean-intersects/test/true/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson rename to src/boolean-intersects/test/true/MultiPoint/MultiPoint/MultiPoint-MultiPoint.geojson diff --git a/packages/turf-boolean-intersects/test/true/MultiPoint/Polygon/MultiPoint-Polygon.geojson b/src/boolean-intersects/test/true/MultiPoint/Polygon/MultiPoint-Polygon.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/MultiPoint/Polygon/MultiPoint-Polygon.geojson rename to src/boolean-intersects/test/true/MultiPoint/Polygon/MultiPoint-Polygon.geojson diff --git a/packages/turf-boolean-intersects/test/true/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson b/src/boolean-intersects/test/true/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson rename to src/boolean-intersects/test/true/MultiPolygon/Polygon/MultiPolygon-Polygon.geojson diff --git a/packages/turf-boolean-intersects/test/true/Point/LineString/Point-LineString-1.geojson b/src/boolean-intersects/test/true/Point/LineString/Point-LineString-1.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Point/LineString/Point-LineString-1.geojson rename to src/boolean-intersects/test/true/Point/LineString/Point-LineString-1.geojson diff --git a/packages/turf-boolean-intersects/test/true/Point/LineString/Point-LineString-2.geojson b/src/boolean-intersects/test/true/Point/LineString/Point-LineString-2.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Point/LineString/Point-LineString-2.geojson rename to src/boolean-intersects/test/true/Point/LineString/Point-LineString-2.geojson diff --git a/packages/turf-boolean-intersects/test/true/Point/LineString/Point-LineString-3.geojson b/src/boolean-intersects/test/true/Point/LineString/Point-LineString-3.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Point/LineString/Point-LineString-3.geojson rename to src/boolean-intersects/test/true/Point/LineString/Point-LineString-3.geojson diff --git a/packages/turf-boolean-intersects/test/true/Point/LineString/Point-LineString-4.geojson b/src/boolean-intersects/test/true/Point/LineString/Point-LineString-4.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Point/LineString/Point-LineString-4.geojson rename to src/boolean-intersects/test/true/Point/LineString/Point-LineString-4.geojson diff --git a/packages/turf-boolean-intersects/test/true/Point/MultiPoint/Point-MultiPoint.geojson b/src/boolean-intersects/test/true/Point/MultiPoint/Point-MultiPoint.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Point/MultiPoint/Point-MultiPoint.geojson rename to src/boolean-intersects/test/true/Point/MultiPoint/Point-MultiPoint.geojson diff --git a/packages/turf-boolean-intersects/test/true/Point/Point/Point-Point.geojson b/src/boolean-intersects/test/true/Point/Point/Point-Point.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Point/Point/Point-Point.geojson rename to src/boolean-intersects/test/true/Point/Point/Point-Point.geojson diff --git a/packages/turf-boolean-intersects/test/true/Point/Polygon/Point-Polygon-1.geojson b/src/boolean-intersects/test/true/Point/Polygon/Point-Polygon-1.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Point/Polygon/Point-Polygon-1.geojson rename to src/boolean-intersects/test/true/Point/Polygon/Point-Polygon-1.geojson diff --git a/packages/turf-boolean-intersects/test/true/Point/Polygon/Point-Polygon-2.geojson b/src/boolean-intersects/test/true/Point/Polygon/Point-Polygon-2.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Point/Polygon/Point-Polygon-2.geojson rename to src/boolean-intersects/test/true/Point/Polygon/Point-Polygon-2.geojson diff --git a/packages/turf-boolean-intersects/test/true/Polygon/LineString/Polygon-Containing-Linestring.geojson b/src/boolean-intersects/test/true/Polygon/LineString/Polygon-Containing-Linestring.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Polygon/LineString/Polygon-Containing-Linestring.geojson rename to src/boolean-intersects/test/true/Polygon/LineString/Polygon-Containing-Linestring.geojson diff --git a/packages/turf-boolean-intersects/test/true/Polygon/LineString/Polygon-LineString.geojson b/src/boolean-intersects/test/true/Polygon/LineString/Polygon-LineString.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Polygon/LineString/Polygon-LineString.geojson rename to src/boolean-intersects/test/true/Polygon/LineString/Polygon-LineString.geojson diff --git a/packages/turf-boolean-intersects/test/true/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson b/src/boolean-intersects/test/true/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson rename to src/boolean-intersects/test/true/Polygon/MultiPolygon/Polygon-MultiPolygon.geojson diff --git a/packages/turf-boolean-intersects/test/true/Polygon/Point/Polygon-Point.geojson b/src/boolean-intersects/test/true/Polygon/Point/Polygon-Point.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Polygon/Point/Polygon-Point.geojson rename to src/boolean-intersects/test/true/Polygon/Point/Polygon-Point.geojson diff --git a/packages/turf-boolean-intersects/test/true/Polygon/Polygon/Large-Inside-Small.geojson b/src/boolean-intersects/test/true/Polygon/Polygon/Large-Inside-Small.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Polygon/Polygon/Large-Inside-Small.geojson rename to src/boolean-intersects/test/true/Polygon/Polygon/Large-Inside-Small.geojson diff --git a/packages/turf-boolean-intersects/test/true/Polygon/Polygon/Polygon-Polygon.geojson b/src/boolean-intersects/test/true/Polygon/Polygon/Polygon-Polygon.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Polygon/Polygon/Polygon-Polygon.geojson rename to src/boolean-intersects/test/true/Polygon/Polygon/Polygon-Polygon.geojson diff --git a/packages/turf-boolean-intersects/test/true/Polygon/Polygon/Small-Inside-Large.geojson b/src/boolean-intersects/test/true/Polygon/Polygon/Small-Inside-Large.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Polygon/Polygon/Small-Inside-Large.geojson rename to src/boolean-intersects/test/true/Polygon/Polygon/Small-Inside-Large.geojson diff --git a/packages/turf-boolean-intersects/test/true/Polygon/Polygon/issue-1216.geojson b/src/boolean-intersects/test/true/Polygon/Polygon/issue-1216.geojson similarity index 100% rename from packages/turf-boolean-intersects/test/true/Polygon/Polygon/issue-1216.geojson rename to src/boolean-intersects/test/true/Polygon/Polygon/issue-1216.geojson diff --git a/packages/turf-boolean-overlap/bench.js b/src/boolean-overlap/bench.js old mode 100755 new mode 100644 similarity index 100% rename from packages/turf-boolean-overlap/bench.js rename to src/boolean-overlap/bench.js diff --git a/packages/turf-boolean-overlap/diagrams/esri-overlaps.gif b/src/boolean-overlap/diagrams/esri-overlaps.gif similarity index 100% rename from packages/turf-boolean-overlap/diagrams/esri-overlaps.gif rename to src/boolean-overlap/diagrams/esri-overlaps.gif diff --git a/src/boolean-overlap/index.js b/src/boolean-overlap/index.js new file mode 100644 index 0000000000..5f8b87ebe8 --- /dev/null +++ b/src/boolean-overlap/index.js @@ -0,0 +1,71 @@ +import { coordAll, segmentEach } from '../meta'; +import { getGeom } from '../invariant'; +import lineOverlap from '../line-overlap'; +import lineIntersect from '../line-intersect'; +import booleanEqual from '../boolean-equal'; + + +/** + * Compares two geometries of the same dimension and returns true if their intersection set results in a geometry + * different from both but of the same dimension. It applies to Polygon/Polygon, LineString/LineString, + * Multipoint/Multipoint, MultiLineString/MultiLineString and MultiPolygon/MultiPolygon. + * + * @name booleanOverlap + * @param {Geometry|Feature} feature1 input + * @param {Geometry|Feature} feature2 input + * @returns {boolean} true/false + * @example + * var poly1 = turf.polygon([[[0,0],[0,5],[5,5],[5,0],[0,0]]]); + * var poly2 = turf.polygon([[[1,1],[1,6],[6,6],[6,1],[1,1]]]); + * var poly3 = turf.polygon([[[10,10],[10,15],[15,15],[15,10],[10,10]]]); + * + * turf.booleanOverlap(poly1, poly2) + * //=true + * turf.booleanOverlap(poly2, poly3) + * //=false + */ +export default function booleanOverlap(feature1, feature2) { + const geom1 = getGeom(feature1); + const geom2 = getGeom(feature2); + const type1 = geom1.type; + const type2 = geom2.type; + + if (type1 === 'Point') throw new Error('Point geometry not supported'); + + // features must be not equal + if (booleanEqual(feature1, feature2)) return false; + + let overlap = 0; + + switch (type1) { + case 'MultiPoint': //eslint-disable-line + const coords1 = coordAll(feature1); + const coords2 = coordAll(feature2); + coords1.forEach((coord1) => { + coords2.forEach((coord2) => { + if (coord1[0] === coord2[0] && coord1[1] === coord2[1]) overlap++; + }); + }); + break; + + case 'LineString': + case 'MultiLineString': + segmentEach(feature1, (segment1) => { + segmentEach(feature2, (segment2) => { + if (lineOverlap(segment1, segment2).features.length) overlap++; + }); + }); + break; + + case 'Polygon': + case 'MultiPolygon': + segmentEach(feature1, (segment1) => { + segmentEach(feature2, (segment2) => { + if (lineIntersect(segment1, segment2).features.length) overlap++; + }); + }); + break; + } + + return overlap > 0; +} diff --git a/src/boolean-overlap/test.js b/src/boolean-overlap/test.js new file mode 100644 index 0000000000..1cb4b6fe69 --- /dev/null +++ b/src/boolean-overlap/test.js @@ -0,0 +1,56 @@ +const glob = require('glob'); +const path = require('path'); +const test = require('tape'); +const load = require('load-json-file'); +const shapely = require('boolean-shapely'); +const { point, lineString, polygon } = require('../helpers'); +const overlap = require('./').default; + +test('turf-boolean-overlap', t => { + // True Fixtures + glob.sync(path.join(__dirname, 'test', 'true', '**', '*.geojson')).forEach(filepath => { + const name = path.parse(filepath).name; + const geojson = load.sync(filepath); + const feature1 = geojson.features[0]; + const feature2 = geojson.features[1]; + const result = overlap(feature1, feature2); + + if (process.env.SHAPELY) shapely.contains(feature1, feature2).then(result => t.true(result, '[true] shapely - ' + name)); + t.true(result, '[true] ' + name); + }); + // False Fixtures + glob.sync(path.join(__dirname, 'test', 'false', '**', '*.geojson')).forEach(filepath => { + const name = path.parse(filepath).name; + const geojson = load.sync(filepath); + const feature1 = geojson.features[0]; + const feature2 = geojson.features[1]; + const result = overlap(feature1, feature2); + + if (process.env.SHAPELY) shapely.contains(feature1, feature2).then(result => t.false(result, '[false] shapely - ' + name)); + t.false(result, '[false] ' + name); + }); + t.end(); +}); + +const pt = point([9, 50]); +const line1 = lineString([[7, 50], [8, 50], [9, 50]]); +const line2 = lineString([[8, 50], [9, 50], [10, 50]]); +const poly1 = polygon([[[8.5, 50], [9.5, 50], [9.5, 49], [8.5, 49], [8.5, 50]]]); +const poly2 = polygon([[[8, 50], [9, 50], [9, 49], [8, 49], [8, 50]]]); +const poly3 = polygon([[[10, 50], [10.5, 50], [10.5, 49], [10, 49], [10, 50]]]); + +test('turf-boolean-overlap -- geometries', t => { + t.true(overlap(line1.geometry, line2.geometry), '[true] LineString geometry'); + t.true(overlap(poly1.geometry, poly2.geometry), '[true] Polygon geometry'); + t.false(overlap(poly1.geometry, poly3.geometry), '[false] Polygon geometry'); + t.end(); +}); + +test('turf-boolean-overlap -- throws', t => { + // t.throws(() => overlap(null, line1), /feature1 is required/, 'missing feature1'); + // t.throws(() => overlap(line1, null), /feature2 is required/, 'missing feature2'); + // t.throws(() => overlap(pt, line1), /features must be of the same type/, 'different types'); + t.throws(() => overlap(pt, pt), /Point geometry not supported/, 'geometry not supported'); + + t.end(); +}); diff --git a/packages/turf-boolean-overlap/test/false/equal-linear-rings.geojson b/src/boolean-overlap/test/false/equal-linear-rings.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/false/equal-linear-rings.geojson rename to src/boolean-overlap/test/false/equal-linear-rings.geojson diff --git a/packages/turf-boolean-overlap/test/false/equal-lines.geojson b/src/boolean-overlap/test/false/equal-lines.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/false/equal-lines.geojson rename to src/boolean-overlap/test/false/equal-lines.geojson diff --git a/packages/turf-boolean-overlap/test/false/equal-multipoints.geojson b/src/boolean-overlap/test/false/equal-multipoints.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/false/equal-multipoints.geojson rename to src/boolean-overlap/test/false/equal-multipoints.geojson diff --git a/packages/turf-boolean-overlap/test/false/equal-polygons.geojson b/src/boolean-overlap/test/false/equal-polygons.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/false/equal-polygons.geojson rename to src/boolean-overlap/test/false/equal-polygons.geojson diff --git a/packages/turf-boolean-overlap/test/false/linear-rings.geojson b/src/boolean-overlap/test/false/linear-rings.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/false/linear-rings.geojson rename to src/boolean-overlap/test/false/linear-rings.geojson diff --git a/packages/turf-boolean-overlap/test/false/lines.geojson b/src/boolean-overlap/test/false/lines.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/false/lines.geojson rename to src/boolean-overlap/test/false/lines.geojson diff --git a/packages/turf-boolean-overlap/test/false/multipoints.geojson b/src/boolean-overlap/test/false/multipoints.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/false/multipoints.geojson rename to src/boolean-overlap/test/false/multipoints.geojson diff --git a/packages/turf-boolean-overlap/test/false/polygon-with-hole-polygon.geojson b/src/boolean-overlap/test/false/polygon-with-hole-polygon.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/false/polygon-with-hole-polygon.geojson rename to src/boolean-overlap/test/false/polygon-with-hole-polygon.geojson diff --git a/packages/turf-boolean-overlap/test/false/polygons.geojson b/src/boolean-overlap/test/false/polygons.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/false/polygons.geojson rename to src/boolean-overlap/test/false/polygons.geojson diff --git a/packages/turf-boolean-overlap/test/true/linear-rings.geojson b/src/boolean-overlap/test/true/linear-rings.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/true/linear-rings.geojson rename to src/boolean-overlap/test/true/linear-rings.geojson diff --git a/packages/turf-boolean-overlap/test/true/lines.geojson b/src/boolean-overlap/test/true/lines.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/true/lines.geojson rename to src/boolean-overlap/test/true/lines.geojson diff --git a/packages/turf-boolean-overlap/test/true/multipoints.geojson b/src/boolean-overlap/test/true/multipoints.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/true/multipoints.geojson rename to src/boolean-overlap/test/true/multipoints.geojson diff --git a/packages/turf-boolean-overlap/test/true/polygon-with-hole-polygon.geojson b/src/boolean-overlap/test/true/polygon-with-hole-polygon.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/true/polygon-with-hole-polygon.geojson rename to src/boolean-overlap/test/true/polygon-with-hole-polygon.geojson diff --git a/packages/turf-boolean-overlap/test/true/polygons.geojson b/src/boolean-overlap/test/true/polygons.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/true/polygons.geojson rename to src/boolean-overlap/test/true/polygons.geojson diff --git a/packages/turf-boolean-overlap/test/true/simple-lines.geojson b/src/boolean-overlap/test/true/simple-lines.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/true/simple-lines.geojson rename to src/boolean-overlap/test/true/simple-lines.geojson diff --git a/packages/turf-boolean-overlap/test/true/single-multipoints.geojson b/src/boolean-overlap/test/true/single-multipoints.geojson similarity index 100% rename from packages/turf-boolean-overlap/test/true/single-multipoints.geojson rename to src/boolean-overlap/test/true/single-multipoints.geojson diff --git a/packages/turf-boolean-parallel/bench.js b/src/boolean-parallel/bench.js similarity index 100% rename from packages/turf-boolean-parallel/bench.js rename to src/boolean-parallel/bench.js diff --git a/src/boolean-parallel/index.js b/src/boolean-parallel/index.js new file mode 100644 index 0000000000..8af1dd9fab --- /dev/null +++ b/src/boolean-parallel/index.js @@ -0,0 +1,71 @@ +import cleanCoords from '../clean-coords'; +import lineSegment from '../line-segment'; +import rhumbBearing from '../rhumb-bearing'; +import { bearingToAzimuth } from '../helpers'; + +/** + * Boolean-Parallel returns True if each segment of `line1` is parallel to the correspondent segment of `line2` + * + * @name booleanParallel + * @param {Geometry|Feature} line1 GeoJSON Feature or Geometry + * @param {Geometry|Feature} line2 GeoJSON Feature or Geometry + * @returns {boolean} true/false if the lines are parallel + * @example + * var line1 = turf.lineString([[0, 0], [0, 1]]); + * var line2 = turf.lineString([[1, 0], [1, 1]]); + * + * turf.booleanParallel(line1, line2); + * //=true + */ +function booleanParallel(line1, line2) { + // validation + if (!line1) throw new Error('line1 is required'); + if (!line2) throw new Error('line2 is required'); + const type1 = getType(line1, 'line1'); + if (type1 !== 'LineString') throw new Error('line1 must be a LineString'); + const type2 = getType(line2, 'line2'); + if (type2 !== 'LineString') throw new Error('line2 must be a LineString'); + + const segments1 = lineSegment(cleanCoords(line1)).features; + const segments2 = lineSegment(cleanCoords(line2)).features; + + for (let i = 0; i < segments1.length; i++) { + const segment1 = segments1[i].geometry.coordinates; + if (!segments2[i]) break; + const segment2 = segments2[i].geometry.coordinates; + if (!isParallel(segment1, segment2)) return false; + } + return true; +} + + +/** + * Compares slopes and return result + * + * @private + * @param {Geometry|Feature} segment1 Geometry or Feature + * @param {Geometry|Feature} segment2 Geometry or Feature + * @returns {boolean} if slopes are equal + */ +function isParallel(segment1, segment2) { + const slope1 = bearingToAzimuth(rhumbBearing(segment1[0], segment1[1])); + const slope2 = bearingToAzimuth(rhumbBearing(segment2[0], segment2[1])); + return slope1 === slope2; +} + + +/** + * Returns Feature's type + * + * @private + * @param {Geometry|Feature} geojson Geometry or Feature + * @param {string} name of the variable + * @returns {string} Feature's type + */ +function getType(geojson, name) { + if (geojson.geometry && geojson.geometry.type) return geojson.geometry.type; + if (geojson.type) return geojson.type; // if GeoJSON geometry + throw new Error(`Invalid GeoJSON object for ${name}`); +} + +export default booleanParallel; diff --git a/src/boolean-parallel/test.js b/src/boolean-parallel/test.js new file mode 100644 index 0000000000..3e159acd94 --- /dev/null +++ b/src/boolean-parallel/test.js @@ -0,0 +1,45 @@ +const glob = require('glob'); +const path = require('path'); +const test = require('tape'); +const load = require('load-json-file'); +const { lineString, polygon } = require('../helpers'); +const booleanParallel = require('.').default; + +test('turf-boolean-parallel', t => { + // True Fixtures + glob.sync(path.join(__dirname, 'test', 'true', '**', '*.geojson')).forEach(filepath => { + const name = path.parse(filepath).name; + const geojson = load.sync(filepath); + const line1 = geojson.features[0]; + const line2 = geojson.features[1]; + const result = booleanParallel(line1, line2); + + t.true(result, '[true] ' + name); + }); + // False Fixtures + glob.sync(path.join(__dirname, 'test', 'false', '**', '*.geojson')).forEach(filepath => { + const name = path.parse(filepath).name; + const geojson = load.sync(filepath); + const line1 = geojson.features[0]; + const line2 = geojson.features[1]; + const result = booleanParallel(line1, line2); + + t.false(result, '[false] ' + name); + }); + t.end(); +}); + + +test('turf-boolean-parallel -- throws', t => { + const line = lineString([[0, 0], [0, 1]]); + const poly = polygon([[[0, 0], [0, 1], [1, 1], [0, 0]]]); + + // t.throws(() => booleanParallel(null, line), /line1 is required/, 'missing line1'); + // t.throws(() => booleanParallel(line, null), /line2 is required/, 'missing line2'); + // t.throws(() => booleanParallel(poly, line), /line1 must be a LineString/, 'different types'); + // t.throws(() => booleanParallel(line, poly), /line2 must be a LineString/, 'different types'); + t.throws(() => booleanParallel({}, line), /Invalid GeoJSON object for line1/, 'invalid types'); + t.throws(() => booleanParallel(line, {}), /Invalid GeoJSON object for line2/, 'invalid types'); + + t.end(); +}); diff --git a/packages/turf-boolean-parallel/test/false/line1.geojson b/src/boolean-parallel/test/false/line1.geojson similarity index 100% rename from packages/turf-boolean-parallel/test/false/line1.geojson rename to src/boolean-parallel/test/false/line1.geojson diff --git a/packages/turf-boolean-parallel/test/false/line2.geojson b/src/boolean-parallel/test/false/line2.geojson similarity index 100% rename from packages/turf-boolean-parallel/test/false/line2.geojson rename to src/boolean-parallel/test/false/line2.geojson diff --git a/packages/turf-boolean-parallel/test/true/city-line.geojson b/src/boolean-parallel/test/true/city-line.geojson similarity index 100% rename from packages/turf-boolean-parallel/test/true/city-line.geojson rename to src/boolean-parallel/test/true/city-line.geojson diff --git a/packages/turf-boolean-parallel/test/true/fiji.geojson b/src/boolean-parallel/test/true/fiji.geojson similarity index 100% rename from packages/turf-boolean-parallel/test/true/fiji.geojson rename to src/boolean-parallel/test/true/fiji.geojson diff --git a/packages/turf-boolean-parallel/test/true/line1.geojson b/src/boolean-parallel/test/true/line1.geojson similarity index 100% rename from packages/turf-boolean-parallel/test/true/line1.geojson rename to src/boolean-parallel/test/true/line1.geojson diff --git a/packages/turf-boolean-parallel/test/true/line3-reverse.geojson b/src/boolean-parallel/test/true/line3-reverse.geojson similarity index 100% rename from packages/turf-boolean-parallel/test/true/line3-reverse.geojson rename to src/boolean-parallel/test/true/line3-reverse.geojson diff --git a/packages/turf-boolean-parallel/test/true/line3.geojson b/src/boolean-parallel/test/true/line3.geojson similarity index 100% rename from packages/turf-boolean-parallel/test/true/line3.geojson rename to src/boolean-parallel/test/true/line3.geojson diff --git a/packages/turf-boolean-parallel/test/true/resolute.geojson b/src/boolean-parallel/test/true/resolute.geojson similarity index 100% rename from packages/turf-boolean-parallel/test/true/resolute.geojson rename to src/boolean-parallel/test/true/resolute.geojson diff --git a/packages/turf-boolean-parallel/test/true/segment1.geojson b/src/boolean-parallel/test/true/segment1.geojson similarity index 100% rename from packages/turf-boolean-parallel/test/true/segment1.geojson rename to src/boolean-parallel/test/true/segment1.geojson diff --git a/packages/turf-boolean-parallel/test/true/segment2.geojson b/src/boolean-parallel/test/true/segment2.geojson similarity index 100% rename from packages/turf-boolean-parallel/test/true/segment2.geojson rename to src/boolean-parallel/test/true/segment2.geojson diff --git a/packages/turf-boolean-parallel/test/true/segment3.geojson b/src/boolean-parallel/test/true/segment3.geojson similarity index 100% rename from packages/turf-boolean-parallel/test/true/segment3.geojson rename to src/boolean-parallel/test/true/segment3.geojson diff --git a/packages/turf-boolean-point-in-polygon/bench.js b/src/boolean-point-in-polygon/bench.js similarity index 100% rename from packages/turf-boolean-point-in-polygon/bench.js rename to src/boolean-point-in-polygon/bench.js diff --git a/packages/turf-boolean-point-in-polygon/index.d.ts b/src/boolean-point-in-polygon/index.d.ts similarity index 100% rename from packages/turf-boolean-point-in-polygon/index.d.ts rename to src/boolean-point-in-polygon/index.d.ts diff --git a/src/boolean-point-in-polygon/index.js b/src/boolean-point-in-polygon/index.js new file mode 100644 index 0000000000..b61d75bf4c --- /dev/null +++ b/src/boolean-point-in-polygon/index.js @@ -0,0 +1,116 @@ +import { getCoord, getGeom } from '../invariant'; +import { checkIfOptionsExist } from '../helpers'; +// http://en.wikipedia.org/wiki/Even%E2%80%93odd_rule +// modified from: https://github.com/substack/point-in-polygon/blob/master/index.js +// which was modified from http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html +/** + * Takes a {@link Point} and a {@link Polygon} or {@link MultiPolygon} and determines if the point + * resides inside the polygon. The polygon can be convex or concave. The function accounts for holes. + * + * @name booleanPointInPolygon + * @param {Coord} point input point + * @param {Feature} polygon input polygon or multipolygon + * @param {Object} [options={}] Optional parameters + * @param {boolean} [options.ignoreBoundary=false] True if polygon boundary should be ignored when determining if + * the point is inside the polygon otherwise false. + * @returns {boolean} `true` if the Point is inside the Polygon; `false` if the Point is not inside the Polygon + * @example + * var pt = turf.point([-77, 44]); + * var poly = turf.polygon([[ + * [-81, 41], + * [-81, 47], + * [-72, 47], + * [-72, 41], + * [-81, 41] + * ]]); + * + * turf.booleanPointInPolygon(pt, poly); + * //= true + */ +export default function booleanPointInPolygon(point, polygon, options) { + options = checkIfOptionsExist(options); + // validation + if (!point) { throw new Error('point is required'); } + if (!polygon) { throw new Error('polygon is required'); } + + const pt = getCoord(point); + const geom = getGeom(polygon); + const type = geom.type; + const bbox = polygon.bbox; + let polys = geom.coordinates; + + // Quick elimination if point is not inside bbox + if (bbox && inBBox(pt, bbox) === false) { + return false; + } + // normalize to multipolygon + if (type === 'Polygon') { + polys = [polys]; + } + let insidePoly = false; + for (let i = 0; i < polys.length && !insidePoly; i++) { + // check if it is in the outer ring first + if (inRing(pt, polys[i][0], options.ignoreBoundary)) { + let inHole = false; + let k = 1; + // check for the point in any of the holes + while (k < polys[i].length && !inHole) { + if (inRing(pt, polys[i][k], !options.ignoreBoundary)) { + inHole = true; + } + k++; + } + if (!inHole) { + insidePoly = true; + } + } + } + return insidePoly; +} + +/** + * inRing + * + * @private + * @param {Array} pt [x,y] + * @param {Array>} ring [[x,y], [x,y],..] + * @param {boolean} ignoreBoundary ignoreBoundary + * @returns {boolean} inRing + */ +function inRing(pt, ring, ignoreBoundary) { + let isInside = false; + if (ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1]) { + ring = ring.slice(0, ring.length - 1); + } + for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) { + const xi = ring[i][0]; + const yi = ring[i][1]; + const xj = ring[j][0]; + const yj = ring[j][1]; + const onBoundary = (pt[1] * (xi - xj) + yi * (xj - pt[0]) + yj * (pt[0] - xi) === 0) && + ((xi - pt[0]) * (xj - pt[0]) <= 0) && ((yi - pt[1]) * (yj - pt[1]) <= 0); + if (onBoundary) { + return !ignoreBoundary; + } + const intersect = ((yi > pt[1]) !== (yj > pt[1])) && + (pt[0] < (xj - xi) * (pt[1] - yi) / (yj - yi) + xi); + if (intersect) { + isInside = !isInside; + } + } + return isInside; +} +/** + * inBBox + * + * @private + * @param {Position} pt point [x,y] + * @param {BBox} bbox BBox [west, south, east, north] + * @returns {boolean} true/false if point is inside BBox + */ +function inBBox(pt, bbox) { + return bbox[0] <= pt[0] && + bbox[1] <= pt[1] && + bbox[2] >= pt[0] && + bbox[3] >= pt[1]; +} diff --git a/src/boolean-point-in-polygon/test.js b/src/boolean-point-in-polygon/test.js new file mode 100644 index 0000000000..92fd379c0b --- /dev/null +++ b/src/boolean-point-in-polygon/test.js @@ -0,0 +1,169 @@ +const fs = require('fs'); +const test = require('tape'); +const { point, polygon } = require('../helpers'); +const booleanPointInPolygon = require('./').default; + +test('boolean-point-in-polygon -- featureCollection', function (t) { + // test for a simple polygon + var poly = polygon([[[0, 0], [0, 100], [100, 100], [100, 0], [0, 0]]]); + var ptIn = point([50, 50]); + var ptOut = point([140, 150]); + + t.true(booleanPointInPolygon(ptIn, poly), 'point inside simple polygon'); + t.false(booleanPointInPolygon(ptOut, poly), 'point outside simple polygon'); + + // test for a concave polygon + var concavePoly = polygon([[[0, 0], [50, 50], [0, 100], [100, 100], [100, 0], [0, 0]]]); + var ptConcaveIn = point([75, 75]); + var ptConcaveOut = point([25, 50]); + + t.true(booleanPointInPolygon(ptConcaveIn, concavePoly), 'point inside concave polygon'); + t.false(booleanPointInPolygon(ptConcaveOut, concavePoly), 'point outside concave polygon'); + + t.end(); +}); + +test('boolean-point-in-polygon -- poly with hole', function (t) { + var ptInHole = point([-86.69208526611328, 36.20373274711739]); + var ptInPoly = point([-86.72229766845702, 36.20258997094334]); + var ptOutsidePoly = point([-86.75079345703125, 36.18527313913089]); + var polyHole = JSON.parse(fs.readFileSync(__dirname + '/test/in/poly-with-hole.geojson')); + + t.false(booleanPointInPolygon(ptInHole, polyHole)); + t.true(booleanPointInPolygon(ptInPoly, polyHole)); + t.false(booleanPointInPolygon(ptOutsidePoly, polyHole)); + + t.end(); +}); + +test('boolean-point-in-polygon -- multipolygon with hole', function (t) { + var ptInHole = point([-86.69208526611328, 36.20373274711739]); + var ptInPoly = point([-86.72229766845702, 36.20258997094334]); + var ptInPoly2 = point([-86.75079345703125, 36.18527313913089]); + var ptOutsidePoly = point([-86.75302505493164, 36.23015046460186]); + var multiPolyHole = JSON.parse(fs.readFileSync(__dirname + '/test/in/multipoly-with-hole.geojson')); + + t.false(booleanPointInPolygon(ptInHole, multiPolyHole)); + t.true(booleanPointInPolygon(ptInPoly, multiPolyHole)); + t.true(booleanPointInPolygon(ptInPoly2, multiPolyHole)); + t.true(booleanPointInPolygon(ptInPoly, multiPolyHole)); + t.false(booleanPointInPolygon(ptOutsidePoly, multiPolyHole)); + + t.end(); +}); + +test('boolean-point-in-polygon -- Boundary test', function (t) { + var poly1 = polygon([[ + [10, 10], + [30, 20], + [50, 10], + [30, 0], + [10, 10] + ]]); + var poly2 = polygon([[ + [10, 0], + [30, 20], + [50, 0], + [30, 10], + [10, 0] + ]]); + var poly3 = polygon([[ + [10, 0], + [30, 20], + [50, 0], + [30, -20], + [10, 0] + ]]); + var poly4 = polygon([[ + [0, 0], + [0, 20], + [50, 20], + [50, 0], + [40, 0], + [30, 10], + [30, 0], + [20, 10], + [10, 10], + [10, 0], + [0, 0] + ]]); + var poly5 = polygon([[ + [0, 20], + [20, 40], + [40, 20], + [20, 0], + [0, 20] + ], [ + [10, 20], + [20, 30], + [30, 20], + [20, 10], + [10, 20] + ]]); + function runTest(t, ignoreBoundary) { + var isBoundaryIncluded = (ignoreBoundary === false); + var tests = [ + [poly1, point([10, 10]), isBoundaryIncluded], //0 + [poly1, point([30, 20]), isBoundaryIncluded], + [poly1, point([50, 10]), isBoundaryIncluded], + [poly1, point([30, 10]), true], + [poly1, point([0, 10]), false], + [poly1, point([60, 10]), false], + [poly1, point([30, -10]), false], + [poly1, point([30, 30]), false], + [poly2, point([30, 0]), false], + [poly2, point([0, 0]), false], + [poly2, point([60, 0]), false], //10 + [poly3, point([30, 0]), true], + [poly3, point([0, 0]), false], + [poly3, point([60, 0]), false], + [poly4, point([0, 20]), isBoundaryIncluded], + [poly4, point([10, 20]), isBoundaryIncluded], + [poly4, point([50, 20]), isBoundaryIncluded], + [poly4, point([0, 10]), isBoundaryIncluded], + [poly4, point([5, 10]), true], + [poly4, point([25, 10]), true], + [poly4, point([35, 10]), true], //20 + [poly4, point([0, 0]), isBoundaryIncluded], + [poly4, point([20, 0]), false], + [poly4, point([35, 0]), false], + [poly4, point([50, 0]), isBoundaryIncluded], + [poly4, point([50, 10]), isBoundaryIncluded], + [poly4, point([5, 0]), isBoundaryIncluded], + [poly4, point([10, 0]), isBoundaryIncluded], + [poly5, point([20, 30]), isBoundaryIncluded], + [poly5, point([25, 25]), isBoundaryIncluded], + [poly5, point([30, 20]), isBoundaryIncluded], //30 + [poly5, point([25, 15]), isBoundaryIncluded], + [poly5, point([20, 10]), isBoundaryIncluded], + [poly5, point([15, 15]), isBoundaryIncluded], + [poly5, point([10, 20]), isBoundaryIncluded], + [poly5, point([15, 25]), isBoundaryIncluded], + [poly5, point([20, 20]), false] + ]; + + var testTitle = 'Boundary ' + (ignoreBoundary ? 'ignored ' : '') + 'test number '; + for (var i = 0; i < tests.length; i++) { + var item = tests[i]; + t.true(booleanPointInPolygon(item[1], item[0], {ignoreBoundary: ignoreBoundary}) == item[2], testTitle + i); + } + } + runTest(t, false); + runTest(t, true); + t.end(); +}); + +// https://github.com/Turfjs/turf-inside/issues/15 +test('boolean-point-in-polygon -- issue #15', t => { + var pt1 = point([-9.9964077, 53.8040989]); + var poly = polygon([[ + [5.080336744095521, 67.89398938540765], + [0.35070899909145403, 69.32470003971179], + [-24.453622256504122, 41.146696777884564], + [-21.6445524714804, 40.43225902006474], + [5.080336744095521, 67.89398938540765] + ]]); + + t.true(booleanPointInPolygon(pt1, poly)); + t.end(); +}); diff --git a/packages/turf-boolean-point-in-polygon/test/in/multipoly-with-hole.geojson b/src/boolean-point-in-polygon/test/in/multipoly-with-hole.geojson similarity index 100% rename from packages/turf-boolean-point-in-polygon/test/in/multipoly-with-hole.geojson rename to src/boolean-point-in-polygon/test/in/multipoly-with-hole.geojson diff --git a/packages/turf-boolean-point-in-polygon/test/in/poly-with-hole.geojson b/src/boolean-point-in-polygon/test/in/poly-with-hole.geojson similarity index 100% rename from packages/turf-boolean-point-in-polygon/test/in/poly-with-hole.geojson rename to src/boolean-point-in-polygon/test/in/poly-with-hole.geojson diff --git a/packages/turf-boolean-point-on-line/bench.js b/src/boolean-point-on-line/bench.js similarity index 100% rename from packages/turf-boolean-point-on-line/bench.js rename to src/boolean-point-on-line/bench.js diff --git a/packages/turf-boolean-point-on-line/index.d.ts b/src/boolean-point-on-line/index.d.ts similarity index 100% rename from packages/turf-boolean-point-on-line/index.d.ts rename to src/boolean-point-on-line/index.d.ts diff --git a/src/boolean-point-on-line/index.js b/src/boolean-point-on-line/index.js new file mode 100644 index 0000000000..2f5ffb082d --- /dev/null +++ b/src/boolean-point-on-line/index.js @@ -0,0 +1,88 @@ +import { getCoord, getCoords } from '../invariant'; +import { checkIfOptionsExist } from '../helpers'; +/** + * Returns true if a point is on a line. Accepts a optional parameter to ignore the + * start and end vertices of the linestring. + * + * @name booleanPointOnLine + * @param {Coord} pt GeoJSON Point + * @param {Feature} line GeoJSON LineString + * @param {Object} [options={}] Optional parameters + * @param {boolean} [options.ignoreEndVertices=false] whether to ignore the start and end vertices. + * @returns {boolean} true/false + * @example + * var pt = turf.point([0, 0]); + * var line = turf.lineString([[-1, -1],[1, 1],[1.5, 2.2]]); + * var isPointOnLine = turf.booleanPointOnLine(pt, line); + * //=true + */ +function booleanPointOnLine(pt, line, options) { + + options = checkIfOptionsExist(options); + // Normalize inputs + const ptCoords = getCoord(pt); + const lineCoords = getCoords(line); + + // Main + for (let i = 0; i < lineCoords.length - 1; i++) { + let ignoreBoundary = false; + if (options.ignoreEndVertices) { + if (i === 0) { ignoreBoundary = 'start'; } + if (i === lineCoords.length - 2) { ignoreBoundary = 'end'; } + if (i === 0 && i + 1 === lineCoords.length - 1) { ignoreBoundary = 'both'; } + } + if (isPointOnLineSegment(lineCoords[i], lineCoords[i + 1], ptCoords, ignoreBoundary)) { return true; } + } + return false; +} + +// See http://stackoverflow.com/a/4833823/1979085 +/** + * @private + * @param {Position} lineSegmentStart coord pair of start of line + * @param {Position} lineSegmentEnd coord pair of end of line + * @param {Position} pt coord pair of point to check + * @param {boolean|string} excludeBoundary whether the point is allowed to fall on the line ends. + * If true which end to ignore. + * @returns {boolean} true/false + */ +function isPointOnLineSegment(lineSegmentStart, lineSegmentEnd, pt, excludeBoundary) { + const x = pt[0]; + const y = pt[1]; + const x1 = lineSegmentStart[0]; + const y1 = lineSegmentStart[1]; + const x2 = lineSegmentEnd[0]; + const y2 = lineSegmentEnd[1]; + const dxc = pt[0] - x1; + const dyc = pt[1] - y1; + const dxl = x2 - x1; + const dyl = y2 - y1; + const cross = dxc * dyl - dyc * dxl; + if (cross !== 0) { + return false; + } + if (!excludeBoundary) { + if (Math.abs(dxl) >= Math.abs(dyl)) { + return dxl > 0 ? x1 <= x && x <= x2 : x2 <= x && x <= x1; + } + return dyl > 0 ? y1 <= y && y <= y2 : y2 <= y && y <= y1; + } else if (excludeBoundary === 'start') { + if (Math.abs(dxl) >= Math.abs(dyl)) { + return dxl > 0 ? x1 < x && x <= x2 : x2 <= x && x < x1; + } + return dyl > 0 ? y1 < y && y <= y2 : y2 <= y && y < y1; + } else if (excludeBoundary === 'end') { + if (Math.abs(dxl) >= Math.abs(dyl)) { + return dxl > 0 ? x1 <= x && x < x2 : x2 < x && x <= x1; + } + return dyl > 0 ? y1 <= y && y < y2 : y2 < y && y <= y1; + } else if (excludeBoundary === 'both') { + if (Math.abs(dxl) >= Math.abs(dyl)) { + return dxl > 0 ? x1 < x && x < x2 : x2 < x && x < x1; + } + return dyl > 0 ? y1 < y && y < y2 : y2 < y && y < y1; + } + return false; +} + +export default booleanPointOnLine; diff --git a/src/boolean-point-on-line/test.js b/src/boolean-point-on-line/test.js new file mode 100644 index 0000000000..ce79891b3f --- /dev/null +++ b/src/boolean-point-on-line/test.js @@ -0,0 +1,32 @@ +const glob = require('glob'); +const path = require('path'); +const test = require('tape'); +const load = require('load-json-file'); +const pointOnLine = require('./').default; +const { point, lineString } = require('../helpers'); + +test('turf-boolean-point-on-line', t => { + // True Fixtures + glob.sync(path.join(__dirname, 'test', 'true', '**', '*.geojson')).forEach(filepath => { + const name = path.parse(filepath).name; + const geojson = load.sync(filepath); + const options = geojson.propeties; + const feature1 = geojson.features[0]; + const feature2 = geojson.features[1]; + const result = pointOnLine(feature1, feature2, options); + + t.true(result, '[true] ' + name); + }); + // False Fixtures + glob.sync(path.join(__dirname, 'test', 'false', '**', '*.geojson')).forEach(filepath => { + const name = path.parse(filepath).name; + const geojson = load.sync(filepath); + const options = geojson.properties; + const feature1 = geojson.features[0]; + const feature2 = geojson.features[1]; + const result = pointOnLine(feature1, feature2, options); + + t.false(result, '[false] ' + name); + }); + t.end(); +}); diff --git a/packages/turf-boolean-point-on-line/test/false/LineWithOnly1SegmentIgnoreBoundary.geojson b/src/boolean-point-on-line/test/false/LineWithOnly1SegmentIgnoreBoundary.geojson similarity index 100% rename from packages/turf-boolean-point-on-line/test/false/LineWithOnly1SegmentIgnoreBoundary.geojson rename to src/boolean-point-on-line/test/false/LineWithOnly1SegmentIgnoreBoundary.geojson diff --git a/packages/turf-boolean-point-on-line/test/false/LineWithOnly1SegmentIgnoreBoundaryEnd.geojson b/src/boolean-point-on-line/test/false/LineWithOnly1SegmentIgnoreBoundaryEnd.geojson similarity index 100% rename from packages/turf-boolean-point-on-line/test/false/LineWithOnly1SegmentIgnoreBoundaryEnd.geojson rename to src/boolean-point-on-line/test/false/LineWithOnly1SegmentIgnoreBoundaryEnd.geojson diff --git a/packages/turf-boolean-point-on-line/test/false/PointOnEndFailsWhenIgnoreEndpoints.geojson b/src/boolean-point-on-line/test/false/PointOnEndFailsWhenIgnoreEndpoints.geojson similarity index 100% rename from packages/turf-boolean-point-on-line/test/false/PointOnEndFailsWhenIgnoreEndpoints.geojson rename to src/boolean-point-on-line/test/false/PointOnEndFailsWhenIgnoreEndpoints.geojson diff --git a/packages/turf-boolean-point-on-line/test/false/PointOnStartFailsWhenIgnoreEndpoints.geojson b/src/boolean-point-on-line/test/false/PointOnStartFailsWhenIgnoreEndpoints.geojson similarity index 100% rename from packages/turf-boolean-point-on-line/test/false/PointOnStartFailsWhenIgnoreEndpoints.geojson rename to src/boolean-point-on-line/test/false/PointOnStartFailsWhenIgnoreEndpoints.geojson diff --git a/packages/turf-boolean-point-on-line/test/false/notOnLine.geojson b/src/boolean-point-on-line/test/false/notOnLine.geojson similarity index 100% rename from packages/turf-boolean-point-on-line/test/false/notOnLine.geojson rename to src/boolean-point-on-line/test/false/notOnLine.geojson diff --git a/packages/turf-boolean-point-on-line/test/true/LineWithOnly1Segment.geojson b/src/boolean-point-on-line/test/true/LineWithOnly1Segment.geojson similarity index 100% rename from packages/turf-boolean-point-on-line/test/true/LineWithOnly1Segment.geojson rename to src/boolean-point-on-line/test/true/LineWithOnly1Segment.geojson diff --git a/packages/turf-boolean-point-on-line/test/true/LineWithOnly1SegmentOnStart.geojson b/src/boolean-point-on-line/test/true/LineWithOnly1SegmentOnStart.geojson similarity index 100% rename from packages/turf-boolean-point-on-line/test/true/LineWithOnly1SegmentOnStart.geojson rename to src/boolean-point-on-line/test/true/LineWithOnly1SegmentOnStart.geojson diff --git a/packages/turf-boolean-point-on-line/test/true/PointOnFirstSegment.geojson b/src/boolean-point-on-line/test/true/PointOnFirstSegment.geojson similarity index 100% rename from packages/turf-boolean-point-on-line/test/true/PointOnFirstSegment.geojson rename to src/boolean-point-on-line/test/true/PointOnFirstSegment.geojson diff --git a/packages/turf-boolean-point-on-line/test/true/PointOnLastSegment.geojson b/src/boolean-point-on-line/test/true/PointOnLastSegment.geojson similarity index 100% rename from packages/turf-boolean-point-on-line/test/true/PointOnLastSegment.geojson rename to src/boolean-point-on-line/test/true/PointOnLastSegment.geojson diff --git a/packages/turf-boolean-point-on-line/test/true/PointOnLineEnd.geojson b/src/boolean-point-on-line/test/true/PointOnLineEnd.geojson similarity index 100% rename from packages/turf-boolean-point-on-line/test/true/PointOnLineEnd.geojson rename to src/boolean-point-on-line/test/true/PointOnLineEnd.geojson diff --git a/packages/turf-boolean-point-on-line/test/true/PointOnLineMidVertice.geojson b/src/boolean-point-on-line/test/true/PointOnLineMidVertice.geojson similarity index 100% rename from packages/turf-boolean-point-on-line/test/true/PointOnLineMidVertice.geojson rename to src/boolean-point-on-line/test/true/PointOnLineMidVertice.geojson diff --git a/packages/turf-boolean-point-on-line/test/true/PointOnLineMidpoint.geojson b/src/boolean-point-on-line/test/true/PointOnLineMidpoint.geojson similarity index 100% rename from packages/turf-boolean-point-on-line/test/true/PointOnLineMidpoint.geojson rename to src/boolean-point-on-line/test/true/PointOnLineMidpoint.geojson diff --git a/packages/turf-boolean-point-on-line/test/true/PointOnLineStart.geojson b/src/boolean-point-on-line/test/true/PointOnLineStart.geojson similarity index 100% rename from packages/turf-boolean-point-on-line/test/true/PointOnLineStart.geojson rename to src/boolean-point-on-line/test/true/PointOnLineStart.geojson diff --git a/packages/turf-boolean-touches/bench.js b/src/boolean-touches/bench.js similarity index 100% rename from packages/turf-boolean-touches/bench.js rename to src/boolean-touches/bench.js diff --git a/src/boolean-touches/index.js b/src/boolean-touches/index.js new file mode 100644 index 0000000000..8f916bb6b2 --- /dev/null +++ b/src/boolean-touches/index.js @@ -0,0 +1,448 @@ +import calcBbox from '../bbox'; +import booleanPointOnLine from '../boolean-point-on-line'; +import booleanPointInPolygon from '../boolean-point-in-polygon'; +import { getGeom, getType } from '../invariant'; + +/** + * Boolean-touches true if none of the points common to both geometries + * intersect the interiors of both geometries. + * @name booleanTouches + * @param {Geometry|Feature} feature1 GeoJSON Feature or Geometry + * @param {Geometry|Feature} feature2 GeoJSON Feature or Geometry + * @returns {boolean} true/false + * @example + * var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); + * var point = turf.point([1, 1]); + * + * turf.booleanTouches(point, line); + * //=true + */ +function booleanTouches(feature1, feature2) { + var geom1 = getGeom(feature1); + var geom2 = getGeom(feature2); + var type1 = geom1.type; + var type2 = geom2.type; + + switch (type1) { + case 'Point': + switch (type2) { + case 'LineString': + return isPointOnLineEnd(geom1, geom2); + case 'MultiLineString': + var foundTouchingPoint = false + for (var ii = 0; ii < geom2.coordinates.length; ii++) { + if (isPointOnLineEnd(geom1, {type: 'LineString', coordinates: geom2.coordinates[ii]})) foundTouchingPoint = true; + } + return foundTouchingPoint + case 'Polygon': + for (var i = 0; i < geom2.coordinates.length; i++) { + if (booleanPointOnLine(geom1, {type:'LineString', coordinates: geom2.coordinates[i]})) return true; + } + return false + case 'MultiPolygon': + for (var i = 0; i < geom2.coordinates.length; i++) { + for (var ii = 0; ii < geom2.coordinates[i].length; ii++) { + if (booleanPointOnLine(geom1, {type:'LineString', coordinates: geom2.coordinates[i][ii]})) return true; + } + } + return false; + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + case 'MultiPoint': + switch (type2) { + case 'LineString': + var foundTouchingPoint = false; + for (var i = 0; i < geom1.coordinates.length; i++) { + if (!foundTouchingPoint) { + if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[i]}, geom2)) foundTouchingPoint = true; + } + if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i]}, geom2, {ignoreEndVertices: true})) return false; + } + return foundTouchingPoint + case 'MultiLineString': + var foundTouchingPoint = false + for (var i = 0; i < geom1.coordinates.length; i++) { + for (var ii = 0; ii < geom2.coordinates.length; ii++) { + if (!foundTouchingPoint) { + if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[i]}, {type: 'LineString', coordinates: geom2.coordinates[ii]})) foundTouchingPoint = true; + } + if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i]}, {type: 'LineString', coordinates: geom2.coordinates[ii]}, {ignoreEndVertices: true})) return false; + } + } + return foundTouchingPoint + case 'Polygon': + var foundTouchingPoint = false; + for (var i = 0; i < geom1.coordinates.length; i++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i]}, {type:'LineString', coordinates: geom2.coordinates[0]})) foundTouchingPoint = true; + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[i]}, geom2, {ignoreBoundary: true})) return false; + } + return foundTouchingPoint + case 'MultiPolygon': + var foundTouchingPoint = false; + for (var i = 0; i < geom1.coordinates.length; i++) { + for (var ii = 0; ii < geom2.coordinates.length; ii++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i]}, {type:'LineString', coordinates: geom2.coordinates[ii][0]})) foundTouchingPoint = true; + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[i]}, {type: 'Polygon', coordinates: geom2.coordinates[ii]}, {ignoreBoundary: true})) return false; + } + } + return foundTouchingPoint; + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + case 'LineString': + switch (type2) { + case 'Point': + return isPointOnLineEnd(geom2, geom1); + case 'MultiPoint': + var foundTouchingPoint = false; + for (var i = 0; i < geom2.coordinates.length; i++) { + if (!foundTouchingPoint) { + if (isPointOnLineEnd({type: 'Point', coordinates: geom2.coordinates[i]}, geom1)) foundTouchingPoint = true; + } + if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[i]}, geom1, {ignoreEndVertices: true})) return false; + } + return foundTouchingPoint + case 'LineString': + var endMatch = false; + if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[0]}, geom2)) endMatch = true; + if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[geom1.coordinates.length - 1]}, geom2)) endMatch = true; + if (endMatch === false) return false; + for (var i = 0; i < geom1.coordinates.length; i++) { + if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i]}, geom2, {ignoreEndVertices: true})) return false; + } + return endMatch; + case 'MultiLineString': + var endMatch = false; + for (var i = 0; i < geom2.coordinates.length; i++) { + if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[0]}, {type:'LineString', coordinates: geom2.coordinates[i]})) endMatch = true; + if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[geom1.coordinates.length - 1]}, {type:'LineString', coordinates: geom2.coordinates[i]})) endMatch = true; + for (var ii = 0; ii < geom1.coordinates[i].length; ii++) { + if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[ii]}, {type:'LineString', coordinates: geom2.coordinates[i]}, {ignoreEndVertices: true})) return false; + } + } + return endMatch + case 'Polygon': + var foundTouchingPoint = false; + for (var i = 0; i < geom1.coordinates.length; i++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i]}, {type:'LineString', coordinates: geom2.coordinates[0]})) foundTouchingPoint = true; + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[i]}, geom2, {ignoreBoundary: true})) return false; + } + return foundTouchingPoint; + case 'MultiPolygon': + var foundTouchingPoint = false; + for (var i = 0; i < geom1.coordinates.length; i++) { + for (var ii = 0; ii < geom2.coordinates.length; ii++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i]}, {type:'LineString', coordinates: geom2.coordinates[ii][0]})) foundTouchingPoint = true; + } + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[i]}, geom2, {ignoreBoundary: true})) return false; + } + return foundTouchingPoint; + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + case 'MultiLineString': + switch (type2) { + case 'Point': + for (var i = 0; i < geom1.coordinates.length; i++) { + if (isPointOnLineEnd(geom2, {type:'LineString', coordinates: geom1.coordinates[i]})) return true; + } + return false; + case 'MultiPoint': + var foundTouchingPoint = false; + for (var i = 0; i < geom1.coordinates.length; i++) { + for (var ii = 0; ii < geom2.coordinates.length; ii++) { + if (!foundTouchingPoint) { + if (isPointOnLineEnd({type: 'Point', coordinates: geom2.coordinates[ii]}, {type:'LineString', coordinates: geom1.coordinates[ii]})) foundTouchingPoint = true; + } + if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[ii]}, {type:'LineString', coordinates: geom1.coordinates[ii]}, {ignoreEndVertices: true})) return false; + } + } + return foundTouchingPoint; + case 'LineString': + var endMatch = false; + for (var i = 0; i < geom1.coordinates.length; i++) { + if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[i][0]}, geom2)) endMatch = true; + if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[i][geom1.coordinates[i].length - 1]}, geom2)) endMatch = true; + for (var ii = 0; ii < geom2.coordinates.length; ii++) { + if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[ii]}, {type:'LineString', coordinates: geom1.coordinates[i]}, {ignoreEndVertices: true})) return false; + } + } + return endMatch + case 'MultiLineString': + var endMatch = false + for (var i = 0; i < geom1.coordinates.length; i++) { + for (var ii = 0; ii < geom2.coordinates.length; ii++) { + if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[i][0]}, {type:'LineString', coordinates: geom2.coordinates[ii]})) endMatch = true + if (isPointOnLineEnd({type: 'Point', coordinates: geom1.coordinates[i][geom1.coordinates[i].length - 1]}, {type:'LineString', coordinates: geom2.coordinates[ii]})) endMatch = true + for (var iii = 0; iii < geom1.coordinates[i].length; iii++) { + if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i][iii]}, {type:'LineString', coordinates: geom2.coordinates[ii]}, {ignoreEndVertices: true})) return false + } + } + } + return endMatch + case 'Polygon': + var foundTouchingPoint = false; + for (var i = 0; i < geom1.coordinates.length; i++) { + for (var ii = 0; ii < geom1.coordinates.length; ii++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[i][ii]}, {type:'LineString', coordinates: geom2.coordinates[0]})) foundTouchingPoint = true; + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[i][ii]}, geom2, {ignoreBoundary: true})) return false; + } + } + return foundTouchingPoint + case 'MultiPolygon': + var foundTouchingPoint = false; + for (var i = 0; i < geom2.coordinates[0].length; i++) { + for (var ii = 0; ii < geom1.coordinates.length; ii++) { + for (var iii = 0; iii < geom1.coordinates[ii].length; iii++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[ii][iii]}, {type:'LineString', coordinates: geom2.coordinates[0][i]})) foundTouchingPoint = true; + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[ii][iii]}, {type:'Polygon', coordinates: [geom2.coordinates[0][i]]}, {ignoreBoundary: true})) return false; + } + } + } + return foundTouchingPoint; + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + case 'Polygon': + switch (type2) { + case 'Point': + for (var i = 0; i < geom1.coordinates.length; i++) { + if (booleanPointOnLine(geom2, {type:'LineString', coordinates: geom1.coordinates[i]})) return true; + } + return false + case 'MultiPoint': + var foundTouchingPoint = false + for (var i = 0; i < geom2.coordinates.length; i++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[i]}, {type:'LineString', coordinates: geom1.coordinates[0]})) foundTouchingPoint = true; + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom2.coordinates[i]}, geom1, {ignoreBoundary: true})) return false; + } + return foundTouchingPoint; + case 'LineString': + var foundTouchingPoint = false; + for (var i = 0; i < geom2.coordinates.length; i++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[i]}, {type:'LineString', coordinates: geom1.coordinates[0]})) foundTouchingPoint = true; + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom2.coordinates[i]}, geom1, {ignoreBoundary: true})) return false; + } + return foundTouchingPoint + case 'MultiLineString': + var foundTouchingPoint = false + for (var i = 0; i < geom2.coordinates.length; i++) { + for (var ii = 0; ii < geom2.coordinates[i].length; ii++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[i][ii]}, {type:'LineString', coordinates: geom1.coordinates[0]})) foundTouchingPoint = true; + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom2.coordinates[i][ii]}, geom1, {ignoreBoundary: true})) return false; + } + } + return foundTouchingPoint + case 'Polygon': + var foundTouchingPoint = false + for (var i = 0; i < geom1.coordinates[0].length; i++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[0][i]}, {type:'LineString', coordinates: geom2.coordinates[0]})) foundTouchingPoint = true; + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[0][i]}, geom2, {ignoreBoundary: true})) return false; + } + return foundTouchingPoint + case 'MultiPolygon': + var foundTouchingPoint = false + for (var i = 0; i < geom2.coordinates[0].length; i++) { + for (var ii = 0; ii < geom1.coordinates[0].length; ii++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[0][ii]}, {type:'LineString', coordinates: geom2.coordinates[0][i]})) foundTouchingPoint = true; + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[0][ii]}, {type:'Polygon', coordinates: geom2.coordinates[0][i]}, {ignoreBoundary: true})) return false; + } + } + return foundTouchingPoint + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + case 'MultiPolygon': + switch (type2) { + case 'Point': + for (var i = 0; i < geom1.coordinates[0].length; i++) { + if (booleanPointOnLine(geom2, {type:'LineString', coordinates: geom1.coordinates[0][i]})) return true; + } + return false + case 'MultiPoint': + var foundTouchingPoint = false + for (var i = 0; i < geom1.coordinates[0].length; i++) { + for (var ii = 0; ii < geom2.coordinates.length; ii++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[ii]}, {type:'LineString', coordinates: geom1.coordinates[0][i]})) foundTouchingPoint = true; + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom2.coordinates[ii]}, {type:'Polygon', coordinates: geom1.coordinates[0][i]}, {ignoreBoundary: true})) return false; + } + } + return foundTouchingPoint + case 'LineString': + var foundTouchingPoint = false + for (var i = 0; i < geom1.coordinates[0].length; i++) { + for (var ii = 0; ii < geom2.coordinates.length; ii++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[ii]}, {type:'LineString', coordinates: geom1.coordinates[0][i]})) foundTouchingPoint = true; + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom2.coordinates[ii]}, {type:'Polygon', coordinates: geom1.coordinates[0][i]}, {ignoreBoundary: true})) return false; + } + } + return foundTouchingPoint + case 'MultiLineString': + var foundTouchingPoint = false + for (var i = 0; i < geom1.coordinates.length; i++) { + for (var ii = 0; ii < geom2.coordinates.length; ii++) { + for (var iii = 0; iii < geom2.coordinates[ii].length; iii++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom2.coordinates[ii][iii]}, {type:'LineString', coordinates: geom1.coordinates[i][0]})) foundTouchingPoint = true; + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom2.coordinates[ii][iii]}, {type:'Polygon', coordinates: [geom1.coordinates[i][0]]}, {ignoreBoundary: true})) return false; + } + } + } + + return foundTouchingPoint + case 'Polygon': + var foundTouchingPoint = false + for (var i = 0; i < geom1.coordinates[0].length; i++) { + for (var ii = 0; ii < geom1.coordinates[0][i].length; ii++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[0][i][ii]}, {type:'LineString', coordinates: geom2.coordinates[0]})) foundTouchingPoint = true; + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[0][i][ii]}, geom2, {ignoreBoundary: true})) return false; + } + } + return foundTouchingPoint + case 'MultiPolygon': + var foundTouchingPoint = false + for (var i = 0; i < geom1.coordinates[0].length; i++) { + for (var ii = 0; ii < geom2.coordinates[0].length; ii++) { + for (var iii = 0; iii < geom1.coordinates[0].length; iii++) { + if (!foundTouchingPoint) { + if (booleanPointOnLine({type: 'Point', coordinates: geom1.coordinates[0][i][iii]}, {type:'LineString', coordinates: geom2.coordinates[0][ii]})) foundTouchingPoint = true; + } + if (booleanPointInPolygon({type: 'Point', coordinates: geom1.coordinates[0][i][iii]}, {type:'Polygon', coordinates: geom2.coordinates[0][ii]}, {ignoreBoundary: true})) return false; + } + } + } + return foundTouchingPoint + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + default: + throw new Error('feature1 ' + type1 + ' geometry not supported'); + } +} + +function isPointOnLineEnd(point, line) { + if (compareCoords(line.coordinates[0], point.coordinates)) return true + if (compareCoords(line.coordinates[line.coordinates.length - 1], point.coordinates)) return true + return false +} + + +function isLineOnLine(lineString1, lineString2) { + for (var i = 0; i < lineString1.coordinates.length; i++) { + if (!booleanPointOnLine(lineString1.coordinates[i], lineString2)) { + return false; + } + } + return true; +} + +function isLineInPoly(linestring, polygon) { + var polyBbox = calcBbox(polygon); + var lineBbox = calcBbox(linestring); + if (!doBBoxOverlap(polyBbox, lineBbox)) { + return false; + } + var foundInsidePoint = false; + + for (var i = 0; i < linestring.coordinates.length - 1; i++) { + if (!booleanPointInPolygon(linestring.coordinates[i], polygon)) { + return false; + } + if (!foundInsidePoint) { + foundInsidePoint = booleanPointInPolygon(linestring.coordinates[i], polygon, {ignoreBoundary: true}); + } + if (!foundInsidePoint) { + var midpoint = getMidpoint(linestring.coordinates[i], linestring.coordinates[i + 1]); + foundInsidePoint = booleanPointInPolygon(midpoint, polygon, {ignoreBoundary: true}); + + } + } + return foundInsidePoint; +} + +/** + * Is Polygon2 in Polygon1 + * Only takes into account outer rings + * + * @private + * @param {Geometry|Feature} feature1 Polygon1 + * @param {Geometry|Feature} feature2 Polygon2 + * @returns {boolean} true/false + */ +function isPolyInPoly(feature1, feature2) { + var poly1Bbox = calcBbox(feature1); + var poly2Bbox = calcBbox(feature2); + if (!doBBoxOverlap(poly2Bbox, poly1Bbox)) { + return false; + } + for (var i = 0; i < feature1.coordinates[0].length; i++) { + if (!booleanPointInPolygon(feature1.coordinates[0][i], feature2)) { + return false; + } + } + return true; +} + +function doBBoxOverlap(bbox1, bbox2) { + if (bbox1[0] > bbox2[0]) return false; + if (bbox1[2] < bbox2[2]) return false; + if (bbox1[1] > bbox2[1]) return false; + if (bbox1[3] < bbox2[3]) return false; + return true; +} + +/** + * compareCoords + * + * @private + * @param {Position} pair1 point [x,y] + * @param {Position} pair2 point [x,y] + * @returns {boolean} true/false if coord pairs match + */ +function compareCoords(pair1, pair2) { + return pair1[0] === pair2[0] && pair1[1] === pair2[1]; +} + +/** + * getMidpoint + * + * @private + * @param {Position} pair1 point [x,y] + * @param {Position} pair2 point [x,y] + * @returns {Position} midpoint of pair1 and pair2 + */ +function getMidpoint(pair1, pair2) { + return [(pair1[0] + pair2[0]) / 2, (pair1[1] + pair2[1]) / 2]; +} + +export default booleanTouches; diff --git a/packages/turf-boolean-touches/test.js b/src/boolean-touches/test.js similarity index 100% rename from packages/turf-boolean-touches/test.js rename to src/boolean-touches/test.js diff --git a/packages/turf-boolean-touches/test/false/LineString/LineString/LinesExactSame.geojson b/src/boolean-touches/test/false/LineString/LineString/LinesExactSame.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/LineString/LineString/LinesExactSame.geojson rename to src/boolean-touches/test/false/LineString/LineString/LinesExactSame.geojson diff --git a/packages/turf-boolean-touches/test/false/LineString/LineString/LivesOverlap.geojson b/src/boolean-touches/test/false/LineString/LineString/LivesOverlap.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/LineString/LineString/LivesOverlap.geojson rename to src/boolean-touches/test/false/LineString/LineString/LivesOverlap.geojson diff --git a/packages/turf-boolean-touches/test/false/LineString/MultiLineString/LineStringOverlapsMultiLinestring.geojson b/src/boolean-touches/test/false/LineString/MultiLineString/LineStringOverlapsMultiLinestring.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/LineString/MultiLineString/LineStringOverlapsMultiLinestring.geojson rename to src/boolean-touches/test/false/LineString/MultiLineString/LineStringOverlapsMultiLinestring.geojson diff --git a/packages/turf-boolean-touches/test/false/LineString/MultiLineString/LineStringSameAsMultiLinestring.geojson b/src/boolean-touches/test/false/LineString/MultiLineString/LineStringSameAsMultiLinestring.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/LineString/MultiLineString/LineStringSameAsMultiLinestring.geojson rename to src/boolean-touches/test/false/LineString/MultiLineString/LineStringSameAsMultiLinestring.geojson diff --git a/packages/turf-boolean-touches/test/false/LineString/MultiPoint/LineStringDoesNotTouchMP.geojson b/src/boolean-touches/test/false/LineString/MultiPoint/LineStringDoesNotTouchMP.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/LineString/MultiPoint/LineStringDoesNotTouchMP.geojson rename to src/boolean-touches/test/false/LineString/MultiPoint/LineStringDoesNotTouchMP.geojson diff --git a/packages/turf-boolean-touches/test/false/LineString/MultiPoint/LineStringTouchesMultiPointButInternal.geojson b/src/boolean-touches/test/false/LineString/MultiPoint/LineStringTouchesMultiPointButInternal.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/LineString/MultiPoint/LineStringTouchesMultiPointButInternal.geojson rename to src/boolean-touches/test/false/LineString/MultiPoint/LineStringTouchesMultiPointButInternal.geojson diff --git a/packages/turf-boolean-touches/test/false/LineString/MultiPolygon/LineDoesNotTouchMultiPoly.geojson b/src/boolean-touches/test/false/LineString/MultiPolygon/LineDoesNotTouchMultiPoly.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/LineString/MultiPolygon/LineDoesNotTouchMultiPoly.geojson rename to src/boolean-touches/test/false/LineString/MultiPolygon/LineDoesNotTouchMultiPoly.geojson diff --git a/packages/turf-boolean-touches/test/false/LineString/Polygon/LineCrossesPolygon.geojson b/src/boolean-touches/test/false/LineString/Polygon/LineCrossesPolygon.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/LineString/Polygon/LineCrossesPolygon.geojson rename to src/boolean-touches/test/false/LineString/Polygon/LineCrossesPolygon.geojson diff --git a/packages/turf-boolean-touches/test/false/LineString/Polygon/LineDoesNotTouch.geojson b/src/boolean-touches/test/false/LineString/Polygon/LineDoesNotTouch.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/LineString/Polygon/LineDoesNotTouch.geojson rename to src/boolean-touches/test/false/LineString/Polygon/LineDoesNotTouch.geojson diff --git a/packages/turf-boolean-touches/test/false/LineString/Polygon/LineWIthinPolygon.geojson b/src/boolean-touches/test/false/LineString/Polygon/LineWIthinPolygon.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/LineString/Polygon/LineWIthinPolygon.geojson rename to src/boolean-touches/test/false/LineString/Polygon/LineWIthinPolygon.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiLineString/LineString/MultiLineStringOverlapsLine.geojson b/src/boolean-touches/test/false/MultiLineString/LineString/MultiLineStringOverlapsLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiLineString/LineString/MultiLineStringOverlapsLine.geojson rename to src/boolean-touches/test/false/MultiLineString/LineString/MultiLineStringOverlapsLine.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiLineString/LineString/MultiLineStringSameAsLine.geojson b/src/boolean-touches/test/false/MultiLineString/LineString/MultiLineStringSameAsLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiLineString/LineString/MultiLineStringSameAsLine.geojson rename to src/boolean-touches/test/false/MultiLineString/LineString/MultiLineStringSameAsLine.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiLineString/MultiLineString/MultiLineStringsOverlap.geojson b/src/boolean-touches/test/false/MultiLineString/MultiLineString/MultiLineStringsOverlap.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiLineString/MultiLineString/MultiLineStringsOverlap.geojson rename to src/boolean-touches/test/false/MultiLineString/MultiLineString/MultiLineStringsOverlap.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiLineString/MultiLineString/MultiLineStringsSame.geojson b/src/boolean-touches/test/false/MultiLineString/MultiLineString/MultiLineStringsSame.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiLineString/MultiLineString/MultiLineStringsSame.geojson rename to src/boolean-touches/test/false/MultiLineString/MultiLineString/MultiLineStringsSame.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiLineString/MultiPoint/MpTouchesInternalMultiline.geojson b/src/boolean-touches/test/false/MultiLineString/MultiPoint/MpTouchesInternalMultiline.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiLineString/MultiPoint/MpTouchesInternalMultiline.geojson rename to src/boolean-touches/test/false/MultiLineString/MultiPoint/MpTouchesInternalMultiline.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiLineString/MultiPoint/MultiPointNotTouchMultiline.geojson b/src/boolean-touches/test/false/MultiLineString/MultiPoint/MultiPointNotTouchMultiline.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiLineString/MultiPoint/MultiPointNotTouchMultiline.geojson rename to src/boolean-touches/test/false/MultiLineString/MultiPoint/MultiPointNotTouchMultiline.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiLineString/MultiPolygon/MultiLineInsideMultipoly.geojson b/src/boolean-touches/test/false/MultiLineString/MultiPolygon/MultiLineInsideMultipoly.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiLineString/MultiPolygon/MultiLineInsideMultipoly.geojson rename to src/boolean-touches/test/false/MultiLineString/MultiPolygon/MultiLineInsideMultipoly.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiLineString/Point/PointNotTouchMultiLinestring.geojson b/src/boolean-touches/test/false/MultiLineString/Point/PointNotTouchMultiLinestring.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiLineString/Point/PointNotTouchMultiLinestring.geojson rename to src/boolean-touches/test/false/MultiLineString/Point/PointNotTouchMultiLinestring.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiLineString/Point/PointTouchesMidLineString.geojson b/src/boolean-touches/test/false/MultiLineString/Point/PointTouchesMidLineString.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiLineString/Point/PointTouchesMidLineString.geojson rename to src/boolean-touches/test/false/MultiLineString/Point/PointTouchesMidLineString.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiLineString/Polygon/MultiLineInsidePoly.geojson b/src/boolean-touches/test/false/MultiLineString/Polygon/MultiLineInsidePoly.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiLineString/Polygon/MultiLineInsidePoly.geojson rename to src/boolean-touches/test/false/MultiLineString/Polygon/MultiLineInsidePoly.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiLineString/Polygon/MultiLineNotTouchPoly.geojson b/src/boolean-touches/test/false/MultiLineString/Polygon/MultiLineNotTouchPoly.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiLineString/Polygon/MultiLineNotTouchPoly.geojson rename to src/boolean-touches/test/false/MultiLineString/Polygon/MultiLineNotTouchPoly.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiPoint/LineString/MultiPointTouchesInsideLine.geojson b/src/boolean-touches/test/false/MultiPoint/LineString/MultiPointTouchesInsideLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiPoint/LineString/MultiPointTouchesInsideLine.geojson rename to src/boolean-touches/test/false/MultiPoint/LineString/MultiPointTouchesInsideLine.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiPoint/LineString/MultipointDoesNotTouchLine.geojson b/src/boolean-touches/test/false/MultiPoint/LineString/MultipointDoesNotTouchLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiPoint/LineString/MultipointDoesNotTouchLine.geojson rename to src/boolean-touches/test/false/MultiPoint/LineString/MultipointDoesNotTouchLine.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiPoint/MultiLineString/MpDoesNotTouchMultiLine.geojson b/src/boolean-touches/test/false/MultiPoint/MultiLineString/MpDoesNotTouchMultiLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiPoint/MultiLineString/MpDoesNotTouchMultiLine.geojson rename to src/boolean-touches/test/false/MultiPoint/MultiLineString/MpDoesNotTouchMultiLine.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiPoint/MultiLineString/MpTouchesInternalMultiLine.geojson b/src/boolean-touches/test/false/MultiPoint/MultiLineString/MpTouchesInternalMultiLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiPoint/MultiLineString/MpTouchesInternalMultiLine.geojson rename to src/boolean-touches/test/false/MultiPoint/MultiLineString/MpTouchesInternalMultiLine.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiPoint/MultiPolygon/MultiPointDoesNotTouchMultipolygon b/src/boolean-touches/test/false/MultiPoint/MultiPolygon/MultiPointDoesNotTouchMultipolygon similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiPoint/MultiPolygon/MultiPointDoesNotTouchMultipolygon rename to src/boolean-touches/test/false/MultiPoint/MultiPolygon/MultiPointDoesNotTouchMultipolygon diff --git a/packages/turf-boolean-touches/test/false/MultiPoint/MultiPolygon/multipoint-inside-multipolygon.geojson b/src/boolean-touches/test/false/MultiPoint/MultiPolygon/multipoint-inside-multipolygon.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiPoint/MultiPolygon/multipoint-inside-multipolygon.geojson rename to src/boolean-touches/test/false/MultiPoint/MultiPolygon/multipoint-inside-multipolygon.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiPoint/Polygon/MultiPointInsidePolygon.geojson b/src/boolean-touches/test/false/MultiPoint/Polygon/MultiPointInsidePolygon.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiPoint/Polygon/MultiPointInsidePolygon.geojson rename to src/boolean-touches/test/false/MultiPoint/Polygon/MultiPointInsidePolygon.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiPoint/Polygon/MultiPointNoTouchPolygon.geojson b/src/boolean-touches/test/false/MultiPoint/Polygon/MultiPointNoTouchPolygon.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiPoint/Polygon/MultiPointNoTouchPolygon.geojson rename to src/boolean-touches/test/false/MultiPoint/Polygon/MultiPointNoTouchPolygon.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiPolygon/LineString/MultiPolyNotTouchLineString.geojson b/src/boolean-touches/test/false/MultiPolygon/LineString/MultiPolyNotTouchLineString.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiPolygon/LineString/MultiPolyNotTouchLineString.geojson rename to src/boolean-touches/test/false/MultiPolygon/LineString/MultiPolyNotTouchLineString.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiPolygon/MultiLineString/MultiPolyOverlapsMultiLine.geojson b/src/boolean-touches/test/false/MultiPolygon/MultiLineString/MultiPolyOverlapsMultiLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiPolygon/MultiLineString/MultiPolyOverlapsMultiLine.geojson rename to src/boolean-touches/test/false/MultiPolygon/MultiLineString/MultiPolyOverlapsMultiLine.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiPolygon/MultiPoint/MultiPolyNotTouchMultiPoint.geojson b/src/boolean-touches/test/false/MultiPolygon/MultiPoint/MultiPolyNotTouchMultiPoint.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiPolygon/MultiPoint/MultiPolyNotTouchMultiPoint.geojson rename to src/boolean-touches/test/false/MultiPolygon/MultiPoint/MultiPolyNotTouchMultiPoint.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiPolygon/MultiPolygon/MultiPolysDoNotTouch.geojson b/src/boolean-touches/test/false/MultiPolygon/MultiPolygon/MultiPolysDoNotTouch.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiPolygon/MultiPolygon/MultiPolysDoNotTouch.geojson rename to src/boolean-touches/test/false/MultiPolygon/MultiPolygon/MultiPolysDoNotTouch.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiPolygon/MultiPolygon/MultiPolysOverlap.geojson b/src/boolean-touches/test/false/MultiPolygon/MultiPolygon/MultiPolysOverlap.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiPolygon/MultiPolygon/MultiPolysOverlap.geojson rename to src/boolean-touches/test/false/MultiPolygon/MultiPolygon/MultiPolysOverlap.geojson diff --git a/packages/turf-boolean-touches/test/false/MultiPolygon/Point/MultiPolyNotTouchPoint.geojson b/src/boolean-touches/test/false/MultiPolygon/Point/MultiPolyNotTouchPoint.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/MultiPolygon/Point/MultiPolyNotTouchPoint.geojson rename to src/boolean-touches/test/false/MultiPolygon/Point/MultiPolyNotTouchPoint.geojson diff --git a/packages/turf-boolean-touches/test/false/Point/LineString/PointIsNotTouchLine.geojson b/src/boolean-touches/test/false/Point/LineString/PointIsNotTouchLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Point/LineString/PointIsNotTouchLine.geojson rename to src/boolean-touches/test/false/Point/LineString/PointIsNotTouchLine.geojson diff --git a/packages/turf-boolean-touches/test/false/Point/LineString/PointOnMidLinestring.geojson b/src/boolean-touches/test/false/Point/LineString/PointOnMidLinestring.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Point/LineString/PointOnMidLinestring.geojson rename to src/boolean-touches/test/false/Point/LineString/PointOnMidLinestring.geojson diff --git a/packages/turf-boolean-touches/test/false/Point/MultiLineString/MpNotTouchMidLineString.geojson b/src/boolean-touches/test/false/Point/MultiLineString/MpNotTouchMidLineString.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Point/MultiLineString/MpNotTouchMidLineString.geojson rename to src/boolean-touches/test/false/Point/MultiLineString/MpNotTouchMidLineString.geojson diff --git a/packages/turf-boolean-touches/test/false/Point/MultiLineString/MpOnMidLineString.geojson b/src/boolean-touches/test/false/Point/MultiLineString/MpOnMidLineString.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Point/MultiLineString/MpOnMidLineString.geojson rename to src/boolean-touches/test/false/Point/MultiLineString/MpOnMidLineString.geojson diff --git a/packages/turf-boolean-touches/test/false/Point/MultiPolygon/PointNotTouchMultipolygon.geojson b/src/boolean-touches/test/false/Point/MultiPolygon/PointNotTouchMultipolygon.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Point/MultiPolygon/PointNotTouchMultipolygon.geojson rename to src/boolean-touches/test/false/Point/MultiPolygon/PointNotTouchMultipolygon.geojson diff --git a/packages/turf-boolean-touches/test/false/Point/Polygon/PointDoesNotTouchPolygon.geojson b/src/boolean-touches/test/false/Point/Polygon/PointDoesNotTouchPolygon.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Point/Polygon/PointDoesNotTouchPolygon.geojson rename to src/boolean-touches/test/false/Point/Polygon/PointDoesNotTouchPolygon.geojson diff --git a/packages/turf-boolean-touches/test/false/Point/Polygon/PointInsidePolygon.geojson b/src/boolean-touches/test/false/Point/Polygon/PointInsidePolygon.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Point/Polygon/PointInsidePolygon.geojson rename to src/boolean-touches/test/false/Point/Polygon/PointInsidePolygon.geojson diff --git a/packages/turf-boolean-touches/test/false/Polygon/LineString/PolyDoesNotTouchLine.geojson b/src/boolean-touches/test/false/Polygon/LineString/PolyDoesNotTouchLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Polygon/LineString/PolyDoesNotTouchLine.geojson rename to src/boolean-touches/test/false/Polygon/LineString/PolyDoesNotTouchLine.geojson diff --git a/packages/turf-boolean-touches/test/false/Polygon/MultiLineString/PolyNotTouchMultiLine.geojson b/src/boolean-touches/test/false/Polygon/MultiLineString/PolyNotTouchMultiLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Polygon/MultiLineString/PolyNotTouchMultiLine.geojson rename to src/boolean-touches/test/false/Polygon/MultiLineString/PolyNotTouchMultiLine.geojson diff --git a/packages/turf-boolean-touches/test/false/Polygon/MultiLineString/PolyOverlapMultiLine.geojson b/src/boolean-touches/test/false/Polygon/MultiLineString/PolyOverlapMultiLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Polygon/MultiLineString/PolyOverlapMultiLine.geojson rename to src/boolean-touches/test/false/Polygon/MultiLineString/PolyOverlapMultiLine.geojson diff --git a/packages/turf-boolean-touches/test/false/Polygon/MultiPoint/PolygonNoTouchMultiPoint.geojson b/src/boolean-touches/test/false/Polygon/MultiPoint/PolygonNoTouchMultiPoint.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Polygon/MultiPoint/PolygonNoTouchMultiPoint.geojson rename to src/boolean-touches/test/false/Polygon/MultiPoint/PolygonNoTouchMultiPoint.geojson diff --git a/packages/turf-boolean-touches/test/false/Polygon/MultiPoint/PolygonOverlapsMultiPoint.geojson b/src/boolean-touches/test/false/Polygon/MultiPoint/PolygonOverlapsMultiPoint.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Polygon/MultiPoint/PolygonOverlapsMultiPoint.geojson rename to src/boolean-touches/test/false/Polygon/MultiPoint/PolygonOverlapsMultiPoint.geojson diff --git a/packages/turf-boolean-touches/test/false/Polygon/MultiPolygon/PolyNotTouchMultipoly.geojson b/src/boolean-touches/test/false/Polygon/MultiPolygon/PolyNotTouchMultipoly.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Polygon/MultiPolygon/PolyNotTouchMultipoly.geojson rename to src/boolean-touches/test/false/Polygon/MultiPolygon/PolyNotTouchMultipoly.geojson diff --git a/packages/turf-boolean-touches/test/false/Polygon/Point/PolygonDoesNotTouchPoint.geojson b/src/boolean-touches/test/false/Polygon/Point/PolygonDoesNotTouchPoint.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Polygon/Point/PolygonDoesNotTouchPoint.geojson rename to src/boolean-touches/test/false/Polygon/Point/PolygonDoesNotTouchPoint.geojson diff --git a/packages/turf-boolean-touches/test/false/Polygon/Point/PolygonOverlapsPoint.geojson b/src/boolean-touches/test/false/Polygon/Point/PolygonOverlapsPoint.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Polygon/Point/PolygonOverlapsPoint.geojson rename to src/boolean-touches/test/false/Polygon/Point/PolygonOverlapsPoint.geojson diff --git a/packages/turf-boolean-touches/test/false/Polygon/Polygon/PolygonsDontTouch.geojson b/src/boolean-touches/test/false/Polygon/Polygon/PolygonsDontTouch.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Polygon/Polygon/PolygonsDontTouch.geojson rename to src/boolean-touches/test/false/Polygon/Polygon/PolygonsDontTouch.geojson diff --git a/packages/turf-boolean-touches/test/false/Polygon/Polygon/PolygonsOverlap.geojson b/src/boolean-touches/test/false/Polygon/Polygon/PolygonsOverlap.geojson similarity index 100% rename from packages/turf-boolean-touches/test/false/Polygon/Polygon/PolygonsOverlap.geojson rename to src/boolean-touches/test/false/Polygon/Polygon/PolygonsOverlap.geojson diff --git a/packages/turf-boolean-touches/test/true/LineString/LineString/LineTouchesEndpoint.geojson b/src/boolean-touches/test/true/LineString/LineString/LineTouchesEndpoint.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/LineString/LineString/LineTouchesEndpoint.geojson rename to src/boolean-touches/test/true/LineString/LineString/LineTouchesEndpoint.geojson diff --git a/packages/turf-boolean-touches/test/true/LineString/MultiLineString/LineStringTouchesEnd.geojson b/src/boolean-touches/test/true/LineString/MultiLineString/LineStringTouchesEnd.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/LineString/MultiLineString/LineStringTouchesEnd.geojson rename to src/boolean-touches/test/true/LineString/MultiLineString/LineStringTouchesEnd.geojson diff --git a/packages/turf-boolean-touches/test/true/LineString/MultiLineString/LineStringTouchesStart.geojson b/src/boolean-touches/test/true/LineString/MultiLineString/LineStringTouchesStart.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/LineString/MultiLineString/LineStringTouchesStart.geojson rename to src/boolean-touches/test/true/LineString/MultiLineString/LineStringTouchesStart.geojson diff --git a/packages/turf-boolean-touches/test/true/LineString/MultiPoint/MultipointTouchesLine.geojson b/src/boolean-touches/test/true/LineString/MultiPoint/MultipointTouchesLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/LineString/MultiPoint/MultipointTouchesLine.geojson rename to src/boolean-touches/test/true/LineString/MultiPoint/MultipointTouchesLine.geojson diff --git a/packages/turf-boolean-touches/test/true/LineString/MultiPolygon/LineTouchesMultiPoly.geojson b/src/boolean-touches/test/true/LineString/MultiPolygon/LineTouchesMultiPoly.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/LineString/MultiPolygon/LineTouchesMultiPoly.geojson rename to src/boolean-touches/test/true/LineString/MultiPolygon/LineTouchesMultiPoly.geojson diff --git a/packages/turf-boolean-touches/test/true/LineString/MultiPolygon/LineTouchesSecondMultiPoly.geojson b/src/boolean-touches/test/true/LineString/MultiPolygon/LineTouchesSecondMultiPoly.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/LineString/MultiPolygon/LineTouchesSecondMultiPoly.geojson rename to src/boolean-touches/test/true/LineString/MultiPolygon/LineTouchesSecondMultiPoly.geojson diff --git a/packages/turf-boolean-touches/test/true/LineString/Polygon/LineTouchesPolygon.geojson b/src/boolean-touches/test/true/LineString/Polygon/LineTouchesPolygon.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/LineString/Polygon/LineTouchesPolygon.geojson rename to src/boolean-touches/test/true/LineString/Polygon/LineTouchesPolygon.geojson diff --git a/packages/turf-boolean-touches/test/true/MultiLineString/LineString/MultiLineTouchesLine.geojson b/src/boolean-touches/test/true/MultiLineString/LineString/MultiLineTouchesLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/MultiLineString/LineString/MultiLineTouchesLine.geojson rename to src/boolean-touches/test/true/MultiLineString/LineString/MultiLineTouchesLine.geojson diff --git a/packages/turf-boolean-touches/test/true/MultiLineString/MultiLineString/MultiLineTouchesMultiLine.geojson b/src/boolean-touches/test/true/MultiLineString/MultiLineString/MultiLineTouchesMultiLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/MultiLineString/MultiLineString/MultiLineTouchesMultiLine.geojson rename to src/boolean-touches/test/true/MultiLineString/MultiLineString/MultiLineTouchesMultiLine.geojson diff --git a/packages/turf-boolean-touches/test/true/MultiLineString/MultiPoint/MultiLineTouchesMultiPoint.geojson b/src/boolean-touches/test/true/MultiLineString/MultiPoint/MultiLineTouchesMultiPoint.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/MultiLineString/MultiPoint/MultiLineTouchesMultiPoint.geojson rename to src/boolean-touches/test/true/MultiLineString/MultiPoint/MultiLineTouchesMultiPoint.geojson diff --git a/packages/turf-boolean-touches/test/true/MultiLineString/Point/MultiLineTouchesPoint.geojson b/src/boolean-touches/test/true/MultiLineString/Point/MultiLineTouchesPoint.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/MultiLineString/Point/MultiLineTouchesPoint.geojson rename to src/boolean-touches/test/true/MultiLineString/Point/MultiLineTouchesPoint.geojson diff --git a/packages/turf-boolean-touches/test/true/MultiLineString/Polygon/MultiLineTouchesPolygon.geojson b/src/boolean-touches/test/true/MultiLineString/Polygon/MultiLineTouchesPolygon.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/MultiLineString/Polygon/MultiLineTouchesPolygon.geojson rename to src/boolean-touches/test/true/MultiLineString/Polygon/MultiLineTouchesPolygon.geojson diff --git a/packages/turf-boolean-touches/test/true/MultiPoint/LineString/MultipointTouchesLine.geojson b/src/boolean-touches/test/true/MultiPoint/LineString/MultipointTouchesLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/MultiPoint/LineString/MultipointTouchesLine.geojson rename to src/boolean-touches/test/true/MultiPoint/LineString/MultipointTouchesLine.geojson diff --git a/packages/turf-boolean-touches/test/true/MultiPoint/MultiLineString/MpTouchesEndMultiLine.geojson b/src/boolean-touches/test/true/MultiPoint/MultiLineString/MpTouchesEndMultiLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/MultiPoint/MultiLineString/MpTouchesEndMultiLine.geojson rename to src/boolean-touches/test/true/MultiPoint/MultiLineString/MpTouchesEndMultiLine.geojson diff --git a/packages/turf-boolean-touches/test/true/MultiPoint/MultiLineString/MpTouchesSecondMultiLine.geojson b/src/boolean-touches/test/true/MultiPoint/MultiLineString/MpTouchesSecondMultiLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/MultiPoint/MultiLineString/MpTouchesSecondMultiLine.geojson rename to src/boolean-touches/test/true/MultiPoint/MultiLineString/MpTouchesSecondMultiLine.geojson diff --git a/packages/turf-boolean-touches/test/true/MultiPoint/MultiPolygon/multipoint-touches-multipolygon.geojson b/src/boolean-touches/test/true/MultiPoint/MultiPolygon/multipoint-touches-multipolygon.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/MultiPoint/MultiPolygon/multipoint-touches-multipolygon.geojson rename to src/boolean-touches/test/true/MultiPoint/MultiPolygon/multipoint-touches-multipolygon.geojson diff --git a/packages/turf-boolean-touches/test/true/MultiPoint/Polygon/MultiPointIsWithinPolygon.geojson b/src/boolean-touches/test/true/MultiPoint/Polygon/MultiPointIsWithinPolygon.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/MultiPoint/Polygon/MultiPointIsWithinPolygon.geojson rename to src/boolean-touches/test/true/MultiPoint/Polygon/MultiPointIsWithinPolygon.geojson diff --git a/packages/turf-boolean-touches/test/true/MultiPolygon/MultiLineString/MultiLineTouchesMultiPoly.geojson b/src/boolean-touches/test/true/MultiPolygon/MultiLineString/MultiLineTouchesMultiPoly.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/MultiPolygon/MultiLineString/MultiLineTouchesMultiPoly.geojson rename to src/boolean-touches/test/true/MultiPolygon/MultiLineString/MultiLineTouchesMultiPoly.geojson diff --git a/packages/turf-boolean-touches/test/true/MultiPolygon/MultiPoint/MultiPolyTouchesMultiPoint.geojson b/src/boolean-touches/test/true/MultiPolygon/MultiPoint/MultiPolyTouchesMultiPoint.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/MultiPolygon/MultiPoint/MultiPolyTouchesMultiPoint.geojson rename to src/boolean-touches/test/true/MultiPolygon/MultiPoint/MultiPolyTouchesMultiPoint.geojson diff --git a/packages/turf-boolean-touches/test/true/MultiPolygon/MultiPolygon/MultiPolyTouchesMultiPoly.geojson b/src/boolean-touches/test/true/MultiPolygon/MultiPolygon/MultiPolyTouchesMultiPoly.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/MultiPolygon/MultiPolygon/MultiPolyTouchesMultiPoly.geojson rename to src/boolean-touches/test/true/MultiPolygon/MultiPolygon/MultiPolyTouchesMultiPoly.geojson diff --git a/packages/turf-boolean-touches/test/true/MultiPolygon/Point/MpTouchesPoint.geojson b/src/boolean-touches/test/true/MultiPolygon/Point/MpTouchesPoint.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/MultiPolygon/Point/MpTouchesPoint.geojson rename to src/boolean-touches/test/true/MultiPolygon/Point/MpTouchesPoint.geojson diff --git a/packages/turf-boolean-touches/test/true/MultiPolygon/Polygon/MultiPolyTouchesPoly.geojson b/src/boolean-touches/test/true/MultiPolygon/Polygon/MultiPolyTouchesPoly.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/MultiPolygon/Polygon/MultiPolyTouchesPoly.geojson rename to src/boolean-touches/test/true/MultiPolygon/Polygon/MultiPolyTouchesPoly.geojson diff --git a/packages/turf-boolean-touches/test/true/Point/LineString/PointOnEndLine.geojson b/src/boolean-touches/test/true/Point/LineString/PointOnEndLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Point/LineString/PointOnEndLine.geojson rename to src/boolean-touches/test/true/Point/LineString/PointOnEndLine.geojson diff --git a/packages/turf-boolean-touches/test/true/Point/LineString/PointOnStartLine.geojson b/src/boolean-touches/test/true/Point/LineString/PointOnStartLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Point/LineString/PointOnStartLine.geojson rename to src/boolean-touches/test/true/Point/LineString/PointOnStartLine.geojson diff --git a/packages/turf-boolean-touches/test/true/Point/MultiLineString/MpOnEndLine.geojson b/src/boolean-touches/test/true/Point/MultiLineString/MpOnEndLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Point/MultiLineString/MpOnEndLine.geojson rename to src/boolean-touches/test/true/Point/MultiLineString/MpOnEndLine.geojson diff --git a/packages/turf-boolean-touches/test/true/Point/MultiLineString/MpOnStartLine.geojson b/src/boolean-touches/test/true/Point/MultiLineString/MpOnStartLine.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Point/MultiLineString/MpOnStartLine.geojson rename to src/boolean-touches/test/true/Point/MultiLineString/MpOnStartLine.geojson diff --git a/packages/turf-boolean-touches/test/true/Point/MultiPolygon/PointTouchesMultipolygon.geojson b/src/boolean-touches/test/true/Point/MultiPolygon/PointTouchesMultipolygon.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Point/MultiPolygon/PointTouchesMultipolygon.geojson rename to src/boolean-touches/test/true/Point/MultiPolygon/PointTouchesMultipolygon.geojson diff --git a/packages/turf-boolean-touches/test/true/Point/MultiPolygon/PointTouchesMultipolygonHole.geojson b/src/boolean-touches/test/true/Point/MultiPolygon/PointTouchesMultipolygonHole.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Point/MultiPolygon/PointTouchesMultipolygonHole.geojson rename to src/boolean-touches/test/true/Point/MultiPolygon/PointTouchesMultipolygonHole.geojson diff --git a/packages/turf-boolean-touches/test/true/Point/Polygon/PointOnEdgePolygon.geojson b/src/boolean-touches/test/true/Point/Polygon/PointOnEdgePolygon.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Point/Polygon/PointOnEdgePolygon.geojson rename to src/boolean-touches/test/true/Point/Polygon/PointOnEdgePolygon.geojson diff --git a/packages/turf-boolean-touches/test/true/Point/Polygon/PointOnHole.geojson b/src/boolean-touches/test/true/Point/Polygon/PointOnHole.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Point/Polygon/PointOnHole.geojson rename to src/boolean-touches/test/true/Point/Polygon/PointOnHole.geojson diff --git a/packages/turf-boolean-touches/test/true/Point/Polygon/PointOnVerticePolygon.geojson b/src/boolean-touches/test/true/Point/Polygon/PointOnVerticePolygon.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Point/Polygon/PointOnVerticePolygon.geojson rename to src/boolean-touches/test/true/Point/Polygon/PointOnVerticePolygon.geojson diff --git a/packages/turf-boolean-touches/test/true/Polygon/LineString/PolygonTouchesLines.geojson b/src/boolean-touches/test/true/Polygon/LineString/PolygonTouchesLines.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Polygon/LineString/PolygonTouchesLines.geojson rename to src/boolean-touches/test/true/Polygon/LineString/PolygonTouchesLines.geojson diff --git a/packages/turf-boolean-touches/test/true/Polygon/MultiLineString/PolygonTouchesMultiline.geojson b/src/boolean-touches/test/true/Polygon/MultiLineString/PolygonTouchesMultiline.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Polygon/MultiLineString/PolygonTouchesMultiline.geojson rename to src/boolean-touches/test/true/Polygon/MultiLineString/PolygonTouchesMultiline.geojson diff --git a/packages/turf-boolean-touches/test/true/Polygon/MultiPoint/PolygonTouchesMultiPoint.geojson b/src/boolean-touches/test/true/Polygon/MultiPoint/PolygonTouchesMultiPoint.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Polygon/MultiPoint/PolygonTouchesMultiPoint.geojson rename to src/boolean-touches/test/true/Polygon/MultiPoint/PolygonTouchesMultiPoint.geojson diff --git a/packages/turf-boolean-touches/test/true/Polygon/MultiPolygon/PolyTouchMultiPolys.geojson b/src/boolean-touches/test/true/Polygon/MultiPolygon/PolyTouchMultiPolys.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Polygon/MultiPolygon/PolyTouchMultiPolys.geojson rename to src/boolean-touches/test/true/Polygon/MultiPolygon/PolyTouchMultiPolys.geojson diff --git a/packages/turf-boolean-touches/test/true/Polygon/Point/PolygonTouchesPoint.geojson b/src/boolean-touches/test/true/Polygon/Point/PolygonTouchesPoint.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Polygon/Point/PolygonTouchesPoint.geojson rename to src/boolean-touches/test/true/Polygon/Point/PolygonTouchesPoint.geojson diff --git a/packages/turf-boolean-touches/test/true/Polygon/Point/PolygonTouchesPointVertice.geojson b/src/boolean-touches/test/true/Polygon/Point/PolygonTouchesPointVertice.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Polygon/Point/PolygonTouchesPointVertice.geojson rename to src/boolean-touches/test/true/Polygon/Point/PolygonTouchesPointVertice.geojson diff --git a/packages/turf-boolean-touches/test/true/Polygon/Polygon/PolygonTouchesEdges.geojson b/src/boolean-touches/test/true/Polygon/Polygon/PolygonTouchesEdges.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Polygon/Polygon/PolygonTouchesEdges.geojson rename to src/boolean-touches/test/true/Polygon/Polygon/PolygonTouchesEdges.geojson diff --git a/packages/turf-boolean-touches/test/true/Polygon/Polygon/PolygonsTouchVertices.geojson b/src/boolean-touches/test/true/Polygon/Polygon/PolygonsTouchVertices.geojson similarity index 100% rename from packages/turf-boolean-touches/test/true/Polygon/Polygon/PolygonsTouchVertices.geojson rename to src/boolean-touches/test/true/Polygon/Polygon/PolygonsTouchVertices.geojson diff --git a/packages/turf-boolean-valid/bench.js b/src/boolean-valid/bench.js similarity index 100% rename from packages/turf-boolean-valid/bench.js rename to src/boolean-valid/bench.js diff --git a/src/boolean-valid/index.js b/src/boolean-valid/index.js new file mode 100644 index 0000000000..0276c61bdd --- /dev/null +++ b/src/boolean-valid/index.js @@ -0,0 +1,104 @@ +import { segmentEach } from '../meta'; +import { getGeom, getCoords, getType } from '../invariant'; +import { polygon, lineString } from '../helpers'; +import booleanDisjoint from '../boolean-disjoint'; +import booleanCrosses from '../boolean-crosses'; +import lineIntersect from '../line-intersect'; +import isPointOnLine from '../boolean-point-on-line'; + +/** + * booleanValid checks if the geometry is a valid according to the OGC Simple Feature Specification. + * + * @name booleanValid + * @param {Geometry|Feature} feature GeoJSON Feature or Geometry + * @returns {boolean} true/false + * @example + * var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); + * + * turf.booleanValid(line); // => true + * turf.booleanValid({foo: "bar"}); // => false + */ +export default function booleanValid(feature) { + // Automatic False + if (!feature.type) return false; + + // Parse GeoJSON + const geom = getGeom(feature); + const type = geom.type; + const coords = geom.coordinates; + + switch (type) { + case 'Point': + return coords.length > 1; + case 'MultiPoint': + for (var i = 0; i < coords.length; i++) { + if (coords[i].length < 2) return false; + } + return true; + case 'LineString': + if (coords.length < 2) return false + for (var i = 0; i < coords.length; i++) { + if (coords[i].length < 2) return false; + } + return true; + case 'MultiLineString': + if (coords.length < 2) return false + for (var i = 0; i < coords.length; i++) { + if (coords[i].length < 2) return false; + } + return true; + case 'Polygon': + for (var i = 0; i < geom.coordinates.length; i++) { + if (coords[i].length < 4) return false + if (!checkRingsClose(coords[i])) return false + if (checkRingsForSpikesPunctures(coords[i])) return false + if (i > 0) { + if (lineIntersect(polygon([coords[0]]), polygon([coords[i]])).features.length > 1) return false + } + } + return true + case 'MultiPolygon': + for (var i = 0; i < geom.coordinates.length; i++) { + var poly = geom.coordinates[i]; + + for (var ii = 0; ii < poly.length; ii++) { + if (poly[ii].length < 4) return false + if (!checkRingsClose(poly[ii])) return false + if (checkRingsForSpikesPunctures(poly[ii])) return false + if (ii === 0) { + if (!checkPolygonAgainstOthers(poly, geom.coordinates, i)) return false + } + if (ii > 0) { + if (lineIntersect(polygon([poly[0]]), polygon([poly[ii]])).features.length > 1) return false + } + } + } + return true + default: return false; + } +} + +function checkRingsClose(geom) { + return geom[0][0] === geom[geom.length - 1][0] || geom[0][1] === geom[geom.length - 1][1] +} + +function checkRingsForSpikesPunctures(geom) { + for (var i = 0; i < geom.length - 1; i++) { + var point = geom[i] + for (var ii = i + 1; ii < geom.length - 2; ii++) { + var seg = [geom[ii], geom[ii + 1]] + if (isPointOnLine(point, lineString(seg))) return true + } + } + return false +} + +function checkPolygonAgainstOthers(poly, geom, index) { + var polyToCheck = polygon(poly) + for (var i = index + 1; i < geom.length; i++) { + if (!booleanDisjoint(polyToCheck, polygon(geom[i]))) { + if (booleanCrosses(polyToCheck, lineString(geom[i][0]))) return false + } + } + return true +} \ No newline at end of file diff --git a/packages/turf-boolean-valid/test.js b/src/boolean-valid/test.js similarity index 100% rename from packages/turf-boolean-valid/test.js rename to src/boolean-valid/test.js diff --git a/packages/turf-boolean-valid/test/false/MultiPoint/multipoint.geojson b/src/boolean-valid/test/false/MultiPoint/multipoint.geojson similarity index 100% rename from packages/turf-boolean-valid/test/false/MultiPoint/multipoint.geojson rename to src/boolean-valid/test/false/MultiPoint/multipoint.geojson diff --git a/packages/turf-boolean-valid/test/false/MultiPolygon/multipoly-with-2-vertices-touching.geojson b/src/boolean-valid/test/false/MultiPolygon/multipoly-with-2-vertices-touching.geojson similarity index 100% rename from packages/turf-boolean-valid/test/false/MultiPolygon/multipoly-with-2-vertices-touching.geojson rename to src/boolean-valid/test/false/MultiPolygon/multipoly-with-2-vertices-touching.geojson diff --git a/packages/turf-boolean-valid/test/false/MultiPolygon/multipolygons-overlap.geojson b/src/boolean-valid/test/false/MultiPolygon/multipolygons-overlap.geojson similarity index 100% rename from packages/turf-boolean-valid/test/false/MultiPolygon/multipolygons-overlap.geojson rename to src/boolean-valid/test/false/MultiPolygon/multipolygons-overlap.geojson diff --git a/packages/turf-boolean-valid/test/false/MultiPolygon/not-enough-coords.geojson b/src/boolean-valid/test/false/MultiPolygon/not-enough-coords.geojson similarity index 100% rename from packages/turf-boolean-valid/test/false/MultiPolygon/not-enough-coords.geojson rename to src/boolean-valid/test/false/MultiPolygon/not-enough-coords.geojson diff --git a/packages/turf-boolean-valid/test/false/Point/point.geojson b/src/boolean-valid/test/false/Point/point.geojson similarity index 100% rename from packages/turf-boolean-valid/test/false/Point/point.geojson rename to src/boolean-valid/test/false/Point/point.geojson diff --git a/packages/turf-boolean-valid/test/false/Polygon/not-enough-coords.geojson b/src/boolean-valid/test/false/Polygon/not-enough-coords.geojson similarity index 100% rename from packages/turf-boolean-valid/test/false/Polygon/not-enough-coords.geojson rename to src/boolean-valid/test/false/Polygon/not-enough-coords.geojson diff --git a/packages/turf-boolean-valid/test/false/Polygon/polygon-with-hole-2-vertices-touching.geojson b/src/boolean-valid/test/false/Polygon/polygon-with-hole-2-vertices-touching.geojson similarity index 100% rename from packages/turf-boolean-valid/test/false/Polygon/polygon-with-hole-2-vertices-touching.geojson rename to src/boolean-valid/test/false/Polygon/polygon-with-hole-2-vertices-touching.geojson diff --git a/packages/turf-boolean-valid/test/false/Polygon/polygon-with-puncture.geojson b/src/boolean-valid/test/false/Polygon/polygon-with-puncture.geojson similarity index 100% rename from packages/turf-boolean-valid/test/false/Polygon/polygon-with-puncture.geojson rename to src/boolean-valid/test/false/Polygon/polygon-with-puncture.geojson diff --git a/packages/turf-boolean-valid/test/false/Polygon/polygon-with-spike.geojson b/src/boolean-valid/test/false/Polygon/polygon-with-spike.geojson similarity index 100% rename from packages/turf-boolean-valid/test/false/Polygon/polygon-with-spike.geojson rename to src/boolean-valid/test/false/Polygon/polygon-with-spike.geojson diff --git a/packages/turf-boolean-valid/test/true/LineString/linestring.geojson b/src/boolean-valid/test/true/LineString/linestring.geojson similarity index 100% rename from packages/turf-boolean-valid/test/true/LineString/linestring.geojson rename to src/boolean-valid/test/true/LineString/linestring.geojson diff --git a/packages/turf-boolean-valid/test/true/MultiLineString/multilinestring.geojson b/src/boolean-valid/test/true/MultiLineString/multilinestring.geojson similarity index 100% rename from packages/turf-boolean-valid/test/true/MultiLineString/multilinestring.geojson rename to src/boolean-valid/test/true/MultiLineString/multilinestring.geojson diff --git a/packages/turf-boolean-valid/test/true/MultiPoint/multipoint-with-z.geojson b/src/boolean-valid/test/true/MultiPoint/multipoint-with-z.geojson similarity index 100% rename from packages/turf-boolean-valid/test/true/MultiPoint/multipoint-with-z.geojson rename to src/boolean-valid/test/true/MultiPoint/multipoint-with-z.geojson diff --git a/packages/turf-boolean-valid/test/true/MultiPoint/multipoint.geojson b/src/boolean-valid/test/true/MultiPoint/multipoint.geojson similarity index 100% rename from packages/turf-boolean-valid/test/true/MultiPoint/multipoint.geojson rename to src/boolean-valid/test/true/MultiPoint/multipoint.geojson diff --git a/packages/turf-boolean-valid/test/true/MultiPolygon/multipolygon-touch.geojson b/src/boolean-valid/test/true/MultiPolygon/multipolygon-touch.geojson similarity index 100% rename from packages/turf-boolean-valid/test/true/MultiPolygon/multipolygon-touch.geojson rename to src/boolean-valid/test/true/MultiPolygon/multipolygon-touch.geojson diff --git a/packages/turf-boolean-valid/test/true/MultiPolygon/multipolygon-with-hole.geojson b/src/boolean-valid/test/true/MultiPolygon/multipolygon-with-hole.geojson similarity index 100% rename from packages/turf-boolean-valid/test/true/MultiPolygon/multipolygon-with-hole.geojson rename to src/boolean-valid/test/true/MultiPolygon/multipolygon-with-hole.geojson diff --git a/packages/turf-boolean-valid/test/true/MultiPolygon/multipolygon.geojson b/src/boolean-valid/test/true/MultiPolygon/multipolygon.geojson similarity index 100% rename from packages/turf-boolean-valid/test/true/MultiPolygon/multipolygon.geojson rename to src/boolean-valid/test/true/MultiPolygon/multipolygon.geojson diff --git a/packages/turf-boolean-valid/test/true/Point/point-with-z.geojson b/src/boolean-valid/test/true/Point/point-with-z.geojson similarity index 100% rename from packages/turf-boolean-valid/test/true/Point/point-with-z.geojson rename to src/boolean-valid/test/true/Point/point-with-z.geojson diff --git a/packages/turf-boolean-valid/test/true/Point/point.geojson b/src/boolean-valid/test/true/Point/point.geojson similarity index 100% rename from packages/turf-boolean-valid/test/true/Point/point.geojson rename to src/boolean-valid/test/true/Point/point.geojson diff --git a/packages/turf-boolean-valid/test/true/Polygon/polygon-internal-hole.geojson b/src/boolean-valid/test/true/Polygon/polygon-internal-hole.geojson similarity index 100% rename from packages/turf-boolean-valid/test/true/Polygon/polygon-internal-hole.geojson rename to src/boolean-valid/test/true/Polygon/polygon-internal-hole.geojson diff --git a/packages/turf-boolean-valid/test/true/Polygon/polygon-with-hole-1-vertice-touching.geojson b/src/boolean-valid/test/true/Polygon/polygon-with-hole-1-vertice-touching.geojson similarity index 100% rename from packages/turf-boolean-valid/test/true/Polygon/polygon-with-hole-1-vertice-touching.geojson rename to src/boolean-valid/test/true/Polygon/polygon-with-hole-1-vertice-touching.geojson diff --git a/packages/turf-boolean-valid/test/true/Polygon/polygon.geojson b/src/boolean-valid/test/true/Polygon/polygon.geojson similarity index 100% rename from packages/turf-boolean-valid/test/true/Polygon/polygon.geojson rename to src/boolean-valid/test/true/Polygon/polygon.geojson diff --git a/packages/turf-boolean-within/bench.js b/src/boolean-within/bench.js similarity index 100% rename from packages/turf-boolean-within/bench.js rename to src/boolean-within/bench.js diff --git a/packages/turf-boolean-within/digrams/esri-within.gif b/src/boolean-within/digrams/esri-within.gif similarity index 100% rename from packages/turf-boolean-within/digrams/esri-within.gif rename to src/boolean-within/digrams/esri-within.gif diff --git a/src/boolean-within/index.js b/src/boolean-within/index.js new file mode 100644 index 0000000000..c0f68f28fb --- /dev/null +++ b/src/boolean-within/index.js @@ -0,0 +1,222 @@ +import calcBbox from '../bbox'; +import booleanPointOnLine from '../boolean-point-on-line'; +import booleanPointInPolygon from '../boolean-point-in-polygon'; +import { getGeom, getType } from '../invariant'; + +/** + * Boolean-within returns true if the first geometry is completely within the second geometry. + * The interiors of both geometries must intersect and, the interior and boundary of the primary (geometry a) + * must not intersect the exterior of the secondary (geometry b). + * Boolean-within returns the exact opposite result of the `@turf/boolean-contains`. + * + * @name booleanWithin + * @param {Geometry|Feature} feature1 GeoJSON Feature or Geometry + * @param {Geometry|Feature} feature2 GeoJSON Feature or Geometry + * @returns {boolean} true/false + * @example + * var line = turf.lineString([[1, 1], [1, 2], [1, 3], [1, 4]]); + * var point = turf.point([1, 2]); + * + * turf.booleanWithin(point, line); + * //=true + */ +function booleanWithin(feature1, feature2) { + var geom1 = getGeom(feature1); + var geom2 = getGeom(feature2); + var type1 = geom1.type; + var type2 = geom2.type; + + switch (type1) { + case 'Point': + switch (type2) { + case 'MultiPoint': + return isPointInMultiPoint(geom1, geom2); + case 'LineString': + return booleanPointOnLine(geom1, geom2, {ignoreEndVertices: true}); + case 'Polygon': + case 'MultiPolygon': + return booleanPointInPolygon(geom1, geom2, {ignoreBoundary: true}); + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + case 'MultiPoint': + switch (type2) { + case 'MultiPoint': + return isMultiPointInMultiPoint(geom1, geom2); + case 'LineString': + return isMultiPointOnLine(geom1, geom2); + case 'Polygon': + case 'MultiPolygon': + return isMultiPointInPoly(geom1, geom2); + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + case 'LineString': + switch (type2) { + case 'LineString': + return isLineOnLine(geom1, geom2); + case 'Polygon': + case 'MultiPolygon': + return isLineInPoly(geom1, geom2); + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + case 'Polygon': + switch (type2) { + case 'Polygon': + case 'MultiPolygon': + return isPolyInPoly(geom1, geom2); + default: + throw new Error('feature2 ' + type2 + ' geometry not supported'); + } + default: + throw new Error('feature1 ' + type1 + ' geometry not supported'); + } +} + +function isPointInMultiPoint(point, multiPoint) { + var i; + var output = false; + for (i = 0; i < multiPoint.coordinates.length; i++) { + if (compareCoords(multiPoint.coordinates[i], point.coordinates)) { + output = true; + break; + } + } + return output; +} + +function isMultiPointInMultiPoint(multiPoint1, multiPoint2) { + for (var i = 0; i < multiPoint1.coordinates.length; i++) { + var anyMatch = false; + for (var i2 = 0; i2 < multiPoint2.coordinates.length; i2++) { + if (compareCoords(multiPoint1.coordinates[i], multiPoint2.coordinates[i2])) { + anyMatch = true; + } + } + if (!anyMatch) { + return false; + } + } + return true; +} + +function isMultiPointOnLine(multiPoint, lineString) { + var foundInsidePoint = false; + + for (var i = 0; i < multiPoint.coordinates.length; i++) { + if (!booleanPointOnLine(multiPoint.coordinates[i], lineString)) { + return false; + } + if (!foundInsidePoint) { + foundInsidePoint = booleanPointOnLine(multiPoint.coordinates[i], lineString, {ignoreEndVertices: true}); + } + } + return foundInsidePoint; +} + +function isMultiPointInPoly(multiPoint, polygon) { + var output = true; + var oneInside = false; + for (var i = 0; i < multiPoint.coordinates.length; i++) { + var isInside = booleanPointInPolygon(multiPoint.coordinates[1], polygon); + if (!isInside) { + output = false; + break; + } + if (!oneInside) { + isInside = booleanPointInPolygon(multiPoint.coordinates[1], polygon, {ignoreBoundary: true}); + } + } + return output && isInside; +} + +function isLineOnLine(lineString1, lineString2) { + for (var i = 0; i < lineString1.coordinates.length; i++) { + if (!booleanPointOnLine(lineString1.coordinates[i], lineString2)) { + return false; + } + } + return true; +} + +function isLineInPoly(linestring, polygon) { + var polyBbox = calcBbox(polygon); + var lineBbox = calcBbox(linestring); + if (!doBBoxOverlap(polyBbox, lineBbox)) { + return false; + } + var foundInsidePoint = false; + + for (var i = 0; i < linestring.coordinates.length - 1; i++) { + if (!booleanPointInPolygon(linestring.coordinates[i], polygon)) { + return false; + } + if (!foundInsidePoint) { + foundInsidePoint = booleanPointInPolygon(linestring.coordinates[i], polygon, {ignoreBoundary: true}); + } + if (!foundInsidePoint) { + var midpoint = getMidpoint(linestring.coordinates[i], linestring.coordinates[i + 1]); + foundInsidePoint = booleanPointInPolygon(midpoint, polygon, {ignoreBoundary: true}); + + } + } + return foundInsidePoint; +} + +/** + * Is Polygon2 in Polygon1 + * Only takes into account outer rings + * + * @private + * @param {Geometry|Feature} feature1 Polygon1 + * @param {Geometry|Feature} feature2 Polygon2 + * @returns {boolean} true/false + */ +function isPolyInPoly(feature1, feature2) { + var poly1Bbox = calcBbox(feature1); + var poly2Bbox = calcBbox(feature2); + if (!doBBoxOverlap(poly2Bbox, poly1Bbox)) { + return false; + } + for (var i = 0; i < feature1.coordinates[0].length; i++) { + if (!booleanPointInPolygon(feature1.coordinates[0][i], feature2)) { + return false; + } + } + return true; +} + +function doBBoxOverlap(bbox1, bbox2) { + if (bbox1[0] > bbox2[0]) return false; + if (bbox1[2] < bbox2[2]) return false; + if (bbox1[1] > bbox2[1]) return false; + if (bbox1[3] < bbox2[3]) return false; + return true; +} + +/** + * compareCoords + * + * @private + * @param {Position} pair1 point [x,y] + * @param {Position} pair2 point [x,y] + * @returns {boolean} true/false if coord pairs match + */ +function compareCoords(pair1, pair2) { + return pair1[0] === pair2[0] && pair1[1] === pair2[1]; +} + +/** + * getMidpoint + * + * @private + * @param {Position} pair1 point [x,y] + * @param {Position} pair2 point [x,y] + * @returns {Position} midpoint of pair1 and pair2 + */ +function getMidpoint(pair1, pair2) { + return [(pair1[0] + pair2[0]) / 2, (pair1[1] + pair2[1]) / 2]; +} + +export default booleanWithin; diff --git a/packages/turf-boolean-within/test.js b/src/boolean-within/test.js similarity index 100% rename from packages/turf-boolean-within/test.js rename to src/boolean-within/test.js diff --git a/packages/turf-boolean-within/test/false/LineString/LineString/LineIsNotWithinLine.geojson b/src/boolean-within/test/false/LineString/LineString/LineIsNotWithinLine.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/LineString/LineString/LineIsNotWithinLine.geojson rename to src/boolean-within/test/false/LineString/LineString/LineIsNotWithinLine.geojson diff --git a/packages/turf-boolean-within/test/false/LineString/Polygon/LineIsNotWIthinPolygon.geojson b/src/boolean-within/test/false/LineString/Polygon/LineIsNotWIthinPolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/LineString/Polygon/LineIsNotWIthinPolygon.geojson rename to src/boolean-within/test/false/LineString/Polygon/LineIsNotWIthinPolygon.geojson diff --git a/packages/turf-boolean-within/test/false/LineString/Polygon/LineIsNotWIthinPolygonBoundary.geojson b/src/boolean-within/test/false/LineString/Polygon/LineIsNotWIthinPolygonBoundary.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/LineString/Polygon/LineIsNotWIthinPolygonBoundary.geojson rename to src/boolean-within/test/false/LineString/Polygon/LineIsNotWIthinPolygonBoundary.geojson diff --git a/packages/turf-boolean-within/test/false/MultiLineString/MultiPolygon/skip-multilinestring-not-within-multipolygon.geojson b/src/boolean-within/test/false/MultiLineString/MultiPolygon/skip-multilinestring-not-within-multipolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/MultiLineString/MultiPolygon/skip-multilinestring-not-within-multipolygon.geojson rename to src/boolean-within/test/false/MultiLineString/MultiPolygon/skip-multilinestring-not-within-multipolygon.geojson diff --git a/packages/turf-boolean-within/test/false/MultiPoint/LineString/MultiPointsIsNotWIthinLine.geojson b/src/boolean-within/test/false/MultiPoint/LineString/MultiPointsIsNotWIthinLine.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/MultiPoint/LineString/MultiPointsIsNotWIthinLine.geojson rename to src/boolean-within/test/false/MultiPoint/LineString/MultiPointsIsNotWIthinLine.geojson diff --git a/packages/turf-boolean-within/test/false/MultiPoint/LineString/MultiPointsOnLineEndsIsNotWIthinLine.geojson b/src/boolean-within/test/false/MultiPoint/LineString/MultiPointsOnLineEndsIsNotWIthinLine.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/MultiPoint/LineString/MultiPointsOnLineEndsIsNotWIthinLine.geojson rename to src/boolean-within/test/false/MultiPoint/LineString/MultiPointsOnLineEndsIsNotWIthinLine.geojson diff --git a/packages/turf-boolean-within/test/false/MultiPoint/MultiPoint/MultiPointIsNotWithinMultiPoint.geojson b/src/boolean-within/test/false/MultiPoint/MultiPoint/MultiPointIsNotWithinMultiPoint.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/MultiPoint/MultiPoint/MultiPointIsNotWithinMultiPoint.geojson rename to src/boolean-within/test/false/MultiPoint/MultiPoint/MultiPointIsNotWithinMultiPoint.geojson diff --git a/packages/turf-boolean-within/test/false/MultiPoint/MultiPolygon/multipoint-not-within-multipolygon.geojson b/src/boolean-within/test/false/MultiPoint/MultiPolygon/multipoint-not-within-multipolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/MultiPoint/MultiPolygon/multipoint-not-within-multipolygon.geojson rename to src/boolean-within/test/false/MultiPoint/MultiPolygon/multipoint-not-within-multipolygon.geojson diff --git a/packages/turf-boolean-within/test/false/MultiPoint/Polygon/MultiPointAllOnBoundaryIsNotWithinPolygon.geojson b/src/boolean-within/test/false/MultiPoint/Polygon/MultiPointAllOnBoundaryIsNotWithinPolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/MultiPoint/Polygon/MultiPointAllOnBoundaryIsNotWithinPolygon.geojson rename to src/boolean-within/test/false/MultiPoint/Polygon/MultiPointAllOnBoundaryIsNotWithinPolygon.geojson diff --git a/packages/turf-boolean-within/test/false/MultiPoint/Polygon/MultiPointIsNotWithinPolygon.geojson b/src/boolean-within/test/false/MultiPoint/Polygon/MultiPointIsNotWithinPolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/MultiPoint/Polygon/MultiPointIsNotWithinPolygon.geojson rename to src/boolean-within/test/false/MultiPoint/Polygon/MultiPointIsNotWithinPolygon.geojson diff --git a/packages/turf-boolean-within/test/false/Point/LineString/PointIsNotWithinLine.geojson b/src/boolean-within/test/false/Point/LineString/PointIsNotWithinLine.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/Point/LineString/PointIsNotWithinLine.geojson rename to src/boolean-within/test/false/Point/LineString/PointIsNotWithinLine.geojson diff --git a/packages/turf-boolean-within/test/false/Point/LineString/PointIsNotWithinLineBecauseOnEnd.geojson b/src/boolean-within/test/false/Point/LineString/PointIsNotWithinLineBecauseOnEnd.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/Point/LineString/PointIsNotWithinLineBecauseOnEnd.geojson rename to src/boolean-within/test/false/Point/LineString/PointIsNotWithinLineBecauseOnEnd.geojson diff --git a/packages/turf-boolean-within/test/false/Point/LineString/PointOnEndIsWithinLinestring.geojson b/src/boolean-within/test/false/Point/LineString/PointOnEndIsWithinLinestring.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/Point/LineString/PointOnEndIsWithinLinestring.geojson rename to src/boolean-within/test/false/Point/LineString/PointOnEndIsWithinLinestring.geojson diff --git a/packages/turf-boolean-within/test/false/Point/MultiPoint/PointIsNotWithinMultiPoint.geojson b/src/boolean-within/test/false/Point/MultiPoint/PointIsNotWithinMultiPoint.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/Point/MultiPoint/PointIsNotWithinMultiPoint.geojson rename to src/boolean-within/test/false/Point/MultiPoint/PointIsNotWithinMultiPoint.geojson diff --git a/packages/turf-boolean-within/test/false/Point/MultiPolygon/point-not-within-multipolygon.geojson b/src/boolean-within/test/false/Point/MultiPolygon/point-not-within-multipolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/Point/MultiPolygon/point-not-within-multipolygon.geojson rename to src/boolean-within/test/false/Point/MultiPolygon/point-not-within-multipolygon.geojson diff --git a/packages/turf-boolean-within/test/false/Point/Polygon/PointIsNotWithinPolygon.geojson b/src/boolean-within/test/false/Point/Polygon/PointIsNotWithinPolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/Point/Polygon/PointIsNotWithinPolygon.geojson rename to src/boolean-within/test/false/Point/Polygon/PointIsNotWithinPolygon.geojson diff --git a/packages/turf-boolean-within/test/false/Point/Polygon/PointOnPolygonBoundary.geojson b/src/boolean-within/test/false/Point/Polygon/PointOnPolygonBoundary.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/Point/Polygon/PointOnPolygonBoundary.geojson rename to src/boolean-within/test/false/Point/Polygon/PointOnPolygonBoundary.geojson diff --git a/packages/turf-boolean-within/test/false/Polygon/MultiPolygon/polygon-not-within-multipolygon.geojson b/src/boolean-within/test/false/Polygon/MultiPolygon/polygon-not-within-multipolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/Polygon/MultiPolygon/polygon-not-within-multipolygon.geojson rename to src/boolean-within/test/false/Polygon/MultiPolygon/polygon-not-within-multipolygon.geojson diff --git a/packages/turf-boolean-within/test/false/Polygon/Polygon/Polygon-Polygon.geojson b/src/boolean-within/test/false/Polygon/Polygon/Polygon-Polygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/false/Polygon/Polygon/Polygon-Polygon.geojson rename to src/boolean-within/test/false/Polygon/Polygon/Polygon-Polygon.geojson diff --git a/packages/turf-boolean-within/test/true/LineString/LineString/LineIsWithinLine.geojson b/src/boolean-within/test/true/LineString/LineString/LineIsWithinLine.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/LineString/LineString/LineIsWithinLine.geojson rename to src/boolean-within/test/true/LineString/LineString/LineIsWithinLine.geojson diff --git a/packages/turf-boolean-within/test/true/LineString/LineString/LinesExactSame.geojson b/src/boolean-within/test/true/LineString/LineString/LinesExactSame.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/LineString/LineString/LinesExactSame.geojson rename to src/boolean-within/test/true/LineString/LineString/LinesExactSame.geojson diff --git a/packages/turf-boolean-within/test/true/LineString/Polygon/LineIsContainedByPolygon.geojson b/src/boolean-within/test/true/LineString/Polygon/LineIsContainedByPolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/LineString/Polygon/LineIsContainedByPolygon.geojson rename to src/boolean-within/test/true/LineString/Polygon/LineIsContainedByPolygon.geojson diff --git a/packages/turf-boolean-within/test/true/LineString/Polygon/LineIsContainedByPolygonWithNoInternalVertices.geojson b/src/boolean-within/test/true/LineString/Polygon/LineIsContainedByPolygonWithNoInternalVertices.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/LineString/Polygon/LineIsContainedByPolygonWithNoInternalVertices.geojson rename to src/boolean-within/test/true/LineString/Polygon/LineIsContainedByPolygonWithNoInternalVertices.geojson diff --git a/packages/turf-boolean-within/test/true/MultiLineString/MultiPolygon/skip-multilinestring-within-multipolygon.geojson b/src/boolean-within/test/true/MultiLineString/MultiPolygon/skip-multilinestring-within-multipolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/MultiLineString/MultiPolygon/skip-multilinestring-within-multipolygon.geojson rename to src/boolean-within/test/true/MultiLineString/MultiPolygon/skip-multilinestring-within-multipolygon.geojson diff --git a/packages/turf-boolean-within/test/true/MultiPoint/LineString/MultipointsIsWithinLine.geojson b/src/boolean-within/test/true/MultiPoint/LineString/MultipointsIsWithinLine.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/MultiPoint/LineString/MultipointsIsWithinLine.geojson rename to src/boolean-within/test/true/MultiPoint/LineString/MultipointsIsWithinLine.geojson diff --git a/packages/turf-boolean-within/test/true/MultiPoint/MultiPoint/MultiPointsWithinMultiPoints.geojson b/src/boolean-within/test/true/MultiPoint/MultiPoint/MultiPointsWithinMultiPoints.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/MultiPoint/MultiPoint/MultiPointsWithinMultiPoints.geojson rename to src/boolean-within/test/true/MultiPoint/MultiPoint/MultiPointsWithinMultiPoints.geojson diff --git a/packages/turf-boolean-within/test/true/MultiPoint/MultiPolygon/multipoint-within-multipolygon.geojson b/src/boolean-within/test/true/MultiPoint/MultiPolygon/multipoint-within-multipolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/MultiPoint/MultiPolygon/multipoint-within-multipolygon.geojson rename to src/boolean-within/test/true/MultiPoint/MultiPolygon/multipoint-within-multipolygon.geojson diff --git a/packages/turf-boolean-within/test/true/MultiPoint/Polygon/MultiPointIsWithinPolygon.geojson b/src/boolean-within/test/true/MultiPoint/Polygon/MultiPointIsWithinPolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/MultiPoint/Polygon/MultiPointIsWithinPolygon.geojson rename to src/boolean-within/test/true/MultiPoint/Polygon/MultiPointIsWithinPolygon.geojson diff --git a/packages/turf-boolean-within/test/true/MultiPolygon/MultiPolygon/skip-multipolygon-within-multipolygon.geojson b/src/boolean-within/test/true/MultiPolygon/MultiPolygon/skip-multipolygon-within-multipolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/MultiPolygon/MultiPolygon/skip-multipolygon-within-multipolygon.geojson rename to src/boolean-within/test/true/MultiPolygon/MultiPolygon/skip-multipolygon-within-multipolygon.geojson diff --git a/packages/turf-boolean-within/test/true/Point/LineString/PointIsWithinLine.geojson b/src/boolean-within/test/true/Point/LineString/PointIsWithinLine.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/Point/LineString/PointIsWithinLine.geojson rename to src/boolean-within/test/true/Point/LineString/PointIsWithinLine.geojson diff --git a/packages/turf-boolean-within/test/true/Point/MultiPoint/PointIsWithinMultiPoint.geojson b/src/boolean-within/test/true/Point/MultiPoint/PointIsWithinMultiPoint.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/Point/MultiPoint/PointIsWithinMultiPoint.geojson rename to src/boolean-within/test/true/Point/MultiPoint/PointIsWithinMultiPoint.geojson diff --git a/packages/turf-boolean-within/test/true/Point/MultiPolygon/point-within-multipolygon.geojson b/src/boolean-within/test/true/Point/MultiPolygon/point-within-multipolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/Point/MultiPolygon/point-within-multipolygon.geojson rename to src/boolean-within/test/true/Point/MultiPolygon/point-within-multipolygon.geojson diff --git a/packages/turf-boolean-within/test/true/Point/Polygon/PointIsWithinPolygon.geojson b/src/boolean-within/test/true/Point/Polygon/PointIsWithinPolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/Point/Polygon/PointIsWithinPolygon.geojson rename to src/boolean-within/test/true/Point/Polygon/PointIsWithinPolygon.geojson diff --git a/packages/turf-boolean-within/test/true/Polygon/MultiPolygon/polygon-within-multipolygon.geojson b/src/boolean-within/test/true/Polygon/MultiPolygon/polygon-within-multipolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/Polygon/MultiPolygon/polygon-within-multipolygon.geojson rename to src/boolean-within/test/true/Polygon/MultiPolygon/polygon-within-multipolygon.geojson diff --git a/packages/turf-boolean-within/test/true/Polygon/Polygon/PolygonIsWIthinPolygon.geojson b/src/boolean-within/test/true/Polygon/Polygon/PolygonIsWIthinPolygon.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/Polygon/Polygon/PolygonIsWIthinPolygon.geojson rename to src/boolean-within/test/true/Polygon/Polygon/PolygonIsWIthinPolygon.geojson diff --git a/packages/turf-boolean-within/test/true/Polygon/Polygon/PolygonsExactSameShape.geojson b/src/boolean-within/test/true/Polygon/Polygon/PolygonsExactSameShape.geojson similarity index 100% rename from packages/turf-boolean-within/test/true/Polygon/Polygon/PolygonsExactSameShape.geojson rename to src/boolean-within/test/true/Polygon/Polygon/PolygonsExactSameShape.geojson diff --git a/src/buffer/bench.js b/src/buffer/bench.js new file mode 100644 index 0000000000..60d83fe757 --- /dev/null +++ b/src/buffer/bench.js @@ -0,0 +1,54 @@ +import fs from 'fs'; +import path from 'path'; +import load from 'load-json-file'; +import Benchmark from 'benchmark'; +import buffer from './'; + +const directory = path.join(__dirname, 'test', 'in') + path.sep; +const fixtures = fs.readdirSync(directory).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directory + filename) + }; +}); + +/** + * Benchmark Results + * + * feature-collection-points: 139.101ms + * geometry-collection-points: 20.334ms + * issue-#783: 33.209ms + * linestring: 6.371ms + * multi-linestring: 48.786ms + * multi-point: 7.627ms + * multi-polygon: 38.921ms + * negative-buffer: 5.621ms + * north-latitude-points: 71.144ms + * northern-polygon: 2.644ms + * point: 8.155ms + * polygon-with-holes: 6.965ms + * feature-collection-points x 722 ops/sec ±14.28% (65 runs sampled) + * geometry-collection-points x 1,314 ops/sec ±7.87% (66 runs sampled) + * issue-#783 x 1,404 ops/sec ±6.81% (64 runs sampled) + * linestring x 2,936 ops/sec ±6.94% (72 runs sampled) + * multi-linestring x 623 ops/sec ±4.35% (79 runs sampled) + * multi-point x 1,735 ops/sec ±8.60% (65 runs sampled) + * multi-polygon x 1,125 ops/sec ±3.93% (80 runs sampled) + * north-latitude-points x 1,649 ops/sec ±2.09% (86 runs sampled) + * northern-polygon x 4,658 ops/sec ±3.08% (78 runs sampled) + * point x 65,020 ops/sec ±1.29% (85 runs sampled) + * polygon-with-holes x 2,795 ops/sec ±2.98% (81 runs sampled) + */ +const suite = new Benchmark.Suite('turf-buffer'); +for (const {name, geojson} of fixtures) { + console.time(name); + buffer(geojson, 50, {units: 'miles'}); + console.timeEnd(name); + suite.add(name, () => buffer(geojson, 50, {units: 'miles'})); +} + +suite + .on('cycle', e => console.log(String(e.target))) + .on('complete', () => {}) + .run(); diff --git a/src/buffer/index.d.ts b/src/buffer/index.d.ts new file mode 100644 index 0000000000..eb6d0b8bd3 --- /dev/null +++ b/src/buffer/index.d.ts @@ -0,0 +1,31 @@ + +import { + Point, + LineString, + Polygon, + MultiPoint, + MultiLineString, + MultiPolygon, + GeometryObject, + GeometryCollection, + Feature, + FeatureCollection, + Units, +} from '../helpers'; + +interface Options { + units?: Units; + steps?: number +} + +/** + * http://turfjs.org/docs/#buffer + */ +declare function buffer(feature: Feature|Geom, radius?: number, options?: Options): Feature; +declare function buffer(feature: Feature|Geom, radius?: number, options?: Options): Feature; +declare function buffer(feature: FeatureCollection, radius?: number, options?: Options): FeatureCollection; +declare function buffer(feature: FeatureCollection, radius?: number, options?: Options): FeatureCollection; +declare function buffer(feature: FeatureCollection | Feature | GeometryCollection, radius?: number, options?: Options): FeatureCollection; +declare function buffer(feature: Feature | GeometryObject, radius?: number, options?: Options): Feature; + +export default buffer; diff --git a/src/buffer/index.js b/src/buffer/index.js new file mode 100644 index 0000000000..05584a8839 --- /dev/null +++ b/src/buffer/index.js @@ -0,0 +1,270 @@ +import clone from '../clone'; +import { BufferOp, GeoJSONReader, GeoJSONWriter } from 'turf-jsts'; +import centerOfMass from '../center-of-mass'; +import { geomEach, coordEach, featureEach } from '../meta'; +import { featureCollection, + radiansToLength, + lengthToRadians, + feature, + degreesToRadians, radiansToDegrees, checkIfOptionsExist } from '../helpers'; + +/** + * Calculates a buffer for input features for a given radius. Units supported are miles, kilometers, and degrees. + * + * When using a negative radius, the resulting geometry may be invalid if + * it's too small compared to the radius magnitude. If the input is a + * FeatureCollection, only valid members will be returned in the output + * FeatureCollection - i.e., the output collection may have fewer members than + * the input, or even be empty. + * + * @name buffer + * @param {FeatureCollection|Geometry|Feature} geojson input to be buffered + * @param {number} radius distance to draw the buffer (negative values are allowed) + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units="kilometers"] any of the options supported by turf units + * @returns {FeatureCollection|Feature|undefined} buffered features + * @example + * var point = turf.point([-90.548630, 14.616599]); + * var buffered = turf.buffer(point, 500, {units: 'miles'}); + * + * //addToMap + * var addToMap = [point, buffered] + */ +function buffer(geojson, radius, options) { + + // Optional params + options = checkIfOptionsExist(options); + var units = options.units || 'kilometers'; + // var steps = options.steps || 64; + + // validation + if (!geojson) throw new Error('geojson is required'); + if (typeof options !== 'object') throw new Error('options must be an object'); + // if (typeof steps !== 'number') throw new Error('steps must be an number'); + + // Allow negative buffers ("erosion") or zero-sized buffers ("repair geometry") + if (radius === undefined) throw new Error('radius is required'); + // if (steps <= 0) throw new Error('steps must be greater than 0'); + + var distance = radiansToLength(lengthToRadians(radius, units), 'meters'); + var results = []; + + switch (geojson.type) { + case 'GeometryCollection': + geomEach(geojson, function (geometry) { + var buffered = bufferFeature(geometry, distance); + if (buffered) results.push(buffered); + }); + return featureCollection(results); + case 'FeatureCollection': + featureEach(geojson, function (feature) { + var buffered = bufferFeature(feature, distance); + if (buffered) results.push(buffered); + }); + return featureCollection(results); + } + return bufferFeature(geojson, distance); +} + +/** + * Buffer single Feature/Geometry + * + * @private + * @param {Feature} geojson input to be buffered + * @param {number} radius distance to draw the buffer + * @param {number} [steps=64] number of steps + * @returns {Feature} buffered feature + */ +function bufferFeature(geojson, radius) { + var properties = geojson.properties || {}; + var geometry = (geojson.type === 'Feature') ? clone(geojson.geometry) : clone(geojson); + + var centroid = centerOfMass(geometry); + var utmZone = checkUtmZone(centroid.geometry); + reprojectFeature(geometry, utmZone, true); + + var reader = new GeoJSONReader(); + var geom = reader.read(geometry); + var buffered = BufferOp.bufferOp(geom, radius); + var writer = new GeoJSONWriter(); + buffered = writer.write(buffered); + + if (coordsIsNaN(buffered.coordinates)) return undefined; + reprojectFeature(buffered, utmZone, false); + + return (buffered.geometry) ? buffered : feature(buffered, properties); +} + +export default buffer; + +/** + * Coordinates isNaN + * + * @private + * @param {Array} coords GeoJSON Coordinates + * @returns {boolean} if NaN exists + */ +function coordsIsNaN(coords) { + if (Array.isArray(coords[0])) return coordsIsNaN(coords[0]); + return isNaN(coords[0]); +} + +function reprojectFeature(feature, utmZone, toUtm) { + coordEach(feature, function (coord, coordIndex) { //eslint-disable-line + var blah = toUtm ? convertCoordToUtm(coord[0], coord[1], utmZone) : convertUtmToLatLon(coord[0], coord[1], utmZone); + coord.length = 0; + coord.push(blah[0], blah[1]); + }, false); +} + +function checkUtmZone(centerPoint) { + + const lat = centerPoint.coordinates[1]; + const lon = centerPoint.coordinates[0]; + let zoneNumber = Math.floor((lon + 180) / 6) + 1; + let hemisphere = 'N'; + + if (lon === 180) zoneNumber = 60; + if (lat < 0.0) hemisphere = 'S'; + + if (lat >= 56.0 && lat < 64.0 && lon >= 3.0 && lon < 12.0) zoneNumber = 32; + + return {zoneNumber, hemisphere}; +} + +function convertCoordToUtm(lon, lat, zone) { + + let falseEasting = 500e3; + let falseNorthing = 10000e3; + let λ0 = degreesToRadians(((zone.zoneNumber - 1) * 6 - 180 + 3)); + + let mgrsLatBands = 'CDEFGHJKLMNPQRSTUVWXX'; // X is repeated for 80-84°N + let latBand = mgrsLatBands.charAt(Math.floor(lat / 8 + 10)); + + // adjust zone & central meridian for Norway + if (zone === 31 && latBand === 'V' && lon >= 3) { zone++; degreesToRadians(λ0 += 6); } + // adjust zone & central meridian for Svalbard + if (zone === 32 && latBand === 'X' && lon < 9) { zone--; degreesToRadians(λ0 -= 6); } + if (zone === 32 && latBand === 'X' && lon >= 9) { zone++; degreesToRadians(λ0 += 6); } + if (zone === 34 && latBand === 'X' && lon < 21) { zone--; degreesToRadians(λ0 -= 6); } + if (zone === 34 && latBand === 'X' && lon >= 21) { zone++; degreesToRadians(λ0 += 6); } + if (zone === 36 && latBand === 'X' && lon < 33) { zone--; degreesToRadians(λ0 -= 6); } + if (zone === 36 && latBand === 'X' && lon >= 33) { zone++; degreesToRadians(λ0 += 6); } + + var φ = degreesToRadians(lat); // latitude ± from equator + var λ = degreesToRadians(lon) - λ0; // longitude ± from central meridian + + let a = 6378137; + let f = 1 / 298.257223563; + // WGS 84: a = 6378137, b = 6356752.314245, f = 1/298.257223563; + + let k0 = 0.9996; // UTM scale on the central meridian + + // ---- easting, northing: Karney 2011 Eq 7-14, 29, 35: + + let e = Math.sqrt(f * (2 - f)); // eccentricity + let n = f / (2 - f); // 3rd flattening + let n2 = n * n, n3 = n * n2, n4 = n * n3, n5 = n * n4, n6 = n * n5; // TODO: compare Horner-form accuracy? + + let cosλ = Math.cos(λ), sinλ = Math.sin(λ); + + let τ = Math.tan(φ); // τ ≡ tanφ, τʹ ≡ tanφʹ; prime (ʹ) indicates angles on the conformal sphere + let σ = Math.sinh(e * Math.atanh(e * τ / Math.sqrt(1 + τ * τ))); + + let τʹ = τ * Math.sqrt(1 + σ * σ) - σ * Math.sqrt(1 + τ * τ); + + let ξʹ = Math.atan2(τʹ, cosλ); + let ηʹ = Math.asinh(sinλ / Math.sqrt(τʹ * τʹ + cosλ * cosλ)); + + let A = a / (1 + n) * (1 + 1 / 4 * n2 + 1 / 64 * n4 + 1 / 256 * n6); // 2πA is the circumference of a meridian + + let α = [null, // note α is one-based array (6th order Krüger expressions) + 1 / 2 * n - 2 / 3 * n2 + 5 / 16 * n3 + 41 / 180 * n4 - 127 / 288 * n5 + 7891 / 37800 * n6, + 13 / 48 * n2 - 3 / 5 * n3 + 557 / 1440 * n4 + 281 / 630 * n5 - 1983433 / 1935360 * n6, + 61 / 240 * n3 - 103 / 140 * n4 + 15061 / 26880 * n5 + 167603 / 181440 * n6, + 49561 / 161280 * n4 - 179 / 168 * n5 + 6601661 / 7257600 * n6, + 34729 / 80640 * n5 - 3418889 / 1995840 * n6, + 212378941 / 319334400 * n6]; + + let ξ = ξʹ; + for (let j = 1; j <= 6; j++) ξ += α[j] * Math.sin(2 * j * ξʹ) * Math.cosh(2 * j * ηʹ); + + let η = ηʹ; + for (let j = 1; j <= 6; j++) η += α[j] * Math.cos(2 * j * ξʹ) * Math.sinh(2 * j * ηʹ); + + let x = k0 * A * η; + let y = k0 * A * ξ; + + x = x + falseEasting; + if (y < 0) y = y + falseNorthing; + + return [y, x]; +} + +function convertUtmToLatLon(y, x, zone) { + var z = zone.zoneNumber; + var h = zone.hemisphere; + + var falseEasting = 500e3, falseNorthing = 10000e3; + + var a = 6378137, f = 1 / 298.257223563; + + var k0 = 0.9996; // UTM scale on the central meridian + + x = x - falseEasting; // make x ± relative to central meridian + y = h === 'S' ? y - falseNorthing : y; // make y ± relative to equator + + // ---- from Karney 2011 Eq 15-22, 36: + + var e = Math.sqrt(f * (2 - f)); // eccentricity + var n = f / (2 - f); // 3rd flattening + var n2 = n * n, n3 = n * n2, n4 = n * n3, n5 = n * n4, n6 = n * n5; + + var A = a / (1 + n) * (1 + 1 / 4 * n2 + 1 / 64 * n4 + 1 / 256 * n6); // 2πA is the circumference of a meridian + + var η = x / (k0 * A); + var ξ = y / (k0 * A); + + var β = [null, // note β is one-based array (6th order Krüger expressions) + 1 / 2 * n - 2 / 3 * n2 + 37 / 96 * n3 - 1 / 360 * n4 - 81 / 512 * n5 + 96199 / 604800 * n6, + 1 / 48 * n2 + 1 / 15 * n3 - 437 / 1440 * n4 + 46 / 105 * n5 - 1118711 / 3870720 * n6, + 17 / 480 * n3 - 37 / 840 * n4 - 209 / 4480 * n5 + 5569 / 90720 * n6, + 4397 / 161280 * n4 - 11 / 504 * n5 - 830251 / 7257600 * n6, + 4583 / 161280 * n5 - 108847 / 3991680 * n6, + 20648693 / 638668800 * n6]; + + var ξʹ = ξ; + for (var j = 1; j <= 6; j++) ξʹ -= β[j] * Math.sin(2 * j * ξ) * Math.cosh(2 * j * η); + + var ηʹ = η; + for (var j = 1; j <= 6; j++) ηʹ -= β[j] * Math.cos(2 * j * ξ) * Math.sinh(2 * j * η); //eslint-disable-line + + var sinhηʹ = Math.sinh(ηʹ); + var sinξʹ = Math.sin(ξʹ), cosξʹ = Math.cos(ξʹ); + + var τʹ = sinξʹ / Math.sqrt(sinhηʹ * sinhηʹ + cosξʹ * cosξʹ); + + var τi = τʹ; + do { + var σi = Math.sinh(e * Math.atanh(e * τi / Math.sqrt(1 + τi * τi))); + var τiʹ = τi * Math.sqrt(1 + σi * σi) - σi * Math.sqrt(1 + τi * τi); + var δτi = (τʹ - τiʹ) / Math.sqrt(1 + τiʹ * τiʹ) * + (1 + (1 - e * e) * τi * τi) / ((1 - e * e) * Math.sqrt(1 + τi * τi)); + τi += δτi; + } while (Math.abs(δτi) > 1e-12); // using IEEE 754 δτi -> 0 after 2-3 iterations + // note relatively large convergence test as δτi toggles on ±1.12e-16 for eg 31 N 400000 5000000 + var τ = τi; + + var φ = Math.atan(τ); + + var λ = Math.atan2(sinhηʹ, cosξʹ); + + var λ0 = degreesToRadians((z - 1) * 6 - 180 + 3); // longitude of central meridian + λ += λ0; // move λ from zonal to global coordinates + + // round to reasonable precision + var lat = radiansToDegrees(φ); // nm precision (1nm = 10^-11°) + var lon = radiansToDegrees(λ); // (strictly lat rounding should be φ⋅cosφ!) + + return [lon, lat]; +} diff --git a/src/buffer/test.js b/src/buffer/test.js new file mode 100644 index 0000000000..1a58847be5 --- /dev/null +++ b/src/buffer/test.js @@ -0,0 +1,104 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import truncate from '../truncate'; +import { featureEach } from '../meta'; +import { featureCollection, point, polygon, geometryCollection } from '../helpers'; +import buffer from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +var fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); +// fixtures = fixtures.filter(({name}) => name === 'feature-collection-points'); + +test('turf-buffer', t => { + fixtures.forEach(fixture => { + const filename = fixture.filename; + const name = fixture.name; + const geojson = fixture.geojson; + const properties = geojson.properties || {}; + const radius = properties.radius || 50; + const units = properties.units || 'miles'; + const steps = properties.steps; + + const buffered = buffer(geojson, radius, {units: units, steps: steps}); + // Add Results to FeatureCollection + const results = featureCollection([]); + featureEach(buffered, feature => results.features.push(colorize(feature, '#F00'))); + featureEach(geojson, feature => results.features.push(colorize(feature, '#00F'))); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(results, load.sync(directories.out + filename), name); + }); + t.end(); +}); + +// https://github.com/Turfjs/turf/pull/736 +test('turf-buffer - Support Negative Buffer', t => { + const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); + + t.assert(buffer(poly, -50), 'allow negative buffer param'); + t.end(); +}); + +test('turf-buffer - Support Geometry Objects', t => { + const pt = point([61, 5]); + const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); + const gc = geometryCollection([pt.geometry, poly.geometry]); + + t.assert(buffer(gc, 10), 'support Geometry Collection'); + t.assert(buffer(pt.geometry, 10), 'support Point Geometry'); + t.assert(buffer(poly.geometry, 10), 'support Polygon Geometry'); + t.end(); +}); + +test('turf-buffer - Prevent Input Mutation', t => { + const pt = point([61, 5]); + const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); + const collection = featureCollection([pt, poly]); + + const beforePt = JSON.parse(JSON.stringify(pt)); + const beforePoly = JSON.parse(JSON.stringify(poly)); + const beforeCollection = JSON.parse(JSON.stringify(collection)); + + buffer(pt, 10); + buffer(poly, 10); + buffer(collection, 10); + + t.deepEqual(pt, beforePt, 'pt should not mutate'); + t.deepEqual(poly, beforePoly, 'poly should not mutate'); + t.deepEqual(collection, beforeCollection, 'collection should not mutate'); + t.end(); +}); + +// https://github.com/Turfjs/turf/issues/745 +// https://github.com/Turfjs/turf/pull/736#issuecomment-301937747 +test('turf-buffer - morphological closing', t => { + const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); + + t.equal(buffer(poly, -500, {units: 'miles'}), undefined, 'empty geometry should be undefined'); + t.deepEqual(buffer(featureCollection([poly]), -500, {units: 'miles'}), featureCollection([]), 'empty geometries should be an empty FeatureCollection'); + t.end(); +}); + +function colorize(feature, color) { + color = color || '#F00'; + if (feature.properties) { + feature.properties.stroke = color; + feature.properties.fill = color; + feature.properties['marker-color'] = color; + feature.properties['fill-opacity'] = 0.3; + } + return feature; +} diff --git a/packages/turf-buffer/test/in/feature-collection-points.geojson b/src/buffer/test/in/feature-collection-points.geojson similarity index 100% rename from packages/turf-buffer/test/in/feature-collection-points.geojson rename to src/buffer/test/in/feature-collection-points.geojson diff --git a/packages/turf-buffer/test/in/geometry-collection-points.geojson b/src/buffer/test/in/geometry-collection-points.geojson similarity index 100% rename from packages/turf-buffer/test/in/geometry-collection-points.geojson rename to src/buffer/test/in/geometry-collection-points.geojson diff --git a/packages/turf-buffer/test/in/issue-#783.geojson b/src/buffer/test/in/issue-#783.geojson similarity index 100% rename from packages/turf-buffer/test/in/issue-#783.geojson rename to src/buffer/test/in/issue-#783.geojson diff --git a/src/buffer/test/in/issue-#801-Ecuador.geojson b/src/buffer/test/in/issue-#801-Ecuador.geojson new file mode 100644 index 0000000000..394f3f1a4c --- /dev/null +++ b/src/buffer/test/in/issue-#801-Ecuador.geojson @@ -0,0 +1,40 @@ +{ + "type": "FeatureCollection", + "properties": { + "radius": 1, + "units": "miles" + }, + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -78.5096874833107, + -0.22245917455788858 + ], + [ + -78.50966066122055, + -0.22246453893548376 + ], + [ + -78.5096526145935, + -0.2224484458026982 + ], + [ + -78.50967675447464, + -0.2224403992362927 + ], + [ + -78.5096874833107, + -0.22245917455788858 + ] + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/packages/turf-buffer/test/in/issue-#801.geojson b/src/buffer/test/in/issue-#801.geojson similarity index 100% rename from packages/turf-buffer/test/in/issue-#801.geojson rename to src/buffer/test/in/issue-#801.geojson diff --git a/packages/turf-buffer/test/in/issue-#815.geojson b/src/buffer/test/in/issue-#815.geojson similarity index 100% rename from packages/turf-buffer/test/in/issue-#815.geojson rename to src/buffer/test/in/issue-#815.geojson diff --git a/packages/turf-buffer/test/in/issue-#900.geojson b/src/buffer/test/in/issue-#900.geojson similarity index 100% rename from packages/turf-buffer/test/in/issue-#900.geojson rename to src/buffer/test/in/issue-#900.geojson diff --git a/packages/turf-buffer/test/in/issue-#916.geojson b/src/buffer/test/in/issue-#916.geojson similarity index 100% rename from packages/turf-buffer/test/in/issue-#916.geojson rename to src/buffer/test/in/issue-#916.geojson diff --git a/packages/turf-buffer/test/in/linestring.geojson b/src/buffer/test/in/linestring.geojson similarity index 100% rename from packages/turf-buffer/test/in/linestring.geojson rename to src/buffer/test/in/linestring.geojson diff --git a/packages/turf-buffer/test/in/multi-linestring.geojson b/src/buffer/test/in/multi-linestring.geojson similarity index 100% rename from packages/turf-buffer/test/in/multi-linestring.geojson rename to src/buffer/test/in/multi-linestring.geojson diff --git a/packages/turf-buffer/test/in/multi-point.geojson b/src/buffer/test/in/multi-point.geojson similarity index 100% rename from packages/turf-buffer/test/in/multi-point.geojson rename to src/buffer/test/in/multi-point.geojson diff --git a/packages/turf-buffer/test/in/multi-polygon.geojson b/src/buffer/test/in/multi-polygon.geojson similarity index 100% rename from packages/turf-buffer/test/in/multi-polygon.geojson rename to src/buffer/test/in/multi-polygon.geojson diff --git a/packages/turf-buffer/test/in/negative-buffer.geojson b/src/buffer/test/in/negative-buffer.geojson similarity index 100% rename from packages/turf-buffer/test/in/negative-buffer.geojson rename to src/buffer/test/in/negative-buffer.geojson diff --git a/packages/turf-buffer/test/in/north-latitude-points.geojson b/src/buffer/test/in/north-latitude-points.geojson similarity index 100% rename from packages/turf-buffer/test/in/north-latitude-points.geojson rename to src/buffer/test/in/north-latitude-points.geojson diff --git a/packages/turf-buffer/test/in/northern-polygon.geojson b/src/buffer/test/in/northern-polygon.geojson similarity index 100% rename from packages/turf-buffer/test/in/northern-polygon.geojson rename to src/buffer/test/in/northern-polygon.geojson diff --git a/packages/turf-buffer/test/in/point.geojson b/src/buffer/test/in/point.geojson similarity index 100% rename from packages/turf-buffer/test/in/point.geojson rename to src/buffer/test/in/point.geojson diff --git a/packages/turf-buffer/test/in/polygon-with-holes.geojson b/src/buffer/test/in/polygon-with-holes.geojson similarity index 100% rename from packages/turf-buffer/test/in/polygon-with-holes.geojson rename to src/buffer/test/in/polygon-with-holes.geojson diff --git a/src/buffer/test/out/feature-collection-points.geojson b/src/buffer/test/out/feature-collection-points.geojson new file mode 100644 index 0000000000..c4f7090d28 --- /dev/null +++ b/src/buffer/test/out/feature-collection-points.geojson @@ -0,0 +1,849 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "marker-color": "#00F", + "stroke": "#00F", + "fill": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 129.9955087332905, + -19.272924321613566 + ], + [ + 129.84620098649805, + -19.287648589571155 + ], + [ + 129.70272055980678, + -19.32963706082717 + ], + [ + 129.57052138538046, + -19.39729729607754 + ], + [ + 129.45464433334772, + -19.48805869389183 + ], + [ + 129.35952943372388, + -19.598467294010838 + ], + [ + 129.28884762557598, + -19.724313796470817 + ], + [ + 129.24535801168358, + -19.86079044238152 + ], + [ + 129.23079612138207, + -20.002671388282973 + ], + [ + 129.245798071646, + -20.144510325980598 + ], + [ + 129.28986471567327, + -20.280848351558074 + ], + [ + 129.3613688058291, + -20.406424481034307 + ], + [ + 129.4576068006715, + -20.51638078122764 + ], + [ + 129.5748951740798, + -20.606453897375264 + ], + [ + 129.7087089656031, + -20.673144899089554 + ], + [ + 129.85385796238225, + -20.713859918375416 + ], + [ + 130.00469353231483, + -20.727015074858443 + ], + [ + 130.1553370071634, + -20.712100676785095 + ], + [ + 130.29991892719656, + -20.669701583814103 + ], + [ + 130.43281763936588, + -20.60147278155784 + ], + [ + 130.54888581566988, + -20.51007146092365 + ], + [ + 130.6436544147915, + -20.399049014601026 + ], + [ + 130.71350529946827, + -20.272708178890575 + ], + [ + 130.75580589597735, + -20.13593193757474 + ], + [ + 130.76900165171756, + -19.99399171450289 + ], + [ + 130.75266434571668, + -19.852342832296046 + ], + [ + 130.70749633989433, + -19.716415276816274 + ], + [ + 130.6352925257117, + -19.591407574551678 + ], + [ + 130.53886301160597, + -19.482091151096604 + ], + [ + 130.4219205663807, + -19.39263195577757 + ], + [ + 130.2889375667818, + -19.326435438931043 + ], + [ + 130.14497777366978, + -19.286020154844536 + ], + [ + 129.9955087332905, + -19.272924321613566 + ] + ] + ], + [ + [ + [ + 125.49957266654332, + -25.561309944039046 + ], + [ + 125.54060804401765, + -25.593524335541915 + ], + [ + 125.67704557062949, + -25.663769664522 + ], + [ + 125.82611813954657, + -25.708400838507178 + ], + [ + 125.98201638262651, + -25.72566469861406 + ], + [ + 126.13864567852583, + -25.714876123969997 + ], + [ + 126.28987705780509, + -25.676447872724793 + ], + [ + 126.42980044045441, + -25.61187487783273 + ], + [ + 126.55296743574837, + -25.523673618867132 + ], + [ + 126.6546117433819, + -25.415279526271238 + ], + [ + 126.73083694910834, + -25.290907450808735 + ], + [ + 126.77876393744347, + -25.155381880692914 + ], + [ + 126.79663290401042, + -25.013944719923053 + ], + [ + 126.78385769997001, + -24.87204904265657 + ], + [ + 126.74103270959368, + -24.73514736507572 + ], + [ + 126.66989448594258, + -24.60848272170579 + ], + [ + 126.57324189765674, + -24.49689029888803 + ], + [ + 126.45481961014232, + -24.40461664906917 + ], + [ + 126.319170426348, + -24.335162642243414 + ], + [ + 126.17146244770885, + -24.29115533436287 + ], + [ + 126.01729727054348, + -24.274252859343825 + ], + [ + 125.86250556410279, + -24.285085291942273 + ], + [ + 125.71293641336422, + -24.32323320372337 + ], + [ + 125.574246766458, + -24.38724437884789 + ], + [ + 125.49987239114506, + -24.44034141171704 + ], + [ + 125.45919224461367, + -24.408154457119107 + ], + [ + 125.32419465632024, + -24.3378643791752 + ], + [ + 125.17695348782236, + -24.292924686225522 + ], + [ + 125.02305542360567, + -24.275026293537785 + ], + [ + 124.86832220854755, + -24.284833848399543 + ], + [ + 124.71860014348545, + -24.321963509085364 + ], + [ + 124.57954971886846, + -24.384998857668524 + ], + [ + 124.45644159566649, + -24.471544122995578 + ], + [ + 124.35396494281481, + -24.578312725906084 + ], + [ + 124.27605391528407, + -24.701248103669982 + ], + [ + 124.22573782421836, + -24.835672835479595 + ], + [ + 124.20502030474441, + -24.97646126293437 + ], + [ + 124.2147924841067, + -25.118230050890055 + ], + [ + 124.2547847051349, + -25.255540438054375 + ], + [ + 124.32356064603097, + -25.38310527720921 + ], + [ + 124.41855656791978, + -25.495993392718674 + ], + [ + 124.53616681994707, + -25.589823362156846 + ], + [ + 124.6718746180027, + -25.660938669214616 + ], + [ + 124.82042457871894, + -25.70655639968459 + ], + [ + 124.97603074891792, + -25.72488236537551 + ], + [ + 125.13261123631302, + -25.715186793064046 + ], + [ + 125.28403837982101, + -25.677836479008704 + ], + [ + 125.42439202650634, + -25.614281469478176 + ], + [ + 125.49957266654332, + -25.561309944039046 + ] + ] + ], + [ + [ + [ + 134.9654494405914, + -24.277234621676044 + ], + [ + 134.8122245416901, + -24.297108910792712 + ], + [ + 134.66605030408104, + -24.343873175759835 + ], + [ + 134.53247871963217, + -24.415772313224288 + ], + [ + 134.41661103072974, + -24.510090908345912 + ], + [ + 134.32290660822306, + -24.623250876561833 + ], + [ + 134.25501114311348, + -24.750942324190174 + ], + [ + 134.21561063609116, + -24.888283461842075 + ], + [ + 134.20631740062518, + -25.030004228488114 + ], + [ + 134.22759379166533, + -25.170647214655144 + ], + [ + 134.27871854992563, + -25.3047785407139 + ], + [ + 134.35779942075746, + -25.427200594855417 + ], + [ + 134.46183399795834, + -25.533158031772864 + ], + [ + 134.58681854659514, + -25.61852826483598 + ], + [ + 134.72790195826525, + -25.67998794643788 + ], + [ + 134.8795791805456, + -25.715147700688004 + ], + [ + 135.03591573139045, + -25.72264868096936 + ], + [ + 135.19079260461632, + -25.702216333131148 + ], + [ + 135.33815932453842, + -25.654668934586397 + ], + [ + 135.47228235461466, + -25.58188086263549 + ], + [ + 135.58797659289027, + -25.486702895530755 + ], + [ + 135.68080920639073, + -25.37284394458927 + ], + [ + 135.7472673221973, + -25.244720279245318 + ], + [ + 135.78488376306976, + -25.107279441175837 + ], + [ + 135.79231773046197, + -24.965806638707477 + ], + [ + 135.76938979458942, + -24.82572153584249 + ], + [ + 135.71707255438378, + -24.692373117549018 + ], + [ + 135.63743980895254, + -24.570839853966586 + ], + [ + 135.53357807535266, + -24.465741811300564 + ], + [ + 135.40946490622997, + -24.381070736382515 + ], + [ + 135.2698188434951, + -24.320043498308568 + ], + [ + 135.11992611633667, + -24.284983588403396 + ], + [ + 134.9654494405914, + -24.277234621676044 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#00F", + "stroke": "#00F", + "fill": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 129.9935567631016, + -26.77361879461187 + ], + [ + 129.83576800238873, + -26.78859652917551 + ], + [ + 129.68416697196398, + -26.830751651471324 + ], + [ + 129.54448745050652, + -26.898493939338902 + ], + [ + 129.42203625748414, + -26.9892624693734 + ], + [ + 129.32149851389198, + -27.099618152779186 + ], + [ + 129.2467612311347, + -27.225368927962826 + ], + [ + 129.2007612954863, + -27.36172369100683 + ], + [ + 129.1853637901492, + -27.503470048037393 + ], + [ + 129.20127632422933, + -27.645170044819572 + ], + [ + 129.24800451122613, + -27.7813671708609 + ], + [ + 129.32385283022134, + -27.906797171039884 + ], + [ + 129.42597369148248, + -28.01659458381162 + ], + [ + 129.55046554809425, + -28.106486553344695 + ], + [ + 129.69251837686838, + -28.172965448903355 + ], + [ + 129.84660195201238, + -28.2134322816358 + ], + [ + 130.0066893372688, + -28.226303914177098 + ], + [ + 130.166505299272, + -28.211078622078077 + ], + [ + 130.31978728821656, + -28.168356611138876 + ], + [ + 130.46054556445148, + -28.099814459008144 + ], + [ + 130.58330914681147, + -28.00813490965876 + ], + [ + 130.68334550359012, + -27.89689576305429 + ], + [ + 130.75684409495196, + -27.770423555243433 + ], + [ + 130.80105666439766, + -27.63361916990947 + ], + [ + 130.8143901701361, + -27.4917634033762 + ], + [ + 130.7964510806293, + -27.3503108497416 + ], + [ + 130.74804216710697, + -27.214680373308372 + ], + [ + 130.67111477555994, + -27.09005001373342 + ], + [ + 130.56868084356626, + -26.98116354301009 + ], + [ + 130.44468972790435, + -26.892155151063488 + ], + [ + 130.30387535853137, + -26.826397927167335 + ], + [ + 130.15157946736431, + -26.786380940383953 + ], + [ + 129.9935567631016, + -26.77361879461187 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#00F", + "stroke": "#00F", + "fill": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 126.01690195790195, + -23.774205175071966 + ], + [ + 125.8627144883138, + -23.78509855305234 + ], + [ + 125.71374369708346, + -23.823310337069135 + ], + [ + 125.57562587144538, + -23.887385321887805 + ], + [ + 125.45360130172193, + -23.974889325357193 + ], + [ + 125.35232298625488, + -24.082498976500023 + ], + [ + 125.27568369161791, + -24.20612393919781 + ], + [ + 125.22666701187619, + -24.34105754377289 + ], + [ + 125.207227801877, + -24.482150934949743 + ], + [ + 125.21820701652464, + -24.624005066419127 + ], + [ + 125.25928548657821, + -24.76117415793489 + ], + [ + 125.32898038595525, + -24.88837357863421 + ], + [ + 125.42468697494182, + -25.00068456341719 + ], + [ + 125.5427665514311, + -25.09374778210155 + ], + [ + 125.67867939863264, + -25.163937670898072 + ], + [ + 125.8271589824269, + -25.208509720250145 + ], + [ + 125.9824209428138, + -25.225713688447954 + ], + [ + 126.13839785440925, + -25.214867018227817 + ], + [ + 126.28898865237184, + -25.176384536851653 + ], + [ + 126.42831034793129, + -25.111762697561904 + ], + [ + 126.55093939683823, + -25.023518981801903 + ], + [ + 126.65213087889141, + -24.9150894028147 + ], + [ + 126.72800537069261, + -24.79068911692914 + ], + [ + 126.77569578262903, + -24.655142792971958 + ], + [ + 126.79344914776689, + -24.51369252155058 + ], + [ + 126.78068106123965, + -24.371791652982854 + ], + [ + 126.73798290826569, + -24.23489308917067 + ], + [ + 126.66708402677875, + -24.108240312350947 + ], + [ + 126.57077247613833, + -23.996668911693085 + ], + [ + 126.45277916293529, + -23.90442565019117 + ], + [ + 126.31763079475762, + -23.835011254238243 + ], + [ + 126.17047759095715, + -23.791052134859715 + ], + [ + 126.01690195790195, + -23.774205175071966 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#00F", + "stroke": "#00F", + "fill": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "MultiPoint", + "coordinates": [ + [ + 135, + -25 + ], + [ + 130, + -20 + ], + [ + 125, + -25 + ], + [ + 126, + -25 + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#00F", + "stroke": "#00F", + "fill": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Point", + "coordinates": [ + 130, + -27.5 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#00F", + "stroke": "#00F", + "fill": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Point", + "coordinates": [ + 126, + -24.5 + ] + } + } + ] +} diff --git a/src/buffer/test/out/geometry-collection-points.geojson b/src/buffer/test/out/geometry-collection-points.geojson new file mode 100644 index 0000000000..a215cac0f8 --- /dev/null +++ b/src/buffer/test/out/geometry-collection-points.geojson @@ -0,0 +1,575 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "fill": "#F00", + "marker-color": "#F00", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 129.9955087332905, + -19.272924321613566 + ], + [ + 129.84620098649805, + -19.287648589571155 + ], + [ + 129.70272055980678, + -19.32963706082717 + ], + [ + 129.57052138538046, + -19.39729729607754 + ], + [ + 129.45464433334772, + -19.48805869389183 + ], + [ + 129.35952943372388, + -19.598467294010838 + ], + [ + 129.28884762557598, + -19.724313796470817 + ], + [ + 129.24535801168358, + -19.86079044238152 + ], + [ + 129.23079612138207, + -20.002671388282973 + ], + [ + 129.245798071646, + -20.144510325980598 + ], + [ + 129.28986471567327, + -20.280848351558074 + ], + [ + 129.3613688058291, + -20.406424481034307 + ], + [ + 129.4576068006715, + -20.51638078122764 + ], + [ + 129.5748951740798, + -20.606453897375264 + ], + [ + 129.7087089656031, + -20.673144899089554 + ], + [ + 129.85385796238225, + -20.713859918375416 + ], + [ + 130.00469353231483, + -20.727015074858443 + ], + [ + 130.1553370071634, + -20.712100676785095 + ], + [ + 130.29991892719656, + -20.669701583814103 + ], + [ + 130.43281763936588, + -20.60147278155784 + ], + [ + 130.54888581566988, + -20.51007146092365 + ], + [ + 130.6436544147915, + -20.399049014601026 + ], + [ + 130.71350529946827, + -20.272708178890575 + ], + [ + 130.75580589597735, + -20.13593193757474 + ], + [ + 130.76900165171756, + -19.99399171450289 + ], + [ + 130.75266434571668, + -19.852342832296046 + ], + [ + 130.70749633989433, + -19.716415276816274 + ], + [ + 130.6352925257117, + -19.591407574551678 + ], + [ + 130.53886301160597, + -19.482091151096604 + ], + [ + 130.4219205663807, + -19.39263195577757 + ], + [ + 130.2889375667818, + -19.326435438931043 + ], + [ + 130.14497777366978, + -19.286020154844536 + ], + [ + 129.9955087332905, + -19.272924321613566 + ] + ] + ], + [ + [ + [ + 125.02305542360567, + -24.275026293537785 + ], + [ + 124.86832220854755, + -24.284833848399543 + ], + [ + 124.71860014348545, + -24.321963509085364 + ], + [ + 124.57954971886846, + -24.384998857668524 + ], + [ + 124.45644159566649, + -24.471544122995578 + ], + [ + 124.35396494281481, + -24.578312725906084 + ], + [ + 124.27605391528407, + -24.701248103669982 + ], + [ + 124.22573782421836, + -24.835672835479595 + ], + [ + 124.20502030474441, + -24.97646126293437 + ], + [ + 124.2147924841067, + -25.118230050890055 + ], + [ + 124.2547847051349, + -25.255540438054375 + ], + [ + 124.32356064603097, + -25.38310527720921 + ], + [ + 124.41855656791978, + -25.495993392718674 + ], + [ + 124.53616681994707, + -25.589823362156846 + ], + [ + 124.6718746180027, + -25.660938669214616 + ], + [ + 124.82042457871894, + -25.70655639968459 + ], + [ + 124.97603074891792, + -25.72488236537551 + ], + [ + 125.13261123631302, + -25.715186793064046 + ], + [ + 125.28403837982101, + -25.677836479008704 + ], + [ + 125.42439202650634, + -25.614281469478176 + ], + [ + 125.54820312865198, + -25.52699669714826 + ], + [ + 125.65067559891777, + -25.419381356221333 + ], + [ + 125.72787604882099, + -25.295620914743623 + ], + [ + 125.77688342592155, + -25.160518366137413 + ], + [ + 125.79589331794526, + -25.019302512429892 + ], + [ + 125.78427446473931, + -24.87742172873663 + ], + [ + 125.74257753313053, + -24.74033182954177 + ], + [ + 125.67249829191294, + -24.61328643061058 + ], + [ + 125.57679891254843, + -24.501137675353554 + ], + [ + 125.45919224461367, + -24.408154457119107 + ], + [ + 125.32419465632024, + -24.3378643791752 + ], + [ + 125.17695348782236, + -24.292924686225522 + ], + [ + 125.02305542360567, + -24.275026293537785 + ] + ] + ], + [ + [ + [ + 134.9654494405914, + -24.277234621676044 + ], + [ + 134.8122245416901, + -24.297108910792712 + ], + [ + 134.66605030408104, + -24.343873175759835 + ], + [ + 134.53247871963217, + -24.415772313224288 + ], + [ + 134.41661103072974, + -24.510090908345912 + ], + [ + 134.32290660822306, + -24.623250876561833 + ], + [ + 134.25501114311348, + -24.750942324190174 + ], + [ + 134.21561063609116, + -24.888283461842075 + ], + [ + 134.20631740062518, + -25.030004228488114 + ], + [ + 134.22759379166533, + -25.170647214655144 + ], + [ + 134.27871854992563, + -25.3047785407139 + ], + [ + 134.35779942075746, + -25.427200594855417 + ], + [ + 134.46183399795834, + -25.533158031772864 + ], + [ + 134.58681854659514, + -25.61852826483598 + ], + [ + 134.72790195826525, + -25.67998794643788 + ], + [ + 134.8795791805456, + -25.715147700688004 + ], + [ + 135.03591573139045, + -25.72264868096936 + ], + [ + 135.19079260461632, + -25.702216333131148 + ], + [ + 135.33815932453842, + -25.654668934586397 + ], + [ + 135.47228235461466, + -25.58188086263549 + ], + [ + 135.58797659289027, + -25.486702895530755 + ], + [ + 135.68080920639073, + -25.37284394458927 + ], + [ + 135.7472673221973, + -25.244720279245318 + ], + [ + 135.78488376306976, + -25.107279441175837 + ], + [ + 135.79231773046197, + -24.965806638707477 + ], + [ + 135.76938979458942, + -24.82572153584249 + ], + [ + 135.71707255438378, + -24.692373117549018 + ], + [ + 135.63743980895254, + -24.570839853966586 + ], + [ + 135.53357807535266, + -24.465741811300564 + ], + [ + 135.40946490622997, + -24.381070736382515 + ], + [ + 135.2698188434951, + -24.320043498308568 + ], + [ + 135.11992611633667, + -24.284983588403396 + ], + [ + 134.9654494405914, + -24.277234621676044 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "fill": "#F00", + "marker-color": "#F00", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 129.9935567631016, + -26.77361879461187 + ], + [ + 129.83576800238873, + -26.78859652917551 + ], + [ + 129.68416697196398, + -26.830751651471324 + ], + [ + 129.54448745050652, + -26.898493939338902 + ], + [ + 129.42203625748414, + -26.9892624693734 + ], + [ + 129.32149851389198, + -27.099618152779186 + ], + [ + 129.2467612311347, + -27.225368927962826 + ], + [ + 129.2007612954863, + -27.36172369100683 + ], + [ + 129.1853637901492, + -27.503470048037393 + ], + [ + 129.20127632422933, + -27.645170044819572 + ], + [ + 129.24800451122613, + -27.7813671708609 + ], + [ + 129.32385283022134, + -27.906797171039884 + ], + [ + 129.42597369148248, + -28.01659458381162 + ], + [ + 129.55046554809425, + -28.106486553344695 + ], + [ + 129.69251837686838, + -28.172965448903355 + ], + [ + 129.84660195201238, + -28.2134322816358 + ], + [ + 130.0066893372688, + -28.226303914177098 + ], + [ + 130.166505299272, + -28.211078622078077 + ], + [ + 130.31978728821656, + -28.168356611138876 + ], + [ + 130.46054556445148, + -28.099814459008144 + ], + [ + 130.58330914681147, + -28.00813490965876 + ], + [ + 130.68334550359012, + -27.89689576305429 + ], + [ + 130.75684409495196, + -27.770423555243433 + ], + [ + 130.80105666439766, + -27.63361916990947 + ], + [ + 130.8143901701361, + -27.4917634033762 + ], + [ + 130.7964510806293, + -27.3503108497416 + ], + [ + 130.74804216710697, + -27.214680373308372 + ], + [ + 130.67111477555994, + -27.09005001373342 + ], + [ + 130.56868084356626, + -26.98116354301009 + ], + [ + 130.44468972790435, + -26.892155151063488 + ], + [ + 130.30387535853137, + -26.826397927167335 + ], + [ + 130.15157946736431, + -26.786380940383953 + ], + [ + 129.9935567631016, + -26.77361879461187 + ] + ] + ] + } + } + ] +} diff --git a/src/buffer/test/out/issue-#783.geojson b/src/buffer/test/out/issue-#783.geojson new file mode 100644 index 0000000000..3245c2965d --- /dev/null +++ b/src/buffer/test/out/issue-#783.geojson @@ -0,0 +1,557 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.946664103726564, + 52.50946196650922 + ], + [ + 4.946724202118396, + 52.50943828620954 + ], + [ + 4.947188200608335, + 52.50929228688191 + ], + [ + 4.947200821560516, + 52.50928849996884 + ], + [ + 4.947270821312806, + 52.50926850006306 + ], + [ + 4.94734927733871, + 52.5092523548248 + ], + [ + 4.947683275762027, + 52.5092083550581 + ], + [ + 4.947753298832177, + 52.509203342890046 + ], + [ + 4.947823604139211, + 52.50920656421699 + ], + [ + 4.947891615078066, + 52.5092179009808 + ], + [ + 4.9479548391260275, + 52.50923693770216 + ], + [ + 4.948010959187158, + 52.50926297670677 + ], + [ + 4.948057918508833, + 52.50929506369335 + ], + [ + 4.9480939960588, + 52.50933202270656 + ], + [ + 4.94811786960042, + 52.509372499233216 + ], + [ + 4.948128664154403, + 52.50941500984281 + ], + [ + 4.948125984070513, + 52.5094579965532 + ], + [ + 4.948109927533249, + 52.50949988392899 + ], + [ + 4.948081082969095, + 52.50953913682032 + ], + [ + 4.948040507486162, + 52.50957431662577 + ], + [ + 4.947989688135708, + 52.509604134017536 + ], + [ + 4.947930487414655, + 52.50962749619579 + ], + [ + 4.947500486022293, + 52.50976349682132 + ], + [ + 4.9474716369539165, + 52.50977167685851 + ], + [ + 4.946876634663948, + 52.50992167758346 + ], + [ + 4.946809515063312, + 52.50993418390964 + ], + [ + 4.9467397259085155, + 52.50993869477713 + ], + [ + 4.946669801453148, + 52.50993504638241 + ], + [ + 4.946602280864418, + 52.50992337120928 + ], + [ + 4.946539616014289, + 52.50990409321786 + ], + [ + 4.94648408244121, + 52.50987791244862 + ], + [ + 4.946437696716352, + 52.509845779600965 + ], + [ + 4.946402143215464, + 52.50980886150939 + ], + [ + 4.9463787129556485, + 52.50976849877109 + ], + [ + 4.946368256717958, + 52.50972615706419 + ], + [ + 4.946371154157674, + 52.50968337392418 + ], + [ + 4.946387300023344, + 52.509641702911765 + ], + [ + 4.946416107984215, + 52.509602657199174 + ], + [ + 4.9464565319263425, + 52.50956765462406 + ], + [ + 4.9465071039432855, + 52.509537966205336 + ], + [ + 4.946664103726564, + 52.50946196650922 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.946745928905576, + 52.50993862459945 + ], + [ + 4.946673915506936, + 52.50993549035446 + ], + [ + 4.946604288014483, + 52.50992384431738 + ], + [ + 4.946539722209927, + 52.50990413404495 + ], + [ + 4.946482699346483, + 52.5098771170018 + ], + [ + 4.946435410791786, + 52.50984383144987 + ], + [ + 4.946399673813207, + 52.50980555654682 + ], + [ + 4.946376861742086, + 52.50976376318681 + ], + [ + 4.9463678512005265, + 52.509720057473096 + ], + [ + 4.946372988418329, + 52.509676118995294 + ], + [ + 4.946392075933702, + 52.509633636283056 + ], + [ + 4.946424380187905, + 52.509594241917114 + ], + [ + 4.946468659721019, + 52.50955944979095 + ], + [ + 4.946523212884443, + 52.50953059693434 + ], + [ + 4.946585943235972, + 52.509508792133815 + ], + [ + 4.946654440104075, + 52.50949487332454 + ], + [ + 4.946726071225521, + 52.50948937539065 + ], + [ + 4.946798083896743, + 52.50949250961117 + ], + [ + 4.946867710752562, + 52.50950415554111 + ], + [ + 4.946932276108189, + 52.50952386564004 + ], + [ + 4.946989298778758, + 52.509550882469775 + ], + [ + 4.947036587425992, + 52.50958416780086 + ], + [ + 4.9470723247684365, + 52.50962244250922 + ], + [ + 4.947095137419357, + 52.50966423573038 + ], + [ + 4.947104148668376, + 52.50970794138219 + ], + [ + 4.947099012177992, + 52.50975187988449 + ], + [ + 4.947079925299253, + 52.509794362703865 + ], + [ + 4.9470476214939785, + 52.50983375724331 + ], + [ + 4.947003342153741, + 52.50986854958288 + ], + [ + 4.946948788897778, + 52.50989740266036 + ], + [ + 4.946886058182384, + 52.50991920765556 + ], + [ + 4.946817560734483, + 52.509933126603684 + ], + [ + 4.946745928905576, + 52.50993862459945 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.9477709340288385, + 52.50965262447361 + ], + [ + 4.947698921041703, + 52.5096494908486 + ], + [ + 4.947629293748052, + 52.50963784541253 + ], + [ + 4.947564727921958, + 52.50961813569902 + ], + [ + 4.947507704817461, + 52.50959111915122 + ], + [ + 4.947460415811463, + 52.50955783401202 + ], + [ + 4.94742467818868, + 52.50951955942327 + ], + [ + 4.947401865305206, + 52.50947776626699 + ], + [ + 4.947392853814372, + 52.509434060638654 + ], + [ + 4.947397989982453, + 52.509390122124586 + ], + [ + 4.9474170763880005, + 52.5093476392558 + ], + [ + 4.947449379514922, + 52.50930824461907 + ], + [ + 4.947493657946622, + 52.5092734521183 + ], + [ + 4.947548210076824, + 52.509244598797636 + ], + [ + 4.947610939503024, + 52.50922279346145 + ], + [ + 4.947679435589255, + 52.50920887406551 + ], + [ + 4.947751066102327, + 52.509203375516485 + ], + [ + 4.9478230783620525, + 52.509206509117014 + ], + [ + 4.947892705019066, + 52.50921815444596 + ], + [ + 4.947957270396219, + 52.50923786398599 + ], + [ + 4.948014293307816, + 52.50926488032039 + ], + [ + 4.948061582406323, + 52.50929816523871 + ], + [ + 4.948097320392943, + 52.50933643963279 + ], + [ + 4.948120133856188, + 52.509378232650214 + ], + [ + 4.948129146054464, + 52.50942193821665 + ], + [ + 4.948124010613794, + 52.50946587675521 + ], + [ + 4.948104924844882, + 52.5095083597311 + ], + [ + 4.948072622166901, + 52.50954775454131 + ], + [ + 4.948028343928101, + 52.509582547255505 + ], + [ + 4.947973791705389, + 52.50961140079702 + ], + [ + 4.947911061915352, + 52.509633206327884 + ], + [ + 4.947842565249353, + 52.50964712586269 + ], + [ + 4.9477709340288385, + 52.50965262447361 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.946893, + 52.509638 + ], + [ + 4.947357, + 52.509492 + ], + [ + 4.947427, + 52.509472 + ], + [ + 4.947761, + 52.509428 + ], + [ + 4.947331, + 52.509564 + ], + [ + 4.946736, + 52.509714 + ], + [ + 4.946893, + 52.509638 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Point", + "coordinates": [ + 4.946736, + 52.509714 + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Point", + "coordinates": [ + 4.947761, + 52.509428 + ] + } + } + ] +} diff --git a/src/buffer/test/out/issue-#801-Ecuador.geojson b/src/buffer/test/out/issue-#801-Ecuador.geojson new file mode 100644 index 0000000000..75ff6c7bf5 --- /dev/null +++ b/src/buffer/test/out/issue-#801-Ecuador.geojson @@ -0,0 +1,209 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -78.52221204159405, + -0.21520549263883132 + ], + [ + -78.52334588594908, + -0.21771284407259608 + ], + [ + -78.52398982139837, + -0.22039044337948438 + ], + [ + -78.52412074941779, + -0.22314224702827007 + ], + [ + -78.52373397326609, + -0.22586954952097257 + ], + [ + -78.52284336653118, + -0.22847452423247375 + ], + [ + -78.52148087542375, + -0.23086373271817412 + ], + [ + -78.5196953726818, + -0.23295147655559795 + ], + [ + -78.51755090422706, + -0.23466287144310027 + ], + [ + -78.51512439151422, + -0.23593653325788713 + ], + [ + -78.51250287204572, + -0.23672677971607414 + ], + [ + -78.51247604981464, + -0.23673214381814134 + ], + [ + -78.50980959194692, + -0.2370101609675078 + ], + [ + -78.50713801592428, + -0.2367875088815238 + ], + [ + -78.50455327869834, + -0.2360718543845902 + ], + [ + -78.5021443470961, + -0.23488783339264147 + ], + [ + -78.49999413570539, + -0.23327620256276985 + ], + [ + -78.49817665320744, + -0.2312924361525094 + ], + [ + -78.4967544553416, + -0.2290048164237222 + ], + [ + -78.49674640888429, + -0.22898872340268173 + ], + [ + -78.49574851126015, + -0.22640567790456917 + ], + [ + -78.49525536119427, + -0.22367897950043816 + ], + [ + -78.49528485986401, + -0.22090761128126926 + ], + [ + -78.49583593617368, + -0.2181921777008771 + ], + [ + -78.49688858566913, + -0.2156312528548197 + ], + [ + -78.49840459660092, + -0.2133178024355058 + ], + [ + -78.50032893679946, + -0.21133580919027856 + ], + [ + -78.50259175106169, + -0.20975722433640373 + ], + [ + -78.50511089660021, + -0.2086393555753199 + ], + [ + -78.50513503629423, + -0.2086313087890302 + ], + [ + -78.50788610610083, + -0.20800614971476108 + ], + [ + -78.51070540506628, + -0.20793090792547503 + ], + [ + -78.51348552323336, + -0.20840845351289086 + ], + [ + -78.51612054200676, + -0.20942059617698291 + ], + [ + -78.5185100696074, + -0.21092877773918564 + ], + [ + -78.52056306614661, + -0.21287554073657486 + ], + [ + -78.52220131254268, + -0.21518671720617796 + ], + [ + -78.52221204159405, + -0.21520549263883132 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -78.5096874833107, + -0.22245917455788858 + ], + [ + -78.50966066122055, + -0.22246453893548376 + ], + [ + -78.5096526145935, + -0.2224484458026982 + ], + [ + -78.50967675447464, + -0.2224403992362927 + ], + [ + -78.5096874833107, + -0.22245917455788858 + ] + ] + ] + } + } + ] +} diff --git a/src/buffer/test/out/issue-#801.geojson b/src/buffer/test/out/issue-#801.geojson new file mode 100644 index 0000000000..0f7f7b8853 --- /dev/null +++ b/src/buffer/test/out/issue-#801.geojson @@ -0,0 +1,373 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 2, + "stroke-opacity": 1, + "fill": "#00F", + "fill-opacity": 0.3, + "marker-color": "#00F" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 5.825499612021236, + 50.76061716543162 + ], + [ + 5.821335444120894, + 50.75943364077908 + ], + [ + 5.817626344500142, + 50.75774786900184 + ], + [ + 5.814520853464506, + 50.75562738369388 + ], + [ + 5.812143282225955, + 50.7531571246194 + ], + [ + 5.810588737766667, + 50.75043602909391 + ], + [ + 5.809919326976549, + 50.74757306375194 + ], + [ + 5.810161690191021, + 50.74468285675758 + ], + [ + 5.810167065039433, + 50.7446607945276 + ], + [ + 5.811283072043803, + 50.741907872771236 + ], + [ + 5.8132257820864, + 50.73934654880184 + ], + [ + 5.815920080123556, + 50.73707568594587 + ], + [ + 5.819261883932151, + 50.73518292219194 + ], + [ + 5.823122170236891, + 50.73374129339004 + ], + [ + 5.827351954552156, + 50.73280642067556 + ], + [ + 5.831788032784655, + 50.73241436956687 + ], + [ + 5.836259264600357, + 50.7325802623662 + ], + [ + 5.840593158750252, + 50.73329769668137 + ], + [ + 5.844622509571787, + 50.73453899214903 + ], + [ + 5.844657372286916, + 50.73455256598885 + ], + [ + 5.848347526503078, + 50.7363413610131 + ], + [ + 5.85139017047235, + 50.738567525844246 + ], + [ + 5.8536590150729495, + 50.74113873018198 + ], + [ + 5.855059816350896, + 50.7439483182123 + ], + [ + 5.855534300959445, + 50.74687972683313 + ], + [ + 5.855534309210343, + 50.746896698304454 + ], + [ + 5.855128860768936, + 50.74961696936978 + ], + [ + 5.853924246054801, + 50.752240331349064 + ], + [ + 5.851963325944838, + 50.75467316050137 + ], + [ + 5.849315981520908, + 50.75682861867301 + ], + [ + 5.846076632732716, + 50.75862975656131 + ], + [ + 5.84236087484153, + 50.760012265249266 + ], + [ + 5.838301351890781, + 50.76092677699008 + ], + [ + 5.834043014727166, + 50.76134063226585 + ], + [ + 5.82973793407015, + 50.76123904927577 + ], + [ + 5.825539855834711, + 50.76062565353139 + ], + [ + 5.825499612021236, + 50.76061716543162 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 5.833588947862539, + 50.76134197966189 + ], + [ + 5.829126011691592, + 50.76117225351863 + ], + [ + 5.824801137360732, + 50.76045338991017 + ], + [ + 5.820780665537133, + 50.75921303630174 + ], + [ + 5.817219200311388, + 50.75749889595297 + ], + [ + 5.814253652676737, + 50.75537688904127 + ], + [ + 5.811997972142097, + 50.752928612264355 + ], + [ + 5.810538769998176, + 50.750248195635024 + ], + [ + 5.809932002076289, + 50.74743867840233 + ], + [ + 5.810200836766708, + 50.74460804439207 + ], + [ + 5.811334787422026, + 50.7418650698741 + ], + [ + 5.813290139018726, + 50.73931514387919 + ], + [ + 5.8159916490794314, + 50.73705622150456 + ], + [ + 5.819335454303637, + 50.73517506520909 + ], + [ + 5.823193068917409, + 50.73374391768114 + ], + [ + 5.827416320040605, + 50.73281773305898 + ], + [ + 5.831843030759795, + 50.73243207177253 + ], + [ + 5.836303234204003, + 50.73260173888953 + ], + [ + 5.840625682599161, + 50.73332021754838 + ], + [ + 5.844644404604913, + 50.73455991888898 + ], + [ + 5.848205062524532, + 50.73627323895363 + ], + [ + 5.851170868269674, + 50.73839438244572 + ], + [ + 5.853427833036272, + 50.740841884115405 + ], + [ + 5.854889150020847, + 50.74352173195281 + ], + [ + 5.855498541426801, + 50.74633097330232 + ], + [ + 5.855232439462345, + 50.749161666338814 + ], + [ + 5.854100914742295, + 50.75190502580625 + ], + [ + 5.852147312963608, + 50.75445560406883 + ], + [ + 5.849446610209698, + 50.756715346727496 + ], + [ + 5.846102546875776, + 50.758597366442565 + ], + [ + 5.842243648030482, + 50.760029289077934 + ], + [ + 5.838018282066465, + 50.76095604249218 + ], + [ + 5.833588947862539, + 50.76134197966189 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 2, + "stroke-opacity": 1, + "fill": "#00F", + "fill-opacity": 0.3, + "marker-color": "#00F" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 5.832694172859192, + 50.74689044349633 + ], + [ + 5.832699537277222, + 50.74686838040257 + ], + [ + 5.832734405994415, + 50.746881957692274 + ], + [ + 5.832734405994415, + 50.746898929298894 + ], + [ + 5.832694172859192, + 50.74689044349633 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Point", + "coordinates": [ + 5.83271563053131, + 50.746887049174894 + ] + } + } + ] +} diff --git a/src/buffer/test/out/issue-#815.geojson b/src/buffer/test/out/issue-#815.geojson new file mode 100644 index 0000000000..3ec86255ad --- /dev/null +++ b/src/buffer/test/out/issue-#815.geojson @@ -0,0 +1,267 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "radius": 850, + "units": "meters", + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 9.40471091212222, + 52.004298577529 + ], + [ + 9.406909506781952, + 52.00446631854713 + ], + [ + 9.409024518874952, + 52.00487312335862 + ], + [ + 9.41098828179235, + 52.005505977343084 + ], + [ + 9.412737961077362, + 52.00634463341061 + ], + [ + 9.414217562989698, + 52.00736225892602 + ], + [ + 10.289448902232207, + 52.7153734159325 + ], + [ + 11.3799206886876, + 52.71535520791144 + ], + [ + 12.432711591528962, + 52.51563201842639 + ], + [ + 12.435110932541322, + 52.51531816362934 + ], + [ + 12.437564524229334, + 52.51529585395954 + ], + [ + 12.439978124619586, + 52.51556594550586 + ], + [ + 12.442259025983342, + 52.51611806322087 + ], + [ + 12.444319610607842, + 52.51693099895617 + ], + [ + 12.446080712410273, + 52.517973525045946 + ], + [ + 12.447474656043816, + 52.51920559239106 + ], + [ + 12.448447857192393, + 52.52057986730292 + ], + [ + 12.448962884192948, + 52.5220435483843 + ], + [ + 12.448999901393549, + 52.523540393949304 + ], + [ + 12.44855743803853, + 52.52501288232985 + ], + [ + 12.447652452127294, + 52.52640442220678 + ], + [ + 12.446319685675615, + 52.52766152805362 + ], + [ + 12.444610335097783, + 52.528735876990176 + ], + [ + 12.442590086967412, + 52.529586167784345 + ], + [ + 12.44033659415105, + 52.5301797102596 + ], + [ + 11.385493255065008, + 52.730294638992916 + ], + [ + 11.381931996187836, + 52.73062424461264 + ], + [ + 10.283107084437631, + 52.730625966992264 + ], + [ + 10.280832438347234, + 52.73048940765155 + ], + [ + 10.278636017420473, + 52.73010532523939 + ], + [ + 10.276590293845084, + 52.72948639301213 + ], + [ + 10.274762760313214, + 52.72865303287068 + ], + [ + 10.273213700970311, + 52.72763274062873 + ], + [ + 9.397935123368713, + 52.01945155319604 + ], + [ + 7.162291933605081, + 51.95188999528783 + ], + [ + 7.1598997248883345, + 51.95164772425125 + ], + [ + 7.157630021724735, + 51.95112169079071 + ], + [ + 7.155570082227731, + 51.9503321198327 + ], + [ + 7.153799088804942, + 51.94930936717531 + ], + [ + 7.152385102164943, + 51.94809275094684 + ], + [ + 7.151382445416498, + 51.94672903845162 + ], + [ + 7.150829618842435, + 51.945270646884275 + ], + [ + 7.150747825118222, + 51.94377362737012 + ], + [ + 7.1511401609235605, + 51.942295510046335 + ], + [ + 7.151991505034697, + 51.940893093133745 + ], + [ + 7.153269106117553, + 51.939620260975346 + ], + [ + 7.154923846614978, + 51.93852591477666 + ], + [ + 7.156892133356525, + 51.93765209534193 + ], + [ + 7.15909834177311, + 51.93703236964663 + ], + [ + 7.161457719732469, + 51.936690542918576 + ], + [ + 7.163879639764603, + 51.93663974541084 + ], + [ + 9.40471091212222, + 52.004298577529 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "radius": 850, + "units": "meters", + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 7.163085937499999, + 51.944264879028765 + ], + [ + 9.404296875, + 52.01193653675363 + ], + [ + 10.283203125, + 52.72298552457069 + ], + [ + 11.3818359375, + 52.72298552457069 + ], + [ + 12.436523437499998, + 52.522905940278065 + ] + ] + } + } + ] +} diff --git a/src/buffer/test/out/issue-#900.geojson b/src/buffer/test/out/issue-#900.geojson new file mode 100644 index 0000000000..1626503b2f --- /dev/null +++ b/src/buffer/test/out/issue-#900.geojson @@ -0,0 +1,1263 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -85.88767639041292, + 22.263013204860272 + ], + [ + -85.88749391098482, + 22.26379464324936 + ], + [ + -85.8010360398394, + 22.637515753232837 + ], + [ + -85.69850107412707, + 23.0775694216824 + ], + [ + -85.51515733019214, + 23.811385413783384 + ], + [ + -84.7371073648832, + 25.029183932959572 + ], + [ + -84.67715456418989, + 25.15145947739654 + ], + [ + -84.64710482227127, + 25.282650989551477 + ], + [ + -84.57436293647454, + 25.973977818570628 + ], + [ + -84.54704985584705, + 26.23837766436675 + ], + [ + -84.53268634034958, + 26.271094474570265 + ], + [ + -84.52790336800282, + 26.28230106399169 + ], + [ + -84.22437225500781, + 27.0161234904877 + ], + [ + -83.14623496764435, + 27.407327079577378 + ], + [ + -83.02251246587363, + 27.464598694649183 + ], + [ + -82.91329312178235, + 27.542156264591373 + ], + [ + -82.71174082256665, + 27.715979484482922 + ], + [ + -82.70801314793302, + 27.719213092347193 + ], + [ + -82.12010729035767, + 28.230804564308524 + ], + [ + -82.0323343710069, + 28.32244307013246 + ], + [ + -81.96511347227685, + 28.42696190468972 + ], + [ + -81.92088465860081, + 28.540765729113257 + ], + [ + -81.90130568866995, + 28.65990645870112 + ], + [ + -81.8610707113561, + 29.401008681314085 + ], + [ + -81.81081782459789, + 30.283438179969302 + ], + [ + -80.55850682266374, + 31.760987890462335 + ], + [ + -80.52857661536456, + 31.798587295762747 + ], + [ + -78.97081366117064, + 33.879080948535545 + ], + [ + -78.91914959089277, + 33.95840973452472 + ], + [ + -78.74849789994273, + 34.268109733070744 + ], + [ + -78.74760642458558, + 34.269730693515434 + ], + [ + -78.1842555151873, + 35.29198805405751 + ], + [ + -78.17247176661898, + 35.31430635271463 + ], + [ + -78.05607409711179, + 35.545861689547024 + ], + [ + -77.8635156533653, + 35.76146304532446 + ], + [ + -77.49475210699315, + 36.16352933183979 + ], + [ + -77.49220319985132, + 36.16631095786659 + ], + [ + -77.22264677784041, + 36.461083856558425 + ], + [ + -76.64630376015998, + 37.0827948050831 + ], + [ + -76.21464986295253, + 37.49465436642182 + ], + [ + -76.0792722920422, + 37.589337850108635 + ], + [ + -76.05833657584104, + 37.60444389378708 + ], + [ + -75.80713553602337, + 37.79113976898348 + ], + [ + -75.70724459454362, + 37.879040975567804 + ], + [ + -75.31953427719282, + 38.28346147617783 + ], + [ + -75.31267800106424, + 38.29067309248259 + ], + [ + -75.21495381512094, + 38.39473214153315 + ], + [ + -75.08759369687247, + 38.5262186692417 + ], + [ + -74.97373243402684, + 38.63982976817539 + ], + [ + -74.94210385375045, + 38.67337120416583 + ], + [ + -74.88713989901656, + 38.73544194500135 + ], + [ + -73.918938554604, + 39.24345369082135 + ], + [ + -73.90374404949804, + 39.25149587349801 + ], + [ + -73.19080098683885, + 39.6334245087479 + ], + [ + -71.87816830716362, + 40.30347220310914 + ], + [ + -71.33217339253501, + 40.48247719213761 + ], + [ + -69.93647452510712, + 40.581723576583556 + ], + [ + -69.72568472373047, + 40.614359410370476 + ], + [ + -69.53006413348979, + 40.683052644099796 + ], + [ + -66.56192648658511, + 42.001480657761086 + ], + [ + -56.15761061166265, + 44.9142922000588 + ], + [ + -51.74120609739168, + 45.79851870489753 + ], + [ + -51.634802724732594, + 45.82173981098491 + ], + [ + -50.10141356043821, + 46.206967632588714 + ], + [ + -50.096495359219894, + 46.20817117129014 + ], + [ + -49.71527854186787, + 46.30139511274952 + ], + [ + -42.741818546794626, + 47.08932832308753 + ], + [ + -42.739975788113306, + 47.08947810968185 + ], + [ + -39.91296736498305, + 47.28446299339193 + ], + [ + -39.623537049973514, + 47.328766623103874 + ], + [ + -37.68167399134873, + 47.80425935654299 + ], + [ + -37.68009939647044, + 47.80462804342912 + ], + [ + -29.76078815969788, + 49.31359263607847 + ], + [ + -27.644122135922192, + 49.6027911968367 + ], + [ + -27.634195713726758, + 49.60406958173359 + ], + [ + -19.9371899229517, + 50.31712731207673 + ], + [ + -19.307215819634145, + 50.329562107284815 + ], + [ + -19.300285565831274, + 50.329691800236496 + ], + [ + -15.037524240423114, + 50.32890785641893 + ], + [ + -14.989597215318602, + 50.32858013594124 + ], + [ + -14.006084449297228, + 50.33115342444766 + ], + [ + -13.951530647042093, + 50.331923905419586 + ], + [ + -8.543392983229849, + 50.3466251562849 + ], + [ + -8.49564910078701, + 50.34611761777083 + ], + [ + -8.249877098980464, + 50.34680349679876 + ], + [ + -8.245645423180912, + 50.3468153210484 + ], + [ + -8.014634746649442, + 50.34747918871218 + ], + [ + -5.947695374492885, + 50.289881922415255 + ], + [ + -5.941730237539384, + 50.28966115176526 + ], + [ + -4.0727158679933195, + 50.205152186723424 + ], + [ + -4.067746587078215, + 50.20488501157081 + ], + [ + -2.7593156044197764, + 50.12722677582286 + ], + [ + -2.7127791941072608, + 50.12390549868996 + ], + [ + -2.3969452433166287, + 50.06578958709517 + ], + [ + -1.8870912008483534, + 49.969164781650285 + ], + [ + -1.6875527653048308, + 49.944677733413805 + ], + [ + -1.4847161055161482, + 49.94681000964992 + ], + [ + -1.286860688674307, + 49.97540069387861 + ], + [ + -1.1020469762230996, + 50.02922693454252 + ], + [ + -0.5518726294439481, + 50.23211091790308 + ], + [ + -0.013697186376082861, + 50.258740853050895 + ], + [ + 0.16809835695025555, + 50.27810013151892 + ], + [ + 0.3412369195700924, + 50.3185408113283 + ], + [ + 0.4999019266130275, + 50.37867456844708 + ], + [ + 0.6387154170078294, + 50.45646304984822 + ], + [ + 0.752895630175946, + 50.54927804865631 + ], + [ + 0.8384070395784382, + 50.65397763463997 + ], + [ + 0.8921004243905052, + 50.76699771885369 + ], + [ + 0.9118389730256152, + 50.88445842729022 + ], + [ + 0.8966046707269948, + 51.00228425381651 + ], + [ + 0.8465776424480642, + 51.11633622714359 + ], + [ + 0.8183134035462994, + 51.15238446791406 + ], + [ + 0.8040016611370555, + 51.26538943668414 + ], + [ + 0.7503428927262255, + 51.38430093151889 + ], + [ + 0.660278456184632, + 51.49446004498859 + ], + [ + 0.5369479924986849, + 51.59154115563105 + ], + [ + 0.3848977687540114, + 51.67167287675313 + ], + [ + 0.20993886407746284, + 51.731608404912606 + ], + [ + 0.018931304456925976, + 51.768876434161875 + ], + [ + -0.1804996247551183, + 51.78190263454282 + ], + [ + -0.3803012224113887, + 51.77009266638358 + ], + [ + -0.5723650848236536, + 51.73386980202591 + ], + [ + -0.7489078361599588, + 51.67466327657673 + ], + [ + -0.9028344209169333, + 51.594847126692386 + ], + [ + -1.0280591996395017, + 51.49763302235599 + ], + [ + -1.0604192395198893, + 51.45867181859095 + ], + [ + -1.2265820486636403, + 51.427238079627365 + ], + [ + -1.434525274666193, + 51.37083289362257 + ], + [ + -1.7255950285058104, + 51.265006140240544 + ], + [ + -1.822620821982945, + 51.28392435872125 + ], + [ + -2.2285775925677793, + 51.36163466223698 + ], + [ + -2.3932860498449413, + 51.383531491947124 + ], + [ + -2.528797358210337, + 51.39411895657753 + ], + [ + -2.5358986735144655, + 51.39465249914266 + ], + [ + -3.888823321148242, + 51.483354943911884 + ], + [ + -5.815202726617314, + 51.58199662495533 + ], + [ + -7.964984292998105, + 51.65409271678538 + ], + [ + -7.995519475368721, + 51.6544960580797 + ], + [ + -8.247713167041763, + 51.655184152884324 + ], + [ + -8.475188305349947, + 51.655827652323765 + ], + [ + -14.017492699680709, + 51.67055838522242 + ], + [ + -14.981576184133653, + 51.67299178460069 + ], + [ + -19.35977511652173, + 51.69500073222616 + ], + [ + -20.03418182056415, + 51.68472688039244 + ], + [ + -20.087449265180513, + 51.68292783421171 + ], + [ + -28.064340927601457, + 50.97756356870375 + ], + [ + -30.243657939981915, + 50.687204620557225 + ], + [ + -38.39389980451011, + 49.15538049337478 + ], + [ + -40.24139235093673, + 48.70733668324424 + ], + [ + -42.9947201061393, + 48.52065917564696 + ], + [ + -50.22428660772199, + 47.70779622038714 + ], + [ + -50.357416004567284, + 47.68205242914552 + ], + [ + -50.80999174181961, + 47.571287729884 + ], + [ + -52.321046127249964, + 47.19083908760016 + ], + [ + -56.78335209966178, + 46.29128267233601 + ], + [ + -56.78491156335719, + 46.290931702484414 + ], + [ + -67.40881136465347, + 43.275927699129674 + ], + [ + -67.48689158270071, + 43.2457225426504 + ], + [ + -70.32480928250537, + 41.96585564849461 + ], + [ + -71.66828885874065, + 41.861553429504355 + ], + [ + -71.80638623235117, + 41.841933918045015 + ], + [ + -71.93879240459695, + 41.80691837771797 + ], + [ + -72.69316317817211, + 41.55438696927575 + ], + [ + -72.8315420328571, + 41.496147733168115 + ], + [ + -74.21635260798573, + 40.773961341587686 + ], + [ + -74.22318093336749, + 40.7702922225587 + ], + [ + -74.93247918981355, + 40.381469546408645 + ], + [ + -76.025214316668, + 39.793305830862245 + ], + [ + -76.14546071281188, + 39.71416608803379 + ], + [ + -76.24532935685168, + 39.61981746154937 + ], + [ + -76.32754459566932, + 39.52600244710664 + ], + [ + -76.33305579795929, + 39.51962900032809 + ], + [ + -76.38402781216766, + 39.45991233769715 + ], + [ + -76.48329340825852, + 39.357461549701775 + ], + [ + -76.49109372423209, + 39.349272427520795 + ], + [ + -76.62285639879528, + 39.20848662324998 + ], + [ + -76.62969088871789, + 39.20106602893692 + ], + [ + -76.72512341642681, + 39.095820990723205 + ], + [ + -77.05630537387654, + 38.738458988765714 + ], + [ + -77.24068135591084, + 38.59753908210562 + ], + [ + -77.41270927746413, + 38.47387612905937 + ], + [ + -77.50187612378983, + 38.39905931622251 + ], + [ + -77.98038661096773, + 37.92779779870111 + ], + [ + -78.00795661691959, + 37.8989143140964 + ], + [ + -78.58395695083541, + 37.25565660602159 + ], + [ + -78.58470810022843, + 37.25481015447702 + ], + [ + -78.8467273832626, + 36.95808535291917 + ], + [ + -79.20749117077115, + 36.5508143735573 + ], + [ + -79.2120543584641, + 36.545587382925184 + ], + [ + -79.45874953615571, + 36.25926116150091 + ], + [ + -79.55116935013399, + 36.118182459438785 + ], + [ + -79.69162229354288, + 35.822639246678065 + ], + [ + -80.22169492594031, + 34.810272050242084 + ], + [ + -80.36229696833567, + 34.54203473965395 + ], + [ + -81.82859523670068, + 32.5071796400786 + ], + [ + -83.1613826959074, + 30.87786221968085 + ], + [ + -83.23254229508164, + 30.768672876753097 + ], + [ + -83.2778701789546, + 30.649774257514384 + ], + [ + -83.29582084715074, + 30.525628223075355 + ], + [ + -83.33523399618939, + 29.45617068522388 + ], + [ + -83.3354295634, + 29.45089249123257 + ], + [ + -83.35225818999757, + 28.96491007206857 + ], + [ + -83.7290499194458, + 28.62683647489964 + ], + [ + -83.82528429177412, + 28.541438597974928 + ], + [ + -85.06233868697878, + 28.073784080583607 + ], + [ + -85.19029313979529, + 28.009973138675917 + ], + [ + -85.30047803297676, + 27.924251873177614 + ], + [ + -85.38828630411717, + 27.820367009200865 + ], + [ + -85.4501201123372, + 27.702796815774974 + ], + [ + -85.83656692385804, + 26.71692793740433 + ], + [ + -85.88291575652858, + 26.60601423267908 + ], + [ + -85.92543186444311, + 26.43297140028777 + ], + [ + -85.95557555836514, + 26.081534995834076 + ], + [ + -85.95568209847939, + 26.08030071908932 + ], + [ + -86.00400047245975, + 25.530014870366788 + ], + [ + -86.73347452374198, + 24.34542028388064 + ], + [ + -86.77715459478196, + 24.25978438476426 + ], + [ + -86.80600580303962, + 24.169093165596724 + ], + [ + -86.9980181176512, + 23.342614743233174 + ], + [ + -87.00052291685684, + 23.331483827922025 + ], + [ + -87.09638292626103, + 22.888488565911086 + ], + [ + -87.09692790222645, + 22.885963629544122 + ], + [ + -87.17674970678135, + 22.51472948081831 + ], + [ + -87.48102908146565, + 21.15474213583981 + ], + [ + -87.49544920662622, + 21.037069715946558 + ], + [ + -87.4853062107191, + 20.919049020548943 + ], + [ + -87.45105631632808, + 20.805117510200795 + ], + [ + -87.39403499377285, + 20.699549486650422 + ], + [ + -87.31640317156327, + 20.606307701756446 + ], + [ + -87.22106923508275, + 20.52890532090329 + ], + [ + -87.11158890878953, + 20.470281406218337 + ], + [ + -86.99204502148895, + 20.43269316445504 + ], + [ + -86.86690928477846, + 20.41762837550609 + ], + [ + -86.74088863899391, + 20.425741547369732 + ], + [ + -86.61875943958046, + 20.45681729288296 + ], + [ + -86.5051937075359, + 20.50976407180516 + ], + [ + -86.40458273718538, + 20.58264070749041 + ], + [ + -86.32086439599244, + 20.6727169432618 + ], + [ + -86.25736130299383, + 20.776567783270217 + ], + [ + -86.21663757797059, + 20.890199558218146 + ], + [ + -85.88767639041292, + 22.263013204860272 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.85, + 21.025 + ], + [ + -86.53333, + 22.39167 + ], + [ + -86.45, + 22.765 + ], + [ + -86.35, + 23.21 + ], + [ + -86.15, + 24.04 + ], + [ + -85.33333, + 25.34167 + ], + [ + -85.26667, + 26.03 + ], + [ + -85.23333, + 26.38333 + ], + [ + -85.18333, + 26.5 + ], + [ + -84.78333, + 27.49333 + ], + [ + -83.41667, + 28 + ], + [ + -83.21667, + 28.175 + ], + [ + -82.63333, + 28.69 + ], + [ + -82.6, + 29.43 + ], + [ + -82.55, + 30.505 + ], + [ + -81.18333, + 32.14667 + ], + [ + -79.65, + 34.23333 + ], + [ + -79.48333, + 34.54333 + ], + [ + -78.93333, + 35.56667 + ], + [ + -78.78333, + 35.87333 + ], + [ + -78.53333, + 36.15833 + ], + [ + -78.16667, + 36.565 + ], + [ + -77.9, + 36.86167 + ], + [ + -77.31667, + 37.50167 + ], + [ + -76.83333, + 37.97 + ], + [ + -76.65, + 38.1 + ], + [ + -76.4, + 38.28833 + ], + [ + -76.01667, + 38.695 + ], + [ + -75.91667, + 38.80333 + ], + [ + -75.78333, + 38.94333 + ], + [ + -75.66667, + 39.06167 + ], + [ + -75.6, + 39.13833 + ], + [ + -75.51667, + 39.23167 + ], + [ + -74.41667, + 39.81667 + ], + [ + -73.7, + 40.205 + ], + [ + -72.31667, + 40.91833 + ], + [ + -71.56667, + 41.16667 + ], + [ + -70.01667, + 41.28167 + ], + [ + -67, + 42.63333 + ], + [ + -56.46667, + 45.60333 + ], + [ + -52, + 46.5 + ], + [ + -50.45, + 46.89 + ], + [ + -50, + 47 + ], + [ + -42.86667, + 47.805 + ], + [ + -40, + 48 + ], + [ + -38.03333, + 48.48 + ], + [ + -30, + 50 + ], + [ + -27.85, + 50.29 + ], + [ + -20, + 51 + ], + [ + -19.33333, + 51.01167 + ], + [ + -15, + 51 + ], + [ + -14, + 51 + ], + [ + -8.5, + 51 + ], + [ + -8.25, + 51 + ], + [ + -8, + 51 + ], + [ + -5.88333, + 50.935 + ], + [ + -3.98333, + 50.84333 + ], + [ + -2.65, + 50.76 + ], + [ + -2.51667, + 50.75 + ], + [ + -2.11667, + 50.675 + ], + [ + -1.6, + 50.575 + ], + [ + -0.93333, + 50.82 + ], + [ + -0.75, + 50.855 + ], + [ + -0.08333, + 50.88667 + ], + [ + -0.18333, + 50.985 + ], + [ + -0.18333, + 51.14833 + ] + ] + } + } + ] +} diff --git a/src/buffer/test/out/issue-#916.geojson b/src/buffer/test/out/issue-#916.geojson new file mode 100644 index 0000000000..e1eee5d494 --- /dev/null +++ b/src/buffer/test/out/issue-#916.geojson @@ -0,0 +1,343 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 124.26790019618994, + -25.470694560490813 + ], + [ + 124.21101927298409, + -25.538676432824264 + ], + [ + 124.14338958062065, + -25.66291362290798 + ], + [ + 124.10294870674184, + -25.796520684590803 + ], + [ + 124.09125285516312, + -25.934647436639427 + ], + [ + 124.10882703675897, + -26.07226442814918 + ], + [ + 124.57833990508695, + -28.03278842233986 + ], + [ + 124.62517620484833, + -28.163807973393293 + ], + [ + 124.6992047129557, + -28.284612842994484 + ], + [ + 124.79783656414072, + -28.39082295885811 + ], + [ + 124.91756046827972, + -28.47857132404831 + ], + [ + 125.05406297216787, + -28.544650010013484 + ], + [ + 125.20238413041201, + -28.586633362047674 + ], + [ + 125.35710307943894, + -28.60297273085238 + ], + [ + 130.9318365860716, + -28.60379528125188 + ], + [ + 131.10419741038106, + -28.58395194314618 + ], + [ + 131.2678357749556, + -28.532389058562824 + ], + [ + 131.41532848486722, + -28.45146009627827 + ], + [ + 134.89004570506327, + -25.964136965049125 + ], + [ + 134.9938185860811, + -25.871514380515205 + ], + [ + 135.0771292310742, + -25.763369841011883 + ], + [ + 135.137257545097, + -25.643328056071166 + ], + [ + 135.17227750228795, + -25.515396246269002 + ], + [ + 135.18111107341196, + -25.38382857323427 + ], + [ + 135.16355237731173, + -25.25298453824904 + ], + [ + 134.17465973414912, + -20.861039974344624 + ], + [ + 134.12936747712234, + -20.72262559383897 + ], + [ + 134.05584106627336, + -20.595396692475706 + ], + [ + 133.95704803861463, + -20.484393704100277 + ], + [ + 133.8369311782889, + -20.394010159219725 + ], + [ + 133.7002524490249, + -20.327823424521476 + ], + [ + 133.55240897637773, + -20.288456615428675 + ], + [ + 129.87806579101562, + -19.631778237485698 + ], + [ + 129.72743851891101, + -19.617520931098447 + ], + [ + 129.57677092596023, + -19.631433004778412 + ], + [ + 129.431850898074, + -19.672982026344048 + ], + [ + 129.29825439817904, + -19.740572045170357 + ], + [ + 124.25911796365276, + -22.78708557945801 + ], + [ + 124.13364190056842, + -22.8766327504303 + ], + [ + 124.03003366697074, + -22.987673483237124 + ], + [ + 123.95253829866012, + -23.115700713747394 + ], + [ + 123.90437075633996, + -23.255511572532257 + ], + [ + 123.88757924967044, + -23.401412843158873 + ], + [ + 123.87867840375317, + -24.843815903282284 + ], + [ + 123.89459493093075, + -24.99307791794546 + ], + [ + 123.94394270312867, + -25.136154362199328 + ], + [ + 124.02472029449757, + -25.266895718810964 + ], + [ + 124.13354860250769, + -25.379658978858924 + ], + [ + 124.26580025719015, + -25.469556036872177 + ], + [ + 124.26790019618994, + -25.470694560490813 + ] + ], + [ + [ + 126.28574411508468, + -25.78650256511696 + ], + [ + 126.34342722471119, + -25.70904148702555 + ], + [ + 126.4046570071951, + -25.5750590623009 + ], + [ + 126.88050849387616, + -24.120896152683187 + ], + [ + 130.05233283587805, + -22.293029796137876 + ], + [ + 131.5691708137879, + -22.753372767858473 + ], + [ + 132.11784189526264, + -24.953516912436683 + ], + [ + 130.6568607857764, + -25.797177288660954 + ], + [ + 126.66708638990343, + -25.974235295477417 + ], + [ + 126.28574411508468, + -25.78650256511696 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 124.67285156250001, + -24.846565348219734 + ], + [ + 125.63964843750001, + -25.36388227274024 + ], + [ + 126.21093749999999, + -23.644524198573677 + ], + [ + 129.9462890625, + -21.493963563064455 + ], + [ + 132.2314453125, + -22.187404991398775 + ], + [ + 133.0224609375, + -25.28443774698303 + ], + [ + 130.9130859375, + -26.509904531413916 + ], + [ + 126.474609375, + -26.706359857633526 + ], + [ + 124.892578125, + -25.918526162075153 + ], + [ + 125.3759765625, + -27.877928333679495 + ], + [ + 130.9130859375, + -27.877928333679495 + ], + [ + 134.38476562499997, + -25.403584973186703 + ], + [ + 133.41796874999997, + -21.002471054356715 + ], + [ + 129.7265625, + -20.34462694382967 + ], + [ + 124.67285156250001, + -23.40276490540795 + ], + [ + 124.67285156250001, + -24.846565348219734 + ] + ] + ] + } + } + ] +} diff --git a/src/buffer/test/out/linestring.geojson b/src/buffer/test/out/linestring.geojson new file mode 100644 index 0000000000..7dccc1eb81 --- /dev/null +++ b/src/buffer/test/out/linestring.geojson @@ -0,0 +1,299 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 127.22013244621311, + -24.892043480544004 + ], + [ + 132.80646400599005, + -21.50601486261021 + ], + [ + 137.0540572923261, + -21.131237112426195 + ], + [ + 141.7644841659969, + -23.24410872938328 + ], + [ + 146.07270116988553, + -28.94597820716372 + ], + [ + 146.2978283289387, + -31.489579441095735 + ], + [ + 146.32716532006174, + -31.62762345307569 + ], + [ + 146.3875971285775, + -31.758059946166895 + ], + [ + 146.4768829978358, + -31.875807806641646 + ], + [ + 146.591617662056, + -31.976269055930747 + ], + [ + 146.72735705912353, + -32.0555167850505 + ], + [ + 146.87879360620954, + -32.11045658366262 + ], + [ + 147.03997390826035, + -32.13895350997256 + ], + [ + 147.20454849691538, + -32.13991828933155 + ], + [ + 147.36604061084165, + -32.11334860426942 + ], + [ + 147.51811952753872, + -32.06032386596488 + ], + [ + 147.6548637852529, + -31.982954488324072 + ], + [ + 147.77100081505017, + -31.884289148116796 + ], + [ + 147.8621118301574, + -31.76818556378521 + ], + [ + 147.92479390409412, + -31.639151793006782 + ], + [ + 147.95677453425768, + -31.50216587003928 + ], + [ + 147.95697717557061, + -31.362481819314787 + ], + [ + 147.67151847014654, + -28.632540356966327 + ], + [ + 147.64550425721137, + -28.503729391313545 + ], + [ + 147.59341839216376, + -28.381241413489676 + ], + [ + 147.51706910360048, + -28.26915091029034 + ], + [ + 142.9441899449137, + -22.279401170333728 + ], + [ + 142.85337177933837, + -22.17384984611597 + ], + [ + 142.74311798476123, + -22.08583587363726 + ], + [ + 142.61727145081034, + -22.018424266771188 + ], + [ + 137.54141932165535, + -19.736059592956593 + ], + [ + 137.40501106901908, + -19.686218799260697 + ], + [ + 137.2611381063957, + -19.661670974954614 + ], + [ + 137.11495737956835, + -19.66330330353839 + ], + [ + 132.47810452712636, + -20.07296337424562 + ], + [ + 132.34658652909772, + -20.09373746029527 + ], + [ + 132.22079576639794, + -20.13556628637506 + ], + [ + 132.10446826579343, + -20.197202532638663 + ], + [ + 126.23787922109257, + -23.75478051445208 + ], + [ + 126.09961151304762, + -23.85457893615992 + ], + [ + 125.9888260285237, + -23.980108202851113 + ], + [ + 120.44796502192517, + -31.15671608797643 + ], + [ + 120.36466520203695, + -31.275828113591327 + ], + [ + 120.30976818998701, + -31.406541020582413 + ], + [ + 120.28546162051528, + -31.543904883793815 + ], + [ + 120.2928026666241, + -31.682700608377356 + ], + [ + 120.33165936233902, + -31.81763091621443 + ], + [ + 120.40069286111094, + -31.943517781764438 + ], + [ + 120.49738475527029, + -32.05549985432145 + ], + [ + 120.61811227938665, + -32.149222675662536 + ], + [ + 120.75827216014312, + -32.2210139357441 + ], + [ + 120.91245110785613, + -32.26803578236144 + ], + [ + 121.07463769046458, + -32.288406482856544 + ], + [ + 121.23846696604487, + -32.28128464379574 + ], + [ + 121.39748624731273, + -32.24691075494595 + ], + [ + 121.54542820434806, + -32.186602954902 + ], + [ + 121.67647654620136, + -32.102706433201526 + ], + [ + 121.78550992993978, + -31.998498533467828 + ], + [ + 127.22013244621311, + -24.892043480544004 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 121.11328124999999, + -31.57853542647337 + ], + [ + 126.65039062499999, + -24.367113562651262 + ], + [ + 132.5390625, + -20.797201434306984 + ], + [ + 137.197265625, + -20.385825381874263 + ], + [ + 142.294921875, + -22.67484735118852 + ], + [ + 146.865234375, + -28.690587654250685 + ], + [ + 147.12890625, + -31.42866311735861 + ] + ] + } + } + ] +} diff --git a/src/buffer/test/out/multi-linestring.geojson b/src/buffer/test/out/multi-linestring.geojson new file mode 100644 index 0000000000..f78cb54046 --- /dev/null +++ b/src/buffer/test/out/multi-linestring.geojson @@ -0,0 +1,865 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 133.1456377874244, + -27.748413388173244 + ], + [ + 133.00580396873673, + -27.876161425939653 + ], + [ + 132.90569722755788, + -27.987304423543936 + ], + [ + 132.83173862423337, + -28.11359868386515 + ], + [ + 132.78683301646186, + -28.250237708851074 + ], + [ + 132.77280462753225, + -28.392004880322105 + ], + [ + 132.79031278873813, + -28.53346831863892 + ], + [ + 132.83880862082754, + -28.66918659642872 + ], + [ + 132.91653693761648, + -28.79391805402975 + ], + [ + 133.0205863169076, + -28.902825833999305 + ], + [ + 133.14698834694653, + -28.99167033561001 + ], + [ + 133.2908645411406, + -29.056980711281035 + ], + [ + 133.44661647379945, + -29.096197410627756 + ], + [ + 133.60815161448494, + -29.10777871471303 + ], + [ + 133.76913451473533, + -29.09126571477119 + ], + [ + 133.92325083910663, + -29.047302207745542 + ], + [ + 134.06447057601648, + -28.97760834715918 + ], + [ + 134.18729680559906, + -28.884909377873228 + ], + [ + 139.01600112562306, + -24.168489222765196 + ], + [ + 139.10687095808518, + -24.05393202679261 + ], + [ + 139.17161287715265, + -23.925327075112033 + ], + [ + 139.20783078337837, + -23.787609459201473 + ], + [ + 139.2142357231303, + -23.64604483392584 + ], + [ + 139.19068036804418, + -23.506027557757417 + ], + [ + 138.99371759396965, + -22.79400222899974 + ], + [ + 140.72101859598558, + -23.358768756407184 + ], + [ + 140.87049453572067, + -23.391745682816005 + ], + [ + 141.02406069306937, + -23.397013216286688 + ], + [ + 141.17571772673938, + -23.37438495934912 + ], + [ + 141.31955280103287, + -23.32476362104381 + ], + [ + 141.44998049741918, + -23.25010102148956 + ], + [ + 141.56196665702504, + -23.153315767581926 + ], + [ + 141.65122502417898, + -23.03817304278057 + ], + [ + 141.71437870629546, + -22.909132537909134 + ], + [ + 141.74908095943124, + -22.771171625716914 + ], + [ + 141.75409232687116, + -22.629591447823177 + ], + [ + 141.7293134320633, + -22.48981370741109 + ], + [ + 141.67577458969697, + -22.35717575624883 + ], + [ + 141.5955847956552, + -22.23673115066919 + ], + [ + 141.49184363098274, + -22.13306232695063 + ], + [ + 141.36852027122387, + -22.050111470601415 + ], + [ + 141.23030425416755, + -21.991035040075534 + ], + [ + 139.26247409458722, + -21.34224310238433 + ], + [ + 139.0542168866737, + -21.30092543365977 + ], + [ + 138.58089158715558, + -21.268510738634085 + ], + [ + 138.16251331527744, + -19.677588583030353 + ], + [ + 138.11644054935647, + -19.55129960877897 + ], + [ + 138.04683341303658, + -19.43511099593644 + ], + [ + 137.95607210372611, + -19.332927215678602 + ], + [ + 137.8472305575218, + -19.24817825815916 + ], + [ + 134.95294486448333, + -17.341967717244916 + ], + [ + 134.81428323840933, + -17.267964616399944 + ], + [ + 134.6626988463053, + -17.2232265625427 + ], + [ + 134.5047791832159, + -17.209695682406853 + ], + [ + 134.34737745965936, + -17.22795770124567 + ], + [ + 128.83324099561716, + -18.35211368123114 + ], + [ + 128.63161954019705, + -18.419072274134876 + ], + [ + 126.87969957003298, + -19.26566845462921 + ], + [ + 126.20309768864394, + -18.16072473044489 + ], + [ + 126.11671835310983, + -18.04640698226966 + ], + [ + 126.00879516655735, + -17.95039687393182 + ], + [ + 125.88350104792588, + -17.876349669547785 + ], + [ + 125.74564828205651, + -17.82706881332598 + ], + [ + 125.60050411884849, + -17.804404135927868 + ], + [ + 125.45359267360674, + -17.809187041558857 + ], + [ + 125.31049018803202, + -17.84120435208729 + ], + [ + 125.17662057862518, + -17.899211007085302 + ], + [ + 125.0570578749139, + -17.98098043214136 + ], + [ + 124.95634168363961, + -18.08339015862708 + ], + [ + 124.87831127015464, + -18.20253924757466 + ], + [ + 124.82596328727986, + -18.33389324515096 + ], + [ + 124.80133764690031, + -18.472451749280708 + ], + [ + 124.80543552412081, + -18.612933143473615 + ], + [ + 124.83817296279649, + -18.749970596061647 + ], + [ + 124.89837292495737, + -18.878312988582195 + ], + [ + 125.51549231484066, + -19.904408471591672 + ], + [ + 122.20342650875605, + -21.3770040702633 + ], + [ + 122.07465275388348, + -21.446967670688966 + ], + [ + 121.96280288197998, + -21.538959744221316 + ], + [ + 121.87211955570244, + -21.649479701334972 + ], + [ + 121.80606575335271, + -21.77433047819553 + ], + [ + 121.76719571096919, + -21.908772395516916 + ], + [ + 121.75705515231138, + -22.047696366546386 + ], + [ + 121.7761146228984, + -22.18581117812961 + ], + [ + 121.8237393779365, + -22.31783912916863 + ], + [ + 121.89819871320417, + -22.438713832668153 + ], + [ + 121.99671672904823, + -22.543773496165908 + ], + [ + 122.11556517045855, + -22.628942570370118 + ], + [ + 122.25019715653404, + -22.690894420351583 + ], + [ + 122.39541837364575, + -22.72718776880056 + ], + [ + 122.54558984732549, + -22.73637021138549 + ], + [ + 122.69485401213139, + -22.71804318320614 + ], + [ + 122.8373737947359, + -22.672884357832697 + ], + [ + 126.27525306787221, + -21.155243289191215 + ], + [ + 127.1878921619722, + -22.636832108862553 + ], + [ + 126.81338888993282, + -22.769178710694632 + ], + [ + 126.62148308204237, + -22.8670867532013 + ], + [ + 121.59204954677985, + -26.1574242796444 + ], + [ + 121.47334505765453, + -26.246476724025346 + ], + [ + 121.37598051888207, + -26.35456405963767 + ], + [ + 121.30367411260634, + -26.477590981136014 + ], + [ + 121.2592278848952, + -26.610895748815754 + ], + [ + 121.24441745534536, + -26.749419248118798 + ], + [ + 121.25991431284238, + -26.887889406993093 + ], + [ + 121.30524484920879, + -27.02101550443267 + ], + [ + 121.37878986547527, + -27.14368632518932 + ], + [ + 121.47782744980184, + -27.25116550138631 + ], + [ + 121.59862073515616, + -27.33927682129219 + ], + [ + 121.7365500493295, + -27.404571915988452 + ], + [ + 121.88628644615758, + -27.44447271429597 + ], + [ + 122.04200077078026, + -27.457381527273938 + ], + [ + 122.19759959715871, + -27.44275267294218 + ], + [ + 122.34697697710673, + -27.401121181341978 + ], + [ + 122.48426932974859, + -27.33408623417085 + ], + [ + 127.47278138738238, + -24.080713989256267 + ], + [ + 127.98010288120018, + -23.901933848961647 + ], + [ + 129.9565455310538, + -26.960332227479338 + ], + [ + 130.05699200236438, + -27.08108322909391 + ], + [ + 130.18337101259596, + -27.18055076702739 + ], + [ + 130.33022413421043, + -27.254371272696055 + ], + [ + 130.49114914576137, + -27.299290962358697 + ], + [ + 133.1456377874244, + -27.748413388173244 + ] + ], + [ + [ + 127.65186036908231, + -20.51319008682445 + ], + [ + 129.2328792164412, + -19.752509227562143 + ], + [ + 134.3551818876765, + -18.718256485299424 + ], + [ + 136.7380316676794, + -20.291361760257143 + ], + [ + 136.95447378068698, + -21.14675142088533 + ], + [ + 132.49464734521052, + -20.731280741274784 + ], + [ + 132.36223058320857, + -20.727894620471417 + ], + [ + 132.2311373930769, + -20.745746933501625 + ], + [ + 132.1051715706694, + -20.784313489869643 + ], + [ + 128.6534802811417, + -22.106796212007144 + ], + [ + 127.65186036908231, + -20.51319008682445 + ] + ], + [ + [ + 129.45978970389856, + -23.366896622815332 + ], + [ + 132.52269379134668, + -22.196469113998564 + ], + [ + 137.33839578521304, + -22.63476887837502 + ], + [ + 137.56220392400434, + -23.48447700479171 + ], + [ + 134.49101372150182, + -26.496005031038635 + ], + [ + 134.3440394141512, + -26.46016820312111 + ], + [ + 131.15327556646602, + -25.938707114573365 + ], + [ + 129.45978970389856, + -23.366896622815332 + ] + ] + ], + [ + [ + [ + 143.77442661636638, + -25.246563217697254 + ], + [ + 141.46210822929044, + -29.008201160503003 + ], + [ + 139.2278821851676, + -30.777112402607532 + ], + [ + 139.11637190672275, + -30.881615268986945 + ], + [ + 139.0304125564286, + -31.00283639641893 + ], + [ + 138.97338324543261, + -31.136164483205704 + ], + [ + 138.947591744415, + -31.276505370318638 + ], + [ + 138.95416916542197, + -31.41847299473038 + ], + [ + 138.99300571692808, + -31.556594722599414 + ], + [ + 139.06273297340314, + -31.685523609412286 + ], + [ + 139.16075673038958, + -31.800249344429105 + ], + [ + 139.28334246526418, + -31.896299104912224 + ], + [ + 139.42575270633975, + -31.96991939499075 + ], + [ + 139.5824323850185, + -32.01823029744885 + ], + [ + 139.74723481417283, + -32.039344512450825 + ], + [ + 139.91367772379863, + -32.03244511427312 + ], + [ + 140.07521625520386, + -31.997818052011915 + ], + [ + 140.22551836880402, + -31.936837884825774 + ], + [ + 140.35872799951022, + -31.851907836827174 + ], + [ + 142.68593297844816, + -29.984085897978893 + ], + [ + 142.77345884126203, + -29.89942623039856 + ], + [ + 142.84445491885668, + -29.803801293303056 + ], + [ + 145.27903995624038, + -25.74015611976182 + ], + [ + 145.33582686682576, + -25.61512289422364 + ], + [ + 145.3656720280742, + -25.48266987363135 + ], + [ + 145.36761536203036, + -25.34749678604949 + ], + [ + 145.1313389666536, + -22.503846326237387 + ], + [ + 145.10587187894538, + -22.365249639191614 + ], + [ + 145.05194930742215, + -22.233889262918687 + ], + [ + 144.97168597923152, + -22.114761235872848 + ], + [ + 144.86817269301378, + -22.012392401702897 + ], + [ + 144.74535739784199, + -21.930674162414334 + ], + [ + 144.6078986250078, + -21.872719080919058 + ], + [ + 144.46099593257287, + -21.840745019327017 + ], + [ + 144.3102023887842, + -21.835990854339173 + ], + [ + 144.161224534631, + -21.858667021073078 + ], + [ + 144.0197157050256, + -21.90794316861217 + ], + [ + 143.89106900372244, + -21.98197406285673 + ], + [ + 143.7802165632134, + -22.077963575166166 + ], + [ + 143.69144192747123, + -22.192265203065567 + ], + [ + 143.62821243302167, + -22.320516147499735 + ], + [ + 143.59303829890118, + -22.457800584530332 + ], + [ + 143.58736473172004, + -22.59883647498312 + ], + [ + 143.77442661636638, + -25.246563217697254 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [ + 122.03613281249999, + -26.74561038219901 + ], + [ + 127.08984375000001, + -23.443088931121775 + ], + [ + 132.4072265625, + -21.453068633086772 + ], + [ + 138.9990234375, + -22.024545601240337 + ], + [ + 140.9765625, + -22.67484735118852 + ] + ], + [ + [ + 125.5517578125, + -18.521283325496263 + ], + [ + 130.6494140625, + -26.588527147308614 + ], + [ + 134.208984375, + -27.17646913189887 + ] + ], + [ + [ + 122.51953124999999, + -22.024545601240337 + ], + [ + 128.9794921875, + -19.062117883514652 + ], + [ + 134.5166015625, + -17.936928637549432 + ], + [ + 137.4169921875, + -19.84939395842278 + ], + [ + 138.427734375, + -23.68477416688374 + ], + [ + 133.59375, + -28.38173504322308 + ] + ], + [ + [ + 144.3603515625, + -22.55314747840318 + ], + [ + 144.580078125, + -25.403584973186703 + ], + [ + 142.11914062499997, + -29.458731185355315 + ], + [ + 139.7900390625, + -31.316101383495635 + ] + ] + ] + } + } + ] +} diff --git a/src/buffer/test/out/multi-point.geojson b/src/buffer/test/out/multi-point.geojson new file mode 100644 index 0000000000..662dc9ea09 --- /dev/null +++ b/src/buffer/test/out/multi-point.geojson @@ -0,0 +1,407 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "radius": 300, + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 129.6696178514331, + -24.32283020680647 + ], + [ + 129.84348046885094, + -24.34462560762022 + ], + [ + 130.77177457945595, + -24.289779897716784 + ], + [ + 131.66881805542394, + -24.064263451673092 + ], + [ + 132.49662100003863, + -23.67733360807704 + ], + [ + 133.22094321528326, + -23.145167342755467 + ], + [ + 133.8130152012347, + -22.489916461278526 + ], + [ + 134.25069326449548, + -21.7384848532774 + ], + [ + 134.51903831261134, + -20.921171502822272 + ], + [ + 134.61040792052222, + -20.07029975850336 + ], + [ + 134.52420081939061, + -19.21891001087602 + ], + [ + 134.2663910616285, + -18.399547729731566 + ], + [ + 133.84895155864763, + -17.64314651943112 + ], + [ + 133.28921559756068, + -16.977993760480466 + ], + [ + 132.60918017109418, + -16.42877388665649 + ], + [ + 131.83472944491817, + -16.01570451519151 + ], + [ + 130.99475502222808, + -15.753803152579945 + ], + [ + 130.1201684722707, + -15.6523365167178 + ], + [ + 129.24283126186185, + -15.714503273772683 + ], + [ + 128.39445505288927, + -15.93738252042378 + ], + [ + 127.60553971634508, + -16.31214945800451 + ], + [ + 126.90441102238391, + -16.824526046925637 + ], + [ + 126.31639597898614, + -17.45540887524193 + ], + [ + 125.86313928028491, + -18.18160708529926 + ], + [ + 125.56203111031091, + -18.976632462881103 + ], + [ + 125.42569618622419, + -19.811508122901994 + ], + [ + 125.46149450564576, + -20.655593508541383 + ], + [ + 125.47995993708079, + -20.728081989455667 + ], + [ + 125.31261461997994, + -20.703001668373794 + ], + [ + 124.41665822422071, + -20.73252168752046 + ], + [ + 123.54438261096341, + -20.920546061786432 + ], + [ + 122.72622555458788, + -21.25920654553479 + ], + [ + 121.99060201875295, + -21.73545335148907 + ], + [ + 121.36320262415056, + -22.33165420155013 + ], + [ + 120.86641485741012, + -23.026264928569397 + ], + [ + 120.51882400063022, + -23.794518657163064 + ], + [ + 120.33473236861728, + -24.609107416820304 + ], + [ + 120.32363672915567, + -25.440863105747532 + ], + [ + 120.48962851858694, + -26.259474913786388 + ], + [ + 120.83072897256059, + -27.03429865813306 + ], + [ + 121.33823535083626, + -27.73531264110176 + ], + [ + 121.99622170209133, + -28.334250424946546 + ], + [ + 122.78138706492292, + -28.805894312389256 + ], + [ + 123.66345024238738, + -29.129452501068418 + ], + [ + 124.60623295667261, + -29.289883762557427 + ], + [ + 125.56945066642588, + -29.278996693942286 + ], + [ + 126.51106996130187, + -29.096154011919577 + ], + [ + 127.38994581693444, + -28.74846194097248 + ], + [ + 128.1683772747141, + -28.250408831141872 + ], + [ + 128.81424671594323, + -27.623009490820273 + ], + [ + 129.30252304311435, + -26.89258291091487 + ], + [ + 129.6160643016821, + -26.08932181187163 + ], + [ + 129.74579328363347, + -25.24580095174931 + ], + [ + 129.69040149674416, + -24.395530937714796 + ], + [ + 129.6696178514331, + -24.32283020680647 + ] + ] + ], + [ + [ + [ + 144.68738538002003, + -20.703001668373794 + ], + [ + 143.79937203549397, + -20.834211340085947 + ], + [ + 142.95115976445067, + -21.122471389340784 + ], + [ + 142.17381814940023, + -21.558177701702455 + ], + [ + 141.49658789291686, + -22.12603561777089 + ], + [ + 140.94586686262005, + -22.805532778662965 + ], + [ + 140.54424627213882, + -23.57161570772571 + ], + [ + 140.30959850325578, + -24.395530937714806 + ], + [ + 140.2542067163665, + -25.245800951749313 + ], + [ + 140.38393569831788, + -26.089321811871656 + ], + [ + 140.69747695688562, + -26.892582910914882 + ], + [ + 141.18575328405674, + -27.623009490820273 + ], + [ + 141.83162272528588, + -28.250408831141872 + ], + [ + 142.61005418306556, + -28.748461940972497 + ], + [ + 143.48893003869813, + -29.096154011919577 + ], + [ + 144.43054933357408, + -29.278996693942286 + ], + [ + 145.3937670433274, + -29.289883762557427 + ], + [ + 146.33654975761263, + -29.129452501068425 + ], + [ + 147.2186129350771, + -28.805894312389256 + ], + [ + 148.00377829790867, + -28.33425042494654 + ], + [ + 148.66176464916373, + -27.73531264110176 + ], + [ + 149.16927102743938, + -27.03429865813306 + ], + [ + 149.51037148141305, + -26.25947491378638 + ], + [ + 149.67636327084426, + -25.440863105747514 + ], + [ + 149.6652676313827, + -24.609107416820304 + ], + [ + 149.48117599936975, + -23.794518657163064 + ], + [ + 149.13358514258985, + -23.02626492856939 + ], + [ + 148.6367973758494, + -22.331654201550112 + ], + [ + 148.00939798124702, + -21.73545335148906 + ], + [ + 147.27377444541207, + -21.259206545534784 + ], + [ + 146.45561738903655, + -20.920546061786418 + ], + [ + 145.58334177577922, + -20.73252168752046 + ], + [ + 144.68738538002003, + -20.703001668373794 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "radius": 300, + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "MultiPoint", + "coordinates": [ + [ + 145, + -25 + ], + [ + 130, + -20 + ], + [ + 125, + -25 + ] + ] + } + } + ] +} diff --git a/src/buffer/test/out/multi-polygon.geojson b/src/buffer/test/out/multi-polygon.geojson new file mode 100644 index 0000000000..73a2c6b83c --- /dev/null +++ b/src/buffer/test/out/multi-polygon.geojson @@ -0,0 +1,595 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 133.9390410551982, + -32.216150319797514 + ], + [ + 133.94006086734612, + -32.22828875440708 + ], + [ + 133.98643210456922, + -32.368926674720484 + ], + [ + 134.06521568752814, + -32.498795319337376 + ], + [ + 134.17332239413787, + -32.61258188158997 + ], + [ + 134.30641568022847, + -32.70561147728879 + ], + [ + 134.45907941531527, + -32.77404764901404 + ], + [ + 134.6250408366257, + -32.81505956438866 + ], + [ + 142.90992119812142, + -33.817866600744765 + ], + [ + 143.07097999716885, + -33.81896552249665 + ], + [ + 143.2293733846654, + -33.79488603468584 + ], + [ + 143.37946852676185, + -33.74650610451563 + ], + [ + 143.5159576278195, + -33.6755642268528 + ], + [ + 143.6340550185929, + -33.58459078338587 + ], + [ + 143.72966872893835, + -33.47681082819884 + ], + [ + 143.79953994390664, + -33.356023108598556 + ], + [ + 143.84134612760255, + -33.22646086267621 + ], + [ + 143.85376596361763, + -33.09264025520138 + ], + [ + 143.92123284675833, + -16.865253366716136 + ], + [ + 143.9096891830665, + -16.72070725390441 + ], + [ + 143.86839198981787, + -16.58129767735649 + ], + [ + 143.79905849421758, + -16.452642711836663 + ], + [ + 143.70451571827306, + -16.33992348580157 + ], + [ + 143.5885847571874, + -16.24768101231949 + ], + [ + 137.14563593424802, + -11.878409403606268 + ], + [ + 137.03221446686624, + -11.812351718461302 + ], + [ + 136.90871570557837, + -11.76714670399308 + ], + [ + 136.77904540872098, + -11.744228438823091 + ], + [ + 136.64730209916624, + -11.744326340058842 + ], + [ + 136.5176501516209, + -11.767441848288927 + ], + [ + 131.08315242997895, + -13.176728572883993 + ], + [ + 131.00100706345444, + -13.202076904500913 + ], + [ + 125.13402173441682, + -15.283021411658881 + ], + [ + 125.00084147981444, + -15.342646024202459 + ], + [ + 124.88234601095586, + -15.426497638181873 + ], + [ + 124.78314872865793, + -15.531290318310056 + ], + [ + 124.70712407254169, + -15.65292884008342 + ], + [ + 124.65726048439092, + -15.786665332783588 + ], + [ + 124.63554430544326, + -15.927279682715591 + ], + [ + 124.64287868725826, + -16.069277601678323 + ], + [ + 124.67904092827985, + -16.207099809784154 + ], + [ + 124.74268088954608, + -16.335335363203612 + ], + [ + 125.86061755305656, + -18.100685879191712 + ], + [ + 122.01759268819036, + -18.01948550545928 + ], + [ + 121.86697637523618, + -18.029399070095177 + ], + [ + 121.72159163747897, + -18.068110017680464 + ], + [ + 121.58735986361062, + -18.13399508959637 + ], + [ + 121.46974631436062, + -18.22433114807239 + ], + [ + 121.3735480096234, + -18.335408026251145 + ], + [ + 121.30270663287016, + -18.462678196303468 + ], + [ + 121.26015224531248, + -18.600937511962947 + ], + [ + 121.24768293159906, + -18.744530652461233 + ], + [ + 121.1623814996688, + -31.447326768785416 + ], + [ + 121.17277755665577, + -31.583259380702668 + ], + [ + 121.21328347401098, + -31.71501982222534 + ], + [ + 121.28255293795416, + -31.837770182290367 + ], + [ + 121.37816263347644, + -31.946976101874757 + ], + [ + 121.49668256104528, + -32.03857678942434 + ], + [ + 121.63378894233759, + -32.109141438134515 + ], + [ + 121.78441783097172, + -32.15600520336647 + ], + [ + 121.94295481594227, + -32.17737817007038 + ], + [ + 133.9390410551982, + -32.216150319797514 + ] + ], + [ + [ + 135.21741475594808, + -23.069515875069744 + ], + [ + 135.19200351552567, + -18.72720521550416 + ], + [ + 135.17590097479953, + -18.58234799622462 + ], + [ + 135.12989948657858, + -18.44344523882411 + ], + [ + 135.05590577158935, + -18.316048917066237 + ], + [ + 134.95692702774954, + -18.205240443340184 + ], + [ + 134.83694502129134, + -18.115431536593686 + ], + [ + 134.7007553620416, + -18.05019230130497 + ], + [ + 134.55377831141087, + -18.012112713788387 + ], + [ + 134.40184808553914, + -18.002702504172944 + ], + [ + 133.5015882181367, + -18.03099095651218 + ], + [ + 135.7131771235296, + -15.615278771854245 + ], + [ + 138.63231914292277, + -18.668503152067366 + ], + [ + 135.21741475594808, + -23.069515875069744 + ] + ] + ], + [ + [ + [ + 128.2189513769408, + -36.2752762780699 + ], + [ + 128.23395589804787, + -36.41516057142576 + ], + [ + 128.28224275758475, + -36.55005257736415 + ], + [ + 128.36215371217472, + -36.67482929490728 + ], + [ + 128.4707941574902, + -36.78472379707336 + ], + [ + 128.60412212507805, + -36.87551278817642 + ], + [ + 128.75708988382613, + -36.943686844420895 + ], + [ + 128.9238349688487, + -36.9865952298609 + ], + [ + 129.09791370470415, + -37.002557801025645 + ], + [ + 131.8925988483929, + -37.00435211591236 + ], + [ + 132.06691775490714, + -36.988614448584094 + ], + [ + 132.23401581494548, + -36.94590709341232 + ], + [ + 132.38743644561973, + -36.877876891187455 + ], + [ + 132.52129022945775, + -36.78714757015622 + ], + [ + 132.6304929107027, + -36.67721128537407 + ], + [ + 132.71096204991983, + -36.55228560546238 + ], + [ + 132.75976445158926, + -36.417143238190434 + ], + [ + 132.77521025177074, + -36.27692269935623 + ], + [ + 132.75294898776093, + -34.23082034487549 + ], + [ + 132.73430841446213, + -34.088313174877904 + ], + [ + 132.68244769907247, + -33.951624550543045 + ], + [ + 132.59953387728706, + -33.826059556552515 + ], + [ + 132.48890046877386, + -33.71646887848598 + ], + [ + 132.35490402418174, + -33.62706769776631 + ], + [ + 132.20274974735048, + -33.56128080980048 + ], + [ + 132.0382932430876, + -33.52161862473346 + ], + [ + 131.86782514713866, + -33.50958759019451 + ], + [ + 129.12265395665455, + -33.51147670851096 + ], + [ + 128.95243558187397, + -33.52374227550692 + ], + [ + 128.78834130753694, + -33.56361097243617 + ], + [ + 128.63664869926842, + -33.62954140748339 + ], + [ + 128.50318623378948, + -33.71899525755172 + ], + [ + 128.39312233640024, + -33.82853048622274 + ], + [ + 128.31077270517665, + -33.95392715663594 + ], + [ + 128.259431782947, + -34.09034210313401 + ], + [ + 128.24123450762372, + -34.23248792981497 + ], + [ + 128.2189513769408, + -36.2752762780699 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 121.9921875, + -31.466153715024284 + ], + [ + 134.4287109375, + -31.466153715024284 + ], + [ + 134.4287109375, + -18.729501999072138 + ], + [ + 121.9921875, + -18.729501999072138 + ], + [ + 121.9921875, + -31.466153715024284 + ] + ] + ], + [ + [ + [ + 125.3759765625, + -15.961329081596647 + ], + [ + 126.826171875, + -18.22935133838667 + ], + [ + 132.451171875, + -18.062312304546715 + ], + [ + 135.703125, + -14.519780046326085 + ], + [ + 139.6142578125, + -18.60460138845525 + ], + [ + 134.9560546875, + -24.607069137709694 + ], + [ + 134.7802734375, + -32.10118973232094 + ], + [ + 142.998046875, + -33.100745405144245 + ], + [ + 143.173828125, + -16.84660510639629 + ], + [ + 136.7138671875, + -12.46876014482322 + ], + [ + 131.2646484375, + -13.88074584202559 + ], + [ + 125.3759765625, + -15.961329081596647 + ] + ] + ], + [ + [ + [ + 129.111328125, + -36.27970720524016 + ], + [ + 131.8798828125, + -36.27970720524016 + ], + [ + 131.8798828125, + -34.234512362369856 + ], + [ + 129.111328125, + -34.234512362369856 + ], + [ + 129.111328125, + -36.27970720524016 + ] + ] + ] + ] + } + } + ] +} diff --git a/src/buffer/test/out/negative-buffer.geojson b/src/buffer/test/out/negative-buffer.geojson new file mode 100644 index 0000000000..4b24a3fa28 --- /dev/null +++ b/src/buffer/test/out/negative-buffer.geojson @@ -0,0 +1,105 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "radius": -200, + "units": "miles", + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 134.4872196415752, + -17.818207508457554 + ], + [ + 130.1670613506571, + -20.67488973649898 + ], + [ + 131.37977650914993, + -25.65087536229291 + ], + [ + 135.20069844022294, + -27.916822572665637 + ], + [ + 141.20516088686693, + -27.967162573492622 + ], + [ + 141.75286124064328, + -26.130885850429635 + ], + [ + 141.4073390845886, + -19.475495896026985 + ], + [ + 134.4872196415752, + -17.818207508457554 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "radius": -200, + "units": "miles", + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 133.90136718749997, + -14.647368383896618 + ], + [ + 126.73828125, + -19.352610894378625 + ], + [ + 128.49609375, + -27.371767300523032 + ], + [ + 134.1650390625, + -30.789036751261136 + ], + [ + 143.7890625, + -30.789036751261136 + ], + [ + 144.9755859375, + -26.391869671769022 + ], + [ + 144.31640625, + -17.14079039331664 + ], + [ + 133.90136718749997, + -14.647368383896618 + ] + ] + ] + } + } + ] +} diff --git a/src/buffer/test/out/north-latitude-points.geojson b/src/buffer/test/out/north-latitude-points.geojson new file mode 100644 index 0000000000..6ec098c72c --- /dev/null +++ b/src/buffer/test/out/north-latitude-points.geojson @@ -0,0 +1,211 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -94.07572456110556, + 74.0010908111707 + ], + [ + -94.01813322511752, + 73.99980778039591 + ], + [ + -93.50834701172023, + 74.01546746446651 + ], + [ + -93.0172945096782, + 74.05710820034497 + ], + [ + -92.56177623437614, + 74.12331940426488 + ], + [ + -92.15785757200376, + 74.21183688963308 + ], + [ + -91.82046321743574, + 74.31959287488873 + ], + [ + -91.56291715553498, + 74.44278828935825 + ], + [ + -91.39642328399235, + 74.57698987222224 + ], + [ + -91.32949446980795, + 74.71725464745042 + ], + [ + -91.3673551194933, + 74.85828378911285 + ], + [ + -91.5113633541211, + 74.99460638167787 + ], + [ + -91.75852078930814, + 75.12079090383561 + ], + [ + -92.1011555051892, + 75.23167839420988 + ], + [ + -92.526869865373, + 75.32262651781396 + ], + [ + -93.01883208197957, + 75.38974892582446 + ], + [ + -93.55645457998436, + 75.43013058588606 + ], + [ + -94.11644568252865, + 75.4419985009454 + ], + [ + -94.29811493423121, + 75.43655527882717 + ], + [ + -94.51397501020125, + 75.45162117238884 + ], + [ + -95.07541012341252, + 75.46120652854208 + ], + [ + -95.63259765626795, + 75.44176735852955 + ], + [ + -96.16106905228725, + 75.39416341680558 + ], + [ + -96.63809647409674, + 75.32048257601187 + ], + [ + -97.04397321665188, + 75.22391457029333 + ], + [ + -97.36297196509895, + 75.10856629400934 + ], + [ + -97.58391884168819, + 74.9792380325238 + ], + [ + -97.70038663198504, + 74.84118120863215 + ], + [ + -97.71056242422631, + 74.69985616143627 + ], + [ + -97.6168744982624, + 74.56070430024674 + ], + [ + -97.42547035450045, + 74.4289440457837 + ], + [ + -97.41705890860274, + 74.42538190106 + ], + [ + -97.34141954251977, + 74.37262033271949 + ], + [ + -97.06318272996525, + 74.25296335742452 + ], + [ + -96.70848163016484, + 74.14976689286347 + ], + [ + -96.2910481369883, + 74.06665274132769 + ], + [ + -95.82609223408511, + 74.00649209526892 + ], + [ + -95.32985891485546, + 73.97133885119658 + ], + [ + -94.81923612357105, + 73.96238450189458 + ], + [ + -94.31139880026387, + 73.9799328185346 + ], + [ + -94.07572456110556, + 74.0010908111707 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "MultiPoint", + "coordinates": [ + [ + -94.97955322265625, + 74.74046209428195 + ], + [ + -94.90264892578125, + 74.68325030051861 + ], + [ + -94.06494140625, + 74.7209322003536 + ] + ] + } + } + ] +} diff --git a/src/buffer/test/out/northern-polygon.geojson b/src/buffer/test/out/northern-polygon.geojson new file mode 100644 index 0000000000..2034157e83 --- /dev/null +++ b/src/buffer/test/out/northern-polygon.geojson @@ -0,0 +1,233 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -94.58725332424147, + 73.97218218810961 + ], + [ + -94.06368519261217, + 73.9988616039097 + ], + [ + -93.56765188936085, + 74.05311452791568 + ], + [ + -93.11769717011299, + 74.13294838619541 + ], + [ + -92.73130502934087, + 74.23539633705361 + ], + [ + -92.42437826521731, + 74.35659017423343 + ], + [ + -92.21064433458153, + 74.49186292067517 + ], + [ + -92.18692943230882, + 74.5122591718606 + ], + [ + -92.08577250328167, + 74.63570151097785 + ], + [ + -92.06647643892288, + 74.76194072429777 + ], + [ + -92.1316173731066, + 74.88712421323787 + ], + [ + -92.15367676349456, + 74.9123741378019 + ], + [ + -92.31375885163708, + 75.03863439184514 + ], + [ + -92.56398336512834, + 75.1549094392291 + ], + [ + -92.89722709687004, + 75.2569771216363 + ], + [ + -93.30268467242442, + 75.3410490562801 + ], + [ + -93.76611767123163, + 75.40394523818155 + ], + [ + -94.27037319882396, + 75.4432506653222 + ], + [ + -94.7961604660679, + 75.45744057733444 + ], + [ + -94.87390871474415, + 75.45762799707144 + ], + [ + -95.39920532743483, + 75.44604702792844 + ], + [ + -95.90511807885163, + 75.40939764395323 + ], + [ + -96.37236369740937, + 75.34909680791303 + ], + [ + -96.45257050616563, + 75.33610901393318 + ], + [ + -96.86668363980937, + 75.25345277945624 + ], + [ + -97.20892893920278, + 75.15223887601414 + ], + [ + -97.46797448711088, + 75.03627987444268 + ], + [ + -97.6362493612149, + 74.90984854678489 + ], + [ + -97.70996635032468, + 74.77749244404362 + ], + [ + -97.68893646598173, + 74.64385353915988 + ], + [ + -97.57623678238349, + 74.51350129172556 + ], + [ + -97.37779272431298, + 74.39078432691626 + ], + [ + -97.31096132440659, + 74.35780209924643 + ], + [ + -96.99303233616548, + 74.2325261421992 + ], + [ + -96.59041788116497, + 74.12740724628435 + ], + [ + -96.12079157708818, + 74.04669125718945 + ], + [ + -95.60360600510056, + 73.99358780125598 + ], + [ + -95.05948284851922, + 73.97018586036182 + ], + [ + -95.01286084676053, + 73.96949091062267 + ], + [ + -94.63126354769483, + 73.97114306338692 + ], + [ + -94.58725332424147, + 73.97218218810961 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -94.81887817382812, + 74.69068515369659 + ], + [ + -94.79827880859375, + 74.71133916265154 + ], + [ + -94.82437133789062, + 74.73630499357218 + ], + [ + -94.89852905273438, + 74.73648576006866 + ], + [ + -94.976806640625, + 74.72400796764163 + ], + [ + -94.91363525390625, + 74.69032255967197 + ], + [ + -94.86488342285156, + 74.68959734647507 + ], + [ + -94.81887817382812, + 74.69068515369659 + ] + ] + ] + } + } + ] +} diff --git a/src/buffer/test/out/point.geojson b/src/buffer/test/out/point.geojson new file mode 100644 index 0000000000..ddf0cbbe4a --- /dev/null +++ b/src/buffer/test/out/point.geojson @@ -0,0 +1,169 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 135, + -24.273258048132465 + ], + [ + 134.84531216197894, + -24.287144125975388 + ], + [ + 134.69647173024813, + -24.328276955764252 + ], + [ + 134.5591152882848, + -24.39509942288169 + ], + [ + 134.43846405760047, + -24.485079372007707 + ], + [ + 134.3391318656001, + -24.594802015429128 + ], + [ + 134.26495172778493, + -24.720095092356694 + ], + [ + 134.21882697977634, + -24.856182729133295 + ], + [ + 134.2026126475202, + -24.99786298181213 + ], + [ + 134.2170323700623, + -25.139703162374218 + ], + [ + 134.26163560115754, + -25.276246253154923 + ], + [ + 134.33479890218132, + -25.40222101474275 + ], + [ + 134.43377379148274, + -25.512747836459212 + ], + [ + 134.55478176992932, + -25.603532046601725 + ], + [ + 134.6931548188217, + -25.671036398086706 + ], + [ + 134.8435169973282, + -25.71262488158693 + ], + [ + 135, + -25.726670970034586 + ], + [ + 135.1564830026718, + -25.71262488158693 + ], + [ + 135.3068451811783, + -25.671036398086706 + ], + [ + 135.44521823007068, + -25.603532046601725 + ], + [ + 135.56622620851724, + -25.512747836459212 + ], + [ + 135.66520109781868, + -25.40222101474275 + ], + [ + 135.73836439884246, + -25.276246253154923 + ], + [ + 135.78296762993767, + -25.139703162374204 + ], + [ + 135.7973873524798, + -24.99786298181213 + ], + [ + 135.7811730202237, + -24.856182729133295 + ], + [ + 135.73504827221507, + -24.720095092356694 + ], + [ + 135.6608681343999, + -24.594802015429128 + ], + [ + 135.56153594239953, + -24.485079372007707 + ], + [ + 135.4408847117152, + -24.39509942288169 + ], + [ + 135.30352826975187, + -24.328276955764252 + ], + [ + 135.15468783802106, + -24.287144125975388 + ], + [ + 135, + -24.273258048132465 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Point", + "coordinates": [ + 135, + -25 + ] + } + } + ] +} diff --git a/src/buffer/test/out/polygon-with-holes.geojson b/src/buffer/test/out/polygon-with-holes.geojson new file mode 100644 index 0000000000..ee8f4476a1 --- /dev/null +++ b/src/buffer/test/out/polygon-with-holes.geojson @@ -0,0 +1,285 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 123.4100337251248, + -24.54735917972725 + ], + [ + 123.41189659016779, + -24.688179532466307 + ], + [ + 123.44392959333186, + -24.82594913823731 + ], + [ + 123.50500068712356, + -24.955328936624124 + ], + [ + 127.76834416667744, + -31.642491449184924 + ], + [ + 127.86038979404131, + -31.752989187989975 + ], + [ + 127.97522143206452, + -31.846750794433422 + ], + [ + 128.10880056423449, + -31.9204075048797 + ], + [ + 128.25637572896915, + -31.971298519694457 + ], + [ + 128.4126548153941, + -31.997573801314715 + ], + [ + 138.33313708870423, + -32.45320706619508 + ], + [ + 138.49463446513485, + -32.44110971788904 + ], + [ + 138.65040796022222, + -32.40319083271555 + ], + [ + 138.7947447417573, + -32.340853541683195 + ], + [ + 138.9223835098819, + -32.25639300903862 + ], + [ + 139.0287139916281, + -32.152905697126826 + ], + [ + 145.49114725820047, + -23.800841321031704 + ], + [ + 145.5674837972513, + -23.665449014735056 + ], + [ + 145.6109008986517, + -23.51827428127725 + ], + [ + 145.61956165540653, + -23.36597974767267 + ], + [ + 145.59320004279218, + -23.21543088190865 + ], + [ + 145.53311025284398, + -23.07339222314078 + ], + [ + 142.0942437731267, + -16.496491683100842 + ], + [ + 142.01229920083955, + -16.36658269019649 + ], + [ + 141.9041164521006, + -16.256015669901316 + ], + [ + 141.77446473406562, + -16.169655069173814 + ], + [ + 136.07746146139212, + -13.038879683144177 + ], + [ + 135.96061003717517, + -12.984879720707184 + ], + [ + 135.83601208865514, + -12.951510646282598 + ], + [ + 135.70741480427762, + -12.939778069940791 + ], + [ + 130.44956323447838, + -12.856749472872488 + ], + [ + 130.3739719998856, + -12.858581385253785 + ], + [ + 124.8546130503228, + -13.207531504701155 + ], + [ + 124.7212858239261, + -13.226574932723649 + ], + [ + 124.5937916952518, + -13.269158448050304 + ], + [ + 124.47640640031098, + -13.333825803408361 + ], + [ + 124.37306575359588, + -13.418384100163966 + ], + [ + 124.2872383829509, + -13.519978353393457 + ], + [ + 124.22181331665305, + -13.635186758787592 + ], + [ + 124.1790054673401, + -13.76013355941495 + ], + [ + 124.16028163014315, + -13.890616069239252 + ], + [ + 123.4100337251248, + -24.54735917972725 + ] + ], + [ + [ + 130.46117284025553, + -26.315436730609747 + ], + [ + 128.7163605003418, + -18.14025769530649 + ], + [ + 138.32359875954012, + -18.139237631835986 + ], + [ + 138.27806213902724, + -26.318488860983972 + ], + [ + 130.46117284025553, + -26.315436730609747 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "fill": "#00F", + "marker-color": "#00F", + "fill-opacity": 0.3 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 124.18945312500001, + -24.607069137709694 + ], + [ + 128.49609375, + -31.278550858946517 + ], + [ + 138.33984375, + -31.728167146023935 + ], + [ + 144.84375, + -23.40276490540795 + ], + [ + 141.416015625, + -16.804541076383455 + ], + [ + 135.703125, + -13.667338259654947 + ], + [ + 130.4296875, + -13.581920900545844 + ], + [ + 124.892578125, + -13.923403897723334 + ], + [ + 124.18945312500001, + -24.607069137709694 + ] + ], + [ + [ + 129.79296875, + -27.019984007982554 + ], + [ + 139.0869140625, + -27.019984007982554 + ], + [ + 139.0869140625, + -17.392579271057766 + ], + [ + 127.79296875, + -17.392579271057766 + ], + [ + 129.79296875, + -27.019984007982554 + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-center-mean/bench.js b/src/center-mean/bench.js similarity index 100% rename from packages/turf-center-mean/bench.js rename to src/center-mean/bench.js diff --git a/src/center-mean/index.js b/src/center-mean/index.js new file mode 100644 index 0000000000..688eb5d5ee --- /dev/null +++ b/src/center-mean/index.js @@ -0,0 +1,49 @@ +import { geomEach, coordEach } from '../meta'; +import { point, checkIfOptionsExist, isNumber } from '../helpers'; + +/** + * Takes a {@link Feature} or {@link FeatureCollection} and returns the mean center. Can be weighted. + * + * @name centerMean + * @param {GeoJSON} geojson GeoJSON to be centered + * @param {Object} [options={}] Optional parameters + * @param {Object} [options.properties={}] Translate GeoJSON Properties to Point + * @param {Object} [options.bbox={}] Translate GeoJSON BBox to Point + * @param {Object} [options.id={}] Translate GeoJSON Id to Point + * @param {string} [options.weight] the property name used to weight the center + * @returns {Feature} a Point feature at the mean center point of all input features + * @example + * var features = turf.featureCollection([ + * turf.point([-97.522259, 35.4691], {value, + * turf.point([-97.502754, 35.463455], {value, + * turf.point([-97.508269, 35.463245], {value{weight, options); + * + * //addToMap + * var addToMap = [features, mean] + * mean.properties['marker-size'] = 'large'; + * mean.properties['marker-color'] = '#000'; + */ +function centerMean(geojson, options) { + options = checkIfOptionsExist(options); + + var weightTerm = options.weight; + let sumXs = 0; + let sumYs = 0; + let sumNs = 0; + geomEach(geojson, function (geom, featureIndex, properties) { + var weight = properties[weightTerm]; + weight = (weight === undefined || weight === null) ? 1 : weight; + if (!isNumber(weight)) throw new Error('weight value must be a number for feature index ' + featureIndex); + weight = Number(weight); + if (weight > 0) { + coordEach(geom, function (coord) { + sumXs += coord[0] * weight; + sumYs += coord[1] * weight; + sumNs += weight; + }); + } + }); + return point([sumXs / sumNs, sumYs / sumNs], options.properties); +} + +export default centerMean; diff --git a/src/center-mean/test.js b/src/center-mean/test.js new file mode 100644 index 0000000000..2e424027cc --- /dev/null +++ b/src/center-mean/test.js @@ -0,0 +1,54 @@ +const test = require('tape'); +const fs = require('fs'); +const glob = require('glob'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const truncate = require('../truncate').default; +const { featureEach, coordEach } = require('../meta'); +const { lineString, featureCollection } = require('../helpers'); +const center = require('../center').default; +const centerMean = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +var fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-center-mean', t => { + fixtures.forEach(fixture => { + const filename = fixture.filename; + const name = fixture.name; + const geojson = fixture.geojson; + const options = geojson.options || {}; + options.properties = {'marker-symbol': 'star', 'marker-color': '#F00'}; + const centered = truncate(centerMean(geojson, options)); + + // Display Results + const results = featureCollection([]); + featureEach(geojson, feature => results.features.push(feature)); + coordEach(geojson, coord => results.features.push(lineString([coord, centered.geometry.coordinates], {stroke: '#00F', 'stroke-width': 1}))); + // Add @turf/center to compare position + results.features.push(truncate(center(geojson, {properties: {'marker-symbol': 'circle', 'marker-color': '#00F'}}))); + results.features.push(centered); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(results, load.sync(directories.out + filename), name); + }); + t.end(); +}); + +test('turf-center-mean -- properties', t => { + const line = lineString([[0, 0], [1, 1]]); + const pt = centerMean(line, {properties: {foo: 'bar'}}); + t.equal(pt.properties.foo, 'bar', 'translate properties'); + t.end(); +}); diff --git a/packages/turf-center-mean/test/in/feature-collection-negative-weights.geojson b/src/center-mean/test/in/feature-collection-negative-weights.geojson similarity index 100% rename from packages/turf-center-mean/test/in/feature-collection-negative-weights.geojson rename to src/center-mean/test/in/feature-collection-negative-weights.geojson diff --git a/packages/turf-center-mean/test/in/feature-collection-weight.geojson b/src/center-mean/test/in/feature-collection-weight.geojson similarity index 100% rename from packages/turf-center-mean/test/in/feature-collection-weight.geojson rename to src/center-mean/test/in/feature-collection-weight.geojson diff --git a/packages/turf-center-mean/test/in/feature-collection.geojson b/src/center-mean/test/in/feature-collection.geojson similarity index 100% rename from packages/turf-center-mean/test/in/feature-collection.geojson rename to src/center-mean/test/in/feature-collection.geojson diff --git a/packages/turf-center-mean/test/in/imbalanced-polygon.geojson b/src/center-mean/test/in/imbalanced-polygon.geojson similarity index 100% rename from packages/turf-center-mean/test/in/imbalanced-polygon.geojson rename to src/center-mean/test/in/imbalanced-polygon.geojson diff --git a/packages/turf-center-mean/test/in/linestring.geojson b/src/center-mean/test/in/linestring.geojson similarity index 100% rename from packages/turf-center-mean/test/in/linestring.geojson rename to src/center-mean/test/in/linestring.geojson diff --git a/packages/turf-center-mean/test/in/point.geojson b/src/center-mean/test/in/point.geojson similarity index 100% rename from packages/turf-center-mean/test/in/point.geojson rename to src/center-mean/test/in/point.geojson diff --git a/packages/turf-center-mean/test/in/points-with-weights.geojson b/src/center-mean/test/in/points-with-weights.geojson similarity index 100% rename from packages/turf-center-mean/test/in/points-with-weights.geojson rename to src/center-mean/test/in/points-with-weights.geojson diff --git a/packages/turf-center-mean/test/in/polygon-with-weights.geojson b/src/center-mean/test/in/polygon-with-weights.geojson similarity index 100% rename from packages/turf-center-mean/test/in/polygon-with-weights.geojson rename to src/center-mean/test/in/polygon-with-weights.geojson diff --git a/packages/turf-center-mean/test/in/polygon-without-weights.geojson b/src/center-mean/test/in/polygon-without-weights.geojson similarity index 100% rename from packages/turf-center-mean/test/in/polygon-without-weights.geojson rename to src/center-mean/test/in/polygon-without-weights.geojson diff --git a/packages/turf-center-mean/test/in/polygon.geojson b/src/center-mean/test/in/polygon.geojson similarity index 100% rename from packages/turf-center-mean/test/in/polygon.geojson rename to src/center-mean/test/in/polygon.geojson diff --git a/packages/turf-center-mean/test/out/feature-collection-negative-weights.geojson b/src/center-mean/test/out/feature-collection-negative-weights.geojson similarity index 100% rename from packages/turf-center-mean/test/out/feature-collection-negative-weights.geojson rename to src/center-mean/test/out/feature-collection-negative-weights.geojson diff --git a/packages/turf-center-mean/test/out/feature-collection-weight.geojson b/src/center-mean/test/out/feature-collection-weight.geojson similarity index 100% rename from packages/turf-center-mean/test/out/feature-collection-weight.geojson rename to src/center-mean/test/out/feature-collection-weight.geojson diff --git a/packages/turf-center-mean/test/out/feature-collection.geojson b/src/center-mean/test/out/feature-collection.geojson similarity index 100% rename from packages/turf-center-mean/test/out/feature-collection.geojson rename to src/center-mean/test/out/feature-collection.geojson diff --git a/packages/turf-center-mean/test/out/imbalanced-polygon.geojson b/src/center-mean/test/out/imbalanced-polygon.geojson similarity index 100% rename from packages/turf-center-mean/test/out/imbalanced-polygon.geojson rename to src/center-mean/test/out/imbalanced-polygon.geojson diff --git a/packages/turf-center-mean/test/out/linestring.geojson b/src/center-mean/test/out/linestring.geojson similarity index 100% rename from packages/turf-center-mean/test/out/linestring.geojson rename to src/center-mean/test/out/linestring.geojson diff --git a/packages/turf-center-mean/test/out/point.geojson b/src/center-mean/test/out/point.geojson similarity index 100% rename from packages/turf-center-mean/test/out/point.geojson rename to src/center-mean/test/out/point.geojson diff --git a/packages/turf-center-mean/test/out/points-with-weights.geojson b/src/center-mean/test/out/points-with-weights.geojson similarity index 100% rename from packages/turf-center-mean/test/out/points-with-weights.geojson rename to src/center-mean/test/out/points-with-weights.geojson diff --git a/packages/turf-center-mean/test/out/polygon-with-weights.geojson b/src/center-mean/test/out/polygon-with-weights.geojson similarity index 100% rename from packages/turf-center-mean/test/out/polygon-with-weights.geojson rename to src/center-mean/test/out/polygon-with-weights.geojson diff --git a/packages/turf-center-mean/test/out/polygon-without-weights.geojson b/src/center-mean/test/out/polygon-without-weights.geojson similarity index 100% rename from packages/turf-center-mean/test/out/polygon-without-weights.geojson rename to src/center-mean/test/out/polygon-without-weights.geojson diff --git a/packages/turf-center-mean/test/out/polygon.geojson b/src/center-mean/test/out/polygon.geojson similarity index 100% rename from packages/turf-center-mean/test/out/polygon.geojson rename to src/center-mean/test/out/polygon.geojson diff --git a/packages/turf-center-median/bench.js b/src/center-median/bench.js similarity index 100% rename from packages/turf-center-median/bench.js rename to src/center-median/bench.js diff --git a/src/center-median/index.js b/src/center-median/index.js new file mode 100644 index 0000000000..6045136f78 --- /dev/null +++ b/src/center-median/index.js @@ -0,0 +1,126 @@ +import centerMean from '../center-mean'; +import distance from '../distance'; +import centroid from '../centroid'; +import { isNumber, point, isObject, featureCollection, checkIfOptionsExist } from '../helpers'; +import { featureEach } from '../meta'; + +/** + * Takes a {@link FeatureCollection} of points and calculates the median center, + * algorithimically. The median center is understood as the point that is + * requires the least total travel from all other points. + * + * Turfjs has four different functions for calculating the center of a set of + * data. Each is useful depending on circumstance. + * + * `../center` finds the simple center of a dataset, by finding the + * midpoint between the extents of the data. That is, it divides in half the + * farthest east and farthest west point as well as the farthest north and + * farthest south. + * + * `../center-of-mass` imagines that the dataset is a sheet of paper. + * The center of mass is where the sheet would balance on a fingertip. + * + * `../center-mean` takes the averages of all the coordinates and + * produces a value that respects that. Unlike `../center`, it is + * sensitive to clusters and outliers. It lands in the statistical middle of a + * dataset, not the geographical. It can also be weighted, meaning certain + * points are more important than others. + * + * `../center-median` takes the mean center and tries to find, iteratively, + * a new point that requires the least amount of travel from all the points in + * the dataset. It is not as sensitive to outliers as `../center-mean`, but it is + * attracted to clustered data. It, too, can be weighted. + * + * **Bibliography** + * + * Harold W. Kuhn and Robert E. Kuenne, “An Efficient Algorithm for the + * Numerical Solution of the Generalized Weber Problem in Spatial + * Economics,” _Journal of Regional Science_ 4, no. 2 (1962), + * doi{@link https, Gerald M. Barber, and David L. Rigby, _Elementary + * Statistics for Geographers_, 3rd ed., New York, 2009, 150–151. + * + * @name centerMedian + * @param {FeatureCollection} features Any GeoJSON Feature Collection + * @param {Object} [options={}] Optional parameters + * @param {string} [options.weight] the property name used to weight the center + * @param {number} [options.tolerance=0.001] the difference in distance between candidate medians at which point the algorighim stops iterating. + * @param {number} [options.counter=10] how many attempts to find the median, should the tolerance be insufficient. + * @returns {Feature} The median center of the collection + * @example + * var points = turf.points([[0, 0], [1, 0], [0, 1], [5, 8]]); + * var medianCenter = turf.centerMedian(points); + * + * //addToMap + * var addToMap = [points, medianCenter] + */ +function centerMedian(features, options) { + + // Optional params + options = checkIfOptionsExist(options); + + var counter = options.counter || 10; + if (!isNumber(counter)) throw new Error('counter must be a number'); + var weightTerm = options.weight; + + + // Calculate mean center: + var meanCenter = centerMean(features, {weight: options.weight}); + + // Calculate center of every feature: + var centroids = featureCollection([]); + featureEach(features, function (feature) { + centroids.features.push(centroid(feature, {properties: {weight: feature.properties[weightTerm]}})); + }); + + centroids.properties = { + tolerance: options.tolerance, + medianCandidates: [] + }; + return findMedian(meanCenter.geometry.coordinates, [0, 0], centroids, counter); +} + +/** + * Recursive function to find new candidate medians. + * + * @private + * @param {Position} candidateMedian current candidate median + * @param {Position} previousCandidate the previous candidate median + * @param {FeatureCollection} centroids the collection of centroids whose median we are determining + * @param {number} counter how many attempts to try before quitting. + * @returns {Feature} the median center of the dataset. + */ +function findMedian(candidateMedian, previousCandidate, centroids, counter) { + var tolerance = centroids.properties.tolerance || 0.001; + var candidateXsum = 0; + var candidateYsum = 0; + var kSum = 0; + var centroidCount = 0; + featureEach(centroids, function (theCentroid) { + var weightValue = theCentroid.properties.weight; + var weight = (weightValue === undefined || weightValue === null) ? 1 : weightValue; + weight = Number(weight); + if (!isNumber(weight)) throw new Error('weight value must be a number'); + if (weight > 0) { + centroidCount += 1; + var distanceFromCandidate = weight * distance(theCentroid, candidateMedian); + if (distanceFromCandidate === 0) distanceFromCandidate = 1; + var k = weight / distanceFromCandidate; + candidateXsum += theCentroid.geometry.coordinates[0] * k; + candidateYsum += theCentroid.geometry.coordinates[1] * k; + kSum += k; + } + }); + if (centroidCount < 1) throw new Error('no features to measure'); + var candidateX = candidateXsum / kSum; + var candidateY = candidateYsum / kSum; + if (centroidCount === 1 || counter === 0 || (Math.abs(candidateX - previousCandidate[0]) < tolerance && Math.abs(candidateY - previousCandidate[1]) < tolerance)) { + return point([candidateX, candidateY], {medianCandidates: centroids.properties.medianCandidates}); + } else { + centroids.properties.medianCandidates.push([candidateX, candidateY]); + return findMedian([candidateX, candidateY], candidateMedian, centroids, counter - 1); + } +} + +export default centerMedian; + + diff --git a/src/center-median/test.js b/src/center-median/test.js new file mode 100644 index 0000000000..b7efb93509 --- /dev/null +++ b/src/center-median/test.js @@ -0,0 +1,61 @@ +const test = require('tape'); +const fs = require('fs'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const center = require('../center').default; +const truncate = require('../truncate').default; +const centerMean = require('../center-mean').default; +const centerOfMass = require('../center-of-mass').default; +const { featureCollection, round } = require('../helpers'); +const centerMedian = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-center-median', t => { + for (const fixture of fixtures) { + // Define params + const name = fixture.name; + const geojson = fixture.geojson; + const options = geojson.properties; + + // Calculate Centers + const meanCenter = centerMean(geojson, options); + const medianCenter = centerMedian(geojson, options); + const extentCenter = center(geojson); + const massCenter = centerOfMass(geojson); + + // Truncate median properties + medianCenter.properties.medianCandidates.forEach((candidate, index) => { + medianCenter.properties.medianCandidates[index] = [round(candidate[0], 6), round(candidate[1], 6)]; + }); + const results = featureCollection([ + ...geojson.features, + colorize(meanCenter, '#a00'), + colorize(medianCenter, '#0a0'), + colorize(extentCenter, '#00a'), + colorize(massCenter, '#aaa') + ]); + + if (process.env.REGEN) write.sync(directories.out + name + '.json', results); + t.deepEqual(results, load.sync(directories.out + name + '.json'), name); + } + t.end(); +}); + +function colorize(point, color) { + point.properties['marker-color'] = color; + point.properties['marker-symbol'] = 'cross'; + return truncate(point); +} diff --git a/packages/turf-center-median/test/in/brazil-states-weighted.json b/src/center-median/test/in/brazil-states-weighted.json similarity index 100% rename from packages/turf-center-median/test/in/brazil-states-weighted.json rename to src/center-median/test/in/brazil-states-weighted.json diff --git a/packages/turf-center-median/test/in/brazil-states.json b/src/center-median/test/in/brazil-states.json similarity index 100% rename from packages/turf-center-median/test/in/brazil-states.json rename to src/center-median/test/in/brazil-states.json diff --git a/packages/turf-center-median/test/in/burt-barber-rigby-problem-unweighted.json b/src/center-median/test/in/burt-barber-rigby-problem-unweighted.json similarity index 100% rename from packages/turf-center-median/test/in/burt-barber-rigby-problem-unweighted.json rename to src/center-median/test/in/burt-barber-rigby-problem-unweighted.json diff --git a/packages/turf-center-median/test/in/burt-barber-rigby-problem.json b/src/center-median/test/in/burt-barber-rigby-problem.json similarity index 100% rename from packages/turf-center-median/test/in/burt-barber-rigby-problem.json rename to src/center-median/test/in/burt-barber-rigby-problem.json diff --git a/packages/turf-center-median/test/in/kuhn-kuenne-ukraine-problem.json b/src/center-median/test/in/kuhn-kuenne-ukraine-problem.json similarity index 100% rename from packages/turf-center-median/test/in/kuhn-kuenne-ukraine-problem.json rename to src/center-median/test/in/kuhn-kuenne-ukraine-problem.json diff --git a/packages/turf-center-median/test/in/lines.json b/src/center-median/test/in/lines.json similarity index 100% rename from packages/turf-center-median/test/in/lines.json rename to src/center-median/test/in/lines.json diff --git a/packages/turf-center-median/test/in/square.json b/src/center-median/test/in/square.json similarity index 100% rename from packages/turf-center-median/test/in/square.json rename to src/center-median/test/in/square.json diff --git a/packages/turf-center-median/test/in/squares-weighted.json b/src/center-median/test/in/squares-weighted.json similarity index 100% rename from packages/turf-center-median/test/in/squares-weighted.json rename to src/center-median/test/in/squares-weighted.json diff --git a/packages/turf-center-median/test/in/squares.json b/src/center-median/test/in/squares.json similarity index 100% rename from packages/turf-center-median/test/in/squares.json rename to src/center-median/test/in/squares.json diff --git a/packages/turf-center-median/test/in/steiners-problem-bad-weights.json b/src/center-median/test/in/steiners-problem-bad-weights.json similarity index 100% rename from packages/turf-center-median/test/in/steiners-problem-bad-weights.json rename to src/center-median/test/in/steiners-problem-bad-weights.json diff --git a/packages/turf-center-median/test/in/steiners-problem-low-tolerance.json b/src/center-median/test/in/steiners-problem-low-tolerance.json similarity index 100% rename from packages/turf-center-median/test/in/steiners-problem-low-tolerance.json rename to src/center-median/test/in/steiners-problem-low-tolerance.json diff --git a/packages/turf-center-median/test/in/steiners-problem.json b/src/center-median/test/in/steiners-problem.json similarity index 100% rename from packages/turf-center-median/test/in/steiners-problem.json rename to src/center-median/test/in/steiners-problem.json diff --git a/packages/turf-center-median/test/out/brazil-states-weighted.json b/src/center-median/test/out/brazil-states-weighted.json similarity index 99% rename from packages/turf-center-median/test/out/brazil-states-weighted.json rename to src/center-median/test/out/brazil-states-weighted.json index c7d14f63cc..17c1fa5f76 100644 --- a/packages/turf-center-median/test/out/brazil-states-weighted.json +++ b/src/center-median/test/out/brazil-states-weighted.json @@ -23352,44 +23352,44 @@ "properties": { "medianCandidates": [ [ - -47.705366, - -15.383303 + -47.717392, + -15.325783 ], [ - -47.620773, - -14.836346 + -47.625268, + -14.77049 ], [ - -47.490132, - -14.292598 + -47.486291, + -14.239613 ], [ - -47.349383, - -13.870379 + -47.3428, + -13.830916 ], [ - -47.231275, - -13.566987 + -47.225066, + -13.537914 ], [ - -47.143446, - -13.356933 + -47.138475, + -13.335262 ], [ - -47.081927, - -13.21474 + -47.078171, + -13.198161 ], [ - -47.040199, - -13.119889 + -47.037397, + -13.106737 ], [ - -47.012405, - -13.057232 + -47.010288, + -13.046354 ], [ - -46.994091, - -13.016111 + -46.992443, + -13.006728 ] ], "marker-color": "#0a0", @@ -23398,8 +23398,8 @@ "geometry": { "type": "Point", "coordinates": [ - -46.9821, - -12.98924 + -46.980766, + -12.980834 ] } }, diff --git a/packages/turf-center-median/test/out/brazil-states.json b/src/center-median/test/out/brazil-states.json similarity index 99% rename from packages/turf-center-median/test/out/brazil-states.json rename to src/center-median/test/out/brazil-states.json index d06ab591a3..ce3d5d30a1 100644 --- a/packages/turf-center-median/test/out/brazil-states.json +++ b/src/center-median/test/out/brazil-states.json @@ -23352,44 +23352,44 @@ "properties": { "medianCandidates": [ [ - -48.110334, - -12.416954 + -48.10923, + -12.415848 ], [ - -47.342729, - -12.713383 + -47.342077, + -12.711268 ], [ - -47.0857, - -12.838781 + -47.085436, + -12.83535 ], [ - -46.99869, - -12.891475 + -46.998469, + -12.886992 ], [ - -46.969976, - -12.914572 + -46.96966, + -12.909357 ], [ - -46.961099, - -12.925505 + -46.960667, + -12.919802 ], [ - -46.958774, - -12.931148 + -46.958246, + -12.925126 ], [ - -46.958476, - -12.934294 + -46.957876, + -12.928066 ], [ - -46.958707, - -12.936153 + -46.958058, + -12.929791 ], [ - -46.959006, - -12.937295 + -46.958324, + -12.930846 ] ], "marker-color": "#0a0", @@ -23398,8 +23398,8 @@ "geometry": { "type": "Point", "coordinates": [ - -46.959253, - -12.938012 + -46.958549, + -12.931507 ] } }, diff --git a/packages/turf-center-median/test/out/burt-barber-rigby-problem-unweighted.json b/src/center-median/test/out/burt-barber-rigby-problem-unweighted.json similarity index 100% rename from packages/turf-center-median/test/out/burt-barber-rigby-problem-unweighted.json rename to src/center-median/test/out/burt-barber-rigby-problem-unweighted.json diff --git a/packages/turf-center-median/test/out/burt-barber-rigby-problem.json b/src/center-median/test/out/burt-barber-rigby-problem.json similarity index 100% rename from packages/turf-center-median/test/out/burt-barber-rigby-problem.json rename to src/center-median/test/out/burt-barber-rigby-problem.json diff --git a/packages/turf-center-median/test/out/kuhn-kuenne-ukraine-problem.json b/src/center-median/test/out/kuhn-kuenne-ukraine-problem.json similarity index 100% rename from packages/turf-center-median/test/out/kuhn-kuenne-ukraine-problem.json rename to src/center-median/test/out/kuhn-kuenne-ukraine-problem.json diff --git a/packages/turf-center-median/test/out/lines.json b/src/center-median/test/out/lines.json similarity index 100% rename from packages/turf-center-median/test/out/lines.json rename to src/center-median/test/out/lines.json diff --git a/packages/turf-center-median/test/out/square.json b/src/center-median/test/out/square.json similarity index 100% rename from packages/turf-center-median/test/out/square.json rename to src/center-median/test/out/square.json diff --git a/packages/turf-center-median/test/out/squares-weighted.json b/src/center-median/test/out/squares-weighted.json similarity index 98% rename from packages/turf-center-median/test/out/squares-weighted.json rename to src/center-median/test/out/squares-weighted.json index 22f9324ad7..20f592e886 100644 --- a/packages/turf-center-median/test/out/squares-weighted.json +++ b/src/center-median/test/out/squares-weighted.json @@ -1108,40 +1108,40 @@ "properties": { "medianCandidates": [ [ - -9.211135, - 38.251184 + -9.207196, + 38.253611 ], [ - -9.19883, - 38.27041 + -9.193733, + 38.273498 ], [ - -9.194972, - 38.281094 + -9.18952, + 38.284859 ], [ - -9.193009, - 38.286913 + -9.18743, + 38.290992 ], [ - -9.192078, - 38.290311 + -9.186424, + 38.294559 ], [ - -9.191685, - 38.29235 + -9.185995, + 38.296697 ], [ - -9.191527, - 38.293587 + -9.185823, + 38.297992 ], [ - -9.191465, - 38.29434 + -9.185755, + 38.298781 ], [ - -9.191441, - 38.2948 + -9.185728, + 38.299263 ] ], "marker-color": "#0a0", @@ -1150,8 +1150,8 @@ "geometry": { "type": "Point", "coordinates": [ - -9.191431, - 38.295081 + -9.185718, + 38.299557 ] } }, diff --git a/src/center-median/test/out/squares.json b/src/center-median/test/out/squares.json new file mode 100644 index 0000000000..caba046d90 --- /dev/null +++ b/src/center-median/test/out/squares.json @@ -0,0 +1,1135 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299992605418552, + 38.12013592725509 + ], + [ + -9.299992605418552, + 38.16510194544132 + ], + [ + -9.242851861013252, + 38.16510194544132 + ], + [ + -9.242851861013252, + 38.12013592725509 + ], + [ + -9.299992605418552, + 38.12013592725509 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299992605418552, + 38.16510194544132 + ], + [ + -9.299992605418552, + 38.21006796362755 + ], + [ + -9.242851861013252, + 38.21006796362755 + ], + [ + -9.242851861013252, + 38.16510194544132 + ], + [ + -9.299992605418552, + 38.16510194544132 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299992605418552, + 38.21006796362755 + ], + [ + -9.299992605418552, + 38.25503398181378 + ], + [ + -9.242851861013252, + 38.25503398181378 + ], + [ + -9.242851861013252, + 38.21006796362755 + ], + [ + -9.299992605418552, + 38.21006796362755 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299992605418552, + 38.25503398181378 + ], + [ + -9.299992605418552, + 38.30000000000001 + ], + [ + -9.242851861013252, + 38.30000000000001 + ], + [ + -9.242851861013252, + 38.25503398181378 + ], + [ + -9.299992605418552, + 38.25503398181378 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299992605418552, + 38.30000000000001 + ], + [ + -9.299992605418552, + 38.34496601818624 + ], + [ + -9.242851861013252, + 38.34496601818624 + ], + [ + -9.242851861013252, + 38.30000000000001 + ], + [ + -9.299992605418552, + 38.30000000000001 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299992605418552, + 38.34496601818624 + ], + [ + -9.299992605418552, + 38.38993203637247 + ], + [ + -9.242851861013252, + 38.38993203637247 + ], + [ + -9.242851861013252, + 38.34496601818624 + ], + [ + -9.299992605418552, + 38.34496601818624 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299992605418552, + 38.38993203637247 + ], + [ + -9.299992605418552, + 38.4348980545587 + ], + [ + -9.242851861013252, + 38.4348980545587 + ], + [ + -9.242851861013252, + 38.38993203637247 + ], + [ + -9.299992605418552, + 38.38993203637247 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299992605418552, + 38.4348980545587 + ], + [ + -9.299992605418552, + 38.47986407274493 + ], + [ + -9.242851861013252, + 38.47986407274493 + ], + [ + -9.242851861013252, + 38.4348980545587 + ], + [ + -9.299992605418552, + 38.4348980545587 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242851861013252, + 38.12013592725509 + ], + [ + -9.242851861013252, + 38.16510194544132 + ], + [ + -9.185711116607951, + 38.16510194544132 + ], + [ + -9.185711116607951, + 38.12013592725509 + ], + [ + -9.242851861013252, + 38.12013592725509 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242851861013252, + 38.16510194544132 + ], + [ + -9.242851861013252, + 38.21006796362755 + ], + [ + -9.185711116607951, + 38.21006796362755 + ], + [ + -9.185711116607951, + 38.16510194544132 + ], + [ + -9.242851861013252, + 38.16510194544132 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242851861013252, + 38.21006796362755 + ], + [ + -9.242851861013252, + 38.25503398181378 + ], + [ + -9.185711116607951, + 38.25503398181378 + ], + [ + -9.185711116607951, + 38.21006796362755 + ], + [ + -9.242851861013252, + 38.21006796362755 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242851861013252, + 38.25503398181378 + ], + [ + -9.242851861013252, + 38.30000000000001 + ], + [ + -9.185711116607951, + 38.30000000000001 + ], + [ + -9.185711116607951, + 38.25503398181378 + ], + [ + -9.242851861013252, + 38.25503398181378 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242851861013252, + 38.30000000000001 + ], + [ + -9.242851861013252, + 38.34496601818624 + ], + [ + -9.185711116607951, + 38.34496601818624 + ], + [ + -9.185711116607951, + 38.30000000000001 + ], + [ + -9.242851861013252, + 38.30000000000001 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242851861013252, + 38.34496601818624 + ], + [ + -9.242851861013252, + 38.38993203637247 + ], + [ + -9.185711116607951, + 38.38993203637247 + ], + [ + -9.185711116607951, + 38.34496601818624 + ], + [ + -9.242851861013252, + 38.34496601818624 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242851861013252, + 38.38993203637247 + ], + [ + -9.242851861013252, + 38.4348980545587 + ], + [ + -9.185711116607951, + 38.4348980545587 + ], + [ + -9.185711116607951, + 38.38993203637247 + ], + [ + -9.242851861013252, + 38.38993203637247 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242851861013252, + 38.4348980545587 + ], + [ + -9.242851861013252, + 38.47986407274493 + ], + [ + -9.185711116607951, + 38.47986407274493 + ], + [ + -9.185711116607951, + 38.4348980545587 + ], + [ + -9.242851861013252, + 38.4348980545587 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711116607951, + 38.12013592725509 + ], + [ + -9.185711116607951, + 38.16510194544132 + ], + [ + -9.12857037220265, + 38.16510194544132 + ], + [ + -9.12857037220265, + 38.12013592725509 + ], + [ + -9.185711116607951, + 38.12013592725509 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711116607951, + 38.16510194544132 + ], + [ + -9.185711116607951, + 38.21006796362755 + ], + [ + -9.12857037220265, + 38.21006796362755 + ], + [ + -9.12857037220265, + 38.16510194544132 + ], + [ + -9.185711116607951, + 38.16510194544132 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711116607951, + 38.21006796362755 + ], + [ + -9.185711116607951, + 38.25503398181378 + ], + [ + -9.12857037220265, + 38.25503398181378 + ], + [ + -9.12857037220265, + 38.21006796362755 + ], + [ + -9.185711116607951, + 38.21006796362755 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711116607951, + 38.25503398181378 + ], + [ + -9.185711116607951, + 38.30000000000001 + ], + [ + -9.12857037220265, + 38.30000000000001 + ], + [ + -9.12857037220265, + 38.25503398181378 + ], + [ + -9.185711116607951, + 38.25503398181378 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711116607951, + 38.30000000000001 + ], + [ + -9.185711116607951, + 38.34496601818624 + ], + [ + -9.12857037220265, + 38.34496601818624 + ], + [ + -9.12857037220265, + 38.30000000000001 + ], + [ + -9.185711116607951, + 38.30000000000001 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711116607951, + 38.34496601818624 + ], + [ + -9.185711116607951, + 38.38993203637247 + ], + [ + -9.12857037220265, + 38.38993203637247 + ], + [ + -9.12857037220265, + 38.34496601818624 + ], + [ + -9.185711116607951, + 38.34496601818624 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711116607951, + 38.38993203637247 + ], + [ + -9.185711116607951, + 38.4348980545587 + ], + [ + -9.12857037220265, + 38.4348980545587 + ], + [ + -9.12857037220265, + 38.38993203637247 + ], + [ + -9.185711116607951, + 38.38993203637247 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711116607951, + 38.4348980545587 + ], + [ + -9.185711116607951, + 38.47986407274493 + ], + [ + -9.12857037220265, + 38.47986407274493 + ], + [ + -9.12857037220265, + 38.4348980545587 + ], + [ + -9.185711116607951, + 38.4348980545587 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857037220265, + 38.12013592725509 + ], + [ + -9.12857037220265, + 38.16510194544132 + ], + [ + -9.07142962779735, + 38.16510194544132 + ], + [ + -9.07142962779735, + 38.12013592725509 + ], + [ + -9.12857037220265, + 38.12013592725509 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857037220265, + 38.16510194544132 + ], + [ + -9.12857037220265, + 38.21006796362755 + ], + [ + -9.07142962779735, + 38.21006796362755 + ], + [ + -9.07142962779735, + 38.16510194544132 + ], + [ + -9.12857037220265, + 38.16510194544132 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857037220265, + 38.21006796362755 + ], + [ + -9.12857037220265, + 38.25503398181378 + ], + [ + -9.07142962779735, + 38.25503398181378 + ], + [ + -9.07142962779735, + 38.21006796362755 + ], + [ + -9.12857037220265, + 38.21006796362755 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857037220265, + 38.25503398181378 + ], + [ + -9.12857037220265, + 38.30000000000001 + ], + [ + -9.07142962779735, + 38.30000000000001 + ], + [ + -9.07142962779735, + 38.25503398181378 + ], + [ + -9.12857037220265, + 38.25503398181378 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857037220265, + 38.30000000000001 + ], + [ + -9.12857037220265, + 38.34496601818624 + ], + [ + -9.07142962779735, + 38.34496601818624 + ], + [ + -9.07142962779735, + 38.30000000000001 + ], + [ + -9.12857037220265, + 38.30000000000001 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857037220265, + 38.34496601818624 + ], + [ + -9.12857037220265, + 38.38993203637247 + ], + [ + -9.07142962779735, + 38.38993203637247 + ], + [ + -9.07142962779735, + 38.34496601818624 + ], + [ + -9.12857037220265, + 38.34496601818624 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857037220265, + 38.38993203637247 + ], + [ + -9.12857037220265, + 38.4348980545587 + ], + [ + -9.07142962779735, + 38.4348980545587 + ], + [ + -9.07142962779735, + 38.38993203637247 + ], + [ + -9.12857037220265, + 38.38993203637247 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "weight": 1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857037220265, + 38.4348980545587 + ], + [ + -9.12857037220265, + 38.47986407274493 + ], + [ + -9.07142962779735, + 38.47986407274493 + ], + [ + -9.07142962779735, + 38.4348980545587 + ], + [ + -9.12857037220265, + 38.4348980545587 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#a00", + "marker-symbol": "cross" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.191425, + 38.295503 + ] + } + }, + { + "type": "Feature", + "properties": { + "medianCandidates": [ + [ + -9.187967, + 38.297241 + ], + [ + -9.186594, + 38.298321 + ], + [ + -9.186056, + 38.298981 + ], + [ + -9.185845, + 38.299385 + ] + ], + "marker-color": "#0a0", + "marker-symbol": "cross" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.185763, + 38.299631 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#00a", + "marker-symbol": "cross" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.185711, + 38.3 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#aaa", + "marker-symbol": "cross" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.185711, + 38.3 + ] + } + } + ] +} diff --git a/packages/turf-center-median/test/out/steiners-problem-bad-weights.json b/src/center-median/test/out/steiners-problem-bad-weights.json similarity index 100% rename from packages/turf-center-median/test/out/steiners-problem-bad-weights.json rename to src/center-median/test/out/steiners-problem-bad-weights.json diff --git a/packages/turf-center-median/test/out/steiners-problem-low-tolerance.json b/src/center-median/test/out/steiners-problem-low-tolerance.json similarity index 100% rename from packages/turf-center-median/test/out/steiners-problem-low-tolerance.json rename to src/center-median/test/out/steiners-problem-low-tolerance.json diff --git a/packages/turf-center-median/test/out/steiners-problem.json b/src/center-median/test/out/steiners-problem.json similarity index 100% rename from packages/turf-center-median/test/out/steiners-problem.json rename to src/center-median/test/out/steiners-problem.json diff --git a/packages/turf-center-of-mass/bench.js b/src/center-of-mass/bench.js similarity index 100% rename from packages/turf-center-of-mass/bench.js rename to src/center-of-mass/bench.js diff --git a/src/center-of-mass/index.js b/src/center-of-mass/index.js new file mode 100644 index 0000000000..6d0eb8c234 --- /dev/null +++ b/src/center-of-mass/index.js @@ -0,0 +1,96 @@ +import convex from '../convex'; +import centroid from '../centroid'; +import { point, checkIfOptionsExist } from '../helpers'; +import { getType, getCoord } from '../invariant'; +import { coordEach } from '../meta'; + +/** + * Takes any {@link Feature} or a {@link FeatureCollection} and returns its [center of mass](https://en.wikipedia.org/wiki/Center_of_mass) using this formula: [Centroid of Polygon](https://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon). + * + * @name centerOfMass + * @param {GeoJSON} geojson GeoJSON to be centered + * @param {Object} [options={}] Optional Parameters + * @param {Object} [options.properties={}] Translate Properties to Feature + * @returns {Feature} the center of mass + * @example + * var polygon = turf.polygon([[[-81, 41], [-88, 36], [-84, 31], [-80, 33], [-77, 39], [-81, 41]]]); + * + * var center = turf.centerOfMass(polygon); + * + * //addToMap + * var addToMap = [polygon, center] + */ +function centerOfMass(geojson, options) { + options = checkIfOptionsExist(options); + switch (getType(geojson)) { + case 'Point': + return point(getCoord(geojson), options.properties); + case 'Polygon': { + const coords = []; + coordEach(geojson, function (coord) { + coords.push(coord); + }); + // First, we neutralize the feature (set it around coordinates [0,0]) to prevent rounding errors + // We take any point to translate all the points around 0 + const centre = centroid(geojson, {properties: options.properties}); + const translation = centre.geometry.coordinates; + let sx = 0; + let sy = 0; + let sArea = 0; + let i, pi, pj, xi, xj, yi, yj, a; + + const neutralizedPoints = coords.map(function (point) { + return [ + point[0] - translation[0], + point[1] - translation[1] + ]; + }); + + for (i = 0; i < coords.length - 1; i++) { + // pi is the current point + pi = neutralizedPoints[i]; + xi = pi[0]; + yi = pi[1]; + + // pj is the next point (pi+1) + pj = neutralizedPoints[i + 1]; + xj = pj[0]; + yj = pj[1]; + + // a is the common factor to compute the signed area and the final coordinates + a = xi * yj - xj * yi; + + // sArea is the sum used to compute the signed area + sArea += a; + + // sx and sy are the sums used to compute the final coordinates + sx += (xi + xj) * a; + sy += (yi + yj) * a; + } + + // Shape has no area: fallback on turf.centroid + if (sArea === 0) { + return centre; + } else { + // Compute the signed area, and factorize 1/6A + const area = sArea * 0.5; + const areaFactor = 1 / (6 * area); + + // Compute the final coordinates, adding back the values that have been neutralized + return point([ + translation[0] + areaFactor * sx, + translation[1] + areaFactor * sy + ], options.properties); + } + } + default: { + // Not a polygon: Compute the convex hull and work with that + const hull = convex(geojson); + if (hull) return centerOfMass(hull, {properties: options.properties}); + // Hull is empty: fallback on the centroid + else return centroid(geojson, {properties: options.properties}); + } + } +} + +export default centerOfMass; diff --git a/src/center-of-mass/test.js b/src/center-of-mass/test.js new file mode 100644 index 0000000000..f83eb9bbef --- /dev/null +++ b/src/center-of-mass/test.js @@ -0,0 +1,87 @@ +const path = require('path'); +const test = require('tape'); +const glob = require('glob'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { featureEach } = require('../meta'); +const { + point, + lineString, + polygon, + featureCollection, + } = require('../helpers'); +const centerOfMass = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep, +}; + +const fixtures = glob.sync(directories.in + '*.geojson').map(input => { + const base = path.parse(input).base; + return { + name: path.parse(input).name, + filename: base, + geojson: load.sync(input), + out: directories.out + base, + }; +}); + +test('center of mass', t => { + fixtures.forEach(fixture => { + const name = fixture.name; + const out = fixture.out; + const geojson = fixture.geojson; + const centered = centerOfMass(geojson, {'marker-symbol': 'circle'}); + const result = featureCollection([centered]); + featureEach(geojson, feature => result.features.push(feature)); + + if (process.env.REGEN) write.sync(out, result); + t.deepEqual(result, load.sync(out), name); + }); + t.end(); +}); + +test('center of mass -- Geometry Support', t => { + const line = lineString([[0, 0], [1, 1]]); + const poly = polygon([[[0, 0], [3, 3], [-5, -5], [0, 0]]]); + + t.deepEqual(centerOfMass(poly.geometry), centerOfMass(poly), 'polygon geometry/feature should be equal'); + t.deepEqual(centerOfMass(line.geometry), centerOfMass(line), 'lineString geometry/feature should be equal'); + t.end(); +}); + +test('center of mass -- no area', t => { + const poly = polygon([[[0, 0], [0, 0], [0, 0], [0, 0]]]); + const pt = centerOfMass(poly); + t.deepEqual(pt, point([0, 0]), 'polygon has no area'); + t.end(); +}); + +test('center of mass -- point', t => { + const p = point([0, 0]); + const pt = centerOfMass(p); + t.deepEqual(pt, point([0, 0]), 'point returns pt'); + t.end(); +}); + +test('center of mass -- point geom', t => { + const geomPoint = {type: 'Point', coordinates: [0, 0]}; + const pt = centerOfMass(geomPoint); + t.deepEqual(pt, point([0, 0]), 'point geom returns pt'); + t.end(); +}); + +test('center of mass -- properties', t => { + const line = lineString([[0, 0], [1, 1]]); + const pt = centerOfMass(line, {properties: {foo: 'bar'}}); + t.equal(pt.properties.foo, 'bar', 'translate properties'); + t.end(); +}); + +test('center of mass -- polygon properties', t => { + const poly = polygon([[[0, 0], [0, 1], [1, 1], [1, 0],[0, 0]]]); + const pt = centerOfMass(poly, {properties: {foo: 'bar'}}); + t.equal(pt.properties.foo, 'bar', 'translate properties'); + t.end(); +}); diff --git a/packages/turf-center-of-mass/test/in/feature-collection.geojson b/src/center-of-mass/test/in/feature-collection.geojson similarity index 100% rename from packages/turf-center-of-mass/test/in/feature-collection.geojson rename to src/center-of-mass/test/in/feature-collection.geojson diff --git a/packages/turf-center-of-mass/test/in/imbalanced-polygon.geojson b/src/center-of-mass/test/in/imbalanced-polygon.geojson similarity index 100% rename from packages/turf-center-of-mass/test/in/imbalanced-polygon.geojson rename to src/center-of-mass/test/in/imbalanced-polygon.geojson diff --git a/packages/turf-center-of-mass/test/in/linestring.geojson b/src/center-of-mass/test/in/linestring.geojson similarity index 100% rename from packages/turf-center-of-mass/test/in/linestring.geojson rename to src/center-of-mass/test/in/linestring.geojson diff --git a/packages/turf-center-of-mass/test/in/point.geojson b/src/center-of-mass/test/in/point.geojson similarity index 100% rename from packages/turf-center-of-mass/test/in/point.geojson rename to src/center-of-mass/test/in/point.geojson diff --git a/packages/turf-center-of-mass/test/in/polygon.geojson b/src/center-of-mass/test/in/polygon.geojson similarity index 100% rename from packages/turf-center-of-mass/test/in/polygon.geojson rename to src/center-of-mass/test/in/polygon.geojson diff --git a/packages/turf-center-of-mass/test/out/feature-collection.geojson b/src/center-of-mass/test/out/feature-collection.geojson similarity index 100% rename from packages/turf-center-of-mass/test/out/feature-collection.geojson rename to src/center-of-mass/test/out/feature-collection.geojson diff --git a/packages/turf-center-of-mass/test/out/imbalanced-polygon.geojson b/src/center-of-mass/test/out/imbalanced-polygon.geojson similarity index 100% rename from packages/turf-center-of-mass/test/out/imbalanced-polygon.geojson rename to src/center-of-mass/test/out/imbalanced-polygon.geojson diff --git a/packages/turf-center-of-mass/test/out/linestring.geojson b/src/center-of-mass/test/out/linestring.geojson similarity index 100% rename from packages/turf-center-of-mass/test/out/linestring.geojson rename to src/center-of-mass/test/out/linestring.geojson diff --git a/packages/turf-center-of-mass/test/out/point.geojson b/src/center-of-mass/test/out/point.geojson similarity index 100% rename from packages/turf-center-of-mass/test/out/point.geojson rename to src/center-of-mass/test/out/point.geojson diff --git a/packages/turf-center-of-mass/test/out/polygon.geojson b/src/center-of-mass/test/out/polygon.geojson similarity index 100% rename from packages/turf-center-of-mass/test/out/polygon.geojson rename to src/center-of-mass/test/out/polygon.geojson diff --git a/packages/turf-center/bench.js b/src/center/bench.js similarity index 100% rename from packages/turf-center/bench.js rename to src/center/bench.js diff --git a/src/center/index.js b/src/center/index.js new file mode 100644 index 0000000000..803e8383a0 --- /dev/null +++ b/src/center/index.js @@ -0,0 +1,37 @@ +import bbox from '../bbox'; +import { point, checkIfOptionsExist } from '../helpers'; + +/** + * Takes a {@link Feature} or {@link FeatureCollection} and returns the absolute center point of all features. + * + * @name center + * @param {GeoJSON} geojson GeoJSON to be centered + * @param {Object} [options={}] Optional parameters + * @param {Object} [options.properties={}] Translate GeoJSON Properties to Point + * @param {Object} [options.bbox={}] Translate GeoJSON BBox to Point + * @param {Object} [options.id={}] Translate GeoJSON Id to Point + * @returns {Feature} a Point feature at the absolute center point of all input features + * @example + * var features = turf.points([ + * [-97.522259, 35.4691], + * [-97.502754, 35.463455], + * [-97.508269, 35.463245] + * ]); + * + * var center = turf.center(features); + * + * //addToMap + * var addToMap = [features, center] + * center.properties['marker-size'] = 'large'; + * center.properties['marker-color'] = '#000'; + */ +function center(geojson, options) { + options = checkIfOptionsExist(options); + + const ext = bbox(geojson); + const x = (ext[0] + ext[2]) / 2; + const y = (ext[1] + ext[3]) / 2; + return point([x, y], options.properties, options); +} + +export default center; diff --git a/src/center/test.js b/src/center/test.js new file mode 100644 index 0000000000..dff399e30c --- /dev/null +++ b/src/center/test.js @@ -0,0 +1,55 @@ +const fs = require('fs'); +const test = require('tape'); +const glob = require('glob'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const bboxPolygon = require('../bbox-polygon').default; +const bbox = require('../bbox').default; +const { featureEach, coordEach } = require('../meta'); +const { lineString, featureCollection } = require('../helpers'); +const center = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +var fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-center', t => { + fixtures.forEach(fixture => { + const filename = fixture.filename; + const name = fixture.name; + const geojson = fixture.geojson; + + const options = geojson.options || {}; + options.properties = {'marker-symbol': 'star', 'marker-color': '#F00'}; + const centered = center(geojson, options); + + // Display Results + const results = featureCollection([centered]) + featureEach(geojson, feature => results.features.push(feature)) + const extent = bboxPolygon(bbox(geojson)) + extent.properties = {stroke: '#00F', 'stroke-width': 1, 'fill-opacity': 0} + coordEach(extent, coord => results.features.push(lineString([coord, centered.geometry.coordinates], {stroke: '#00F', 'stroke-width': 1}))) + results.features.push(extent) + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(results, load.sync(directories.out + filename), name); + }); + t.end(); +}); + +test('turf-center -- properties', t => { + const line = lineString([[0, 0], [1, 1]]); + const pt = center(line, {properties: {foo: 'bar'}}); + t.equal(pt.properties.foo, 'bar', 'translate properties'); + t.end(); +}); diff --git a/packages/turf-center/test/in/feature-collection.geojson b/src/center/test/in/feature-collection.geojson similarity index 100% rename from packages/turf-center/test/in/feature-collection.geojson rename to src/center/test/in/feature-collection.geojson diff --git a/packages/turf-center/test/in/imbalanced-polygon.geojson b/src/center/test/in/imbalanced-polygon.geojson similarity index 100% rename from packages/turf-center/test/in/imbalanced-polygon.geojson rename to src/center/test/in/imbalanced-polygon.geojson diff --git a/packages/turf-center/test/in/linestring.geojson b/src/center/test/in/linestring.geojson similarity index 100% rename from packages/turf-center/test/in/linestring.geojson rename to src/center/test/in/linestring.geojson diff --git a/packages/turf-center/test/in/point.geojson b/src/center/test/in/point.geojson similarity index 100% rename from packages/turf-center/test/in/point.geojson rename to src/center/test/in/point.geojson diff --git a/packages/turf-center/test/in/points-with-weights.geojson b/src/center/test/in/points-with-weights.geojson similarity index 100% rename from packages/turf-center/test/in/points-with-weights.geojson rename to src/center/test/in/points-with-weights.geojson diff --git a/packages/turf-center/test/in/polygon-without-weights.geojson b/src/center/test/in/polygon-without-weights.geojson similarity index 100% rename from packages/turf-center/test/in/polygon-without-weights.geojson rename to src/center/test/in/polygon-without-weights.geojson diff --git a/packages/turf-center/test/in/polygon.geojson b/src/center/test/in/polygon.geojson similarity index 100% rename from packages/turf-center/test/in/polygon.geojson rename to src/center/test/in/polygon.geojson diff --git a/packages/turf-center/test/out/feature-collection.geojson b/src/center/test/out/feature-collection.geojson similarity index 100% rename from packages/turf-center/test/out/feature-collection.geojson rename to src/center/test/out/feature-collection.geojson diff --git a/packages/turf-center/test/out/imbalanced-polygon.geojson b/src/center/test/out/imbalanced-polygon.geojson similarity index 100% rename from packages/turf-center/test/out/imbalanced-polygon.geojson rename to src/center/test/out/imbalanced-polygon.geojson diff --git a/packages/turf-center/test/out/linestring.geojson b/src/center/test/out/linestring.geojson similarity index 100% rename from packages/turf-center/test/out/linestring.geojson rename to src/center/test/out/linestring.geojson diff --git a/packages/turf-center/test/out/point.geojson b/src/center/test/out/point.geojson similarity index 100% rename from packages/turf-center/test/out/point.geojson rename to src/center/test/out/point.geojson diff --git a/packages/turf-center/test/out/points-with-weights.geojson b/src/center/test/out/points-with-weights.geojson similarity index 100% rename from packages/turf-center/test/out/points-with-weights.geojson rename to src/center/test/out/points-with-weights.geojson diff --git a/packages/turf-center/test/out/polygon-without-weights.geojson b/src/center/test/out/polygon-without-weights.geojson similarity index 100% rename from packages/turf-center/test/out/polygon-without-weights.geojson rename to src/center/test/out/polygon-without-weights.geojson diff --git a/packages/turf-center/test/out/polygon.geojson b/src/center/test/out/polygon.geojson similarity index 100% rename from packages/turf-center/test/out/polygon.geojson rename to src/center/test/out/polygon.geojson diff --git a/packages/turf-centroid/bench.js b/src/centroid/bench.js similarity index 100% rename from packages/turf-centroid/bench.js rename to src/centroid/bench.js diff --git a/src/centroid/index.js b/src/centroid/index.js new file mode 100755 index 0000000000..036cfafabf --- /dev/null +++ b/src/centroid/index.js @@ -0,0 +1,34 @@ +import { coordEach } from '../meta'; +import { point, checkIfOptionsExist } from '../helpers'; + +/** + * Takes one or more features and calculates the centroid using the mean of all vertices. + * This lessens the effect of small islands and artifacts when calculating the centroid of a set of polygons. + * + * @name centroid + * @param {GeoJSON} geojson GeoJSON to be centered + * @param {Object} [options={}] Optional Parameters + * @param {Object} [options.properties={}] an Object that is used as the {@link Feature}'s properties + * @returns {Feature} the centroid of the input features + * @example + * var polygon = turf.polygon([[[-81, 41], [-88, 36], [-84, 31], [-80, 33], [-77, 39], [-81, 41]]]); + * + * var centroid = turf.centroid(polygon); + * + * //addToMap + * var addToMap = [polygon, centroid] + */ +function centroid(geojson, options) { + options = checkIfOptionsExist(options); + let xSum = 0; + let ySum = 0; + let len = 0; + coordEach(geojson, function (coord) { + xSum += coord[0]; + ySum += coord[1]; + len++; + }, true); + return point([xSum / len, ySum / len], options.properties); +} + +export default centroid; diff --git a/src/centroid/test.js b/src/centroid/test.js new file mode 100644 index 0000000000..60f30861f7 --- /dev/null +++ b/src/centroid/test.js @@ -0,0 +1,46 @@ +const path = require('path'); +const test = require('tape'); +const glob = require('glob'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { featureEach } = require('../meta'); +const { featureCollection, lineString } = require('../helpers'); +const centroid = require('.').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep, +}; + +const fixtures = glob.sync(directories.in + '*.geojson').map(input => { + const name = path.parse(input).name; + const base = path.parse(input).base; + return { + name, + filename: base, + geojson: load.sync(input), + out: directories.out + base, + }; +}); + +test('centroid', t => { + fixtures.forEach(fixture => { + const name = fixture.name; + const geojson = fixture.geojson; + const out = fixture.out; + const centered = centroid(geojson, {properties: {'marker-symbol': 'circle'}}); + const result = featureCollection([centered]); + featureEach(geojson, feature => result.features.push(feature)); + + if (process.env.REGEN) write.sync(out, result); + t.deepEqual(result, load.sync(out), name); + }); + t.end(); +}); + +test('centroid -- properties', t => { + const line = lineString([[0, 0], [1, 1]]); + const pt = centroid(line, {properties: {foo: 'bar'}}); + t.equal(pt.properties.foo, 'bar', 'translate properties'); + t.end(); +}); diff --git a/packages/turf-centroid/test/in/feature-collection.geojson b/src/centroid/test/in/feature-collection.geojson similarity index 100% rename from packages/turf-centroid/test/in/feature-collection.geojson rename to src/centroid/test/in/feature-collection.geojson diff --git a/packages/turf-centroid/test/in/imbalanced-polygon.geojson b/src/centroid/test/in/imbalanced-polygon.geojson similarity index 100% rename from packages/turf-centroid/test/in/imbalanced-polygon.geojson rename to src/centroid/test/in/imbalanced-polygon.geojson diff --git a/packages/turf-centroid/test/in/linestring.geojson b/src/centroid/test/in/linestring.geojson similarity index 100% rename from packages/turf-centroid/test/in/linestring.geojson rename to src/centroid/test/in/linestring.geojson diff --git a/packages/turf-centroid/test/in/point.geojson b/src/centroid/test/in/point.geojson similarity index 100% rename from packages/turf-centroid/test/in/point.geojson rename to src/centroid/test/in/point.geojson diff --git a/packages/turf-centroid/test/in/polygon.geojson b/src/centroid/test/in/polygon.geojson similarity index 100% rename from packages/turf-centroid/test/in/polygon.geojson rename to src/centroid/test/in/polygon.geojson diff --git a/src/centroid/test/in/polygon2.geojson b/src/centroid/test/in/polygon2.geojson new file mode 100644 index 0000000000..a96e1c417b --- /dev/null +++ b/src/centroid/test/in/polygon2.geojson @@ -0,0 +1,8 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [[[-1, -1], [1, -1], [1, 1], [-1, 1], [-1, -1]]] + } +} diff --git a/packages/turf-centroid/test/out/feature-collection.geojson b/src/centroid/test/out/feature-collection.geojson similarity index 100% rename from packages/turf-centroid/test/out/feature-collection.geojson rename to src/centroid/test/out/feature-collection.geojson diff --git a/packages/turf-centroid/test/out/imbalanced-polygon.geojson b/src/centroid/test/out/imbalanced-polygon.geojson old mode 100644 new mode 100755 similarity index 97% rename from packages/turf-centroid/test/out/imbalanced-polygon.geojson rename to src/centroid/test/out/imbalanced-polygon.geojson index a8d9325f2e..5f397e9da7 --- a/packages/turf-centroid/test/out/imbalanced-polygon.geojson +++ b/src/centroid/test/out/imbalanced-polygon.geojson @@ -9,8 +9,8 @@ "geometry": { "type": "Point", "coordinates": [ - 4.851914405822754, - 45.78098812633097 + 4.851791984156558, + 45.78143055383553 ] } }, diff --git a/packages/turf-centroid/test/out/linestring.geojson b/src/centroid/test/out/linestring.geojson similarity index 100% rename from packages/turf-centroid/test/out/linestring.geojson rename to src/centroid/test/out/linestring.geojson diff --git a/packages/turf-centroid/test/out/point.geojson b/src/centroid/test/out/point.geojson similarity index 100% rename from packages/turf-centroid/test/out/point.geojson rename to src/centroid/test/out/point.geojson diff --git a/src/centroid/test/out/polygon.geojson b/src/centroid/test/out/polygon.geojson new file mode 100755 index 0000000000..c2b430e812 --- /dev/null +++ b/src/centroid/test/out/polygon.geojson @@ -0,0 +1,61 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "marker-symbol": "circle" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 4.841194152832031, + 45.75807143030368 + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.8250579833984375, + 45.79398056386735 + ], + [ + 4.882392883300781, + 45.79254427435898 + ], + [ + 4.910373687744141, + 45.76081677972451 + ], + [ + 4.894924163818359, + 45.7271539426975 + ], + [ + 4.824199676513671, + 45.71337148333104 + ], + [ + 4.773387908935547, + 45.74021417890731 + ], + [ + 4.778022766113281, + 45.778418789239055 + ], + [ + 4.8250579833984375, + 45.79398056386735 + ] + ] + ] + } + } + ] +} diff --git a/src/centroid/test/out/polygon2.geojson b/src/centroid/test/out/polygon2.geojson new file mode 100644 index 0000000000..83882787bf --- /dev/null +++ b/src/centroid/test/out/polygon2.geojson @@ -0,0 +1,49 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "marker-symbol": "circle" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 0, + 0 + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -1, + -1 + ], + [ + 1, + -1 + ], + [ + 1, + 1 + ], + [ + -1, + 1 + ], + [ + -1, + -1 + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-circle/bench.js b/src/circle/bench.js similarity index 100% rename from packages/turf-circle/bench.js rename to src/circle/bench.js diff --git a/src/circle/index.js b/src/circle/index.js new file mode 100644 index 0000000000..91e91f674e --- /dev/null +++ b/src/circle/index.js @@ -0,0 +1,39 @@ +import destination from '../destination'; +import { polygon, checkIfOptionsExist } from '../helpers'; + +/** + * Takes a {@link Point} and calculates the circle polygon given a radius in degrees, radians, miles, or kilometers; and steps for precision. + * + * @name circle + * @param {Feature|number[]} center center point + * @param {number} radius radius of the circle + * @param {Object} [options={}] Optional parameters + * @param {number} [options.steps=64] number of steps + * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians + * @param {Object} [options.properties={}] properties + * @returns {Feature} circle polygon + * @example + * var center = [-75.343, 39.984]; + * var radius = 5; + * var options = {steps, units, properties{foo, radius, options); + * + * //addToMap + * var addToMap = [turf.point(center), circle] + */ +function circle(center, radius, options) { + options = checkIfOptionsExist(options); + // default params + const steps = options.steps || 64; + const properties = options.properties ? options.properties : (!Array.isArray(center) && center.type === 'Feature' && center.properties) ? center.properties : {}; + + // main + const coordinates = []; + for (let i = 0; i < steps; i++) { + coordinates.push(destination(center, radius, i * -360 / steps, options).geometry.coordinates); + } + coordinates.push(coordinates[0]); + + return polygon([coordinates], properties); +} + +export default circle; diff --git a/src/circle/test.js b/src/circle/test.js new file mode 100644 index 0000000000..7fe506048b --- /dev/null +++ b/src/circle/test.js @@ -0,0 +1,47 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const truncate = require('../truncate').default; +const { featureCollection } = require('../helpers'); +const geojsonhint = require('@mapbox/geojsonhint'); +const circle = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-circle', t => { + fixtures.forEach(fixture => { + const filename = fixture.filename; + const name = fixture.name; + const geojson = fixture.geojson; + const properties = geojson.properties || {}; + const radius = properties.radius; + const steps = properties.steps || 64; + const units = properties.units; + + const C = truncate(circle(geojson, radius, {steps: steps, units: units})); + const results = featureCollection([geojson, C]); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEquals(results, load.sync(directories.out + filename), name); + }); + t.end(); +}); + +test('turf-circle -- validate geojson', t => { + const C = circle([0, 0], 100); + geojsonhint.hint(C).forEach(hint => t.fail(hint.message)); + t.end(); +}); diff --git a/packages/turf-circle/test/in/circle1.geojson b/src/circle/test/in/circle1.geojson similarity index 100% rename from packages/turf-circle/test/in/circle1.geojson rename to src/circle/test/in/circle1.geojson diff --git a/packages/turf-circle/test/out/circle1.geojson b/src/circle/test/out/circle1.geojson similarity index 100% rename from packages/turf-circle/test/out/circle1.geojson rename to src/circle/test/out/circle1.geojson diff --git a/packages/turf-clean-coords/bench.js b/src/clean-coords/bench.js similarity index 100% rename from packages/turf-clean-coords/bench.js rename to src/clean-coords/bench.js diff --git a/src/clean-coords/index.js b/src/clean-coords/index.js new file mode 100644 index 0000000000..6ecc09235d --- /dev/null +++ b/src/clean-coords/index.js @@ -0,0 +1,161 @@ +import { feature, checkIfOptionsExist } from '../helpers'; +import { getCoords, getType } from '../invariant'; + +// To-Do => Improve Typescript GeoJSON handling + +/** + * Removes redundant coordinates from any GeoJSON Geometry. + * + * @name cleanCoords + * @param {Geometry|Feature} geojson Feature or Geometry + * @param {Object} [options={}] Optional parameters + * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated + * @returns {Geometry|Feature} the cleaned input Feature/Geometry + * @example + * var line = turf.lineString([[0, 0], [0, 2], [0, 5], [0, 8], [0, 8], [0, 10]]); + * var multiPoint = turf.multiPoint([[0, 0], [0, 0], [2, 2]]); + * + * turf.cleanCoords(line).geometry.coordinates; + * //= [[0, 0], [0, 10]] + * + * turf.cleanCoords(multiPoint).geometry.coordinates; + * //= [[0, 0], [2, 2]] + */ +function cleanCoords(geojson, options) { + options = checkIfOptionsExist(options); + // Backwards compatible with v4.0 + var mutate = (typeof options === 'object') ? options.mutate : options; + if (!geojson) throw new Error('geojson is required'); + var type = getType(geojson); + + // Store new "clean" points in this Array + var newCoords = []; + + switch (type) { + case 'LineString': + newCoords = cleanLine(geojson); + break; + case 'MultiLineString': + case 'Polygon': + getCoords(geojson).forEach(function (line) { + newCoords.push(cleanLine(line)); + }); + break; + case 'MultiPolygon': + getCoords(geojson).forEach(function (polygons) { + var polyPoints = []; + polygons.forEach(function (ring) { + polyPoints.push(cleanLine(ring)); + }); + newCoords.push(polyPoints); + }); + break; + case 'Point': + return geojson; + case 'MultiPoint': + var existing = {}; + getCoords(geojson).forEach(function (coord) { + var key = coord.join('-'); + if (!existing.hasOwnProperty(key)) { + newCoords.push(coord); + existing[key] = true; + } + }); + break; + default: + throw new Error(type + ' geometry not supported'); + } + + // Support input mutation + if (geojson.coordinates) { + if (mutate === true) { + geojson.coordinates = newCoords; + return geojson; + } + return {type: type, coordinates: newCoords}; + } else { + if (mutate === true) { + geojson.geometry.coordinates = newCoords; + return geojson; + } + return feature({type: type, coordinates: newCoords}, geojson.properties, {bbox: geojson.bbox, id: geojson.id}); + } +} + +/** + * Clean Coords + * + * @private + * @param {Array|LineString} line Line + * @returns {Array} Cleaned coordinates + */ +function cleanLine(line) { + + var points = getCoords(line); + // handle "clean" segment + if (points.length === 2 && !equals(points[0], points[1])) return points; + + var newPoints = []; + var secondToLast = points.length - 1; + var newPointsLength = newPoints.length; + + newPoints.push(points[0]); + for (var i = 1; i < secondToLast; i++) { + var prevAddedPoint = newPoints[newPoints.length - 1]; + if ((points[i][0] === prevAddedPoint[0]) && (points[i][1] === prevAddedPoint[1])) continue; + else { + newPoints.push(points[i]); + newPointsLength = newPoints.length; + if (newPointsLength > 2) { + if (isPointOnLineSegment(newPoints[newPointsLength - 3], newPoints[newPointsLength - 1], newPoints[newPointsLength - 2])) newPoints.splice(newPoints.length - 2, 1); + } + } + } + newPoints.push(points[points.length - 1]); + + newPointsLength = newPoints.length; + if (equals(points[0], points[points.length - 1]) && newPointsLength < 4) throw new Error('invalid polygon'); + if (isPointOnLineSegment(newPoints[newPointsLength - 3], newPoints[newPointsLength - 1], newPoints[newPointsLength - 2])) newPoints.splice(newPoints.length - 2, 1); + + return newPoints; +} + +/** + * Compares two points and returns if they are equals + * + * @private + * @param {Position} pt1 point + * @param {Position} pt2 point + * @returns {boolean} true if they are equals + */ +function equals(pt1, pt2) { + return pt1[0] === pt2[0] && pt1[1] === pt2[1]; +} + +/** + * Returns if `point` is on the segment between `start` and `end`. + * Borrowed from `@turf/boolean-point-on-line` to speed up the evaluation (instead of using the module as dependency) + * + * @private + * @param {Position} start coord pair of start of line + * @param {Position} end coord pair of end of line + * @param {Position} point coord pair of point to check + * @returns {boolean} true/false + */ +function isPointOnLineSegment(start, end, point) { + var x = point[0], y = point[1]; + var startX = start[0], startY = start[1]; + var endX = end[0], endY = end[1]; + + var dxc = x - startX; + var dyc = y - startY; + var dxl = endX - startX; + var dyl = endY - startY; + var cross = dxc * dyl - dyc * dxl; + + if (cross !== 0) return false; + else if (Math.abs(dxl) >= Math.abs(dyl)) return dxl > 0 ? startX <= x && x <= endX : endX <= x && x <= startX; + else return dyl > 0 ? startY <= y && y <= endY : endY <= y && y <= startY; +} + +export default cleanCoords; diff --git a/src/clean-coords/test.js b/src/clean-coords/test.js new file mode 100644 index 0000000000..9ad83748fe --- /dev/null +++ b/src/clean-coords/test.js @@ -0,0 +1,75 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const truncate = require('../truncate').default; +const { + point, + multiPoint, + lineString, + multiPolygon, + polygon, + } = require('../helpers'); +const write = require('write-json-file'); +const cleanCoords = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-clean-coords', t => { + fixtures.forEach(fixture => { + const filename = fixture.filename; + const name = fixture.name; + const geojson = fixture.geojson; + const results = cleanCoords(geojson); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(results, load.sync(directories.out + filename), name); + }); + t.end(); +}); + +test('turf-clean-coords -- extras', t => { + t.equal(cleanCoords(point([0, 0])).geometry.coordinates.length, 2, 'point'); + t.equal(cleanCoords(lineString([[0, 0], [1, 1], [2, 2]])).geometry.coordinates.length, 2, 'lineString'); + t.equal(cleanCoords(polygon([[[0, 0], [1, 1], [2, 2], [0, 2], [0, 0]]])).geometry.coordinates[0].length, 4, 'polygon'); + t.equal(cleanCoords(multiPoint([[0, 0], [0, 0], [2, 2]])).geometry.coordinates.length, 2, 'multiPoint'); + t.end(); +}); + +test('turf-clean-coords -- truncate', t => { + t.equal(cleanCoords(truncate(lineString([[0, 0], [1.1, 1.123], [2.12, 2.32], [3, 3]]), {precision: 0})).geometry.coordinates.length, 2); + t.end(); +}); + +test('turf-clean-coords -- throws', t => { + t.throws(() => cleanCoords(null), /geojson is required/, 'missing geojson'); + t.end(); +}); + +test('turf-clean-coords -- prevent input mutation', t => { + const line = lineString([[0, 0], [1, 1], [2, 2]], {foo: 'bar'}); + const lineBefore = JSON.parse(JSON.stringify(line)); + + cleanCoords(line); + t.deepEqual(lineBefore, line, 'line should NOT be mutated'); + + const multiPoly = multiPolygon([ + [[[0, 0], [1, 1], [2, 2], [2, 0], [0, 0]]], + [[[0, 0], [0, 5], [5, 5], [5, 5], [5, 0], [0, 0]]] + ], {hello: 'world'}); + const multiPolyBefore = JSON.parse(JSON.stringify(multiPoly)); + cleanCoords(multiPoly); + t.deepEqual(multiPolyBefore, multiPoly, 'multiPolygon should NOT be mutated'); + t.end(); +}); diff --git a/packages/turf-clean-coords/test/in/clean-segment.geojson b/src/clean-coords/test/in/clean-segment.geojson similarity index 100% rename from packages/turf-clean-coords/test/in/clean-segment.geojson rename to src/clean-coords/test/in/clean-segment.geojson diff --git a/packages/turf-clean-coords/test/in/geometry.geojson b/src/clean-coords/test/in/geometry.geojson similarity index 100% rename from packages/turf-clean-coords/test/in/geometry.geojson rename to src/clean-coords/test/in/geometry.geojson diff --git a/packages/turf-clean-coords/test/in/multiline.geojson b/src/clean-coords/test/in/multiline.geojson similarity index 100% rename from packages/turf-clean-coords/test/in/multiline.geojson rename to src/clean-coords/test/in/multiline.geojson diff --git a/packages/turf-clean-coords/test/in/multipoint.geojson b/src/clean-coords/test/in/multipoint.geojson similarity index 100% rename from packages/turf-clean-coords/test/in/multipoint.geojson rename to src/clean-coords/test/in/multipoint.geojson diff --git a/packages/turf-clean-coords/test/in/multipolygon.geojson b/src/clean-coords/test/in/multipolygon.geojson similarity index 100% rename from packages/turf-clean-coords/test/in/multipolygon.geojson rename to src/clean-coords/test/in/multipolygon.geojson diff --git a/packages/turf-clean-coords/test/in/point.geojson b/src/clean-coords/test/in/point.geojson similarity index 100% rename from packages/turf-clean-coords/test/in/point.geojson rename to src/clean-coords/test/in/point.geojson diff --git a/packages/turf-clean-coords/test/in/polygon-with-hole.geojson b/src/clean-coords/test/in/polygon-with-hole.geojson similarity index 100% rename from packages/turf-clean-coords/test/in/polygon-with-hole.geojson rename to src/clean-coords/test/in/polygon-with-hole.geojson diff --git a/packages/turf-clean-coords/test/in/polygon.geojson b/src/clean-coords/test/in/polygon.geojson similarity index 100% rename from packages/turf-clean-coords/test/in/polygon.geojson rename to src/clean-coords/test/in/polygon.geojson diff --git a/packages/turf-clean-coords/test/in/segment.geojson b/src/clean-coords/test/in/segment.geojson similarity index 100% rename from packages/turf-clean-coords/test/in/segment.geojson rename to src/clean-coords/test/in/segment.geojson diff --git a/packages/turf-clean-coords/test/in/simple-line.geojson b/src/clean-coords/test/in/simple-line.geojson similarity index 100% rename from packages/turf-clean-coords/test/in/simple-line.geojson rename to src/clean-coords/test/in/simple-line.geojson diff --git a/packages/turf-clean-coords/test/in/triangle.geojson b/src/clean-coords/test/in/triangle.geojson similarity index 100% rename from packages/turf-clean-coords/test/in/triangle.geojson rename to src/clean-coords/test/in/triangle.geojson diff --git a/packages/turf-clean-coords/test/in/triplicate-issue1255.geojson b/src/clean-coords/test/in/triplicate-issue1255.geojson similarity index 100% rename from packages/turf-clean-coords/test/in/triplicate-issue1255.geojson rename to src/clean-coords/test/in/triplicate-issue1255.geojson diff --git a/packages/turf-clean-coords/test/out/clean-segment.geojson b/src/clean-coords/test/out/clean-segment.geojson similarity index 100% rename from packages/turf-clean-coords/test/out/clean-segment.geojson rename to src/clean-coords/test/out/clean-segment.geojson diff --git a/packages/turf-clean-coords/test/out/geometry.geojson b/src/clean-coords/test/out/geometry.geojson similarity index 100% rename from packages/turf-clean-coords/test/out/geometry.geojson rename to src/clean-coords/test/out/geometry.geojson diff --git a/packages/turf-clean-coords/test/out/multiline.geojson b/src/clean-coords/test/out/multiline.geojson similarity index 100% rename from packages/turf-clean-coords/test/out/multiline.geojson rename to src/clean-coords/test/out/multiline.geojson diff --git a/packages/turf-clean-coords/test/out/multipoint.geojson b/src/clean-coords/test/out/multipoint.geojson similarity index 100% rename from packages/turf-clean-coords/test/out/multipoint.geojson rename to src/clean-coords/test/out/multipoint.geojson diff --git a/packages/turf-clean-coords/test/out/multipolygon.geojson b/src/clean-coords/test/out/multipolygon.geojson similarity index 100% rename from packages/turf-clean-coords/test/out/multipolygon.geojson rename to src/clean-coords/test/out/multipolygon.geojson diff --git a/packages/turf-clean-coords/test/out/point.geojson b/src/clean-coords/test/out/point.geojson similarity index 100% rename from packages/turf-clean-coords/test/out/point.geojson rename to src/clean-coords/test/out/point.geojson diff --git a/packages/turf-clean-coords/test/out/polygon-with-hole.geojson b/src/clean-coords/test/out/polygon-with-hole.geojson similarity index 100% rename from packages/turf-clean-coords/test/out/polygon-with-hole.geojson rename to src/clean-coords/test/out/polygon-with-hole.geojson diff --git a/packages/turf-clean-coords/test/out/polygon.geojson b/src/clean-coords/test/out/polygon.geojson similarity index 100% rename from packages/turf-clean-coords/test/out/polygon.geojson rename to src/clean-coords/test/out/polygon.geojson diff --git a/packages/turf-clean-coords/test/out/segment.geojson b/src/clean-coords/test/out/segment.geojson similarity index 100% rename from packages/turf-clean-coords/test/out/segment.geojson rename to src/clean-coords/test/out/segment.geojson diff --git a/packages/turf-clean-coords/test/out/simple-line.geojson b/src/clean-coords/test/out/simple-line.geojson similarity index 100% rename from packages/turf-clean-coords/test/out/simple-line.geojson rename to src/clean-coords/test/out/simple-line.geojson diff --git a/packages/turf-clean-coords/test/out/triangle.geojson b/src/clean-coords/test/out/triangle.geojson similarity index 100% rename from packages/turf-clean-coords/test/out/triangle.geojson rename to src/clean-coords/test/out/triangle.geojson diff --git a/packages/turf-clean-coords/test/out/triplicate-issue1255.geojson b/src/clean-coords/test/out/triplicate-issue1255.geojson similarity index 100% rename from packages/turf-clean-coords/test/out/triplicate-issue1255.geojson rename to src/clean-coords/test/out/triplicate-issue1255.geojson diff --git a/packages/turf-clone/bench.js b/src/clone/bench.js similarity index 100% rename from packages/turf-clone/bench.js rename to src/clone/bench.js diff --git a/packages/turf-clone/index.d.ts b/src/clone/index.d.ts similarity index 100% rename from packages/turf-clone/index.d.ts rename to src/clone/index.d.ts diff --git a/src/clone/index.js b/src/clone/index.js new file mode 100644 index 0000000000..71bce59d1d --- /dev/null +++ b/src/clone/index.js @@ -0,0 +1,153 @@ +/** + * Returns a cloned copy of the passed GeoJSON Object, including possible 'Foreign Members'. + * ~3-5x faster than the common JSON.parse + JSON.stringify combo method. + * + * @name clone + * @param {GeoJSON} geojson GeoJSON Object + * @returns {GeoJSON} cloned GeoJSON Object + * @example + * var line = turf.lineString([[-74, 40], [-78, 42], [-82, 35]], {color: 'red'}); + * + * var lineCloned = turf.clone(line); + */ +function clone(geojson) { + if (!geojson) { throw new Error('geojson is required'); } + + switch (geojson.type) { + case 'Feature': + return cloneFeature(geojson); + case 'FeatureCollection': + return cloneFeatureCollection(geojson); + case 'Point': + case 'LineString': + case 'Polygon': + case 'MultiPoint': + case 'MultiLineString': + case 'MultiPolygon': + case 'GeometryCollection': + return cloneGeometry(geojson); + default: + throw new Error('unknown GeoJSON type'); + } +} + +/** + * Clone Feature + * + * @private + * @param {Feature} geojson GeoJSON Feature + * @returns {Feature} cloned Feature + */ +function cloneFeature(geojson) { + const cloned = {type: 'Feature'}; + // Preserve Foreign Members + Object.keys(geojson).forEach(function (key) { + switch (key) { + case 'type': + case 'properties': + case 'geometry': + return; + default: + cloned[key] = geojson[key]; + } + }); + // Add properties & geometry last + cloned.properties = cloneProperties(geojson.properties); + cloned.geometry = cloneGeometry(geojson.geometry); + return cloned; +} + +/** + * Clone Properties + * + * @private + * @param {Object} properties GeoJSON Properties + * @returns {Object} cloned Properties + */ +function cloneProperties(properties) { + const cloned = {}; + if (!properties) { return cloned; } + Object.keys(properties).forEach(function (key) { + const value = properties[key]; + if (typeof value === 'object') { + if (value === null) { + // handle null + cloned[key] = null; + } else if (Array.isArray(value)) { + // handle Array + cloned[key] = value.map(function (item) { + return item; + }); + } else { + // handle generic Object + cloned[key] = cloneProperties(value); + } + } else { cloned[key] = value; } + }); + return cloned; +} + +/** + * Clone Feature Collection + * + * @private + * @param {FeatureCollection} geojson GeoJSON Feature Collection + * @returns {FeatureCollection} cloned Feature Collection + */ +function cloneFeatureCollection(geojson) { + const cloned = {type: 'FeatureCollection'}; + + // Preserve Foreign Members + Object.keys(geojson).forEach(function (key) { + switch (key) { + case 'type': + case 'features': + return; + default: + cloned[key] = geojson[key]; + } + }); + // Add features + cloned.features = geojson.features.map(function (feature) { + return cloneFeature(feature); + }); + return cloned; +} + +/** + * Clone Geometry + * + * @private + * @param {Geometry} geometry GeoJSON Geometry + * @returns {Geometry} cloned Geometry + */ +function cloneGeometry(geometry) { + const geom = {type: geometry.type}; + if (geometry.bbox) { geom.bbox = geometry.bbox; } + + if (geometry.type === 'GeometryCollection') { + geom.geometries = geometry.geometries.map(function (g) { + return cloneGeometry(g); + }); + return geom; + } + geom.coordinates = deepSlice(geometry.coordinates); + return geom; +} + +/** + * Deep Slice coordinates + * + * @private + * @param {Coordinates} coords Coordinates + * @returns {Coordinates} all coordinates sliced + */ +function deepSlice(coords) { + const cloned = coords; + if (typeof cloned[0] !== 'object') { return cloned.slice(); } + return cloned.map(function (coord) { + return deepSlice(coord); + }); +} + +export default clone; diff --git a/src/clone/test.js b/src/clone/test.js new file mode 100644 index 0000000000..3421ea9ccd --- /dev/null +++ b/src/clone/test.js @@ -0,0 +1,196 @@ +const test = require('tape'); +const { + point, + lineString, + polygon, + featureCollection, + geometryCollection, + } = require('../helpers'); +const { coordEach } = require('../meta'); +const clone = require('./').default; + + +test('turf-clone', t => { + // Define Features + const pt = point([0, 20]); + const line = lineString([[10, 40], [0, 20]]); + const poly = polygon([[[10, 40], [0, 20], [20, 0], [10, 40]]]); + const fc = featureCollection([ + point([0, 20]), + lineString([[10, 40], [0, 20]]), + polygon([[[10, 40], [0, 20], [20, 0], [10, 40]]]) + ]); + const gc = geometryCollection([ + point([0, 20]).geometry, + lineString([[10, 40], [0, 20]]).geometry, + polygon([[[10, 40], [0, 20], [20, 0], [10, 40]]]).geometry + ]).geometry; + + // Clone Features + const ptCloned = clone(pt); + const lineCloned = clone(line); + const polyCloned = clone(poly, true); + const fcCloned = clone(fc); + const gcCloned = clone(gc); + + // Apply Mutation + ptCloned.geometry.coordinates.reverse(); + lineCloned.geometry.coordinates.reverse(); + polyCloned.geometry.coordinates.reverse(); + coordEach(fcCloned, coord => coord.reverse()); + coordEach(gcCloned, coord => coord.reverse()); + + // Original Geometries should not be mutated + t.deepEqual(pt.geometry.coordinates, [0, 20], 'point'); + t.deepEqual(line.geometry.coordinates, [[10, 40], [0, 20]], 'lineString'); + t.deepEqual(poly.geometry.coordinates, [[[10, 40], [0, 20], [20, 0], [10, 40]]], 'polygon'); + + // Feature Collection + t.deepEqual(fc.features[0].geometry.coordinates, [0, 20], 'fc - point'); + t.deepEqual(fc.features[1].geometry.coordinates, [[10, 40], [0, 20]], 'fc - lineString'); + t.deepEqual(fc.features[2].geometry.coordinates, [[[10, 40], [0, 20], [20, 0], [10, 40]]], 'fc - polygon'); + + // Geometry Collection + t.deepEqual(gc.geometries[0].coordinates, [0, 20], 'gc - point'); + t.deepEqual(gc.geometries[1].coordinates, [[10, 40], [0, 20]], 'gc - lineString'); + t.deepEqual(gc.geometries[2].coordinates, [[[10, 40], [0, 20], [20, 0], [10, 40]]], 'gc - polygon'); + t.end(); +}); + +test('turf-clone -- throws', t => { + t.throws(() => clone(), /geojson is required/); + t.end(); +}); + +test('turf-clone -- optional properties', t => { + const pt = point([0, 20]); + pt.properties = undefined; + pt.id = 300; + pt.bbox = [0, 20, 0, 20]; + + const ptCloned = clone(pt); + t.deepEqual(ptCloned.bbox, [0, 20, 0, 20]); + t.equal(ptCloned.id, 300); + t.end(); +}); + +test('turf-clone -- Geometry Objects', t => { + const pt = point([0, 20]).geometry; + const line = lineString([[10, 40], [0, 20]]).geometry; + const poly = polygon([[[10, 40], [0, 20], [20, 0], [10, 40]]]).geometry; + + const ptCloned = clone(pt); + const lineCloned = clone(line); + const polyCloned = clone(poly); + + ptCloned.coordinates.reverse(); + lineCloned.coordinates.reverse(); + polyCloned.coordinates.reverse(); + + t.deepEqual(pt.coordinates, [0, 20], 'geometry point'); + t.deepEqual(line.coordinates, [[10, 40], [0, 20]], 'geometry line'); + t.deepEqual(poly.coordinates, [[[10, 40], [0, 20], [20, 0], [10, 40]]], 'geometry polygon'); + t.end(); +}); + +test('turf-clone -- Preserve Foreign Members -- Feature', t => { + const properties = {foo: 'bar'}; + const bbox = [0, 20, 0, 20]; + const id = 12345; + const pt = point([0, 20], properties, {bbox, id}); + pt.custom = 'foreign members'; + + const cloned = clone(pt); + t.equal(cloned.id, id); + t.equal(cloned.custom, pt.custom); + t.deepEqual(cloned.bbox, bbox); + t.deepEqual(cloned.properties, properties); + t.end(); +}); + +test('turf-clone -- Preserve Foreign Members -- FeatureCollection', t => { + const properties = {foo: 'bar'}; + const bbox = [0, 20, 0, 20]; + const id = 12345; + const fc = featureCollection([point([0, 20])], {bbox, id}); + fc.custom = 'foreign members'; + fc.properties = properties; + + const cloned = clone(fc); + t.equal(cloned.id, id); + t.equal(cloned.custom, fc.custom); + t.deepEqual(cloned.bbox, bbox); + t.deepEqual(cloned.properties, properties); + t.end(); +}); + + +test('turf-clone -- Preserve all properties -- Feature', t => { + const id = 12345; + const bbox = [0, 20, 0, 20]; + const properties = { + foo: 'bar', + object: {property: 1}, + array: [0, 1, 2], + number: 1, + nullity: null, + boolean: true, + length: 1 + }; + const pt = point([0, 20], properties, {bbox, id}); + pt.hello = 'world'; // Foreign member + + // Clone and mutate + const cloned = clone(pt); + + // Clone properly translated all properties + t.equal(cloned.hello, 'world'); + t.equal(cloned.properties.foo, 'bar'); + t.equal(cloned.id, 12345); + t.deepEqual(cloned.bbox, [0, 20, 0, 20]); + t.equal(cloned.properties.object.property, 1); + t.deepEqual(cloned.properties.array, [0, 1, 2]); + t.equal(cloned.properties.number, 1); + t.equal(cloned.properties.nullity, null); + t.equal(cloned.properties.boolean, true); + t.equal(cloned.properties.length, 1); + + // Mutate clone properties + cloned['hello'] = 'universe'; + cloned.properties['foo'] = 'foo'; + cloned['id'] = 54321; + cloned['bbox'] = [30, 40, 30, 40]; + cloned.properties.object['property'] = 2; + cloned.properties.array[0] = 500; + cloned.properties.number = -99; + cloned.properties.boolean = false; + + // Test if original point hasn't been mutated + t.equal(pt.hello, 'world'); + t.equal(pt.properties.foo, 'bar'); + t.equal(pt.id, 12345); + t.deepEqual(pt.bbox, [0, 20, 0, 20]); + t.equal(pt.properties.object.property, 1); + t.deepEqual(pt.properties.array, [0, 1, 2]); + t.equal(pt.properties.number, 1); + t.equal(pt.properties.boolean, true); + t.end(); +}); + +test('turf-clone -- Preserve all properties -- FeatureCollection', t => { + const bbox = [0, 20, 0, 20]; + const id = 12345; + const fc = featureCollection([point([0, 20])], {bbox, id}); + fc.hello = 'world'; // Foreign member + + // Clone and mutate + const cloned = clone(fc); + cloned['hello'] = 'universe'; + cloned['id'] = 54321; + cloned['bbox'] = [30, 40, 30, 40]; + + t.equal(fc.hello, 'world'); + t.equal(fc.id, 12345); + t.deepEqual(fc.bbox, [0, 20, 0, 20]); + t.end(); +}); diff --git a/packages/turf-clusters-dbscan/bench.js b/src/clusters-dbscan/bench.js similarity index 100% rename from packages/turf-clusters-dbscan/bench.js rename to src/clusters-dbscan/bench.js diff --git a/src/clusters-dbscan/index.d.ts b/src/clusters-dbscan/index.d.ts new file mode 100644 index 0000000000..875f7cb106 --- /dev/null +++ b/src/clusters-dbscan/index.d.ts @@ -0,0 +1,27 @@ +import { Units, FeatureCollection, Point, Feature } from '../helpers'; + +export type Dbscan = 'core' | 'edge' | 'noise' +export interface DbscanProps { + dbscan?: Dbscan; + cluster?: number; + [key: string]: any; +} +export interface DbscanPoint extends Feature { + properties: DbscanProps +} +export interface DbscanPoints { + type: 'FeatureCollection' + features: DbscanPoint[]; +} + +/** + * http://turfjs.org/docs/#clustersdbscans + */ +export default function ( + points: FeatureCollection, + maxDistance: number, + options?: { + units?: Units, + minPoints?: number + } +): DbscanPoints; diff --git a/src/clusters-dbscan/index.js b/src/clusters-dbscan/index.js new file mode 100644 index 0000000000..854045e79e --- /dev/null +++ b/src/clusters-dbscan/index.js @@ -0,0 +1,79 @@ +import clone from '../clone'; +import distance from '../distance'; +import { coordAll } from '../meta'; +import { convertLength, checkIfOptionsExist } from '../helpers'; +import { collectionOf } from '../invariant'; +import DBSCAN from './lib/dbscan'; + +/** + * Takes a set of {@link Point|points} and partition them into clusters according to {@link DBSCAN's|https://en.wikipedia.org/wiki/DBSCAN} data clustering algorithm. + * + * @name clustersDbscan + * @param {FeatureCollection} points to be clustered + * @param {number} maxDistance Maximum Distance between any point of the cluster to generate the clusters (kilometers only) + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units=kilometers] in which `maxDistance` is expressed, can be degrees, radians, miles, or kilometers + * @param {number} [options.minPoints=3] Minimum number of points to generate a single cluster, + * points which do not meet this requirement will be classified as an 'edge' or 'noise'. + * @returns {FeatureCollection} Clustered Points with an additional two properties associated to each Feature: + * - {number} cluster - the associated clusterId + * - {string} dbscan - type of point it has been classified as ('core'|'edge'|'noise') + * @example + * // create random points with random z-values in their properties + * var points = turf.randomPoint(100, {bbox: [0, 30, 20, 50]}); + * var maxDistance = 100; + * var clustered = turf.clustersDbscan(points, maxDistance); + * + * //addToMap + * var addToMap = [clustered]; + */ +export function clustersDbscan(points, maxDistance, options) { + + options = checkIfOptionsExist(options); + var minPoints = options.minPoints; + var units = options.units; + + // Input validation + collectionOf(points, 'Point', 'Input must contain Points'); + if (maxDistance === null || maxDistance === undefined) throw new Error('maxDistance is required'); + if (!(Math.sign(maxDistance) > 0)) throw new Error('Invalid maxDistance'); + if (!(minPoints === undefined || minPoints === null || Math.sign(minPoints) > 0)) throw new Error('Invalid minPoints'); + + if (!options.mutate) { + // Clone points to prevent any mutations + points = clone(points, true); + } + + // Defaults + minPoints = minPoints || 3; + + // create clustered ids + var dbscan = new DBSCAN(); + var clusteredIds = dbscan.run(coordAll(points), convertLength(maxDistance, units), minPoints, distance); + + // Tag points to Clusters ID + var clusterId = -1; + clusteredIds.forEach(function (clusterIds) { + clusterId++; + // assign cluster ids to input points + clusterIds.forEach(function (idx) { + var clusterPoint = points.features[idx]; + if (!clusterPoint.properties) clusterPoint.properties = {}; + clusterPoint.properties.cluster = clusterId; + clusterPoint.properties.dbscan = 'core'; + }); + }); + + // handle noise points, if any + // edges points are tagged by DBSCAN as both 'noise' and 'cluster' as they can "reach" less than 'minPoints' number of points + dbscan.noise.forEach(function (noiseId) { + var noisePoint = points.features[noiseId]; + if (!noisePoint.properties) noisePoint.properties = {}; + if (noisePoint.properties.cluster) noisePoint.properties.dbscan = 'edge'; + else noisePoint.properties.dbscan = 'noise'; + }); + + return points; +} + +export default clustersDbscan; diff --git a/src/clusters-dbscan/lib/dbscan.js b/src/clusters-dbscan/lib/dbscan.js new file mode 100644 index 0000000000..0ebdd72eb6 --- /dev/null +++ b/src/clusters-dbscan/lib/dbscan.js @@ -0,0 +1,236 @@ +// Extracted from https://github.com/uhho/density-clustering + +/** + * DBSCAN - Density based clustering + * + * @author Lukasz Krawczyk + * @copyright MIT + */ + +/** + * DBSCAN class construcotr + * @constructor + * + * @param {Array} dataset + * @param {number} epsilon + * @param {number} minPts + * @param {function} distanceFunction + * @returns {DBSCAN} + */ +function DBSCAN(dataset, epsilon, minPts, distanceFunction) { + /** @type {Array} */ + this.dataset = []; + /** @type {number} */ + this.epsilon = 1; + /** @type {number} */ + this.minPts = 2; + /** @type {function} */ + this.distance = this._euclideanDistance; + /** @type {Array} */ + this.clusters = []; + /** @type {Array} */ + this.noise = []; + + // temporary variables used during computation + + /** @type {Array} */ + this._visited = []; + /** @type {Array} */ + this._assigned = []; + /** @type {number} */ + this._datasetLength = 0; + + this._init(dataset, epsilon, minPts, distanceFunction); +}; + +/******************************************************************************/ +// public functions + +/** + * Start clustering + * + * @param {Array} dataset + * @param {number} epsilon + * @param {number} minPts + * @param {function} distanceFunction + * @returns {undefined} + * @access public + */ +DBSCAN.prototype.run = function(dataset, epsilon, minPts, distanceFunction) { + this._init(dataset, epsilon, minPts, distanceFunction); + + for (var pointId = 0; pointId < this._datasetLength; pointId++) { + // if point is not visited, check if it forms a cluster + if (this._visited[pointId] !== 1) { + this._visited[pointId] = 1; + + // if closest neighborhood is too small to form a cluster, mark as noise + var neighbors = this._regionQuery(pointId); + + if (neighbors.length < this.minPts) { + this.noise.push(pointId); + } else { + // create new cluster and add point + var clusterId = this.clusters.length; + this.clusters.push([]); + this._addToCluster(pointId, clusterId); + + this._expandCluster(clusterId, neighbors); + } + } + } + + return this.clusters; +}; + +/******************************************************************************/ +// protected functions + +/** + * Set object properties + * + * @param {Array} dataset + * @param {number} epsilon + * @param {number} minPts + * @param {function} distance + * @returns {undefined} + * @access protected + */ +DBSCAN.prototype._init = function(dataset, epsilon, minPts, distance) { + + if (dataset) { + + if (!(dataset instanceof Array)) { + throw Error('Dataset must be of type array, ' + + typeof dataset + ' given'); + } + + this.dataset = dataset; + this.clusters = []; + this.noise = []; + + this._datasetLength = dataset.length; + this._visited = new Array(this._datasetLength); + this._assigned = new Array(this._datasetLength); + } + + if (epsilon) { + this.epsilon = epsilon; + } + + if (minPts) { + this.minPts = minPts; + } + + if (distance) { + this.distance = distance; + } +}; + +/** + * Expand cluster to closest points of given neighborhood + * + * @param {number} clusterId + * @param {Array} neighbors + * @returns {undefined} + * @access protected + */ +DBSCAN.prototype._expandCluster = function(clusterId, neighbors) { + + /** + * It's very important to calculate length of neighbors array each time, + * as the number of elements changes over time + */ + for (var i = 0; i < neighbors.length; i++) { + var pointId2 = neighbors[i]; + + if (this._visited[pointId2] !== 1) { + this._visited[pointId2] = 1; + var neighbors2 = this._regionQuery(pointId2); + + if (neighbors2.length >= this.minPts) { + neighbors = this._mergeArrays(neighbors, neighbors2); + } + } + + // add to cluster + if (this._assigned[pointId2] !== 1) { + this._addToCluster(pointId2, clusterId); + } + } +}; + +/** + * Add new point to cluster + * + * @param {number} pointId + * @param {number} clusterId + */ +DBSCAN.prototype._addToCluster = function(pointId, clusterId) { + this.clusters[clusterId].push(pointId); + this._assigned[pointId] = 1; +}; + +/** + * Find all neighbors around given point + * + * @param {number} pointId, + * @param {number} epsilon + * @returns {Array} + * @access protected + */ +DBSCAN.prototype._regionQuery = function(pointId) { + var neighbors = []; + + for (var id = 0; id < this._datasetLength; id++) { + var dist = this.distance(this.dataset[pointId], this.dataset[id]); + if (dist < this.epsilon) { + neighbors.push(id); + } + } + + return neighbors; +}; + +/******************************************************************************/ +// helpers + +/** + * @param {Array} a + * @param {Array} b + * @returns {Array} + * @access protected + */ +DBSCAN.prototype._mergeArrays = function(a, b) { + var len = b.length; + + for (var i = 0; i < len; i++) { + var P = b[i]; + if (a.indexOf(P) < 0) { + a.push(P); + } + } + + return a; +}; + +/** + * Calculate euclidean distance in multidimensional space + * + * @param {Array} p + * @param {Array} q + * @returns {number} + * @access protected + */ +DBSCAN.prototype._euclideanDistance = function(p, q) { + var sum = 0; + var i = Math.min(p.length, q.length); + + while (i--) { + sum += (p[i] - q[i]) * (p[i] - q[i]); + } + + return Math.sqrt(sum); +}; + +export default DBSCAN; \ No newline at end of file diff --git a/src/clusters-dbscan/test.js b/src/clusters-dbscan/test.js new file mode 100644 index 0000000000..c481724980 --- /dev/null +++ b/src/clusters-dbscan/test.js @@ -0,0 +1,144 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const centroid = require('../centroid').default; +const chromatism = require('chromatism'); +const concaveman = require('concaveman'); +const { point, polygon, featureCollection } = require('../helpers'); +const { clusterReduce, clusterEach } = require('../clusters'); +const { coordAll, featureEach } = require('../meta'); +const clustersDbscan = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('clusters-dbscan', t => { + fixtures.forEach(fixture => { + const name = fixture.name; + const filename = fixture.filename; + const geojson = fixture.geojson; + const properties = geojson.properties || {}; + const distance = properties.distance || 100; + const minPoints = properties.minPoints; + const units = properties.units; + + // console.log(geojson.features.length); + const clustered = clustersDbscan(geojson, distance, {units: units, minPoints: minPoints}); + const result = styleResult(clustered); + + if (process.env.REGEN) write.sync(directories.out + filename, result); + t.deepEqual(result, load.sync(directories.out + filename), name); + }); + + t.end(); +}); + +const points = featureCollection([ + point([0, 0], {foo: 'bar'}), + point([2, 4], {foo: 'bar'}), + point([3, 6], {foo: 'bar'}) +]); + +test('clusters-dbscan -- throws', t => { + const poly = polygon([[[0, 0], [10, 10], [0, 10], [0, 0]]]); + // Types being handled by Typescript + // t.throws(() => clustersDbscan(poly, 1), /points must consist of a FeatureCollection of only Points/); + // t.throws(() => clustersDbscan(points), /maxDistance is required/); + // t.throws(() => clustersDbscan(points, -4), /maxDistance is invalid/); + // t.throws(() => clustersDbscan(points, 'foo'), /maxDistance is invalid/); + // t.throws(() => clustersDbscan(points, 1, {units: 'nanometers'}), /units is invalid/); + // t.throws(() => clustersDbscan(points, 1, {units: null, minPoints: 0}), /minPoints is invalid/); + // t.throws(() => clustersDbscan(points, 1, {units: 'miles', minPoints: 'baz'}), /minPoints is invalid/); + t.end(); +}); + +test('clusters-dbscan -- prevent input mutation', t => { + clustersDbscan(points, 2, {units: 'kilometers', minPoints: 1}); + t.true(points.features[0].properties.cluster === undefined, 'cluster properties should be undefined'); + t.end(); +}); + +test('clusters-dbscan -- translate properties', t => { + t.equal(clustersDbscan(points, 2, {units: 'kilometers', minPoints: 1}).features[0].properties.foo, 'bar'); + t.end(); +}); + +// style result +function styleResult(clustered) { + const count = clusterReduce(clustered, 'cluster', i => i + 1, 0); + const colours = chromatism.adjacent(360 / count, count, '#0000FF').hex; + const features = []; + + // Add all clusterd points + featureEach(clustered, function (pt) { + const dbscan = pt.properties.dbscan; + const clusterId = pt.properties.cluster; + + switch (dbscan) { + case 'core': + case 'edge': { + const coreColor = colours[clusterId]; + const edgeColor = chromatism.brightness(-20, colours[clusterId]).hex; + pt.properties['marker-color'] = (dbscan === 'core') ? coreColor : edgeColor; + pt.properties['marker-size'] = 'small'; + break; + } + case 'noise': { + pt.properties['marker-color'] = '#AEAEAE'; + pt.properties['marker-symbol'] = 'circle-stroked'; + pt.properties['marker-size'] = 'medium'; + break; + } + } + features.push(pt); + }); + + // Iterate over each Cluster + clusterEach(clustered, 'cluster', (cluster, clusterValue, clusterId) => { + const color = chromatism.brightness(-25, colours[clusterId]).hex; + + // Add Centroid + features.push(centroid(cluster, {properties: { + 'marker-color': colours[clusterId], + 'marker-symbol': 'star-stroked', + 'marker-size': 'large' + }})); + + // Add concave polygon + features.push(polygon([concaveman(coordAll(cluster))], { + fill: color, + stroke: color, + 'fill-opacity': 0.3 + })); + }); + return featureCollection(features); +} + +test('clusters-dbscan -- allow input mutation', t => { + const oldPoints = featureCollection([ + point([0, 0], {foo: 'bar'}), + point([2, 4], {foo: 'bar'}), + point([3, 6], {foo: 'bar'}) + ]); + // No mutation + const newPoints = clustersDbscan(points, 2, {minPoints: 1}); + t.equal(newPoints.features[1].properties.cluster, 1, 'cluster is 1') + t.equal(oldPoints.features[1].properties.cluster, undefined, 'cluster is undefined') + + // Allow mutation + clustersDbscan(oldPoints, 2, {minPoints: 1, mutate: true}); + t.equal(oldPoints.features[1].properties.cluster, 1, 'cluster is 1') + t.end() +}) \ No newline at end of file diff --git a/packages/turf-clusters-dbscan/test/in/fiji.geojson b/src/clusters-dbscan/test/in/fiji.geojson similarity index 100% rename from packages/turf-clusters-dbscan/test/in/fiji.geojson rename to src/clusters-dbscan/test/in/fiji.geojson diff --git a/packages/turf-clusters-dbscan/test/in/many-points.geojson b/src/clusters-dbscan/test/in/many-points.geojson similarity index 100% rename from packages/turf-clusters-dbscan/test/in/many-points.geojson rename to src/clusters-dbscan/test/in/many-points.geojson diff --git a/packages/turf-clusters-dbscan/test/in/noise.geojson b/src/clusters-dbscan/test/in/noise.geojson similarity index 100% rename from packages/turf-clusters-dbscan/test/in/noise.geojson rename to src/clusters-dbscan/test/in/noise.geojson diff --git a/packages/turf-clusters-dbscan/test/in/points-with-properties.geojson b/src/clusters-dbscan/test/in/points-with-properties.geojson similarity index 100% rename from packages/turf-clusters-dbscan/test/in/points-with-properties.geojson rename to src/clusters-dbscan/test/in/points-with-properties.geojson diff --git a/packages/turf-clusters-dbscan/test/in/points1.geojson b/src/clusters-dbscan/test/in/points1.geojson similarity index 100% rename from packages/turf-clusters-dbscan/test/in/points1.geojson rename to src/clusters-dbscan/test/in/points1.geojson diff --git a/packages/turf-clusters-dbscan/test/in/points2.geojson b/src/clusters-dbscan/test/in/points2.geojson similarity index 100% rename from packages/turf-clusters-dbscan/test/in/points2.geojson rename to src/clusters-dbscan/test/in/points2.geojson diff --git a/packages/turf-clusters-dbscan/test/out/fiji.geojson b/src/clusters-dbscan/test/out/fiji.geojson similarity index 100% rename from packages/turf-clusters-dbscan/test/out/fiji.geojson rename to src/clusters-dbscan/test/out/fiji.geojson diff --git a/packages/turf-clusters-dbscan/test/out/many-points.geojson b/src/clusters-dbscan/test/out/many-points.geojson similarity index 100% rename from packages/turf-clusters-dbscan/test/out/many-points.geojson rename to src/clusters-dbscan/test/out/many-points.geojson diff --git a/packages/turf-clusters-dbscan/test/out/noise.geojson b/src/clusters-dbscan/test/out/noise.geojson similarity index 100% rename from packages/turf-clusters-dbscan/test/out/noise.geojson rename to src/clusters-dbscan/test/out/noise.geojson diff --git a/packages/turf-clusters-dbscan/test/out/points-with-properties.geojson b/src/clusters-dbscan/test/out/points-with-properties.geojson similarity index 100% rename from packages/turf-clusters-dbscan/test/out/points-with-properties.geojson rename to src/clusters-dbscan/test/out/points-with-properties.geojson diff --git a/packages/turf-clusters-dbscan/test/out/points1.geojson b/src/clusters-dbscan/test/out/points1.geojson similarity index 100% rename from packages/turf-clusters-dbscan/test/out/points1.geojson rename to src/clusters-dbscan/test/out/points1.geojson diff --git a/packages/turf-clusters-dbscan/test/out/points2.geojson b/src/clusters-dbscan/test/out/points2.geojson similarity index 100% rename from packages/turf-clusters-dbscan/test/out/points2.geojson rename to src/clusters-dbscan/test/out/points2.geojson diff --git a/packages/turf-clusters-kmeans/bench.js b/src/clusters-kmeans/bench.js similarity index 100% rename from packages/turf-clusters-kmeans/bench.js rename to src/clusters-kmeans/bench.js diff --git a/src/clusters-kmeans/index.d.ts b/src/clusters-kmeans/index.d.ts new file mode 100644 index 0000000000..8b4ffd999b --- /dev/null +++ b/src/clusters-kmeans/index.d.ts @@ -0,0 +1,25 @@ +import { Point, Feature, FeatureCollection } from '../helpers'; + +export interface KmeansProps { + cluster?: number; + centroid?: [number, number]; + [key: string]: any; +} +export interface KmeansPoint extends Feature { + properties: KmeansProps +} +export interface KmeansPoints { + type: 'FeatureCollection' + features: KmeansPoint[]; +} + +/** + * http://turfjs.org/docs/#clusterskmeans + */ +export default function ( + points: FeatureCollection, + options?: { + numberOfClusters?: number, + mutate?: boolean + } +): KmeansPoints; \ No newline at end of file diff --git a/src/clusters-kmeans/index.js b/src/clusters-kmeans/index.js new file mode 100644 index 0000000000..b87f7078b5 --- /dev/null +++ b/src/clusters-kmeans/index.js @@ -0,0 +1,73 @@ +import clone from '../clone'; +import { collectionOf } from '../invariant'; +import { coordAll, featureEach } from '../meta'; +import skmeans from 'skmeans'; + +/** + * Takes a set of {@link Point|points} and partition them into clusters using the k-mean . + * It uses the [k-means algorithm](https://en.wikipedia.org/wiki/K-means_clustering) + * + * @name clustersKmeans + * @param {FeatureCollection} points to be clustered + * @param {Object} [options={}] Optional parameters + * @param {number} [options.numberOfClusters=Math.sqrt(numberOfPoints/2)] numberOfClusters that will be generated + * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) + * @returns {FeatureCollection} Clustered Points with an additional two properties associated to each Feature: + * - {number} cluster - the associated clusterId + * - {[number, number]} centroid - Centroid of the cluster [Longitude, Latitude] + * @example + * // create random points with random z-values in their properties + * var points = turf.randomPoint(100, {bbox: [0, 30, 20, 50]}); + * var options = {numberOfClusters: 7}; + * var clustered = turf.clustersKmeans(points, options); + * + * //addToMap + * var addToMap = [clustered]; + */ +function clustersKmeans(points, options) { + // Optional parameters + options = options || {}; + if (typeof options !== 'object') throw new Error('options is invalid'); + var numberOfClusters = options.numberOfClusters; + var mutate = options.mutate; + + // Input validation + collectionOf(points, 'Point', 'Input must contain Points'); + + // Default Params + var count = points.features.length; + numberOfClusters = numberOfClusters || Math.round(Math.sqrt(count / 2)); + + // numberOfClusters can't be greater than the number of points + // fallbacks to count + if (numberOfClusters > count) numberOfClusters = count; + + // Clone points to prevent any mutations (enabled by default) + if (mutate === false || mutate === undefined) points = clone(points, true); + + // collect points coordinates + var data = coordAll(points); + + // create seed to avoid skmeans to drift + var initialCentroids = data.slice(0, numberOfClusters); + + // create skmeans clusters + var skmeansResult = skmeans(data, numberOfClusters, initialCentroids); + + // store centroids {clusterId: [number, number]} + var centroids = {}; + skmeansResult.centroids.forEach(function (coord, idx) { + centroids[idx] = coord; + }); + + // add associated cluster number + featureEach(points, function (point, index) { + var clusterId = skmeansResult.idxs[index]; + point.properties.cluster = clusterId; + point.properties.centroid = centroids[clusterId]; + }); + + return points; +} + +export default clustersKmeans; \ No newline at end of file diff --git a/src/clusters-kmeans/test.js b/src/clusters-kmeans/test.js new file mode 100644 index 0000000000..8413756316 --- /dev/null +++ b/src/clusters-kmeans/test.js @@ -0,0 +1,113 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const centroid = require('../centroid').default; +const chromatism = require('chromatism'); +const concaveman = require('concaveman'); +const { point, polygon, featureCollection } = require('../helpers'); +const { clusterReduce, clusterEach } = require('../clusters'); +const { coordAll, featureEach } = require('../meta'); +const clustersKmeans = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('clusters-kmeans', t => { + fixtures.forEach(fixture => { + const name = fixture.name; + const geojson = fixture.geojson; + const numberOfClusters = (geojson.properties || {}).numberOfClusters; + + const clustered = clustersKmeans(geojson, {numberOfClusters: numberOfClusters}); + const result = styleResult(clustered); + + if (process.env.REGEN) write.sync(directories.out + name + '.geojson', result); + t.deepEqual(result, load.sync(directories.out + name + '.geojson'), name); + }); + + t.end(); +}); + +const points = featureCollection([ + point([0, 0], {foo: 'bar'}), + point([2, 4], {foo: 'bar'}), + point([3, 6], {foo: 'bar'}) +]); + +test('clusters-kmeans -- throws', t => { + const poly = polygon([[[0, 0], [10, 10], [0, 10], [0, 0]]]); + + // Types handled by Typescript + // t.throws(() => clustersKmeans(poly, {numberOfClusters: 1}), /Input must contain Points/); + // t.throws(() => clustersKmeans(points, 5), /numberOfClusters can't be greater than the number of points/); + t.end(); +}); + +test('clusters-kmeans -- translate properties', t => { + t.equal(clustersKmeans(points, {numberOfClusters: 2}).features[0].properties.foo, 'bar'); + t.end(); +}); + +// style result +function styleResult(clustered) { + const count = clusterReduce(clustered, 'cluster', i => i + 1, 0); + const colours = chromatism.adjacent(360 / count, count, '#0000FF').hex; + const features = []; + + // Add all Point + featureEach(clustered, function (pt) { + const clusterId = pt.properties.cluster; + pt.properties['marker-color'] = colours[clusterId]; + pt.properties['marker-size'] = 'small'; + features.push(pt); + }); + + // Iterate over each Cluster + clusterEach(clustered, 'cluster', (cluster, clusterValue, clusterId) => { + const color = chromatism.brightness(-25, colours[clusterId]).hex; + + // Add Centroid + features.push(centroid(cluster, {properties: { + 'marker-color': color, + 'marker-symbol': 'star-stroked', + 'marker-size': 'large' + }})); + + // Add concave polygon + features.push(polygon([concaveman(coordAll(cluster))], { + fill: color, + stroke: color, + 'fill-opacity': 0.3 + })); + }); + return featureCollection(features); +} + +test('clusters-kmeans -- allow input mutation', t => { + const oldPoints = featureCollection([ + point([0, 0], {foo: 'bar'}), + point([2, 4], {foo: 'bar'}), + point([3, 6], {foo: 'bar'}) + ]); + // No mutation + const newPoints = clustersKmeans(points, {numberOfClusters: 3}); + t.equal(newPoints.features[1].properties.cluster, 1, 'cluster is 1'); + t.equal(oldPoints.features[1].properties.cluster, undefined, 'cluster is undefined'); + + // Allow mutation + clustersKmeans(oldPoints, {numberOfClusters: 2, mutate: true}); + t.equal(oldPoints.features[1].properties.cluster, 1, 'cluster is 1'); + t.end() +}) \ No newline at end of file diff --git a/packages/turf-clusters-kmeans/test/in/fiji.geojson b/src/clusters-kmeans/test/in/fiji.geojson similarity index 100% rename from packages/turf-clusters-kmeans/test/in/fiji.geojson rename to src/clusters-kmeans/test/in/fiji.geojson diff --git a/packages/turf-clusters-kmeans/test/in/many-points.geojson b/src/clusters-kmeans/test/in/many-points.geojson similarity index 100% rename from packages/turf-clusters-kmeans/test/in/many-points.geojson rename to src/clusters-kmeans/test/in/many-points.geojson diff --git a/packages/turf-clusters-kmeans/test/in/points-with-properties.geojson b/src/clusters-kmeans/test/in/points-with-properties.geojson similarity index 100% rename from packages/turf-clusters-kmeans/test/in/points-with-properties.geojson rename to src/clusters-kmeans/test/in/points-with-properties.geojson diff --git a/packages/turf-clusters-kmeans/test/in/points1.geojson b/src/clusters-kmeans/test/in/points1.geojson similarity index 100% rename from packages/turf-clusters-kmeans/test/in/points1.geojson rename to src/clusters-kmeans/test/in/points1.geojson diff --git a/packages/turf-clusters-kmeans/test/in/points2.geojson b/src/clusters-kmeans/test/in/points2.geojson similarity index 100% rename from packages/turf-clusters-kmeans/test/in/points2.geojson rename to src/clusters-kmeans/test/in/points2.geojson diff --git a/packages/turf-clusters-kmeans/test/out/fiji.geojson b/src/clusters-kmeans/test/out/fiji.geojson similarity index 100% rename from packages/turf-clusters-kmeans/test/out/fiji.geojson rename to src/clusters-kmeans/test/out/fiji.geojson diff --git a/packages/turf-clusters-kmeans/test/out/many-points.geojson b/src/clusters-kmeans/test/out/many-points.geojson similarity index 100% rename from packages/turf-clusters-kmeans/test/out/many-points.geojson rename to src/clusters-kmeans/test/out/many-points.geojson diff --git a/packages/turf-clusters-kmeans/test/out/points-with-properties.geojson b/src/clusters-kmeans/test/out/points-with-properties.geojson similarity index 100% rename from packages/turf-clusters-kmeans/test/out/points-with-properties.geojson rename to src/clusters-kmeans/test/out/points-with-properties.geojson diff --git a/packages/turf-clusters-kmeans/test/out/points1.geojson b/src/clusters-kmeans/test/out/points1.geojson similarity index 100% rename from packages/turf-clusters-kmeans/test/out/points1.geojson rename to src/clusters-kmeans/test/out/points1.geojson diff --git a/packages/turf-clusters-kmeans/test/out/points2.geojson b/src/clusters-kmeans/test/out/points2.geojson similarity index 100% rename from packages/turf-clusters-kmeans/test/out/points2.geojson rename to src/clusters-kmeans/test/out/points2.geojson diff --git a/packages/turf-clusters/bench.js b/src/clusters/bench.js similarity index 100% rename from packages/turf-clusters/bench.js rename to src/clusters/bench.js diff --git a/src/clusters/index.d.ts b/src/clusters/index.d.ts new file mode 100644 index 0000000000..bb19b275c2 --- /dev/null +++ b/src/clusters/index.d.ts @@ -0,0 +1,27 @@ +import { FeatureCollection, GeometryObject, Feature } from '../helpers' +/** + * http://turfjs.org/docs/#getcluster + */ +export function getCluster( + geojson: FeatureCollection, + filter: any +): FeatureCollection; + +/** + * http://turfjs.org/docs/#clustereach + */ +export function clusterEach( + geojson: FeatureCollection, + property: number | string, + callback: (cluster?: FeatureCollection, clusterValue?: any, currentIndex?: number) => void +): void; + +/** + * http://turfjs.org/docs/#clusterreduce + */ +export function clusterReduce( + geojson: FeatureCollection, + property: number | string, + callback: (previousValue?: any, cluster?: FeatureCollection, clusterValue?: any, currentIndex?: number) => void, + initialValue?: any +): void; \ No newline at end of file diff --git a/src/clusters/index.js b/src/clusters/index.js new file mode 100644 index 0000000000..b33558f6bb --- /dev/null +++ b/src/clusters/index.js @@ -0,0 +1,289 @@ +import { featureEach } from '../meta'; +import { featureCollection } from '../helpers'; + +/** + * Get Cluster + * + * @name getCluster + * @param {FeatureCollection} geojson GeoJSON Features + * @param {*} filter Filter used on GeoJSON properties to get Cluster + * @returns {FeatureCollection} Single Cluster filtered by GeoJSON Properties + * @example + * var geojson = turf.featureCollection([ + * turf.point([0, 0], {'marker-symbol': 'circle'}), + * turf.point([2, 4], {'marker-symbol': 'star'}), + * turf.point([3, 6], {'marker-symbol': 'star'}), + * turf.point([5, 1], {'marker-symbol': 'square'}), + * turf.point([4, 2], {'marker-symbol': 'circle'}) + * ]); + * + * // Create a cluster using K-Means (adds `cluster` to GeoJSON properties) + * var clustered = turf.clustersKmeans(geojson); + * + * // Retrieve first cluster (0) + * var cluster = turf.getCluster(clustered, {cluster: 0}); + * //= cluster + * + * // Retrieve cluster based on custom properties + * turf.getCluster(clustered, {'marker-symbol': 'circle'}).length; + * //= 2 + * turf.getCluster(clustered, {'marker-symbol': 'square'}).length; + * //= 1 + */ +export function getCluster(geojson, filter) { + // Validation + if (!geojson) throw new Error('geojson is required'); + if (geojson.type !== 'FeatureCollection') throw new Error('geojson must be a FeatureCollection'); + if (filter === undefined || filter === null) throw new Error('filter is required'); + + // Filter Features + var features = []; + featureEach(geojson, function (feature) { + if (applyFilter(feature.properties, filter)) features.push(feature); + }); + return featureCollection(features); +} + +/** + * Callback for clusterEach + * + * @callback clusterEachCallback + * @param {FeatureCollection} [cluster] The current cluster being processed. + * @param {*} [clusterValue] Value used to create cluster being processed. + * @param {number} [currentIndex] The index of the current element being processed in the array.Starts at index 0 + * @returns {void} + */ + +/** + * clusterEach + * + * @name clusterEach + * @param {FeatureCollection} geojson GeoJSON Features + * @param {string|number} property GeoJSON property key/value used to create clusters + * @param {Function} callback a method that takes (cluster, clusterValue, currentIndex) + * @returns {void} + * @example + * var geojson = turf.featureCollection([ + * turf.point([0, 0]), + * turf.point([2, 4]), + * turf.point([3, 6]), + * turf.point([5, 1]), + * turf.point([4, 2]) + * ]); + * + * // Create a cluster using K-Means (adds `cluster` to GeoJSON properties) + * var clustered = turf.clustersKmeans(geojson); + * + * // Iterate over each cluster + * turf.clusterEach(clustered, 'cluster', function (cluster, clusterValue, currentIndex) { + * //= cluster + * //= clusterValue + * //= currentIndex + * }) + * + * // Calculate the total number of clusters + * var total = 0 + * turf.clusterEach(clustered, 'cluster', function () { + * total++; + * }); + * + * // Create an Array of all the values retrieved from the 'cluster' property + * var values = [] + * turf.clusterEach(clustered, 'cluster', function (cluster, clusterValue) { + * values.push(clusterValue); + * }); + */ +export function clusterEach(geojson, property, callback) { + // Validation + if (!geojson) throw new Error('geojson is required'); + if (geojson.type !== 'FeatureCollection') throw new Error('geojson must be a FeatureCollection'); + if (property === undefined || property === null) throw new Error('property is required'); + + // Create clusters based on property values + var bins = createBins(geojson, property); + var values = Object.keys(bins); + for (var index = 0; index < values.length; index++) { + var value = values[index]; + var bin = bins[value]; + var features = []; + for (var i = 0; i < bin.length; i++) { + features.push(geojson.features[bin[i]]); + } + callback(featureCollection(features), value, index); + } +} + +/** + * Callback for clusterReduce + * + * The first time the callback function is called, the values provided as arguments depend + * on whether the reduce method has an initialValue argument. + * + * If an initialValue is provided to the reduce method: + * - The previousValue argument is initialValue. + * - The currentValue argument is the value of the first element present in the array. + * + * If an initialValue is not provided: + * - The previousValue argument is the value of the first element present in the array. + * - The currentValue argument is the value of the second element present in the array. + * + * @callback clusterReduceCallback + * @param {*} [previousValue] The accumulated value previously returned in the last invocation + * of the callback, or initialValue, if supplied. + * @param {FeatureCollection} [cluster] The current cluster being processed. + * @param {*} [clusterValue] Value used to create cluster being processed. + * @param {number} [currentIndex] The index of the current element being processed in the + * array. Starts at index 0, if an initialValue is provided, and at index 1 otherwise. + */ + +/** + * Reduce clusters in GeoJSON Features, similar to Array.reduce() + * + * @name clusterReduce + * @param {FeatureCollection} geojson GeoJSON Features + * @param {string|number} property GeoJSON property key/value used to create clusters + * @param {Function} callback a method that takes (previousValue, cluster, clusterValue, currentIndex) + * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. + * @returns {*} The value that results from the reduction. + * @example + * var geojson = turf.featureCollection([ + * turf.point([0, 0]), + * turf.point([2, 4]), + * turf.point([3, 6]), + * turf.point([5, 1]), + * turf.point([4, 2]) + * ]); + * + * // Create a cluster using K-Means (adds `cluster` to GeoJSON properties) + * var clustered = turf.clustersKmeans(geojson); + * + * // Iterate over each cluster and perform a calculation + * var initialValue = 0 + * turf.clusterReduce(clustered, 'cluster', function (previousValue, cluster, clusterValue, currentIndex) { + * //=previousValue + * //=cluster + * //=clusterValue + * //=currentIndex + * return previousValue++; + * }, initialValue); + * + * // Calculate the total number of clusters + * var total = turf.clusterReduce(clustered, 'cluster', function (previousValue) { + * return previousValue++; + * }, 0); + * + * // Create an Array of all the values retrieved from the 'cluster' property + * var values = turf.clusterReduce(clustered, 'cluster', function (previousValue, cluster, clusterValue) { + * return previousValue.concat(clusterValue); + * }, []); + */ +export function clusterReduce(geojson, property, callback, initialValue) { + var previousValue = initialValue; + clusterEach(geojson, property, function (cluster, clusterValue, currentIndex) { + if (currentIndex === 0 && initialValue === undefined) previousValue = cluster; + else previousValue = callback(previousValue, cluster, clusterValue, currentIndex); + }); + return previousValue; +} + +/** + * Create Bins + * + * @private + * @param {FeatureCollection} geojson GeoJSON Features + * @param {string|number} property Property values are used to create bins + * @returns {Object} bins with Feature IDs + * @example + * var geojson = turf.featureCollection([ + * turf.point([0, 0], {cluster: 0, foo: 'null'}), + * turf.point([2, 4], {cluster: 1, foo: 'bar'}), + * turf.point([5, 1], {0: 'foo'}), + * turf.point([3, 6], {cluster: 1}), + * ]); + * createBins(geojson, 'cluster'); + * //= { '0': [ 0 ], '1': [ 1, 3 ] } + */ +export function createBins(geojson, property) { + var bins = {}; + + featureEach(geojson, function (feature, i) { + var properties = feature.properties || {}; + if (properties.hasOwnProperty(property)) { + var value = properties[property]; + if (bins.hasOwnProperty(value)) bins[value].push(i); + else bins[value] = [i]; + } + }); + return bins; +} + +/** + * Apply Filter + * + * @private + * @param {*} properties Properties + * @param {*} filter Filter + * @returns {boolean} applied Filter to properties + */ +export function applyFilter(properties, filter) { + if (properties === undefined) return false; + var filterType = typeof filter; + + // String & Number + if (filterType === 'number' || filterType === 'string') return properties.hasOwnProperty(filter); + // Array + else if (Array.isArray(filter)) { + for (var i = 0; i < filter.length; i++) { + if (!applyFilter(properties, filter[i])) return false; + } + return true; + // Object + } else { + return propertiesContainsFilter(properties, filter); + } +} + +/** + * Properties contains filter (does not apply deepEqual operations) + * + * @private + * @param {*} properties Properties + * @param {Object} filter Filter + * @returns {boolean} does filter equal Properties + * @example + * propertiesContainsFilter({foo: 'bar', cluster: 0}, {cluster: 0}) + * //= true + * propertiesContainsFilter({foo: 'bar', cluster: 0}, {cluster: 1}) + * //= false + */ +export function propertiesContainsFilter(properties, filter) { + var keys = Object.keys(filter); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (properties[key] !== filter[key]) return false; + } + return true; +} + +/** + * Filter Properties + * + * @private + * @param {*} properties Properties + * @param {Array} keys Used to filter Properties + * @returns {*} filtered Properties + * @example + * filterProperties({foo: 'bar', cluster: 0}, ['cluster']) + * //= {cluster: 0} + */ +export function filterProperties(properties, keys) { + if (!keys) return {}; + if (!keys.length) return {}; + + var newProperties = {}; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (properties.hasOwnProperty(key)) newProperties[key] = properties[key]; + } + return newProperties; +} \ No newline at end of file diff --git a/src/clusters/test.js b/src/clusters/test.js new file mode 100644 index 0000000000..b29f248b2f --- /dev/null +++ b/src/clusters/test.js @@ -0,0 +1,88 @@ +const test = require('tape'); +const { point, featureCollection } = require('../helpers'); +const { + getCluster, + clusterEach, + clusterReduce, + // Below methods are not exposed in @turf/turf + createBins, + applyFilter, + filterProperties, + propertiesContainsFilter +} = require('./'); + +const properties = {foo: 'bar', cluster: 0}; +const geojson = featureCollection([ + point([0, 0], {cluster: 0, foo: 'null'}), + point([2, 4], {cluster: 1, foo: 'bar'}), + point([3, 6], {cluster: 1}), + point([5, 1], {0: 'foo'}), + point([4, 2], {'bar': 'foo'}), + point([2, 4], {}), + point([4, 3], undefined) +]); + +test('clusters -- getCluster', t => { + t.equal(getCluster(geojson, 0).features.length, 1, 'number1'); + t.equal(getCluster(geojson, 1).features.length, 0, 'number2'); + t.equal(getCluster(geojson, 'bar').features.length, 1, 'string1'); + t.equal(getCluster(geojson, 'cluster').features.length, 3, 'string2'); + t.equal(getCluster(geojson, {cluster: 1}).features.length, 2, 'object1'); + t.equal(getCluster(geojson, {cluster: 0}).features.length, 1, 'object2'); + t.equal(getCluster(geojson, ['cluster', {foo: 'bar'}]).features.length, 1); + t.equal(getCluster(geojson, ['cluster', 'foo']).features.length, 2); + t.equal(getCluster(geojson, ['cluster']).features.length, 3); + t.end(); +}); + +test('clusters -- clusterEach', t => { + const clusters = []; + let total = 0; + clusterEach(geojson, 'cluster', (cluster) => { + total += cluster.features.length; + clusters.push(cluster); + if (!cluster.features[0]) t.fail('if feature is undefined'); + }); + t.equal(total, 3); + t.equal(clusters.length, 2); + t.end(); +}); + +test('clusters -- clusterReduce', t => { + const clusters = []; + const total = clusterReduce(geojson, 'cluster', (previousValue, cluster) => { + clusters.push(cluster); + return previousValue + cluster.features.length; + }, 0); + t.equal(total, 3); + t.equal(clusters.length, 2); + t.end(); +}); + +test('clusters.utils -- applyFilter', t => { + t.true(applyFilter(properties, 'cluster')); + t.true(applyFilter(properties, ['cluster'])); + t.false(applyFilter(properties, {cluster: 1})); + t.true(applyFilter(properties, {cluster: 0})); + t.false(applyFilter(undefined, {cluster: 0})); + t.end(); +}); + +test('clusters.utils -- filterProperties', t => { + t.deepEqual(filterProperties(properties, ['cluster']), {cluster: 0}); + t.deepEqual(filterProperties(properties, []), {}); + t.deepEqual(filterProperties(properties, undefined), {}); + t.end(); +}); + +test('clusters.utils -- propertiesContainsFilter', t => { + t.deepEqual(propertiesContainsFilter(properties, {cluster: 0}), true); + t.deepEqual(propertiesContainsFilter(properties, {cluster: 1}), false); + t.deepEqual(propertiesContainsFilter(properties, {bar: 'foo'}), false); + t.end(); +}); + +test('clusters.utils -- propertiesContainsFilter', t => { + t.deepEqual(createBins(geojson, 'cluster'), {'0': [0], '1': [1, 2]}); + t.end(); +}); diff --git a/packages/turf-collect/bench.js b/src/collect/bench.js similarity index 100% rename from packages/turf-collect/bench.js rename to src/collect/bench.js diff --git a/src/collect/index.js b/src/collect/index.js new file mode 100644 index 0000000000..4ee8565c61 --- /dev/null +++ b/src/collect/index.js @@ -0,0 +1,60 @@ +import bboxPolygon from '../bbox-polygon'; +import bbox from '../bbox'; +import booleanPointInPolygon from '../boolean-point-in-polygon'; +import spatialIndex from '../spatial-index'; + +/** + * Merges a specified property from a FeatureCollection of points into a + * FeatureCollection of polygons. Given an `inProperty` on points and an `outProperty` + * for polygons, this finds every point that lies within each polygon, collects the + * `inProperty` values from those points, and adds them as an array to `outProperty` + * on the polygon. + * + * @name collect + * @param {FeatureCollection} polygons polygons with values on which to aggregate + * @param {FeatureCollection} points points to be aggregated + * @param {string} inProperty property to be nested from + * @param {string} outProperty property to be nested into + * @returns {FeatureCollection} polygons with properties listed based on `outField` + * @example + * var poly1 = turf.polygon([[[0,0],[10,0],[10,10],[0,10],[0,0]]]); + * var poly2 = turf.polygon([[[10,0],[20,10],[20,20],[20,0],[10,0]]]); + * var polyFC = turf.featureCollection([poly1, poly2]); + * var pt1 = turf.point([5,5], {population: 200}); + * var pt2 = turf.point([1,3], {population: 600}); + * var pt3 = turf.point([14,2], {population: 100}); + * var pt4 = turf.point([13,1], {population: 200}); + * var pt5 = turf.point([19,7], {population: 300}); + * var pointFC = turf.featureCollection([pt1, pt2, pt3, pt4, pt5]); + * var collected = turf.collect(polyFC, pointFC, 'population', 'values'); + * var values = collected.features[0].properties.values + * //=values => [200, 600] + * + * //addToMap + * var addToMap = [pointFC, collected] + */ +function collect(polygons, points, inProperty, outProperty) { + const rtree = spatialIndex(6); + + rtree.load(points.features); + polygons.features.forEach(function (poly) { + + if (!poly.properties) { + poly.properties = {}; + } + const searchBbox = bboxPolygon(bbox(poly)); + const potentialPoints = rtree.search(searchBbox); + const values = []; + potentialPoints.features.forEach(function (pt) { + if (booleanPointInPolygon(pt.geometry.coordinates, poly)) { + values.push(pt.properties[inProperty]); + } + }); + + poly.properties[outProperty] = values; + }); + + return polygons; +} + +export default collect; diff --git a/src/collect/test.js b/src/collect/test.js new file mode 100644 index 0000000000..91ee658c73 --- /dev/null +++ b/src/collect/test.js @@ -0,0 +1,26 @@ +const test = require('tape'); +const { featureCollection, point, polygon } = require('../helpers'); +const collect = require('./').default; + +test('turf collect module', t => { + const poly1 = polygon([[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]); + const poly2 = polygon([[[10, 0], [20, 10], [20, 20], [20, 0], [10, 0]]]); + const poly3 = polygon([[[100, 0], [110, -10], [110, -20], [100, 0]]]); + const polyFC = featureCollection([poly1, poly2, poly3]); + const pt1 = point([5, 5], {population: 200}); + const pt2 = point([1, 3], {population: 600}); + const pt3 = point([14, 2], {population: 100}); + const pt4 = point([13, 1], {population: 200}); + const pt5 = point([19, 7], {population: 300}); + const ptFC = featureCollection([pt1, pt2, pt3, pt4, pt5]); + const aggregated = collect(polyFC, ptFC, 'population', 'values'); + // Check the same number of input and output polys are the same + t.equal(polyFC.features.length, aggregated.features.length); + // Check the right values have been assigned + t.deepEqual(aggregated.features[0].properties.values, [200, 600]); + t.deepEqual(aggregated.features[1].properties.values, [100, 200, 300]); + + // Check the property has been created even if no values have been assigned + t.deepEqual(aggregated.features[2].properties.values, []); + t.end(); +}); diff --git a/packages/turf-combine/bench.js b/src/combine/bench.js similarity index 100% rename from packages/turf-combine/bench.js rename to src/combine/bench.js diff --git a/src/combine/index.js b/src/combine/index.js new file mode 100644 index 0000000000..792e2074bf --- /dev/null +++ b/src/combine/index.js @@ -0,0 +1,64 @@ +import { feature, featureCollection } from '../helpers'; +import { featureEach } from '../meta'; + +/** + * Combines a {@link FeatureCollection} of {@link Point}, {@link LineString}, or {@link Polygon} features + * into {@link MultiPoint}, {@link MultiLineString}, or {@link MultiPolygon} features. + * + * @name combine + * @param {FeatureCollection} fc a FeatureCollection of any type + * @returns {FeatureCollection} a FeatureCollection of corresponding type to input + * @example + * var fc = turf.featureCollection([ + * turf.point([19.026432, 47.49134]), + * turf.point([19.074497, 47.509548]) + * ]); + * + * var combined = turf.combine(fc); + * + * //addToMap + * var addToMap = [combined] + */ +function combine(fc) { + var groups = { + MultiPoint: {coordinates: [], properties: []}, + MultiLineString: {coordinates: [], properties: []}, + MultiPolygon: {coordinates: [], properties: []} + }; + + var multiMapping = Object.keys(groups).reduce(function (memo, item) { + memo[item.replace('Multi', '')] = item; + return memo; + }, {}); + + function addToGroup(feature, key, multi) { + if (!multi) { + groups[key].coordinates.push(feature.geometry.coordinates); + } else { + groups[key].coordinates = groups[key].coordinates.concat(feature.geometry.coordinates); + } + groups[key].properties.push(feature.properties); + } + + featureEach(fc, function (feature) { + if (!feature.geometry) return; + if (groups[feature.geometry.type]) { + addToGroup(feature, feature.geometry.type, true); + } else if (multiMapping[feature.geometry.type]) { + addToGroup(feature, multiMapping[feature.geometry.type], false); + } + }); + + return featureCollection(Object.keys(groups) + .filter(function (key) { + return groups[key].coordinates.length; + }) + .sort() + .map(function (key) { + var geometry = { type: key, coordinates: groups[key].coordinates }; + var properties = { collectedProperties: groups[key].properties }; + return feature(geometry, properties); + })); +} + +export default combine; diff --git a/src/combine/test.js b/src/combine/test.js new file mode 100644 index 0000000000..91f8748f90 --- /dev/null +++ b/src/combine/test.js @@ -0,0 +1,203 @@ +const test = require('tape'); +const { point, multiPoint, polygon, multiPolygon, lineString, multiLineString, featureCollection, feature } = require('../helpers'); +const combine = require('./').default; + +test('combine -- points', t => { + // MultiPoint + const pt1 = point([50, 51]); + const pt2 = point([100, 101]); + + const multiPt = combine(featureCollection([pt1, pt2])); + + t.ok(multiPt, 'should combine two Points into a MultiPoint'); + t.deepEqual(multiPt.features[0].geometry.coordinates, [[50, 51], [100, 101]]); + t.end(); +}); + +test('combine -- mixed multiPoint & point', function (t) { + // MultiPoint + const pt1 = point([50, 51]); + const pt2 = multiPoint([[100, 101], [101, 102]]); + + const multiPt = combine(featureCollection([pt1, pt2])); + + t.ok(multiPt, 'should combine Points + MultiPoint into a MultiPoint'); + t.deepEqual(multiPt.features[0].geometry.coordinates, [[50, 51], [100, 101], [101, 102]]); + t.end(); +}); + +test('combine -- linestrings', function (t) { + // MultiLineString + const l1 = lineString([ + [102.0, + -10.0], + [130.0, + 4.0]]); + const l2 = lineString([ + [40.0, + -20.0], + [150.0, + 18.0]]); + + const multiLine = combine(featureCollection([l1, l2])); + + t.ok(multiLine, 'should combine two LineStrings into a MultiLineString'); + t.equal(multiLine.features[0].geometry.type, 'MultiLineString'); + t.deepEqual(multiLine.features[0].geometry.coordinates, [[[102, -10], [130, 4]], [[40, -20], [150, 18]]]); + t.end(); +}); + +test('combine -- mixed multiLineString & linestring', function (t) { + // MultiLineString + const l1 = lineString([ + [102.0, -10.0], + [130.0, 4.0] + ]); + const l2 = multiLineString([ + [ + [40.0, -20.0], + [150.0, 18.0] + ], + [ + [50, -10], + [160, 28] + ] + ]); + + const multiLine = combine(featureCollection([l1, l2])); + + t.ok(multiLine, 'should combine LineString + MultiLineString into a MultiLineString'); + t.equal(multiLine.features[0].geometry.type, 'MultiLineString'); + t.deepEqual(multiLine.features[0].geometry.coordinates, [[[102, -10], [130, 4]], [[40, -20], [150, 18]], [[50, -10], [160, 28]]]); + t.end(); +}); + +test('combine -- polygons', function (t) { + // MultiPolygon + const p1 = polygon([ + [ + [20.0, 0.0], + [101.0, 0.0], + [101.0, 1.0], + [100.0, 1.0], + [100.0, 0.0], + [20.0, 0.0] + ] + ]); + const p2 = polygon([ + [ + [30.0, 0.0], + [102.0, 0.0], + [103.0, 1.0], + [30.0, 0.0] + ] + ]); + const multiPoly = combine(featureCollection([p1, p2])); + + t.ok(multiPoly, 'should combine two Polygons into a MultiPolygon'); + t.equal(multiPoly.features[0].geometry.type, 'MultiPolygon'); + t.deepEqual(multiPoly.features[0].geometry.coordinates, + [[[[20, 0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0], [20, 0]]], + [[[30.0, 0.0], [102.0, 0.0], [103.0, 1.0], [30.0, 0.0]]]]); + + t.end(); +}); + +test('combine -- polygons', function (t) { + // MultiPolygon + const p1 = polygon([ + [ + [20.0, 0.0], + [101.0, 0.0], + [101.0, 1.0], + [100.0, 1.0], + [100.0, 0.0], + [20.0, 0.0] + ] + ]); + const p2 = multiPolygon([ + [[ + [30.0, 0.0], + [102.0, 0.0], + [103.0, 1.0], + [30.0, 0.0] + ]], + [ + [ + [20.0, 5.0], + [92.0, 5.0], + [93.0, 6.0], + [20.0, 5.0] + ], + [ + [25, 5], + [30, 5], + [30, 5.5], + [25, 5] + ] + ] + ]); + const multiPoly = combine(featureCollection([p1, p2])); + + t.ok(multiPoly, 'should combine two Polygon + MultiPolygon into a MultiPolygon'); + t.equal(multiPoly.features[0].geometry.type, 'MultiPolygon'); + t.deepEqual(multiPoly.features[0].geometry.coordinates, + [[[[20, 0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0], [20, 0]]], + [[[30.0, 0.0], [102.0, 0.0], [103.0, 1.0], [30.0, 0.0]]], + [[[20.0, 5.0], [92.0, 5.0], [93.0, 6.0], [20.0, 5.0]], + [[25, 5], [30, 5], [30, 5.5], [25, 5]]] + ]); + + t.end(); +}); + +test('combine -- heterogenous', function (t) { + // MultiPolygon + const p1 = polygon([ + [ + [20.0, 0.0], + [101.0, 0.0], + [101.0, 1.0], + [100.0, 1.0], + [100.0, 0.0], + [20.0, 0.0] + ] + ]); + const p2 = multiPolygon([ + [[ + [30.0, 0.0], + [102.0, 0.0], + [103.0, 1.0], + [30.0, 0.0] + ]], + [ + [ + [20.0, 5.0], + [92.0, 5.0], + [93.0, 6.0], + [20.0, 5.0] + ], + [ + [25, 5], + [30, 5], + [30, 5.5], + [25, 5] + ] + ] + ]); + const pt1 = point([50, 51]); + const multiPoly = combine(featureCollection([p1, p2, pt1])); + + t.ok(multiPoly, 'should combine two Polygon + MultiPolygon into a MultiPolygon'); + t.equal(multiPoly.features[0].geometry.type, 'MultiPoint'); + + t.equal(multiPoly.features[1].geometry.type, 'MultiPolygon'); + t.deepEqual(multiPoly.features[1].geometry.coordinates, + [[[[20, 0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0], [20, 0]]], + [[[30.0, 0.0], [102.0, 0.0], [103.0, 1.0], [30.0, 0.0]]], + [[[20.0, 5.0], [92.0, 5.0], [93.0, 6.0], [20.0, 5.0]], + [[25, 5], [30, 5], [30, 5.5], [25, 5]]] + ]); + + t.end(); +}); diff --git a/packages/turf-concave/bench.js b/src/concave/bench.js similarity index 100% rename from packages/turf-concave/bench.js rename to src/concave/bench.js diff --git a/packages/turf-concave/index.d.ts b/src/concave/index.d.ts similarity index 100% rename from packages/turf-concave/index.d.ts rename to src/concave/index.d.ts diff --git a/src/concave/index.js b/src/concave/index.js new file mode 100644 index 0000000000..1eee0c4018 --- /dev/null +++ b/src/concave/index.js @@ -0,0 +1,84 @@ +import distance from '../distance'; +import { featureCollection, checkIfOptionsExist } from '../helpers'; +import { featureEach } from '../meta'; +import tin from '../tin'; +import dissolve from '../dissolve'; + +/** + * Takes a set of {@link Point|points} and returns a concave hull Polygon or MultiPolygon. + * Internally, this uses [turf-tin](https://github.com/Turfjs/turf-tin) to generate geometries. + * We also recommend checking out [concaveman](https://github.com/mapbox/concaveman) for a more performant + * solution although it does not offer a maxEdge setting. + * + * @name concave + * @param {FeatureCollection} points input points + * @param {Object} [options={}] Optional parameters + * @param {number} [options.maxEdge=Infinity] the length (in 'units') of an edge necessary for part of the + * hull to become concave. + * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers + * @returns {Feature<(Polygon|MultiPolygon)>|null} a concave hull (null value is returned if unable to compute hull) + * @example + * var points = turf.featureCollection([ + * turf.point([-63.601226, 44.642643]), + * turf.point([-63.591442, 44.651436]), + * turf.point([-63.580799, 44.648749]), + * turf.point([-63.573589, 44.641788]), + * turf.point([-63.587665, 44.64533]), + * turf.point([-63.595218, 44.64765]) + * ]); + * var options = {units: 'miles', maxEdge: 1}; + * + * var hull = turf.concave(points, options); + * + * //addToMap + * var addToMap = [points, hull] + */ +function concave(points, options) { + options = checkIfOptionsExist(options); + + const maxEdge = options.maxEdge || Infinity; + + const cleaned = removeDuplicates(points); + + const tinPolys = tin(cleaned); + // calculate length of all edges and area of all triangles + // and remove triangles that fail the max length test + tinPolys.features = tinPolys.features.filter((triangle) => { + const pt1 = triangle.geometry.coordinates[0][0]; + const pt2 = triangle.geometry.coordinates[0][1]; + const pt3 = triangle.geometry.coordinates[0][2]; + const dist1 = distance(pt1, pt2, options); + const dist2 = distance(pt2, pt3, options); + const dist3 = distance(pt1, pt3, options); + return (dist1 <= maxEdge && dist2 <= maxEdge && dist3 <= maxEdge); + }); + + if (tinPolys.features.length < 1) { return null; } + + // merge the adjacent triangles + return dissolve(tinPolys); +} + +/** + * Removes duplicated points in a collection returning a new collection + * + * @private + * @param {FeatureCollection} points to be cleaned + * @returns {FeatureCollection} cleaned set of points + */ +function removeDuplicates(points) { + const cleaned = []; + const existing = {}; + + featureEach(points, (pt) => { + if (!pt.geometry) { return; } + const key = pt.geometry.coordinates.join("-"); + if (!existing.hasOwnProperty(key)) { + cleaned.push(pt); + existing[key] = true; + } + }); + return featureCollection(cleaned); +} + +export default concave; diff --git a/src/concave/test.js b/src/concave/test.js new file mode 100644 index 0000000000..568a8377f1 --- /dev/null +++ b/src/concave/test.js @@ -0,0 +1,59 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { point, featureCollection } = require('../helpers'); +const { featureEach } = require('../meta'); +const concave = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +// test('turf-concave', t => { +// fixtures.forEach(fixture => { +// const filename = fixture.filename; +// const name = fixture.name; +// const geojson = fixture.geojson; +// const properties = geojson.properties || {}; +// const maxEdge = properties.maxEdge || 1; +// const units = properties.units; + +// const hull = concave(geojson, {units, maxEdge}); +// featureEach(geojson, stylePt); +// const results = featureCollection(geojson.features.concat(hull.features)); + +// if (process.env.REGEN) write.sync(directories.out + filename, results); +// t.deepEquals(results, load.sync(directories.out + filename), name); +// }); +// t.end(); +// }); + + +const points = featureCollection([point([0, 0]), point([1, 1]), point([1, 0])]); +const onePoint = featureCollection([point([0, 0])]); + +test('concave -- throw', t => { + t.equal(concave(onePoint, {maxEdge: 5.5, units: 'miles'}), null, 'too few polygons found to compute concave hull'); + t.equal(concave(onePoint), null, 'too few polygons found to compute concave hull -- maxEdge too small'); + // t.throws(() => concave(null), /points is required/, 'no points'); + // t.throws(() => concave(points, {units: 'foo'}), /units is invalid/, 'invalid units'); + // t.throws(() => concave(points, {maxEdge: 'foo'}), /maxEdge is invalid/, 'invalid maxEdge'); + + t.end(); +}); + +function stylePt(pt) { + pt.properties['marker-color'] = '#f0f'; + pt.properties['marker-size'] = 'small'; +} diff --git a/packages/turf-concave/test/in/concave-hull.geojson b/src/concave/test/in/concave-hull.geojson similarity index 100% rename from packages/turf-concave/test/in/concave-hull.geojson rename to src/concave/test/in/concave-hull.geojson diff --git a/packages/turf-concave/test/in/fiji.geojson b/src/concave/test/in/fiji.geojson similarity index 100% rename from packages/turf-concave/test/in/fiji.geojson rename to src/concave/test/in/fiji.geojson diff --git a/packages/turf-concave/test/in/hole.geojson b/src/concave/test/in/hole.geojson similarity index 100% rename from packages/turf-concave/test/in/hole.geojson rename to src/concave/test/in/hole.geojson diff --git a/src/concave/test/in/issue-1436.geojson b/src/concave/test/in/issue-1436.geojson new file mode 100644 index 0000000000..689ba9f836 --- /dev/null +++ b/src/concave/test/in/issue-1436.geojson @@ -0,0 +1,207 @@ +{ +"type": "FeatureCollection", +"properties": { +"maxEdge": 500, +"units": "meters" +}, +"features": [ +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.490446608177754, +41.8880262819213 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.491900701796553, +41.884893222348325 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.493752410574729, +41.89555906491028 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.492378870470459, +41.89674707108108 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.491042589325572, +41.89588979628056 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.490469677635723, +41.89356439367692 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.490446608177754, +41.8880262819213 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.479482691180369, +41.89657521122995 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.480278040216104, +41.894028607681896 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.480648962395106, +41.89408129845556 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.483770746018557, +41.8942191575813 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.485119995944173, +41.892384062689565 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.488880009400596, +41.89571626668174 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.48691631019514, +41.8965549030047 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.484290532739005, +41.89847574336856 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.48288988828719, +41.89821122875663 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.48052637455828, +41.89849263017274 +] +} +}, +{ +"type": "Feature", +"properties": {}, +"geometry": { +"type": "Point", +"coordinates": [ +12.479482691180369, +41.89657521122995 +] +} +} +] +} \ No newline at end of file diff --git a/packages/turf-concave/test/in/issue-333.geojson b/src/concave/test/in/issue-333.geojson similarity index 100% rename from packages/turf-concave/test/in/issue-333.geojson rename to src/concave/test/in/issue-333.geojson diff --git a/packages/turf-concave/test/in/pts1.geojson b/src/concave/test/in/pts1.geojson similarity index 100% rename from packages/turf-concave/test/in/pts1.geojson rename to src/concave/test/in/pts1.geojson diff --git a/packages/turf-concave/test/in/pts2.geojson b/src/concave/test/in/pts2.geojson similarity index 100% rename from packages/turf-concave/test/in/pts2.geojson rename to src/concave/test/in/pts2.geojson diff --git a/packages/turf-concave/test/in/pts3.geojson b/src/concave/test/in/pts3.geojson similarity index 100% rename from packages/turf-concave/test/in/pts3.geojson rename to src/concave/test/in/pts3.geojson diff --git a/packages/turf-concave/test/in/support-null-geometry.geojson b/src/concave/test/in/support-null-geometry.geojson similarity index 100% rename from packages/turf-concave/test/in/support-null-geometry.geojson rename to src/concave/test/in/support-null-geometry.geojson diff --git a/packages/turf-concave/test/out/concave-hull.geojson b/src/concave/test/out/concave-hull.geojson similarity index 88% rename from packages/turf-concave/test/out/concave-hull.geojson rename to src/concave/test/out/concave-hull.geojson index 9e327fa652..0431fe496a 100644 --- a/packages/turf-concave/test/out/concave-hull.geojson +++ b/src/concave/test/out/concave-hull.geojson @@ -467,60 +467,62 @@ "type": "Feature", "properties": {}, "geometry": { - "type": "Polygon", + "type": "MultiPolygon", "coordinates": [ [ [ - -312.0172119140625, - -13.536530399503015 - ], - [ - -312.07763671875, - -13.368243250897287 - ], - [ - -311.978759765625, - -13.18914225554674 - ], - [ - -311.923828125, - -13.098204859664591 - ], - [ - -311.802978515625, - -13.042020847922622 - ], - [ - -311.4459228515625, - -13.095529720741482 - ], - [ - -311.37451171875, - -13.154376055418515 - ], - [ - -311.3470458984375, - -13.389619591747595 - ], - [ - -311.4788818359375, - -13.552551566455168 - ], - [ - -311.53656005859375, - -13.603278132528756 - ], - [ - -311.627197265625, - -13.667338259654947 - ], - [ - -311.7864990234375, - -13.672675818669807 - ], - [ - -312.0172119140625, - -13.536530399503015 + [ + -312.07763671875, + -13.368243250897287 + ], + [ + -312.0172119140625, + -13.536530399503015 + ], + [ + -311.7864990234375, + -13.672675818669807 + ], + [ + -311.627197265625, + -13.667338259654947 + ], + [ + -311.53656005859375, + -13.603278132528756 + ], + [ + -311.4788818359375, + -13.552551566455168 + ], + [ + -311.3470458984375, + -13.389619591747595 + ], + [ + -311.37451171875, + -13.154376055418515 + ], + [ + -311.4459228515625, + -13.095529720741482 + ], + [ + -311.802978515625, + -13.042020847922622 + ], + [ + -311.923828125, + -13.098204859664591 + ], + [ + -311.978759765625, + -13.18914225554674 + ], + [ + -312.07763671875, + -13.368243250897287 + ] ] ] ] diff --git a/packages/turf-concave/test/out/fiji.geojson b/src/concave/test/out/fiji.geojson similarity index 82% rename from packages/turf-concave/test/out/fiji.geojson rename to src/concave/test/out/fiji.geojson index 4eace7ec88..e8d2b283b0 100644 --- a/packages/turf-concave/test/out/fiji.geojson +++ b/src/concave/test/out/fiji.geojson @@ -187,44 +187,46 @@ "type": "Feature", "properties": {}, "geometry": { - "type": "Polygon", + "type": "MultiPolygon", "coordinates": [ [ [ - -179.85443115234375, - -16.675662043309767 - ], - [ - -179.62921142578125, - -16.675662043309767 - ], - [ - -179.6484375, - -16.90442787825499 - ], - [ - -179.92721557617188, - -16.942528651601 - ], - [ - -180.0823974609375, - -17.069913009885465 - ], - [ - -180.20050048828125, - -16.97274101999901 - ], - [ - -180.142822265625, - -16.825574258731486 - ], - [ - -180.01922607421875, - -16.759837823776632 - ], - [ - -179.85443115234375, - -16.675662043309767 + [ + -180.20050048828125, + -16.97274101999901 + ], + [ + -180.0823974609375, + -17.069913009885465 + ], + [ + -179.92721557617188, + -16.942528651601 + ], + [ + -179.6484375, + -16.90442787825499 + ], + [ + -179.62921142578125, + -16.675662043309767 + ], + [ + -179.85443115234375, + -16.675662043309767 + ], + [ + -180.01922607421875, + -16.759837823776632 + ], + [ + -180.142822265625, + -16.825574258731486 + ], + [ + -180.20050048828125, + -16.97274101999901 + ] ] ] ] diff --git a/packages/turf-concave/test/out/hole.geojson b/src/concave/test/out/hole.geojson similarity index 76% rename from packages/turf-concave/test/out/hole.geojson rename to src/concave/test/out/hole.geojson index fb5f0e7ea7..f4dd0e09ff 100644 --- a/packages/turf-concave/test/out/hole.geojson +++ b/src/concave/test/out/hole.geojson @@ -467,138 +467,140 @@ "type": "Feature", "properties": {}, "geometry": { - "type": "Polygon", + "type": "MultiPolygon", "coordinates": [ [ [ - -312.01446533203125, - -13.266679794815271 + [ + -312.07763671875, + -13.368243250897287 + ], + [ + -312.0172119140625, + -13.536530399503015 + ], + [ + -311.923828125, + -13.573911442504558 + ], + [ + -311.7864990234375, + -13.672675818669807 + ], + [ + -311.627197265625, + -13.667338259654947 + ], + [ + -311.53656005859375, + -13.603278132528756 + ], + [ + -311.4788818359375, + -13.552551566455168 + ], + [ + -311.4129638671875, + -13.467092893859657 + ], + [ + -311.3470458984375, + -13.389619591747595 + ], + [ + -311.363525390625, + -13.330830095126228 + ], + [ + -311.37451171875, + -13.154376055418515 + ], + [ + -311.4459228515625, + -13.095529720741482 + ], + [ + -311.5777587890625, + -13.090179355733726 + ], + [ + -311.7123413085937, + -13.06342578889815 + ], + [ + -311.802978515625, + -13.042020847922622 + ], + [ + -311.923828125, + -13.098204859664591 + ], + [ + -311.978759765625, + -13.18914225554674 + ], + [ + -312.01446533203125, + -13.266679794815271 + ], + [ + -312.07763671875, + -13.368243250897287 + ] ], [ - -311.978759765625, - -13.18914225554674 - ], - [ - -311.923828125, - -13.098204859664591 - ], - [ - -311.802978515625, - -13.042020847922622 - ], - [ - -311.7123413085937, - -13.06342578889815 - ], - [ - -311.5777587890625, - -13.090179355733726 - ], - [ - -311.4459228515625, - -13.095529720741482 - ], - [ - -311.37451171875, - -13.154376055418515 - ], - [ - -311.363525390625, - -13.330830095126228 - ], - [ - -311.3470458984375, - -13.389619591747595 - ], - [ - -311.4129638671875, - -13.467092893859657 - ], - [ - -311.4788818359375, - -13.552551566455168 - ], - [ - -311.53656005859375, - -13.603278132528756 - ], - [ - -311.627197265625, - -13.667338259654947 - ], - [ - -311.7864990234375, - -13.672675818669807 - ], - [ - -311.923828125, - -13.573911442504558 - ], - [ - -312.0172119140625, - -13.536530399503015 - ], - [ - -312.07763671875, - -13.368243250897287 - ], - [ - -312.01446533203125, - -13.266679794815271 - ] - ], - [ - [ - -311.94580078125, - -13.4216805428783 - ], - [ - -311.9183349609375, - -13.523178603049853 - ], - [ - -311.83593749999994, - -13.608617139653036 - ], - [ - -311.66015625, - -13.579251111245878 - ], - [ - -311.55578613281244, - -13.552551566455168 - ], - [ - -311.50360107421875, - -13.435038009690732 - ], - [ - -311.48162841796875, - -13.365571074958245 - ], - [ - -311.5447998046875, - -13.237271908200585 - ], - [ - -311.64642333984375, - -13.098204859664591 - ], - [ - -311.8194580078125, - -13.114255082724755 - ], - [ - -311.87164306640625, - -13.141003126359843 - ], - [ - -311.9403076171875, - -13.288065114120283 - ], - [ - -311.94580078125, - -13.4216805428783 + [ + -311.94580078125, + -13.4216805428783 + ], + [ + -311.9403076171875, + -13.288065114120283 + ], + [ + -311.87164306640625, + -13.141003126359843 + ], + [ + -311.8194580078125, + -13.114255082724755 + ], + [ + -311.64642333984375, + -13.098204859664591 + ], + [ + -311.5447998046875, + -13.237271908200585 + ], + [ + -311.48162841796875, + -13.365571074958245 + ], + [ + -311.50360107421875, + -13.435038009690732 + ], + [ + -311.55578613281244, + -13.552551566455168 + ], + [ + -311.66015625, + -13.579251111245878 + ], + [ + -311.83593749999994, + -13.608617139653036 + ], + [ + -311.9183349609375, + -13.523178603049853 + ], + [ + -311.94580078125, + -13.4216805428783 + ] ] ] ] diff --git a/src/concave/test/out/issue-1436.geojson b/src/concave/test/out/issue-1436.geojson new file mode 100644 index 0000000000..bbdb81f38a --- /dev/null +++ b/src/concave/test/out/issue-1436.geojson @@ -0,0 +1,310 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.490446608177754, + 41.8880262819213 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.491900701796553, + 41.884893222348325 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.493752410574729, + 41.89555906491028 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.492378870470459, + 41.89674707108108 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.491042589325572, + 41.89588979628056 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.490469677635723, + 41.89356439367692 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.490446608177754, + 41.8880262819213 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.479482691180369, + 41.89657521122995 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.480278040216104, + 41.894028607681896 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.480648962395106, + 41.89408129845556 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.483770746018557, + 41.8942191575813 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.485119995944173, + 41.892384062689565 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.488880009400596, + 41.89571626668174 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.48691631019514, + 41.8965549030047 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.484290532739005, + 41.89847574336856 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.48288988828719, + 41.89821122875663 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.48052637455828, + 41.89849263017274 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#f0f", + "marker-size": "small" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 12.479482691180369, + 41.89657521122995 + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 12.479482691180369, + 41.89657521122995 + ], + [ + 12.480278040216104, + 41.894028607681896 + ], + [ + 12.485119995944173, + 41.892384062689565 + ], + [ + 12.490469677635723, + 41.89356439367692 + ], + [ + 12.493752410574729, + 41.89555906491028 + ], + [ + 12.492378870470459, + 41.89674707108108 + ], + [ + 12.48691631019514, + 41.8965549030047 + ], + [ + 12.484290532739005, + 41.89847574336856 + ], + [ + 12.48052637455828, + 41.89849263017274 + ], + [ + 12.479482691180369, + 41.89657521122995 + ] + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-concave/test/out/issue-333.geojson b/src/concave/test/out/issue-333.geojson similarity index 99% rename from packages/turf-concave/test/out/issue-333.geojson rename to src/concave/test/out/issue-333.geojson index 33ccf53986..726ba49c45 100644 --- a/packages/turf-concave/test/out/issue-333.geojson +++ b/src/concave/test/out/issue-333.geojson @@ -1648,136 +1648,136 @@ [ [ [ - -90.53797681111112, - 14.629561677777778 - ], - [ - -90.51274230000001, - 14.639448640000001 + -90.5820498, + 14.6369336 ], [ - -90.5269091, - 14.6573203 + -90.5713858, + 14.6338483 ], [ - -90.5269321, - 14.6573653 + -90.5564985, + 14.627035 ], [ - -90.50523385, - 14.651190725000001 + -90.55477304537037, + 14.62646318703704 ], [ - -90.49116085, - 14.667282275 + -90.5478511, + 14.6249898 ], [ - -90.4875626, - 14.6704823 + -90.54214180000001, + 14.624207466666666 ], [ - -90.4723723, - 14.6485518 + -90.5201483, + 14.615014 ], [ - -90.4722951, - 14.6482883 + -90.5170675, + 14.604278 ], [ - -90.4722628, - 14.6479208 + -90.5148751, + 14.5823441 ], [ - -90.4734413, - 14.6466325 + -90.494049, + 14.5869676 ], [ - -90.47394456363637, - 14.646360845454545 + -90.48639698333334, + 14.607210466666666 ], [ - -90.48284538181817, - 14.644143345454546 + -90.49990055555557, + 14.600796044444444 ], [ - -90.4850658857143, - 14.644084114285715 + -90.5132231, + 14.6165441 ], [ - -90.495238, - 14.6457041 + -90.51289270000001, + 14.618719666666667 ], [ -90.51233063333332, 14.635753766666667 ], [ - -90.51289270000001, - 14.618719666666667 + -90.495238, + 14.6457041 ], [ - -90.5132231, - 14.6165441 + -90.4850658857143, + 14.644084114285715 ], [ - -90.49990055555557, - 14.600796044444444 + -90.48284538181817, + 14.644143345454546 ], [ - -90.48639698333334, - 14.607210466666666 + -90.47394456363637, + 14.646360845454545 ], [ - -90.494049, - 14.5869676 + -90.4734413, + 14.6466325 ], [ - -90.5148751, - 14.5823441 + -90.4722628, + 14.6479208 ], [ - -90.5170675, - 14.604278 + -90.4722951, + 14.6482883 ], [ - -90.5201483, - 14.615014 + -90.4723723, + 14.6485518 ], [ - -90.54214180000001, - 14.624207466666666 + -90.4875626, + 14.6704823 ], [ - -90.5478511, - 14.6249898 + -90.49116085, + 14.667282275 ], [ - -90.55477304537037, - 14.62646318703704 + -90.50523385, + 14.651190725000001 ], [ - -90.5564985, - 14.627035 + -90.5269321, + 14.6573653 ], [ - -90.5713858, - 14.6338483 + -90.5269091, + 14.6573203 ], [ - -90.5820498, - 14.6369336 + -90.51274230000001, + 14.639448640000001 ], [ - -90.5713228, - 14.6338651 + -90.53797681111112, + 14.629561677777778 ], [ -90.5612823875, 14.6354786625 ], [ - -90.53797681111112, - 14.629561677777778 + -90.5713228, + 14.6338651 + ], + [ + -90.5820498, + 14.6369336 ] ] ], @@ -1787,14 +1787,14 @@ -90.5705346, 14.5772148 ], - [ - -90.5621048, - 14.590847633333333 - ], [ -90.56126696666666, 14.590278533333333 ], + [ + -90.5621048, + 14.590847633333333 + ], [ -90.5705346, 14.5772148 diff --git a/packages/turf-concave/test/out/pts1.geojson b/src/concave/test/out/pts1.geojson similarity index 97% rename from packages/turf-concave/test/out/pts1.geojson rename to src/concave/test/out/pts1.geojson index fd435d2be5..2dac34b174 100644 --- a/packages/turf-concave/test/out/pts1.geojson +++ b/src/concave/test/out/pts1.geojson @@ -195,14 +195,14 @@ -122.62527465820311, 37.89327929625019 ], - [ - -122.60467529296875, - 37.902490518640995 - ], [ -122.58682250976562, 37.895988598965644 ], + [ + -122.60467529296875, + 37.902490518640995 + ], [ -122.62527465820311, 37.89327929625019 @@ -211,49 +211,49 @@ ], [ [ - [ - -122.52639770507812, - 37.83473402375478 - ], [ -122.53395080566405, 37.83690319650768 ], [ - -122.51541137695311, + -122.52639770507812, 37.83473402375478 ], [ - -122.52639770507812, + -122.51541137695311, 37.83473402375478 + ], + [ + -122.53395080566405, + 37.83690319650768 ] ] ], [ [ [ - -122.40898132324217, - 37.77505678240509 - ], - [ - -122.4103546142578, - 37.72184917678752 + -122.47833251953125, + 37.73651223296987 ], [ -122.44331359863283, 37.726194088705576 ], [ - -122.47833251953125, - 37.73651223296987 + -122.4103546142578, + 37.72184917678752 + ], + [ + -122.40898132324217, + 37.77505678240509 ], [ -122.43095397949219, 37.74411415606583 ], [ - -122.40898132324217, - 37.77505678240509 + -122.47833251953125, + 37.73651223296987 ] ] ] diff --git a/packages/turf-concave/test/out/pts2.geojson b/src/concave/test/out/pts2.geojson similarity index 97% rename from packages/turf-concave/test/out/pts2.geojson rename to src/concave/test/out/pts2.geojson index 21545cbc7a..b7be3304e8 100644 --- a/packages/turf-concave/test/out/pts2.geojson +++ b/src/concave/test/out/pts2.geojson @@ -3580,150 +3580,152 @@ "type": "Feature", "properties": {}, "geometry": { - "type": "Polygon", + "type": "MultiPolygon", "coordinates": [ [ [ - -77.10263460574787, - 38.92444192485095 + [ + -77.10263460574787, + 38.92444192485095 + ], + [ + -77.08498118309296, + 38.909915833213795 + ], + [ + -77.0511477096272, + 38.898862835793516 + ], + [ + -77.04818646563815, + 38.89812378757083 + ], + [ + -77.02291065460415, + 38.87987059942476 + ], + [ + -77.01279249959418, + 38.87501581074506 + ], + [ + -76.99535456253949, + 38.85976175834964 + ], + [ + -77.00097525758831, + 38.83938233153192 + ], + [ + -77.00866130403007, + 38.83401036254331 + ], + [ + -77.00847560019479, + 38.8269811922012 + ], + [ + -76.99918484024232, + 38.82898558049571 + ], + [ + -76.99226881799031, + 38.834327886510565 + ], + [ + -76.96952139706708, + 38.85335576413945 + ], + [ + -76.95609228878696, + 38.86298923901404 + ], + [ + -76.93761630232859, + 38.87906795106383 + ], + [ + -76.92611549373204, + 38.88359849788337 + ], + [ + -76.92270804396746, + 38.89619288755561 + ], + [ + -76.9299476407989, + 38.90541498719898 + ], + [ + -76.9404849391363, + 38.90822873259865 + ], + [ + -76.95763369669753, + 38.92730594377001 + ], + [ + -76.98499562999821, + 38.94201213500814 + ], + [ + -76.99988253848109, + 38.95997180998364 + ], + [ + -77.01805167618295, + 38.96888669131412 + ], + [ + -77.03399523386544, + 38.98460295003216 + ], + [ + -77.05520494037229, + 38.962417220863394 + ], + [ + -77.06803711636698, + 38.96662722064828 + ], + [ + -77.07510861326296, + 38.96515842127339 + ], + [ + -77.08244680641738, + 38.9482176667262 + ], + [ + -77.10263460574787, + 38.92444192485095 + ] ], [ - -77.08244680641738, - 38.9482176667262 - ], - [ - -77.07510861326296, - 38.96515842127339 - ], - [ - -77.06803711636698, - 38.96662722064828 - ], - [ - -77.05520494037229, - 38.962417220863394 - ], - [ - -77.03399523386544, - 38.98460295003216 - ], - [ - -77.01805167618295, - 38.96888669131412 - ], - [ - -76.99988253848109, - 38.95997180998364 - ], - [ - -76.98499562999821, - 38.94201213500814 - ], - [ - -76.95763369669753, - 38.92730594377001 - ], - [ - -76.9404849391363, - 38.90822873259865 - ], - [ - -76.9299476407989, - 38.90541498719898 - ], - [ - -76.92270804396746, - 38.89619288755561 - ], - [ - -76.92611549373204, - 38.88359849788337 - ], - [ - -76.93761630232859, - 38.87906795106383 - ], - [ - -76.95609228878696, - 38.86298923901404 - ], - [ - -76.96952139706708, - 38.85335576413945 - ], - [ - -76.99226881799031, - 38.834327886510565 - ], - [ - -76.99918484024232, - 38.82898558049571 - ], - [ - -77.00847560019479, - 38.8269811922012 - ], - [ - -77.00866130403007, - 38.83401036254331 - ], - [ - -77.00097525758831, - 38.83938233153192 - ], - [ - -76.99535456253949, - 38.85976175834964 - ], - [ - -77.01279249959418, - 38.87501581074506 - ], - [ - -77.02291065460415, - 38.87987059942476 - ], - [ - -77.04818646563815, - 38.89812378757083 - ], - [ - -77.0511477096272, - 38.898862835793516 - ], - [ - -77.08498118309296, - 38.909915833213795 - ], - [ - -77.10263460574787, - 38.92444192485095 - ] - ], - [ - [ - -76.98652958387164, - 38.9375726751204 - ], - [ - -76.99726738315395, - 38.95334052572905 - ], - [ - -77.00866515707142, - 38.95406774426341 - ], - [ - -77.0177770800083, - 38.948230614415095 - ], - [ - -77.00253831800221, - 38.923654687421774 - ], - [ - -76.98652958387164, - 38.9375726751204 + [ + -77.0177770800083, + 38.948230614415095 + ], + [ + -77.00866515707142, + 38.95406774426341 + ], + [ + -76.99726738315395, + 38.95334052572905 + ], + [ + -76.98652958387164, + 38.9375726751204 + ], + [ + -77.00253831800221, + 38.923654687421774 + ], + [ + -77.0177770800083, + 38.948230614415095 + ] ] ] ] diff --git a/packages/turf-concave/test/out/pts3.geojson b/src/concave/test/out/pts3.geojson similarity index 84% rename from packages/turf-concave/test/out/pts3.geojson rename to src/concave/test/out/pts3.geojson index 9788fa70fe..ab414fd84e 100644 --- a/packages/turf-concave/test/out/pts3.geojson +++ b/src/concave/test/out/pts3.geojson @@ -103,24 +103,26 @@ "type": "Feature", "properties": {}, "geometry": { - "type": "Polygon", + "type": "MultiPolygon", "coordinates": [ [ [ - -122.43198394775389, - 37.72836644908416 - ], - [ - -122.42786407470703, - 37.738141282210385 - ], - [ - -122.41859436035156, - 37.729724141962045 - ], - [ - -122.43198394775389, - 37.72836644908416 + [ + -122.43198394775389, + 37.72836644908416 + ], + [ + -122.41859436035156, + 37.729724141962045 + ], + [ + -122.42786407470703, + 37.738141282210385 + ], + [ + -122.43198394775389, + 37.72836644908416 + ] ] ] ] diff --git a/packages/turf-concave/test/out/support-null-geometry.geojson b/src/concave/test/out/support-null-geometry.geojson similarity index 97% rename from packages/turf-concave/test/out/support-null-geometry.geojson rename to src/concave/test/out/support-null-geometry.geojson index 59704fd5a6..c6c716c1ba 100644 --- a/packages/turf-concave/test/out/support-null-geometry.geojson +++ b/src/concave/test/out/support-null-geometry.geojson @@ -189,14 +189,14 @@ -122.62527465820311, 37.89327929625019 ], - [ - -122.60467529296875, - 37.902490518640995 - ], [ -122.58682250976562, 37.895988598965644 ], + [ + -122.60467529296875, + 37.902490518640995 + ], [ -122.62527465820311, 37.89327929625019 @@ -205,49 +205,49 @@ ], [ [ - [ - -122.52639770507812, - 37.83473402375478 - ], [ -122.53395080566405, 37.83690319650768 ], [ - -122.51541137695311, + -122.52639770507812, 37.83473402375478 ], [ - -122.52639770507812, + -122.51541137695311, 37.83473402375478 + ], + [ + -122.53395080566405, + 37.83690319650768 ] ] ], [ [ [ - -122.4103546142578, - 37.72184917678752 + -122.47833251953125, + 37.73651223296987 ], [ -122.44331359863283, 37.726194088705576 ], [ - -122.47833251953125, - 37.73651223296987 - ], - [ - -122.43095397949219, - 37.74411415606583 + -122.4103546142578, + 37.72184917678752 ], [ -122.41790771484375, 37.74682893940135 ], [ - -122.4103546142578, - 37.72184917678752 + -122.43095397949219, + 37.74411415606583 + ], + [ + -122.47833251953125, + 37.73651223296987 ] ] ] diff --git a/packages/turf-convex/bench.js b/src/convex/bench.js similarity index 100% rename from packages/turf-convex/bench.js rename to src/convex/bench.js diff --git a/packages/turf-convex/index.d.ts b/src/convex/index.d.ts similarity index 100% rename from packages/turf-convex/index.d.ts rename to src/convex/index.d.ts diff --git a/src/convex/index.js b/src/convex/index.js new file mode 100644 index 0000000000..c728f9c9fc --- /dev/null +++ b/src/convex/index.js @@ -0,0 +1,56 @@ +import { polygon, checkIfOptionsExist } from '../helpers'; +import { coordEach } from '../meta'; +import { convexHull } from './lib/convexHull'; + +/** + * Takes a {@link Feature} or a {@link FeatureCollection} and returns a convex hull {@link Polygon}. + * + * Internally this uses + * the [convexhull-js](https://github.com/indy256/convexhull-js) module that implements a + * [monotone chain hull](http://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain). + * + * @name convex + * @param {GeoJSON} geojson input Feature or FeatureCollection + * @param {Object} [options={}] Optional parameters + * @param {Object} [options.properties={}] Translate Properties to Feature + * @returns {Feature} a convex hull + * @example + * var points = turf.featureCollection([ + * turf.point([10.195312, 43.755225]), + * turf.point([10.404052, 43.8424511]), + * turf.point([10.579833, 43.659924]), + * turf.point([10.360107, 43.516688]), + * turf.point([10.14038, 43.588348]), + * turf.point([10.195312, 43.755225]) + * ]); + * + * var hull = turf.convex(points); + * + * //addToMap + * var addToMap = [points, hull] + */ +export default function convex(geojson, options) { + options = checkIfOptionsExist(options); + + // Default parameters + options.properties = options.properties || {}; + + // Container + const points = []; + + // Convert all points to flat 2D coordinate Array + coordEach(geojson, (coord) => { + points.push([coord[0], coord[1]]); + }); + if (!points.length) { return null; } + + const outHull = convexHull(points); + + // Convex hull should have at least 3 different vertices in order to create a valid polygon + if (outHull.length > 3) { + outHull.push(outHull[0]); + return polygon([outHull], options.properties); + } + return null; +} + diff --git a/src/convex/lib/convexHull.js b/src/convex/lib/convexHull.js new file mode 100644 index 0000000000..32c166858c --- /dev/null +++ b/src/convex/lib/convexHull.js @@ -0,0 +1,28 @@ +// Internalise convexhulljs +// https://github.com/indy256/convexhull-js +// MIT licensed + +export function convexHull(points) { + points.sort(function (a, b) { + return a[1] !== b[1] ? a[1] - b[1] : a[0] - b[0]; + }); + + const n = points.length; + const hull = []; + + for (let i = 0; i < 2 * n; i++) { + const j = i < n ? i : 2 * n - 1 - i; + while (hull.length >= 2 && removeMiddle(hull[hull.length - 2], hull[hull.length - 1], points[j])) + hull.pop(); + hull.push(points[j]); + } + + hull.pop(); + return hull; +} + +function removeMiddle(a, b, c) { + const cross = (a[1] - b[1]) * (c[0] - b[0]) - (a[0] - b[0]) * (c[1] - b[1]); + const dot = (a[1] - b[1]) * (c[1] - b[1]) + (a[0] - b[0]) * (c[0] - b[0]); + return cross < 0 || cross === 0 && dot <= 0; +} diff --git a/src/convex/test.js b/src/convex/test.js new file mode 100644 index 0000000000..d3e1424d03 --- /dev/null +++ b/src/convex/test.js @@ -0,0 +1,31 @@ +const test = require('tape'); +const glob = require('glob'); +const path = require('path'); +const write = require('write-json-file'); +const load = require('load-json-file'); +const { featureCollection } = require('../helpers'); +const convex = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +test('convex hull', t => { + glob.sync(directories.in + '*.geojson').forEach(filepath => { + const fileout = filepath.replace('/in/', '/out/'); + const geojson = load.sync(filepath); + + const convexHull = convex(geojson); + geojson.features.push(convexHull); + + if (process.env.REGEN) write.sync(fileout, geojson); + t.deepEqual(geojson, load.sync(fileout), path.parse(filepath).name); + }); + t.end(); +}); + +test('turf-convex -- empty', t => { + t.deepEqual(convex(featureCollection([])), null, 'corner case: null hull'); + t.end(); +}); diff --git a/packages/turf-convex/test/in/elevation1.geojson b/src/convex/test/in/elevation1.geojson similarity index 100% rename from packages/turf-convex/test/in/elevation1.geojson rename to src/convex/test/in/elevation1.geojson diff --git a/packages/turf-convex/test/in/elevation2.geojson b/src/convex/test/in/elevation2.geojson similarity index 100% rename from packages/turf-convex/test/in/elevation2.geojson rename to src/convex/test/in/elevation2.geojson diff --git a/packages/turf-convex/test/in/elevation3.geojson b/src/convex/test/in/elevation3.geojson similarity index 100% rename from packages/turf-convex/test/in/elevation3.geojson rename to src/convex/test/in/elevation3.geojson diff --git a/packages/turf-convex/test/in/elevation4.geojson b/src/convex/test/in/elevation4.geojson similarity index 100% rename from packages/turf-convex/test/in/elevation4.geojson rename to src/convex/test/in/elevation4.geojson diff --git a/packages/turf-convex/test/in/elevation5.geojson b/src/convex/test/in/elevation5.geojson similarity index 100% rename from packages/turf-convex/test/in/elevation5.geojson rename to src/convex/test/in/elevation5.geojson diff --git a/packages/turf-convex/test/out/elevation1.geojson b/src/convex/test/out/elevation1.geojson similarity index 99% rename from packages/turf-convex/test/out/elevation1.geojson rename to src/convex/test/out/elevation1.geojson index b8e4ff8823..61fa857895 100644 --- a/packages/turf-convex/test/out/elevation1.geojson +++ b/src/convex/test/out/elevation1.geojson @@ -264,40 +264,40 @@ "coordinates": [ [ [ - -75.534, - 39.123 - ], - [ - -75.9221, - 39.27 + -75.44, + 39.11 ], [ - -75.88, - 39.98 + -75.21, + 39.12 ], [ - -75.6, - 39.984 + -75.05, + 39.92 ], [ -75.358, 39.987 ], [ - -75.05, - 39.92 + -75.6, + 39.984 ], [ - -75.21, - 39.12 + -75.88, + 39.98 ], [ - -75.44, - 39.11 + -75.9221, + 39.27 ], [ -75.534, 39.123 + ], + [ + -75.44, + 39.11 ] ] ] diff --git a/packages/turf-convex/test/out/elevation2.geojson b/src/convex/test/out/elevation2.geojson similarity index 100% rename from packages/turf-convex/test/out/elevation2.geojson rename to src/convex/test/out/elevation2.geojson index e20558601f..ffdd5bcf4c 100644 --- a/packages/turf-convex/test/out/elevation2.geojson +++ b/src/convex/test/out/elevation2.geojson @@ -68,20 +68,20 @@ 39.35766163717121 ], [ - -76.21490478515625, - 39.60145584096999 - ], - [ - -76.06109619140625, - 40.0759697987031 + -74.5587158203125, + 39.816975090490004 ], [ -75.1300048828125, 40.157885249506506 ], [ - -74.5587158203125, - 39.816975090490004 + -76.06109619140625, + 40.0759697987031 + ], + [ + -76.21490478515625, + 39.60145584096999 ], [ -74.77020263671875, diff --git a/packages/turf-convex/test/out/elevation3.geojson b/src/convex/test/out/elevation3.geojson similarity index 99% rename from packages/turf-convex/test/out/elevation3.geojson rename to src/convex/test/out/elevation3.geojson index b8e4ff8823..61fa857895 100644 --- a/packages/turf-convex/test/out/elevation3.geojson +++ b/src/convex/test/out/elevation3.geojson @@ -264,40 +264,40 @@ "coordinates": [ [ [ - -75.534, - 39.123 - ], - [ - -75.9221, - 39.27 + -75.44, + 39.11 ], [ - -75.88, - 39.98 + -75.21, + 39.12 ], [ - -75.6, - 39.984 + -75.05, + 39.92 ], [ -75.358, 39.987 ], [ - -75.05, - 39.92 + -75.6, + 39.984 ], [ - -75.21, - 39.12 + -75.88, + 39.98 ], [ - -75.44, - 39.11 + -75.9221, + 39.27 ], [ -75.534, 39.123 + ], + [ + -75.44, + 39.11 ] ] ] diff --git a/packages/turf-convex/test/out/elevation4.geojson b/src/convex/test/out/elevation4.geojson similarity index 100% rename from packages/turf-convex/test/out/elevation4.geojson rename to src/convex/test/out/elevation4.geojson index 3a152449eb..9e3dc9b0bd 100644 --- a/packages/turf-convex/test/out/elevation4.geojson +++ b/src/convex/test/out/elevation4.geojson @@ -73,20 +73,20 @@ 39.35766163717121 ], [ - -76.21490478515625, - 39.60145584096999 - ], - [ - -76.06109619140625, - 40.0759697987031 + -74.5587158203125, + 39.816975090490004 ], [ -75.1300048828125, 40.157885249506506 ], [ - -74.5587158203125, - 39.816975090490004 + -76.06109619140625, + 40.0759697987031 + ], + [ + -76.21490478515625, + 39.60145584096999 ], [ -74.77020263671875, diff --git a/packages/turf-convex/test/out/elevation5.geojson b/src/convex/test/out/elevation5.geojson similarity index 97% rename from packages/turf-convex/test/out/elevation5.geojson rename to src/convex/test/out/elevation5.geojson index 530b2d33d3..a85bdfff65 100644 --- a/packages/turf-convex/test/out/elevation5.geojson +++ b/src/convex/test/out/elevation5.geojson @@ -84,64 +84,64 @@ "coordinates": [ [ [ - -74.56146240234375, - 40.47620304302563 - ], - [ - -74.59991455078125, - 40.60144147645398 + -74.01214599609375, + 40.317231732315236 ], [ - -74.5697021484375, - 40.74309523218185 + -73.85009765625, + 40.34654412118006 ], [ - -74.5257568359375, - 40.851215574282456 + -73.76220703125, + 40.444856858961764 ], [ - -74.410400390625, - 40.977824533189526 + -73.7567138671875, + 40.8595252289932 ], [ - -74.24285888671875, - 41.04828819952275 + -73.86383056640625, + 40.97575093157534 ], [ -74.0203857421875, 41.04621681452063 ], [ - -73.86383056640625, - 40.97575093157534 + -74.24285888671875, + 41.04828819952275 ], [ - -73.7567138671875, - 40.8595252289932 + -74.410400390625, + 40.977824533189526 ], [ - -73.76220703125, - 40.444856858961764 + -74.5257568359375, + 40.851215574282456 ], [ - -73.85009765625, - 40.34654412118006 + -74.5697021484375, + 40.74309523218185 ], [ - -74.01214599609375, - 40.317231732315236 + -74.59991455078125, + 40.60144147645398 ], [ - -74.2236328125, - 40.32141999593439 + -74.56146240234375, + 40.47620304302563 ], [ -74.41864013671875, 40.386304853509046 ], [ - -74.56146240234375, - 40.47620304302563 + -74.2236328125, + 40.32141999593439 + ], + [ + -74.01214599609375, + 40.317231732315236 ] ] ] diff --git a/src/destination/bench.js b/src/destination/bench.js new file mode 100644 index 0000000000..565cdc7474 --- /dev/null +++ b/src/destination/bench.js @@ -0,0 +1,14 @@ +const fs = require('fs'); +const Benchmark = require('benchmark'); +const destination = require('./').default + +var pt1 = [-75.0, 39.0] +var dist = 100; +var bear = 180; + +var suite = new Benchmark.Suite('destination'); +suite + .add('destination',() => destination(pt1, dist, bear)) + .on('cycle', e => console.log(String(e.target))) + .on('complete', () => {}) + .run(); \ No newline at end of file diff --git a/src/destination/index.d.ts b/src/destination/index.d.ts new file mode 100644 index 0000000000..ee7328c70b --- /dev/null +++ b/src/destination/index.d.ts @@ -0,0 +1,31 @@ +import { Coord, Feature, Point, Properties, Units } from "../helpers"; +/** + * Takes a {@link Point} and calculates the location of a destination point given a distance in + * degrees, radians, miles, or kilometers; and bearing in degrees. + * This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature. + * + * @name destination + * @param {Coord} origin starting point + * @param {number} distance distance from the origin point + * @param {number} bearing ranging from -180 to 180 + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians + * @param {Object} [options.properties={}] Translate properties to Point + * @returns {Feature} destination point + * @example + * var point = turf.point([-75.343, 39.984]); + * var distance = 50; + * var bearing = 90; + * var options = {units: 'miles'}; + * + * var destination = turf.destination(point, distance, bearing, options); + * + * //addToMap + * var addToMap = [point, destination] + * destination.properties['marker-color'] = '#f00'; + * point.properties['marker-color'] = '#0f0'; + */ +export default function destination

(origin: Coord, distance: number, bearing: number, options?: { + units?: Units; + properties?: P; +}): Feature; diff --git a/src/destination/index.js b/src/destination/index.js new file mode 100644 index 0000000000..c675df465f --- /dev/null +++ b/src/destination/index.js @@ -0,0 +1,51 @@ +// http://en.wikipedia.org/wiki/Haversine_formula +// http://www.movable-type.co.uk/scripts/latlong.html +import { degreesToRadians, radiansToDegrees, lengthToRadians, point, checkIfOptionsExist } from '../helpers'; +import { getCoord } from '../invariant'; + +/** + * Takes a {@link Point} and calculates the location of a destination point given a distance in + * degrees, radians, miles, or kilometers; and bearing in degrees. + * This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature. + * + * @name destination + * @param {Coord} origin starting point + * @param {number} distance distance from the origin point + * @param {number} bearing ranging from -180 to 180 + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians + * @param {Object} [options.properties={}] Translate properties to Point + * @returns {Feature} destination point + * @example + * var point = turf.point([-75.343, 39.984]); + * var distance = 50; + * var bearing = 90; + * var options = {units: 'miles'}; + * + * var destination = turf.destination(point, distance, bearing, options); + * + * //addToMap + * var addToMap = [point, destination] + * destination.properties['marker-color'] = '#f00'; + * point.properties['marker-color'] = '#0f0'; + */ +export default function destination(origin, distance, bearing, options) { + + options = checkIfOptionsExist(options); + // Handle input + const coordinates1 = getCoord(origin); + const longitude1 = degreesToRadians(coordinates1[0]); + const latitude1 = degreesToRadians(coordinates1[1]); + const bearingRad = degreesToRadians(bearing); + const radians = lengthToRadians(distance, options.units); + + // Main + const latitude2 = Math.asin(Math.sin(latitude1) * Math.cos(radians) + + Math.cos(latitude1) * Math.sin(radians) * Math.cos(bearingRad)); + const longitude2 = longitude1 + Math.atan2(Math.sin(bearingRad) * Math.sin(radians) * Math.cos(latitude1), + Math.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2)); + const lng = radiansToDegrees(longitude2); + const lat = radiansToDegrees(latitude2); + + return point([lng, lat], options.properties); +} diff --git a/src/destination/test.js b/src/destination/test.js new file mode 100644 index 0000000000..02200f4369 --- /dev/null +++ b/src/destination/test.js @@ -0,0 +1,34 @@ +const path = require('path'); +const test = require('tape'); +const glob = require('glob'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { getCoords } = require('../invariant'); +const { lineString, featureCollection, round } = require('../helpers'); +const truncate = require('../truncate').default; +const destination = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +test('turf-destination', t => { + glob.sync(directories.in + '*.geojson').forEach(filepath => { + const geojson = load.sync(filepath); + const name = path.parse(filepath).name; + const base = path.parse(filepath).base; + + // Params + const properties = geojson.properties || {}; + const bearing = (properties.bearing !== undefined) ? properties.bearing : 180; + const dist = (properties.dist !== undefined) ? properties.dist : 100; + + const dest = truncate(destination(geojson, dist, bearing)); + const result = featureCollection([geojson, dest, lineString([getCoords(geojson), getCoords(dest)])]); + + if (process.env.REGEN) write.sync(directories.out + base, result); + t.deepEqual(result, load.sync(directories.out + base), name); + }); + t.end(); +}); diff --git a/packages/turf-destination/test/in/point-0.geojson b/src/destination/test/in/point-0.geojson similarity index 100% rename from packages/turf-destination/test/in/point-0.geojson rename to src/destination/test/in/point-0.geojson diff --git a/packages/turf-destination/test/in/point-180.geojson b/src/destination/test/in/point-180.geojson similarity index 100% rename from packages/turf-destination/test/in/point-180.geojson rename to src/destination/test/in/point-180.geojson diff --git a/packages/turf-destination/test/in/point-90.geojson b/src/destination/test/in/point-90.geojson similarity index 100% rename from packages/turf-destination/test/in/point-90.geojson rename to src/destination/test/in/point-90.geojson diff --git a/packages/turf-destination/test/in/point-way-far-away.geojson b/src/destination/test/in/point-way-far-away.geojson similarity index 100% rename from packages/turf-destination/test/in/point-way-far-away.geojson rename to src/destination/test/in/point-way-far-away.geojson diff --git a/packages/turf-destination/test/out/point-0.geojson b/src/destination/test/out/point-0.geojson similarity index 100% rename from packages/turf-destination/test/out/point-0.geojson rename to src/destination/test/out/point-0.geojson diff --git a/packages/turf-destination/test/out/point-180.geojson b/src/destination/test/out/point-180.geojson similarity index 100% rename from packages/turf-destination/test/out/point-180.geojson rename to src/destination/test/out/point-180.geojson diff --git a/packages/turf-destination/test/out/point-90.geojson b/src/destination/test/out/point-90.geojson similarity index 100% rename from packages/turf-destination/test/out/point-90.geojson rename to src/destination/test/out/point-90.geojson diff --git a/packages/turf-destination/test/out/point-way-far-away.geojson b/src/destination/test/out/point-way-far-away.geojson similarity index 100% rename from packages/turf-destination/test/out/point-way-far-away.geojson rename to src/destination/test/out/point-way-far-away.geojson diff --git a/packages/turf-difference/bench.js b/src/difference/bench.js similarity index 100% rename from packages/turf-difference/bench.js rename to src/difference/bench.js diff --git a/src/difference/index.d.ts b/src/difference/index.d.ts new file mode 100644 index 0000000000..2f08ba24ac --- /dev/null +++ b/src/difference/index.d.ts @@ -0,0 +1,10 @@ +import { Polygon, MultiPolygon, Feature } from '../helpers' + +/** + * http://turfjs.org/docs/#difference + */ +export default function difference( + polygon1: Feature | Polygon | MultiPolygon, + polygon2: Feature | Polygon | MultiPolygon +): Feature | null; + diff --git a/src/difference/index.js b/src/difference/index.js new file mode 100644 index 0000000000..087949f2c6 --- /dev/null +++ b/src/difference/index.js @@ -0,0 +1,48 @@ +import polygonClipping from 'polygon-clipping'; +import { multiPolygon } from '../helpers'; +import { getGeom } from '../invariant'; + +/** + * Finds the difference between two {@link Polygon|polygons} by clipping the second polygon from the first. + * + * @name difference + * @param {Feature} polygon1 input Polygon feature + * @param {Feature} polygon2 Polygon feature to difference from polygon1 + * @returns {Feature|null} a Polygon or MultiPolygon feature showing the area of `polygon1` excluding the area of `polygon2` (if empty returns `null`) + * @example + * var polygon1 = turf.polygon([[ + * [128, -26], + * [141, -26], + * [141, -21], + * [128, -21], + * [128, -26] + * ]], { + * "fill": "#F00", + * "fill-opacity": 0.1 + * }); + * var polygon2 = turf.polygon([[ + * [126, -28], + * [140, -28], + * [140, -20], + * [126, -20], + * [126, -28] + * ]], { + * "fill": "#00F", + * "fill-opacity": 0.1 + * }); + * + * var difference = turf.difference(polygon1, polygon2); + * + * //addToMap + * var addToMap = [polygon1, polygon2, difference]; + */ +function difference(polygon1, polygon2) { + const geom1 = getGeom(polygon1); + const geom2 = getGeom(polygon2); + const properties = polygon1.properties || {}; + const differenced = polygonClipping.difference(geom1.coordinates, geom2.coordinates); + if (differenced.length === 0) return null; + return multiPolygon(differenced, properties); +} + +export default difference; diff --git a/src/difference/test.js b/src/difference/test.js new file mode 100644 index 0000000000..ce71670fca --- /dev/null +++ b/src/difference/test.js @@ -0,0 +1,66 @@ +const path = require('path'); +const test = require('tape'); +const glob = require('glob'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { featureCollection, polygon } = require('../helpers'); +const difference = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +test('turf-difference', t => { + glob.sync(directories.in + '*.geojson').forEach(filepath => { + const { name, base } = path.parse(filepath); + const [polygon1, polygon2] = load.sync(filepath).features; + + if (name.includes('skip')) return t.skip(name); + + // Red Polygon1 + polygon1.properties = Object.assign(polygon1.properties || {}, {'fill-opacity': 0.5, fill: '#F00'}); + // Blue Polygon2 + polygon2.properties = Object.assign(polygon2.properties || {}, {'fill-opacity': 0.5, fill: '#00F'}); + + const results = featureCollection([polygon1, polygon2]); + + const result = difference(polygon1, polygon2); + if (result) { + // Green Polygon + result.properties = {'fill-opacity': 1, fill: '#0F0'}; + results.features.push(result); + } + + if (process.env.REGEN) write.sync(directories.out + base, results); + t.deepEqual(results, load.sync(directories.out + base), name); + }); + t.end(); +}); + +test('turf-difference - support Geometry Objects', t => { + const poly1 = polygon([[[121, -31], [144, -31], [144, -15], [121, -15], [121, -31]]]); + const poly2 = polygon([[[126, -28], [140, -28], [140, -20], [126, -20], [126, -28]]]); + t.isNot(difference(poly1.geometry, poly2.geometry), null, 'geometry object support'); + t.end(); +}); + +test('turf-difference - prevent input mutation', t => { + const poly1 = polygon([[[121, -31], [144, -31], [144, -15], [121, -15], [121, -31]]]); + const poly2 = polygon([[[126, -28], [140, -28], [140, -20], [126, -20], [126, -28]]]); + const before1 = JSON.parse(JSON.stringify(poly1)); + const before2 = JSON.parse(JSON.stringify(poly2)); + + difference(poly1, poly2); + t.deepEqual(poly1, before1, 'polygon1 should not mutate'); + t.deepEqual(poly2, before2, 'polygon2 should not mutate'); + t.end(); +}); + +test('turf-difference - complete overlap', t => { + const poly = polygon([[[121, -31], [144, -31], [144, -15], [121, -15], [121, -31]]]); + + const result = difference(poly, poly); + t.deepEqual(result, null, 'difference should be null'); + t.end(); +}); diff --git a/packages/turf-difference/test/in/clip-polygons.geojson b/src/difference/test/in/clip-polygons.geojson similarity index 100% rename from packages/turf-difference/test/in/clip-polygons.geojson rename to src/difference/test/in/clip-polygons.geojson diff --git a/packages/turf-difference/test/in/completely-overlapped.geojson b/src/difference/test/in/completely-overlapped.geojson similarity index 100% rename from packages/turf-difference/test/in/completely-overlapped.geojson rename to src/difference/test/in/completely-overlapped.geojson diff --git a/packages/turf-difference/test/in/create-hole.geojson b/src/difference/test/in/create-hole.geojson similarity index 100% rename from packages/turf-difference/test/in/create-hole.geojson rename to src/difference/test/in/create-hole.geojson diff --git a/src/difference/test/in/difference-multihole.geojson b/src/difference/test/in/difference-multihole.geojson new file mode 100644 index 0000000000..aef2d3229a --- /dev/null +++ b/src/difference/test/in/difference-multihole.geojson @@ -0,0 +1,55 @@ +{ + "type": "FeatureCollection", + "features": [{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [-74.007991, 40.712882], + [-74.002844, 40.710215], + [-73.995466, 40.714509], + [-74.002983, 40.716637], + [-74.003519, 40.71568], + [-74.005797, 40.715789], + [-74.007991, 40.712882] + ] + ], + [ + [ + [-74.005369, 40.716355], + [-74.003402, 40.716756], + [-74.004774, 40.717144], + [-74.005369, 40.716355] + ], + [ + [-74.003605, 40.713988], + [-74.002854, 40.714769], + [-74.001266, 40.714167], + [-74.001609, 40.713289], + [-74.003605, 40.713988] + ] + ] + ] + } +}, +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [-74.005558, 40.713403], + [-74.005558, 40.712573], + [-74.003949, 40.712573], + [-74.003949, 40.713517], + [-74.005558, 40.713403] + ] + ] + } +} + ] +} \ No newline at end of file diff --git a/src/difference/test/in/issue-1393.geojson b/src/difference/test/in/issue-1393.geojson new file mode 100644 index 0000000000..206ed5a471 --- /dev/null +++ b/src/difference/test/in/issue-1393.geojson @@ -0,0 +1,7 @@ +{ + "type": "FeatureCollection", + "features": [ + {"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[16.2,48.0],[16.6,48.0],[16.6,48.1],[16.2,48.1],[16.2,48.0]]]}}, + {"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[16.4,48.0],[16.6,48.0],[16.6,48.1],[16.4,48.1],[16.4,48.0]]]}} + ] +} \ No newline at end of file diff --git a/packages/turf-difference/test/in/multi-polygon-input.geojson b/src/difference/test/in/multi-polygon-input.geojson similarity index 100% rename from packages/turf-difference/test/in/multi-polygon-input.geojson rename to src/difference/test/in/multi-polygon-input.geojson diff --git a/packages/turf-difference/test/in/multi-polygon-target.geojson b/src/difference/test/in/multi-polygon-target.geojson similarity index 100% rename from packages/turf-difference/test/in/multi-polygon-target.geojson rename to src/difference/test/in/multi-polygon-target.geojson diff --git a/packages/turf-difference/test/in/skip-martinez-issue-#35.geojson b/src/difference/test/in/skip-martinez-issue-#35.geojson similarity index 100% rename from packages/turf-difference/test/in/skip-martinez-issue-#35.geojson rename to src/difference/test/in/skip-martinez-issue-#35.geojson diff --git a/packages/turf-difference/test/in/split-polygon.geojson b/src/difference/test/in/split-polygon.geojson similarity index 100% rename from packages/turf-difference/test/in/split-polygon.geojson rename to src/difference/test/in/split-polygon.geojson diff --git a/packages/turf-difference/test/in/issue-#721-inverse.geojson b/src/difference/test/issue-#721-inverse.geojson similarity index 100% rename from packages/turf-difference/test/in/issue-#721-inverse.geojson rename to src/difference/test/issue-#721-inverse.geojson diff --git a/packages/turf-difference/test/in/issue-#721.geojson b/src/difference/test/issue-#721.geojson similarity index 100% rename from packages/turf-difference/test/in/issue-#721.geojson rename to src/difference/test/issue-#721.geojson diff --git a/src/difference/test/out/clip-polygons.geojson b/src/difference/test/out/clip-polygons.geojson new file mode 100644 index 0000000000..7f1aec3092 --- /dev/null +++ b/src/difference/test/out/clip-polygons.geojson @@ -0,0 +1,123 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6, + "stroke-opacity": 1, + "fill": "#F00", + "fill-opacity": 0.5 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 127.705078125, + -34.52466147177172 + ], + [ + 139.5703125, + -34.52466147177172 + ], + [ + 139.5703125, + -15.28418511407642 + ], + [ + 127.705078125, + -15.28418511407642 + ], + [ + 127.705078125, + -34.52466147177172 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 6, + "stroke-opacity": 1, + "fill": "#00F", + "fill-opacity": 0.5 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 133.154296875, + -29.075375179558346 + ], + [ + 144.228515625, + -29.075375179558346 + ], + [ + 144.228515625, + -12.983147716796566 + ], + [ + 133.154296875, + -12.983147716796566 + ], + [ + 133.154296875, + -29.075375179558346 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "fill-opacity": 1, + "fill": "#0F0" + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 127.705078125, + -34.52466147177172 + ], + [ + 139.5703125, + -34.52466147177172 + ], + [ + 139.5703125, + -29.075375179558346 + ], + [ + 133.154296875, + -29.075375179558346 + ], + [ + 133.154296875, + -15.28418511407642 + ], + [ + 127.705078125, + -15.28418511407642 + ], + [ + 127.705078125, + -34.52466147177172 + ] + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-difference/test/out/completely-overlapped.geojson b/src/difference/test/out/completely-overlapped.geojson similarity index 100% rename from packages/turf-difference/test/out/completely-overlapped.geojson rename to src/difference/test/out/completely-overlapped.geojson diff --git a/src/difference/test/out/create-hole.geojson b/src/difference/test/out/create-hole.geojson new file mode 100644 index 0000000000..09d30fc19f --- /dev/null +++ b/src/difference/test/out/create-hole.geojson @@ -0,0 +1,137 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6, + "stroke-opacity": 1, + "fill": "#F00", + "fill-opacity": 0.5 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 121, + -31 + ], + [ + 144, + -31 + ], + [ + 144, + -15 + ], + [ + 121, + -15 + ], + [ + 121, + -31 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 6, + "stroke-opacity": 1, + "fill": "#00F", + "fill-opacity": 0.5 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 126, + -28 + ], + [ + 140, + -28 + ], + [ + 140, + -20 + ], + [ + 126, + -20 + ], + [ + 126, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "fill-opacity": 1, + "fill": "#0F0" + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 121, + -31 + ], + [ + 144, + -31 + ], + [ + 144, + -15 + ], + [ + 121, + -15 + ], + [ + 121, + -31 + ] + ], + [ + [ + 126, + -28 + ], + [ + 126, + -20 + ], + [ + 140, + -20 + ], + [ + 140, + -28 + ], + [ + 126, + -28 + ] + ] + ] + ] + } + } + ] +} diff --git a/src/difference/test/out/difference-multihole.geojson b/src/difference/test/out/difference-multihole.geojson new file mode 100644 index 0000000000..63f7e55783 --- /dev/null +++ b/src/difference/test/out/difference-multihole.geojson @@ -0,0 +1,211 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "fill-opacity": 0.5, + "fill": "#F00" + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -74.007991, + 40.712882 + ], + [ + -74.002844, + 40.710215 + ], + [ + -73.995466, + 40.714509 + ], + [ + -74.002983, + 40.716637 + ], + [ + -74.003519, + 40.71568 + ], + [ + -74.005797, + 40.715789 + ], + [ + -74.007991, + 40.712882 + ] + ] + ], + [ + [ + [ + -74.005369, + 40.716355 + ], + [ + -74.003402, + 40.716756 + ], + [ + -74.004774, + 40.717144 + ], + [ + -74.005369, + 40.716355 + ] + ], + [ + [ + -74.003605, + 40.713988 + ], + [ + -74.002854, + 40.714769 + ], + [ + -74.001266, + 40.714167 + ], + [ + -74.001609, + 40.713289 + ], + [ + -74.003605, + 40.713988 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "fill-opacity": 0.5, + "fill": "#00F" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -74.005558, + 40.713403 + ], + [ + -74.005558, + 40.712573 + ], + [ + -74.003949, + 40.712573 + ], + [ + -74.003949, + 40.713517 + ], + [ + -74.005558, + 40.713403 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "fill-opacity": 1, + "fill": "#0F0" + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -74.007991, + 40.712882 + ], + [ + -74.002844, + 40.710215 + ], + [ + -73.995466, + 40.714509 + ], + [ + -74.002983, + 40.716637 + ], + [ + -74.003519, + 40.71568 + ], + [ + -74.005797, + 40.715789 + ], + [ + -74.007991, + 40.712882 + ] + ], + [ + [ + -74.005558, + 40.712573 + ], + [ + -74.005558, + 40.713403 + ], + [ + -74.003949, + 40.713517 + ], + [ + -74.003949, + 40.712573 + ], + [ + -74.005558, + 40.712573 + ] + ] + ], + [ + [ + [ + -74.005369, + 40.716355 + ], + [ + -74.003402, + 40.716756 + ], + [ + -74.004774, + 40.717144 + ], + [ + -74.005369, + 40.716355 + ] + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-difference/test/out/issue-#721-inverse.geojson b/src/difference/test/out/issue-#721-inverse.geojson similarity index 100% rename from packages/turf-difference/test/out/issue-#721-inverse.geojson rename to src/difference/test/out/issue-#721-inverse.geojson diff --git a/src/difference/test/out/issue-#721.geojson b/src/difference/test/out/issue-#721.geojson new file mode 100644 index 0000000000..46ae0e7fee --- /dev/null +++ b/src/difference/test/out/issue-#721.geojson @@ -0,0 +1,397 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6, + "stroke-opacity": 1, + "fill": "#F00", + "fill-opacity": 0.5 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -0.6474134, + 44.805326 + ], + [ + -0.6471907, + 44.8053946 + ], + [ + -0.6465049, + 44.8055554 + ], + [ + -0.6464734, + 44.8056645 + ], + [ + -0.6465119, + 44.8057959 + ], + [ + -0.6465922, + 44.8059124 + ], + [ + -0.6466376, + 44.8059546 + ], + [ + -0.6466831, + 44.8059719 + ], + [ + -0.6467005, + 44.8059967 + ], + [ + -0.6466971, + 44.8060413 + ], + [ + -0.64662, + 44.806065 + ], + [ + -0.64649, + 44.80611 + ], + [ + -0.646437, + 44.806159 + ], + [ + -0.6463809, + 44.8061882 + ], + [ + -0.6461987, + 44.8060367 + ], + [ + -0.6461042, + 44.8059451 + ], + [ + -0.6460542, + 44.8057952 + ], + [ + -0.6460421, + 44.8056729 + ], + [ + -0.6460848, + 44.8054585 + ], + [ + -0.6461073, + 44.8053383 + ], + [ + -0.6461218, + 44.8051741 + ], + [ + -0.6460827, + 44.8050017 + ], + [ + -0.6460168, + 44.8047948 + ], + [ + -0.645829, + 44.8043891 + ], + [ + -0.646075, + 44.8042943 + ], + [ + -0.6462847, + 44.8042192 + ], + [ + -0.6465997, + 44.8047375 + ], + [ + -0.6469113, + 44.8048572 + ], + [ + -0.6472295, + 44.8050484 + ], + [ + -0.6474134, + 44.805326 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 6, + "stroke-opacity": 1, + "fill": "#00F", + "fill-opacity": 0.5 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -0.6462588068806041, + 44.80608667910215 + ], + [ + -0.6461987, + 44.8060367 + ], + [ + -0.6461042, + 44.8059451 + ], + [ + -0.6461041344154722, + 44.805944903377586 + ], + [ + -0.6461991369724274, + 44.80603699057963 + ], + [ + -0.6462588068806041, + 44.80608667910215 + ] + ] + ], + [ + [ + [ + -0.646069093721612, + 44.80583985137739 + ], + [ + -0.6460542, + 44.8057952 + ], + [ + -0.6460421, + 44.8056729 + ], + [ + -0.6460471709105139, + 44.80564743856641 + ], + [ + -0.6460422277450562, + 44.805672561504906 + ], + [ + -0.6460542976856232, + 44.80579530680288 + ], + [ + -0.646069093721612, + 44.80583985137739 + ] + ] + ], + [ + [ + [ + -0.646093673696575, + 44.80541109474097 + ], + [ + -0.6461073, + 44.8053383 + ], + [ + -0.6461158838109077, + 44.80524109574131 + ], + [ + -0.646107941865921, + 44.80533857879061 + ], + [ + -0.646093673696575, + 44.80541109474097 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "fill-opacity": 1, + "fill": "#0F0" + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -0.6474134, + 44.805326 + ], + [ + -0.6472295, + 44.8050484 + ], + [ + -0.6469113, + 44.8048572 + ], + [ + -0.6465997, + 44.8047375 + ], + [ + -0.6462847, + 44.8042192 + ], + [ + -0.646075, + 44.8042943 + ], + [ + -0.645829, + 44.8043891 + ], + [ + -0.6460168, + 44.8047948 + ], + [ + -0.6460827, + 44.8050017 + ], + [ + -0.6461218, + 44.8051741 + ], + [ + -0.6461158838109077, + 44.80524109574131 + ], + [ + -0.646107941865921, + 44.80533857879061 + ], + [ + -0.646093673696575, + 44.80541109474097 + ], + [ + -0.6460848, + 44.8054585 + ], + [ + -0.6460471709105139, + 44.80564743856641 + ], + [ + -0.6460422277450562, + 44.805672561504906 + ], + [ + -0.6460542976856232, + 44.80579530680288 + ], + [ + -0.646069093721612, + 44.80583985137739 + ], + [ + -0.6461041344154722, + 44.805944903377586 + ], + [ + -0.6461991369724274, + 44.80603699057963 + ], + [ + -0.6462588068806041, + 44.80608667910215 + ], + [ + -0.6463809, + 44.8061882 + ], + [ + -0.646437, + 44.806159 + ], + [ + -0.64649, + 44.80611 + ], + [ + -0.64662, + 44.806065 + ], + [ + -0.6466971, + 44.8060413 + ], + [ + -0.6467005, + 44.8059967 + ], + [ + -0.6466831, + 44.8059719 + ], + [ + -0.6466376, + 44.8059546 + ], + [ + -0.6465922, + 44.8059124 + ], + [ + -0.6465119, + 44.8057959 + ], + [ + -0.6464734, + 44.8056645 + ], + [ + -0.6465049, + 44.8055554 + ], + [ + -0.6471907, + 44.8053946 + ], + [ + -0.6474134, + 44.805326 + ] + ] + ] + ] + } + } + ] +} diff --git a/src/difference/test/out/issue-1393.geojson b/src/difference/test/out/issue-1393.geojson new file mode 100644 index 0000000000..acb08afb0a --- /dev/null +++ b/src/difference/test/out/issue-1393.geojson @@ -0,0 +1,109 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "fill-opacity": 0.5, + "fill": "#F00" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 16.2, + 48 + ], + [ + 16.6, + 48 + ], + [ + 16.6, + 48.1 + ], + [ + 16.2, + 48.1 + ], + [ + 16.2, + 48 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "fill-opacity": 0.5, + "fill": "#00F" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 16.4, + 48 + ], + [ + 16.6, + 48 + ], + [ + 16.6, + 48.1 + ], + [ + 16.4, + 48.1 + ], + [ + 16.4, + 48 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "fill-opacity": 1, + "fill": "#0F0" + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 16.2, + 48 + ], + [ + 16.4, + 48 + ], + [ + 16.4, + 48.1 + ], + [ + 16.2, + 48.1 + ], + [ + 16.2, + 48 + ] + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-difference/test/out/jsts/clip-polygons.geojson b/src/difference/test/out/jsts/clip-polygons.geojson similarity index 100% rename from packages/turf-difference/test/out/jsts/clip-polygons.geojson rename to src/difference/test/out/jsts/clip-polygons.geojson diff --git a/packages/turf-difference/test/out/jsts/completely-overlapped.geojson b/src/difference/test/out/jsts/completely-overlapped.geojson similarity index 100% rename from packages/turf-difference/test/out/jsts/completely-overlapped.geojson rename to src/difference/test/out/jsts/completely-overlapped.geojson diff --git a/packages/turf-difference/test/out/jsts/create-hole.geojson b/src/difference/test/out/jsts/create-hole.geojson similarity index 100% rename from packages/turf-difference/test/out/jsts/create-hole.geojson rename to src/difference/test/out/jsts/create-hole.geojson diff --git a/packages/turf-difference/test/out/jsts/issue-#721-inverse.geojson b/src/difference/test/out/jsts/issue-#721-inverse.geojson similarity index 100% rename from packages/turf-difference/test/out/jsts/issue-#721-inverse.geojson rename to src/difference/test/out/jsts/issue-#721-inverse.geojson diff --git a/packages/turf-difference/test/out/jsts/issue-#721.geojson b/src/difference/test/out/jsts/issue-#721.geojson similarity index 100% rename from packages/turf-difference/test/out/jsts/issue-#721.geojson rename to src/difference/test/out/jsts/issue-#721.geojson diff --git a/packages/turf-difference/test/out/jsts/multi-polygon-input.geojson b/src/difference/test/out/jsts/multi-polygon-input.geojson similarity index 100% rename from packages/turf-difference/test/out/jsts/multi-polygon-input.geojson rename to src/difference/test/out/jsts/multi-polygon-input.geojson diff --git a/packages/turf-difference/test/out/jsts/multi-polygon-target.geojson b/src/difference/test/out/jsts/multi-polygon-target.geojson similarity index 100% rename from packages/turf-difference/test/out/jsts/multi-polygon-target.geojson rename to src/difference/test/out/jsts/multi-polygon-target.geojson diff --git a/packages/turf-difference/test/out/jsts/split-polygon.geojson b/src/difference/test/out/jsts/split-polygon.geojson similarity index 100% rename from packages/turf-difference/test/out/jsts/split-polygon.geojson rename to src/difference/test/out/jsts/split-polygon.geojson diff --git a/packages/turf-difference/test/out/multi-polygon-input.geojson b/src/difference/test/out/multi-polygon-input.geojson similarity index 100% rename from packages/turf-difference/test/out/multi-polygon-input.geojson rename to src/difference/test/out/multi-polygon-input.geojson diff --git a/packages/turf-difference/test/out/multi-polygon-target.geojson b/src/difference/test/out/multi-polygon-target.geojson similarity index 98% rename from packages/turf-difference/test/out/multi-polygon-target.geojson rename to src/difference/test/out/multi-polygon-target.geojson index 38325c0af7..2b6e006525 100644 --- a/packages/turf-difference/test/out/multi-polygon-target.geojson +++ b/src/difference/test/out/multi-polygon-target.geojson @@ -168,7 +168,7 @@ ], [ 136.23046875, - -20.220965779522302 + -20.2209657795223 ], [ 130.6494140625, @@ -185,16 +185,16 @@ -27.313213898568247 ], [ - 135.1318359375, - -27.313213898568247 + 132.38525390625, + -24.467150664738988 ], [ 135.1318359375, -24.467150664738988 ], [ - 132.38525390625, - -24.467150664738988 + 135.1318359375, + -27.313213898568247 ], [ 132.38525390625, @@ -218,7 +218,7 @@ ], [ 138.6474609375, - -20.220965779522302 + -20.2209657795223 ], [ 138.6474609375, diff --git a/packages/turf-difference/test/out/split-polygon.geojson b/src/difference/test/out/split-polygon.geojson similarity index 100% rename from packages/turf-difference/test/out/split-polygon.geojson rename to src/difference/test/out/split-polygon.geojson diff --git a/packages/turf-directional-mean/bench.js b/src/directional-mean/bench.js similarity index 100% rename from packages/turf-directional-mean/bench.js rename to src/directional-mean/bench.js diff --git a/src/directional-mean/index.d.ts b/src/directional-mean/index.d.ts new file mode 100644 index 0000000000..5e0c02c9e6 --- /dev/null +++ b/src/directional-mean/index.d.ts @@ -0,0 +1,47 @@ +import { Feature, FeatureCollection, LineString } from "../helpers"; +export interface DirectionalMeanLine extends Feature { + properties: { + cartesianAngle: number; + bearingAngle: number; + circularVariance: number; + averageX: number; + averageY: number; + averageLength: number; + countOfLines: number; + [key: string]: any; + }; +} +/** + * @typedef {Object} DirectionalMeanLine + * @property {number} cartesianAngle the mean angle of all lines. (measure from due earth counterclockwise). + * @property {number} bearingAngle the mean angle of all lines. (bearing). + * @property {number} circularVariance the extent to which features all point in the same direction. + * the value ranges 0-1, the bigger the value, the more variation in directions between lines. + * @property {number} averageX the centroid of all lines. + * @property {number} averageY the centroid of all line. + * @property {number} averageLength the average length of line. + * @property {number} countOfLines the count of features. + */ +/** + * This module calculate the average angle of a set of lines, measuring the trend of it. + * It can be used in both project coordinate system and geography coordinate system. + * It can handle segments of line or the whole line. + * @name directionalMean + * @param {FeatureCollection} lines + * @param {object} [options={}] + * @param {boolean} [options.planar=true] whether the spatial reference system is projected or geographical. + * @param {boolean} [options.segment=false] whether treat a LineString as a whole or a set of segments. + * @returns {DirectionalMeanLine} Directional Mean Line + * @example + * + * var lines = turf.lineStrings([ + * [[110, 45], [120, 50]], + * [[100, 50], [115, 55]], + * ]) + * var directionalMeanLine = turf.directionalMean(lines); + * // => directionalMeanLine + */ +export default function directionalMean(lines: FeatureCollection, options?: { + planar?: boolean; + segment?: boolean; +}): DirectionalMeanLine; diff --git a/src/directional-mean/index.js b/src/directional-mean/index.js new file mode 100644 index 0000000000..bc7742cf37 --- /dev/null +++ b/src/directional-mean/index.js @@ -0,0 +1,238 @@ +import bearing from "../bearing"; +import centroid from "../centroid"; +import destination from "../destination"; +import { featureCollection, geometry, lineString, point } from "../helpers"; +import { getCoord } from "../invariant"; +import length from "../length"; +import { featureEach, segmentEach, segmentReduce } from "../meta"; + +/** + * @typedef {Object} DirectionalMeanLine + * @property {number} cartesianAngle the mean angle of all lines. (measure from due earth counterclockwise). + * @property {number} bearingAngle the mean angle of all lines. (bearing). + * @property {number} circularVariance the extent to which features all point in the same direction. + * the value ranges 0-1, the bigger the value, the more variation in directions between lines. + * @property {number} averageX the centroid of all lines. + * @property {number} averageY the centroid of all line. + * @property {number} averageLength the average length of line. + * @property {number} countOfLines the count of features. + */ + +/** + * This module calculate the average angle of a set of lines, measuring the trend of it. + * It can be used in both project coordinate system and geography coordinate system. + * It can handle segments of line or the whole line. + * @name directionalMean + * @param {FeatureCollection} lines + * @param {object} [options={}] + * @param {boolean} [options.planar=true] whether the spatial reference system is projected or geographical. + * @param {boolean} [options.segment=false] whether treat a LineString as a whole or a set of segments. + * @returns {DirectionalMeanLine} Directional Mean Line + * @example + * + * var lines = turf.lineStrings([ + * [[110, 45], [120, 50]], + * [[100, 50], [115, 55]], + * ]) + * var directionalMeanLine = turf.directionalMean(lines); + * // => directionalMeanLine + */ +export default function directionalMean(lines, options) { + + const isPlanar = !!options.planar; // you can't use options.planar || true here. + const isSegment = options.segment || false; + let sigmaSin = 0; + let sigmaCos = 0; + let countOfLines = 0; + let sumOfLen = 0; + const centroidList = []; + + if (isSegment) { + segmentEach(lines, function (currentSegment) { // todo fix turf-meta's declaration file + const [sin1, cos1] = getCosAndSin(currentSegment.geometry.coordinates, isPlanar); + const lenOfLine = getLengthOfLineString(currentSegment, isPlanar); + if (isNaN(sin1) || isNaN(cos1)) { + return; + } else { + sigmaSin += sin1; + sigmaCos += cos1; + countOfLines += 1; + sumOfLen += lenOfLine; + centroidList.push(centroid(currentSegment)); + } + }); + // planar and segment + } else { + // planar and non-segment + featureEach(lines, function (currentFeature, featureIndex) { + if (currentFeature.geometry.type !== "LineString") { + throw new Error("shold to support MultiLineString?"); + } + const [sin1, cos1] = getCosAndSin(currentFeature.geometry.coordinates, isPlanar); + const lenOfLine = getLengthOfLineString(currentFeature, isPlanar); + if (isNaN(sin1) || isNaN(cos1)) { + return; + } else { + sigmaSin += sin1; + sigmaCos += cos1; + countOfLines += 1; + sumOfLen += lenOfLine; + centroidList.push(centroid(currentFeature)); + } + }); + } + + const cartesianAngle = getAngleBySinAndCos(sigmaSin, sigmaCos); + const bearingAngle = bearingToCartesian(cartesianAngle); + const circularVariance = getCircularVariance(sigmaSin, sigmaCos, countOfLines); + const averageLength = sumOfLen / countOfLines; + const centroidOfLines = centroid(featureCollection(centroidList)); + const [averageX, averageY] = getCoord(centroidOfLines); + let meanLinestring; + if (isPlanar) { + meanLinestring = getMeanLineString([averageX, averageY], cartesianAngle, averageLength, isPlanar); + } else { + meanLinestring = getMeanLineString([averageX, averageY], bearingAngle, averageLength, isPlanar); + } + + return lineString(meanLinestring, { + averageLength, + averageX, + averageY, + bearingAngle, + cartesianAngle, + circularVariance, + countOfLines, + }); +} + +/** + * get euclidean distance between two points. + * @private + * @name euclideanDistance + * @param coords + */ +function euclideanDistance(coords) { + const [x0, y0] = coords[0]; + const [x1, y1] = coords[1]; + const dx = x1 - x0; + const dy = y1 - y0; + return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); +} + +/** + * get the length of a LineString, both in projected or geographical coordinate system. + * @private + * @name getLengthOfLineString + * @param {Feature} line + * @param {boolean} isPlanar + */ +function getLengthOfLineString(line, isPlanar) { + if (isPlanar) { + return segmentReduce(line, function (previousValue, segment){ + const coords = segment.geometry.coordinates; // the signatrue of segmentReduce has problem ? + return previousValue + euclideanDistance(coords); + }, 0); + } else { + return length(line, { + units: "meters", + }); + } +} + +/** + * bearing to xy(from due earth counterclockwise 0-180) + * convert between two forms + * @private + * @name bearingToCartesian + * @param angle + */ +function bearingToCartesian(angle) { + let result = 90 - angle; + if (result > 180) { + result -= 360; + } + return result; +} + +/** + * @private + * @name getCosAndSin + * @param {Array>} coordinates + * @returns {Array} [cos, sin] + */ +function getCosAndSin(coordinates, isPlanar) { + const beginPoint = coordinates[0]; + const endPoint = coordinates[coordinates.length - 1]; + if (isPlanar) { + const [x0, y0] = beginPoint; + const [x1, y1] = endPoint; + const dx = x1 - x0; + const dy = y1 - y0; + const h = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); + if (h < 0.000000001) { + return [NaN, NaN]; + } + const sin1 = dy / h; + const cos1 = dx / h; + return [sin1, cos1]; + } else { + const angle = bearingToCartesian(bearing(beginPoint, endPoint)); + const radian = angle * Math.PI / 180; + return [Math.sin(radian), Math.cos(radian)]; + } + +} + +function getAngleBySinAndCos(sin1, cos1) { + let angle = 0; + if (Math.abs(cos1) < 0.000000001) { + angle = 90; + } else { + angle = Math.atan2(sin1, cos1) * 180 / Math.PI; + } + if (sin1 >= 0) { + if (cos1 < 0) { + angle += 180; + } + } else { + if (cos1 < 0) { + angle -= 180; + } + } + return angle; +} + +function getCircularVariance(sin1, cos1, len) { + if (len === 0) { + throw new Error("the size of the features set must be greater than 0"); + } + return 1 - (Math.sqrt(Math.pow(sin1, 2) + Math.pow(cos1, 2)) / len); +} + +function getMeanLineString(centroidOfLine, angle, lenOfLine, isPlanar) { + if (isPlanar) { + const [averageX, averageY] = centroidOfLine; + let beginX = null; + let beginY= null; + let endX = null; + let endY = null; + const r = angle * Math.PI / 180; + const sin = Math.sin(r); + const cos = Math.cos(r); + beginX = averageX - lenOfLine / 2 * cos; + beginY = averageY - lenOfLine / 2 * sin; + endX = averageX + lenOfLine / 2 * cos; + endY = averageY + lenOfLine / 2 * sin; + return [ + [beginX, beginY], + [endX, endY], + ]; + } else { + const end = destination(point(centroidOfLine), lenOfLine / 2, angle, { units: "meters" }); + const begin = destination(point(centroidOfLine), -lenOfLine / 2, angle, { units: "meters" }); + return [ + getCoord(begin), getCoord(end), + ]; + } +} diff --git a/src/directional-mean/test.js b/src/directional-mean/test.js new file mode 100644 index 0000000000..a9048cc784 --- /dev/null +++ b/src/directional-mean/test.js @@ -0,0 +1,56 @@ +const test = require('tape'); +const glob = require('glob'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const directionalMean = require('.').default; + +test('turf-directional-mean', t => { + + + const outGpsJsonPath1 = path.join(__dirname, 'test', 'out', 'bus_route_gps1.json'); + const outGpsJsonPath2 = path.join(__dirname, 'test', 'out', 'bus_route_gps2.json'); + const outUtmJsonPath1 = path.join(__dirname, 'test', 'out', 'bus_route_utm1.json'); + const outUtmJsonPath2 = path.join(__dirname, 'test', 'out', 'bus_route_utm2.json'); + + const utmFilepath = path.join(__dirname, 'test', 'in', 'bus_route_utm.json'); + const utmGeojson = load.sync(utmFilepath); + + const gpsFilepath = path.join(__dirname, 'test', 'in', 'bus_route_gps.json'); + const gpsGeojson = load.sync(gpsFilepath); + + // utm + let utmResult1 = directionalMean(utmGeojson, { + planar: true, + segment: false + }); + t.deepEqual(utmResult1, load.sync(outUtmJsonPath1), 'utm'); + // utm segment + let utmResult2 = directionalMean(utmGeojson, { + planar: true, + segment: true + }); + t.deepEqual(utmResult2, load.sync(outUtmJsonPath2), 'utm segment'); + + // gps + let gpsResult1 = directionalMean(gpsGeojson, { + planar: false + }); + t.deepEqual(gpsResult1, load.sync(outGpsJsonPath1), 'gps'); + // gps segment + let gpsResult2 = directionalMean(gpsGeojson, { + planar: false, + segment: true + }); + t.deepEqual(gpsResult2, load.sync(outGpsJsonPath2), 'gps segment'); + + if (process.env.REGEN) { + write.sync(outGpsJsonPath1, gpsResult1); + write.sync(outGpsJsonPath2, gpsResult2); + write.sync(outUtmJsonPath1, utmResult1); + write.sync(outUtmJsonPath2, utmResult2); + } + + t.end(); + +}); diff --git a/packages/turf-directional-mean/test/in/bus_route_gps.json b/src/directional-mean/test/in/bus_route_gps.json similarity index 100% rename from packages/turf-directional-mean/test/in/bus_route_gps.json rename to src/directional-mean/test/in/bus_route_gps.json diff --git a/packages/turf-directional-mean/test/in/bus_route_utm.json b/src/directional-mean/test/in/bus_route_utm.json similarity index 100% rename from packages/turf-directional-mean/test/in/bus_route_utm.json rename to src/directional-mean/test/in/bus_route_utm.json diff --git a/packages/turf-directional-mean/test/out/bus_route_gps.json b/src/directional-mean/test/out/bus_route_gps.json similarity index 100% rename from packages/turf-directional-mean/test/out/bus_route_gps.json rename to src/directional-mean/test/out/bus_route_gps.json diff --git a/packages/turf-directional-mean/test/out/bus_route_gps1.json b/src/directional-mean/test/out/bus_route_gps1.json similarity index 100% rename from packages/turf-directional-mean/test/out/bus_route_gps1.json rename to src/directional-mean/test/out/bus_route_gps1.json diff --git a/packages/turf-directional-mean/test/out/bus_route_gps2.json b/src/directional-mean/test/out/bus_route_gps2.json similarity index 100% rename from packages/turf-directional-mean/test/out/bus_route_gps2.json rename to src/directional-mean/test/out/bus_route_gps2.json diff --git a/packages/turf-directional-mean/test/out/bus_route_utm1.json b/src/directional-mean/test/out/bus_route_utm1.json similarity index 100% rename from packages/turf-directional-mean/test/out/bus_route_utm1.json rename to src/directional-mean/test/out/bus_route_utm1.json diff --git a/packages/turf-directional-mean/test/out/bus_route_utm2.json b/src/directional-mean/test/out/bus_route_utm2.json similarity index 100% rename from packages/turf-directional-mean/test/out/bus_route_utm2.json rename to src/directional-mean/test/out/bus_route_utm2.json diff --git a/packages/turf-dissolve/bench.js b/src/dissolve/bench.js similarity index 100% rename from packages/turf-dissolve/bench.js rename to src/dissolve/bench.js diff --git a/packages/turf-dissolve/index.d.ts b/src/dissolve/index.d.ts similarity index 100% rename from packages/turf-dissolve/index.d.ts rename to src/dissolve/index.d.ts diff --git a/src/dissolve/index.js b/src/dissolve/index.js new file mode 100644 index 0000000000..7cd57d11b5 --- /dev/null +++ b/src/dissolve/index.js @@ -0,0 +1,57 @@ +import { featureCollection, isObject } from '../helpers'; +import { collectionOf } from '../invariant'; +import { featureEach } from '../meta'; +import union from '../union'; + +/** + * Dissolves a FeatureCollection of {@link polygon} features, filtered by an optional property name:value. + * Note that {@link mulitpolygon} features within the collection are not supported + * + * @name dissolve + * @param {FeatureCollection} fc input feature collection to be dissolved + * @param {Object} [options={}] Optional parameters + * @param {string} [options.propertyName] features with equals 'propertyName' in `properties` will be merged + * @returns {FeatureCollection} a FeatureCollection containing the dissolved polygons + * @example + * var features = turf.featureCollection([ + * turf.polygon([[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]], {combine: 'yes'}), + * turf.polygon([[[0, -1], [0, 0], [1, 0], [1, -1], [0,-1]]], {combine: 'yes'}), + * turf.polygon([[[1,-1],[1, 0], [2, 0], [2, -1], [1, -1]]], {combine: 'no'}), + * ]); + * + * var dissolved = turf.dissolve(features, {propertyName: 'combine'}); + * + * //addToMap + * var addToMap = [features, dissolved] + */ +function dissolve(fc, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + const propertyName = options.propertyName; + + // Input validation + collectionOf(fc, 'Polygon', 'dissolve'); + + // Main + const outFeatures = []; + if (!options.propertyName) { + return union(fc); + } else { + const uniquePropertyVals = {}; + featureEach(fc, function (feature) { + if (!uniquePropertyVals.hasOwnProperty(feature.properties[propertyName])) { + uniquePropertyVals[feature.properties[propertyName]] = []; + } + uniquePropertyVals[feature.properties[propertyName]].push(feature); + }); + const vals = Object.keys(uniquePropertyVals); + for (let i = 0; i < vals.length; i++) { + outFeatures.push(union(featureCollection(uniquePropertyVals[vals[i]]))); + } + } + + return featureCollection(outFeatures); +} + +export default dissolve; diff --git a/src/dissolve/test.js b/src/dissolve/test.js new file mode 100644 index 0000000000..966e7bc0d3 --- /dev/null +++ b/src/dissolve/test.js @@ -0,0 +1,38 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import glob from 'glob' +import {polygon, point, featureCollection} from '../helpers'; +import dissolve from './'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +test('turf-dissolve', t => { + glob.sync(directories.in + '*.geojson').forEach(filepath => { + const { name, base } = path.parse(filepath); + const geojson = load.sync(filepath); + + const propertyName = geojson.propertyName; + const results = dissolve(geojson, {propertyName}); + + if (process.env.REGEN) write.sync(directories.out + base, results); + t.deepEqual(results, load.sync(directories.out + base), name); + }) + t.end(); +}); + + +test('dissolve -- throw', t => { + const poly = polygon([[[-61,27],[-59,27],[-59,29],[-61,29],[-61,27]]]); + const pt = point([-62,29]); + + t.throws(() => dissolve(null), /No featureCollection passed/, 'missing featureCollection'); + t.throws(() => dissolve(poly), /Invalid input to dissolve, FeatureCollection required/, 'invalid featureCollection'); + t.throws(() => dissolve(featureCollection([poly, pt])), /Invalid input to dissolve: must be a Polygon, given Point/, 'invalid collection type'); + t.end(); +}); \ No newline at end of file diff --git a/packages/turf-dissolve/test/in/hexagons-issue#742.geojson b/src/dissolve/test/in/hexagons-issue#742.geojson similarity index 100% rename from packages/turf-dissolve/test/in/hexagons-issue#742.geojson rename to src/dissolve/test/in/hexagons-issue#742.geojson diff --git a/src/dissolve/test/in/issue-1237.geojson b/src/dissolve/test/in/issue-1237.geojson new file mode 100644 index 0000000000..1498fe366d --- /dev/null +++ b/src/dissolve/test/in/issue-1237.geojson @@ -0,0 +1,12 @@ +{"type":"FeatureCollection","features":[ +{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-83.49609375,42.64507129879989],[-83.49609375,42.645576368740564],[-83.49540710449219,42.645576368740564],[-83.49540710449219,42.64507129879989],[-83.49609375,42.64507129879989]]]}}, +{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-83.49609375,42.64456622475866],[-83.49609375,42.64507129879989],[-83.49540710449219,42.64507129879989],[-83.49540710449219,42.64456622475866],[-83.49609375,42.64456622475866]]]}}, +{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-83.49609375,42.64052548480924],[-83.49609375,42.64103059165476],[-83.49540710449219,42.64103059165476],[-83.49540710449219,42.64052548480924],[-83.49609375,42.64052548480924]]]}}, +{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-83.42674255371094,42.681930627802714],[-83.42674255371094,42.68243539838622],[-83.42605590820312,42.68243539838622],[-83.42605590820312,42.681930627802714],[-83.42674255371094,42.681930627802714]]]}}, +{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-83.42193603515625,42.681930627802714],[-83.42193603515625,42.68243539838622],[-83.42124938964844,42.68243539838622],[-83.42124938964844,42.681930627802714],[-83.42193603515625,42.681930627802714]]]}}, +{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-83.42262268066406,42.681930627802714],[-83.42262268066406,42.68243539838622],[-83.42193603515625,42.68243539838622],[-83.42193603515625,42.681930627802714],[-83.42262268066406,42.681930627802714]]]}}, +{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-83.41850280761719,42.681930627802714],[-83.41850280761719,42.68243539838622],[-83.41781616210938,42.68243539838622],[-83.41781616210938,42.681930627802714],[-83.41850280761719,42.681930627802714]]]}}, +{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-83.49609375,42.66880515319917],[-83.49609375,42.66931003040664],[-83.49540710449219,42.66931003040664],[-83.49540710449219,42.66880515319917],[-83.49609375,42.66880515319917]]]}}, +{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-83.49540710449219,42.66830027189085],[-83.49540710449219,42.66880515319917],[-83.49472045898438,42.66880515319917],[-83.49472045898438,42.66830027189085],[-83.49540710449219,42.66830027189085]]]}}, +{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-83.49472045898438,42.66830027189085],[-83.49472045898438,42.66880515319917],[-83.49403381347656,42.66880515319917],[-83.49403381347656,42.66830027189085],[-83.49472045898438,42.66830027189085]]]}} +]} \ No newline at end of file diff --git a/src/dissolve/test/in/polysByProperty.geojson b/src/dissolve/test/in/polysByProperty.geojson new file mode 100644 index 0000000000..2e88e9c57f --- /dev/null +++ b/src/dissolve/test/in/polysByProperty.geojson @@ -0,0 +1,237 @@ +{ + "type":"FeatureCollection", + "propertyName":"combine", + "features":[ + { + "type":"Feature", + "properties":{ + "stroke":"#555555", + "stroke-width":2, + "stroke-opacity":1, + "fill":"#ff0000", + "fill-opacity":0.5, + "combine":"yes" + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [ + 0.5, + 0 + ], + [ + 0, + 1 + ], + [ + 1, + 1 + ], + [ + 1, + 0.5 + ], + [ + 0.7, + 0 + ], + [ + 0.5, + 0 + ] + ] + ] + } + }, + { + "type":"Feature", + "properties":{ + "stroke":"#555555", + "stroke-width":2, + "stroke-opacity":1, + "fill":"#ff0000", + "fill-opacity":0.5, + "combine":"yes" + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [ + 1, + 0 + ], + [ + 1, + 1 + ], + [ + 2, + 1 + ], + [ + 2, + 0 + ], + [ + 1, + 0 + ] + ] + ] + } + }, + { + "type":"Feature", + "properties":{ + "stroke":"#555555", + "stroke-width":2, + "stroke-opacity":1, + "fill":"#ff0000", + "fill-opacity":0.5, + "combine":"yes" + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [ + 0.23620605468749623, + -0.8901516807502449 + ], + [ + 0.23620605468749623, + 0.10986321392741416 + ], + [ + 1.2362060546874962, + 0.10986321392741416 + ], + [ + 1.2362060546874962, + -0.8901516807502449 + ], + [ + 0.23620605468749623, + -0.8901516807502449 + ] + ] + ] + } + }, + { + "type":"Feature", + "properties":{ + "stroke":"#555555", + "stroke-width":2, + "stroke-opacity":1, + "fill":"#00ff00", + "fill-opacity":0.5, + "combine":"no" + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [ + 1, + -1 + ], + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 2, + -1 + ], + [ + 1, + -1 + ] + ] + ] + } + }, + { + "type":"Feature", + "properties":{ + "stroke":"#555555", + "stroke-width":2, + "stroke-opacity":1, + "fill":"#00ff00", + "fill-opacity":0.5, + "combine":"no" + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [ + 0.851440429687502, + -1.647722051796948 + ], + [ + 0.851440429687502, + 1.4500404973607692 + ], + [ + 1.516113281250002, + 1.4500404973607692 + ], + [ + 1.516113281250002, + -1.647722051796948 + ], + [ + 0.851440429687502, + -1.647722051796948 + ] + ] + ] + } + }, + { + "type":"Feature", + "properties":{ + "stroke":"#555555", + "stroke-width":2, + "stroke-opacity":1, + "fill":"#ffff00", + "fill-opacity":0.5 + }, + "geometry":{ + "type":"Polygon", + "coordinates":[ + [ + [ + -0.252685546875, + 1.252341676699629 + ], + [ + -0.252685546875, + 1.653212936926045 + ], + [ + 0.28564453125, + 1.653212936926045 + ], + [ + 0.28564453125, + 1.252341676699629 + ], + [ + -0.252685546875, + 1.252341676699629 + ] + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/packages/turf-dissolve/test/in/polysWithoutProperty.geojson b/src/dissolve/test/in/polysWithoutProperty.geojson similarity index 100% rename from packages/turf-dissolve/test/in/polysWithoutProperty.geojson rename to src/dissolve/test/in/polysWithoutProperty.geojson diff --git a/src/dissolve/test/out/hexagons-issue#742.geojson b/src/dissolve/test/out/hexagons-issue#742.geojson new file mode 100644 index 0000000000..e17321f243 --- /dev/null +++ b/src/dissolve/test/out/hexagons-issue#742.geojson @@ -0,0 +1,8985 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -76.715, + 45.481 + ], + [ + -76.711, + 45.475 + ], + [ + -76.7068947368421, + 45.47408771929825 + ], + [ + -76.706, + 45.472 + ], + [ + -76.69830909090909, + 45.470290909090906 + ], + [ + -76.697, + 45.468 + ], + [ + -76.69163157894737, + 45.46680701754386 + ], + [ + -76.69, + 45.463 + ], + [ + -76.68491304347826, + 45.46186956521739 + ], + [ + -76.681, + 45.456 + ], + [ + -76.672, + 45.454 + ], + [ + -76.663, + 45.456 + ], + [ + -76.659, + 45.462 + ], + [ + -76.6606, + 45.4648 + ], + [ + -76.65799999999996, + 45.46566666666668 + ], + [ + -76.652, + 45.467 + ], + [ + -76.64964705882352, + 45.471117647058826 + ], + [ + -76.644, + 45.473 + ], + [ + -76.64, + 45.479 + ], + [ + -76.644, + 45.485 + ], + [ + -76.653, + 45.488 + ], + [ + -76.662, + 45.485 + ], + [ + -76.66400000000002, + 45.482 + ], + [ + -76.666, + 45.48133333333333 + ], + [ + -76.672, + 45.48 + ], + [ + -76.67392, + 45.476639999999996 + ], + [ + -76.67542857142858, + 45.47714285714286 + ], + [ + -76.678, + 45.481 + ], + [ + -76.68639999999999, + 45.4838 + ], + [ + -76.687, + 45.485 + ], + [ + -76.6921724137931, + 45.48655172413793 + ], + [ + -76.693, + 45.488 + ], + [ + -76.702, + 45.49 + ], + [ + -76.711, + 45.488 + ], + [ + -76.715, + 45.481 + ] + ] + ], + [ + [ + [ + -76.711, + 45.578 + ], + [ + -76.707, + 45.571 + ], + [ + -76.698, + 45.569 + ], + [ + -76.689, + 45.571 + ], + [ + -76.685, + 45.578 + ], + [ + -76.689, + 45.584 + ], + [ + -76.698, + 45.587 + ], + [ + -76.707, + 45.584 + ], + [ + -76.711, + 45.578 + ] + ] + ], + [ + [ + [ + -76.523, + 45.439 + ], + [ + -76.519, + 45.432 + ], + [ + -76.51, + 45.43 + ], + [ + -76.501, + 45.432 + ], + [ + -76.497, + 45.439 + ], + [ + -76.501, + 45.445 + ], + [ + -76.51, + 45.448 + ], + [ + -76.519, + 45.445 + ], + [ + -76.523, + 45.439 + ] + ] + ], + [ + [ + [ + -76.507, + 45.6 + ], + [ + -76.503, + 45.594 + ], + [ + -76.50085714285714, + 45.59328571428571 + ], + [ + -76.5, + 45.592 + ], + [ + -76.49523529411765, + 45.590411764705884 + ], + [ + -76.495, + 45.59 + ], + [ + -76.49200000000002, + 45.58933333333334 + ], + [ + -76.491, + 45.589 + ], + [ + -76.4908, + 45.58906666666667 + ], + [ + -76.486, + 45.588 + ], + [ + -76.477, + 45.59 + ], + [ + -76.473, + 45.597 + ], + [ + -76.477, + 45.603 + ], + [ + -76.48176470588236, + 45.60458823529412 + ], + [ + -76.482, + 45.605 + ], + [ + -76.48481249999999, + 45.605624999999996 + ], + [ + -76.485, + 45.606 + ], + [ + -76.494, + 45.609 + ], + [ + -76.503, + 45.606 + ], + [ + -76.507, + 45.6 + ] + ] + ], + [ + [ + [ + -76.504, + 45.355 + ], + [ + -76.5, + 45.349 + ], + [ + -76.491, + 45.346 + ], + [ + -76.482, + 45.349 + ], + [ + -76.478, + 45.355 + ], + [ + -76.482, + 45.361 + ], + [ + -76.491, + 45.364 + ], + [ + -76.5, + 45.361 + ], + [ + -76.504, + 45.355 + ] + ] + ], + [ + [ + [ + -76.413, + 45.459 + ], + [ + -76.409, + 45.453 + ], + [ + -76.4, + 45.45 + ], + [ + -76.391, + 45.453 + ], + [ + -76.387, + 45.459 + ], + [ + -76.391, + 45.466 + ], + [ + -76.4, + 45.468 + ], + [ + -76.409, + 45.466 + ], + [ + -76.413, + 45.459 + ] + ] + ], + [ + [ + [ + -76.39, + 45.419 + ], + [ + -76.387, + 45.412 + ], + [ + -76.381, + 45.410666666666664 + ], + [ + -76.376, + 45.409 + ], + [ + -76.367, + 45.412 + ], + [ + -76.36471428571429, + 45.41542857142857 + ], + [ + -76.36, + 45.417 + ], + [ + -76.35857142857142, + 45.41914285714286 + ], + [ + -76.356, + 45.42 + ], + [ + -76.353, + 45.426 + ], + [ + -76.35331249999999, + 45.426624999999994 + ], + [ + -76.34899999999996, + 45.42566666666665 + ], + [ + -76.34657142857144, + 45.42485714285714 + ], + [ + -76.346, + 45.424 + ], + [ + -76.337, + 45.421 + ], + [ + -76.328, + 45.424 + ], + [ + -76.324, + 45.43 + ], + [ + -76.328, + 45.437 + ], + [ + -76.33405454545455, + 45.438345454545455 + ], + [ + -76.335, + 45.44 + ], + [ + -76.34100000000004, + 45.44133333333334 + ], + [ + -76.346, + 45.443 + ], + [ + -76.355, + 45.44 + ], + [ + -76.359, + 45.434 + ], + [ + -76.35829411764706, + 45.432764705882356 + ], + [ + -76.365, + 45.435 + ], + [ + -76.374, + 45.432 + ], + [ + -76.37457142857143, + 45.43114285714285 + ], + [ + -76.378, + 45.43 + ], + [ + -76.3797142857143, + 45.427428571428564 + ], + [ + -76.387, + 45.425 + ], + [ + -76.39, + 45.419 + ] + ] + ], + [ + [ + [ + -76.369, + 45.011 + ], + [ + -76.366, + 45.004 + ], + [ + -76.357, + 45.002 + ], + [ + -76.348, + 45.004 + ], + [ + -76.344, + 45.011 + ], + [ + -76.348, + 45.017 + ], + [ + -76.357, + 45.02 + ], + [ + -76.366, + 45.017 + ], + [ + -76.369, + 45.011 + ] + ] + ], + [ + [ + [ + -76.339, + 45.192 + ], + [ + -76.335, + 45.186 + ], + [ + -76.326, + 45.183 + ], + [ + -76.317, + 45.186 + ], + [ + -76.314, + 45.192 + ], + [ + -76.317, + 45.198 + ], + [ + -76.326, + 45.201 + ], + [ + -76.335, + 45.198 + ], + [ + -76.339, + 45.192 + ] + ] + ], + [ + [ + [ + -76.303, + 45.333 + ], + [ + -76.3, + 45.327 + ], + [ + -76.291, + 45.324 + ], + [ + -76.282, + 45.327 + ], + [ + -76.278, + 45.333 + ], + [ + -76.27828571428572, + 45.3335 + ], + [ + -76.278, + 45.334 + ], + [ + -76.282, + 45.34 + ], + [ + -76.291, + 45.343 + ], + [ + -76.3, + 45.34 + ], + [ + -76.303, + 45.334 + ], + [ + -76.3027857142857, + 45.3335 + ], + [ + -76.303, + 45.333 + ] + ] + ], + [ + [ + [ + -76.295, + 45.408 + ], + [ + -76.292, + 45.402 + ], + [ + -76.283, + 45.399 + ], + [ + -76.273, + 45.402 + ], + [ + -76.27, + 45.408 + ], + [ + -76.273, + 45.415 + ], + [ + -76.283, + 45.417 + ], + [ + -76.292, + 45.415 + ], + [ + -76.295, + 45.408 + ] + ] + ], + [ + [ + [ + -76.277, + 44.911 + ], + [ + -76.273, + 44.904 + ], + [ + -76.2667, + 44.9026 + ], + [ + -76.267, + 44.902 + ], + [ + -76.264, + 44.895 + ], + [ + -76.258, + 44.89366666666667 + ], + [ + -76.253, + 44.892 + ], + [ + -76.25, + 44.886 + ], + [ + -76.241, + 44.883 + ], + [ + -76.232, + 44.886 + ], + [ + -76.228, + 44.892 + ], + [ + -76.232, + 44.899 + ], + [ + -76.24012903225805, + 44.90080645161291 + ], + [ + -76.24, + 44.901 + ], + [ + -76.244, + 44.907 + ], + [ + -76.24571428571427, + 44.90757142857142 + ], + [ + -76.246, + 44.908 + ], + [ + -76.25164000000001, + 44.90988 + ], + [ + -76.251, + 44.911 + ], + [ + -76.255, + 44.917 + ], + [ + -76.264, + 44.92 + ], + [ + -76.273, + 44.917 + ], + [ + -76.277, + 44.911 + ] + ] + ], + [ + [ + [ + -76.262, + 45.06 + ], + [ + -76.258, + 45.054 + ], + [ + -76.249, + 45.051 + ], + [ + -76.24, + 45.054 + ], + [ + -76.236, + 45.06 + ], + [ + -76.24, + 45.067 + ], + [ + -76.249, + 45.069 + ], + [ + -76.258, + 45.067 + ], + [ + -76.262, + 45.06 + ] + ] + ], + [ + [ + [ + -76.243, + 45.521 + ], + [ + -76.239, + 45.514 + ], + [ + -76.23, + 45.512 + ], + [ + -76.221, + 45.514 + ], + [ + -76.217, + 45.521 + ], + [ + -76.221, + 45.527 + ], + [ + -76.23, + 45.53 + ], + [ + -76.239, + 45.527 + ], + [ + -76.243, + 45.521 + ] + ] + ], + [ + [ + [ + -76.241, + 45.239 + ], + [ + -76.237, + 45.233 + ], + [ + -76.228, + 45.23 + ], + [ + -76.219, + 45.233 + ], + [ + -76.216, + 45.239 + ], + [ + -76.219, + 45.246 + ], + [ + -76.228, + 45.248 + ], + [ + -76.237, + 45.246 + ], + [ + -76.241, + 45.239 + ] + ] + ], + [ + [ + [ + -76.217, + 45.221 + ], + [ + -76.214, + 45.214 + ], + [ + -76.205, + 45.212 + ], + [ + -76.19717391304349, + 45.21373913043478 + ], + [ + -76.201, + 45.208 + ], + [ + -76.197, + 45.201 + ], + [ + -76.188, + 45.199 + ], + [ + -76.179, + 45.201 + ], + [ + -76.175, + 45.208 + ], + [ + -76.179, + 45.214 + ], + [ + -76.188, + 45.217 + ], + [ + -76.19576470588235, + 45.214411764705886 + ], + [ + -76.19435294117646, + 45.21688235294118 + ], + [ + -76.188, + 45.219 + ], + [ + -76.184, + 45.225 + ], + [ + -76.18422535211268, + 45.225394366197186 + ], + [ + -76.177, + 45.227 + ], + [ + -76.17605454545455, + 45.228654545454546 + ], + [ + -76.17, + 45.23 + ], + [ + -76.167, + 45.237 + ], + [ + -76.17, + 45.243 + ], + [ + -76.179, + 45.246 + ], + [ + -76.188, + 45.243 + ], + [ + -76.18857142857144, + 45.24214285714286 + ], + [ + -76.195, + 45.24 + ], + [ + -76.198, + 45.234 + ], + [ + -76.19791304347825, + 45.23379710144928 + ], + [ + -76.206, + 45.232 + ], + [ + -76.20764705882353, + 45.22911764705882 + ], + [ + -76.214, + 45.227 + ], + [ + -76.217, + 45.221 + ] + ] + ], + [ + [ + [ + -76.201, + 45.392 + ], + [ + -76.198, + 45.385 + ], + [ + -76.188, + 45.383 + ], + [ + -76.179, + 45.385 + ], + [ + -76.176, + 45.392 + ], + [ + -76.179, + 45.398 + ], + [ + -76.188, + 45.401 + ], + [ + -76.198, + 45.398 + ], + [ + -76.201, + 45.392 + ] + ] + ], + [ + [ + [ + -76.155, + 45.137 + ], + [ + -76.152, + 45.131 + ], + [ + -76.143, + 45.128 + ], + [ + -76.142, + 45.12833333333333 + ], + [ + -76.141, + 45.128 + ], + [ + -76.135875, + 45.12970833333333 + ], + [ + -76.133, + 45.123 + ], + [ + -76.124, + 45.121 + ], + [ + -76.115, + 45.123 + ], + [ + -76.11358823529412, + 45.12547058823529 + ], + [ + -76.112, + 45.126 + ], + [ + -76.108, + 45.132 + ], + [ + -76.112, + 45.139 + ], + [ + -76.1151304347826, + 45.13969565217391 + ], + [ + -76.115, + 45.14 + ], + [ + -76.118, + 45.146 + ], + [ + -76.127, + 45.149 + ], + [ + -76.13, + 45.147999999999996 + ], + [ + -76.129, + 45.15 + ], + [ + -76.132, + 45.157 + ], + [ + -76.141, + 45.159 + ], + [ + -76.15, + 45.157 + ], + [ + -76.154, + 45.15 + ], + [ + -76.15, + 45.144 + ], + [ + -76.1495, + 45.14383333333333 + ], + [ + -76.152, + 45.143 + ], + [ + -76.155, + 45.137 + ] + ] + ], + [ + [ + [ + -76.154, + 44.849 + ], + [ + -76.15, + 44.843 + ], + [ + -76.141, + 44.84 + ], + [ + -76.132, + 44.843 + ], + [ + -76.129, + 44.849 + ], + [ + -76.132, + 44.856 + ], + [ + -76.141, + 44.858 + ], + [ + -76.15, + 44.856 + ], + [ + -76.154, + 44.849 + ] + ] + ], + [ + [ + [ + -76.118, + 45.107 + ], + [ + -76.115, + 45.1 + ], + [ + -76.106, + 45.098 + ], + [ + -76.097, + 45.1 + ], + [ + -76.093, + 45.107 + ], + [ + -76.097, + 45.113 + ], + [ + -76.106, + 45.116 + ], + [ + -76.115, + 45.113 + ], + [ + -76.118, + 45.107 + ] + ] + ], + [ + [ + [ + -76.087, + 45.463 + ], + [ + -76.084, + 45.456 + ], + [ + -76.075, + 45.454 + ], + [ + -76.066, + 45.456 + ], + [ + -76.062, + 45.463 + ], + [ + -76.066, + 45.469 + ], + [ + -76.075, + 45.472 + ], + [ + -76.084, + 45.469 + ], + [ + -76.087, + 45.463 + ] + ] + ], + [ + [ + [ + -76.086, + 45.486 + ], + [ + -76.083, + 45.48 + ], + [ + -76.074, + 45.477 + ], + [ + -76.065, + 45.48 + ], + [ + -76.061, + 45.486 + ], + [ + -76.065, + 45.493 + ], + [ + -76.074, + 45.495 + ], + [ + -76.083, + 45.493 + ], + [ + -76.086, + 45.486 + ] + ] + ], + [ + [ + [ + -76.072, + 45.039 + ], + [ + -76.068, + 45.033 + ], + [ + -76.059, + 45.03 + ], + [ + -76.05, + 45.033 + ], + [ + -76.047, + 45.039 + ], + [ + -76.05, + 45.045 + ], + [ + -76.059, + 45.048 + ], + [ + -76.068, + 45.045 + ], + [ + -76.072, + 45.039 + ] + ] + ], + [ + [ + [ + -76.063, + 45.318 + ], + [ + -76.059, + 45.311 + ], + [ + -76.05, + 45.309 + ], + [ + -76.041, + 45.311 + ], + [ + -76.037, + 45.318 + ], + [ + -76.041, + 45.324 + ], + [ + -76.05, + 45.327 + ], + [ + -76.059, + 45.324 + ], + [ + -76.063, + 45.318 + ] + ] + ], + [ + [ + [ + -76.046, + 44.889 + ], + [ + -76.042, + 44.883 + ], + [ + -76.033, + 44.88 + ], + [ + -76.02780000000001, + 44.88173333333334 + ], + [ + -76.02, + 44.88 + ], + [ + -76.011, + 44.882 + ], + [ + -76.007, + 44.889 + ], + [ + -76.0104193548387, + 44.894129032258064 + ], + [ + -76.002, + 44.896 + ], + [ + -75.999, + 44.903 + ], + [ + -76.002, + 44.909 + ], + [ + -76.00870588235294, + 44.911235294117645 + ], + [ + -76.012, + 44.917 + ], + [ + -76.021, + 44.919 + ], + [ + -76.03, + 44.917 + ], + [ + -76.03123943661971, + 44.91483098591549 + ], + [ + -76.032, + 44.915 + ], + [ + -76.041, + 44.913 + ], + [ + -76.045, + 44.906 + ], + [ + -76.041, + 44.9 + ], + [ + -76.038, + 44.899 + ], + [ + -76.04028571428572, + 44.89557142857144 + ], + [ + -76.042, + 44.895 + ], + [ + -76.046, + 44.889 + ] + ] + ], + [ + [ + [ + -76.033, + 45.539 + ], + [ + -76.03, + 45.532 + ], + [ + -76.021, + 45.53 + ], + [ + -76.011, + 45.532 + ], + [ + -76.008, + 45.539 + ], + [ + -76.011, + 45.545 + ], + [ + -76.021, + 45.548 + ], + [ + -76.03, + 45.545 + ], + [ + -76.033, + 45.539 + ] + ] + ], + [ + [ + [ + -75.982, + 45.383 + ], + [ + -75.979, + 45.377 + ], + [ + -75.969, + 45.374 + ], + [ + -75.96, + 45.377 + ], + [ + -75.957, + 45.383 + ], + [ + -75.96, + 45.389 + ], + [ + -75.969, + 45.392 + ], + [ + -75.979, + 45.389 + ], + [ + -75.982, + 45.383 + ] + ] + ], + [ + [ + [ + -75.968, + 45.279 + ], + [ + -75.9652, + 45.2748 + ], + [ + -75.964, + 45.272 + ], + [ + -75.96023636363635, + 45.27116363636364 + ], + [ + -75.959, + 45.269 + ], + [ + -75.95039130434782, + 45.26708695652174 + ], + [ + -75.947, + 45.262 + ], + [ + -75.938, + 45.259 + ], + [ + -75.929, + 45.262 + ], + [ + -75.92757142857143, + 45.26414285714285 + ], + [ + -75.922, + 45.266 + ], + [ + -75.92085714285714, + 45.26771428571429 + ], + [ + -75.914, + 45.27 + ], + [ + -75.91356521739131, + 45.27065217391304 + ], + [ + -75.912, + 45.271 + ], + [ + -75.908, + 45.278 + ], + [ + -75.912, + 45.284 + ], + [ + -75.921, + 45.287 + ], + [ + -75.93, + 45.284 + ], + [ + -75.9304347826087, + 45.28334782608695 + ], + [ + -75.932, + 45.283 + ], + [ + -75.93216666666667, + 45.2826111111111 + ], + [ + -75.934, + 45.282 + ], + [ + -75.93530434782609, + 45.28004347826087 + ], + [ + -75.93912903225807, + 45.2791935483871 + ], + [ + -75.941, + 45.282 + ], + [ + -75.94435294117646, + 45.28311764705882 + ], + [ + -75.946, + 45.286 + ], + [ + -75.955, + 45.288 + ], + [ + -75.964, + 45.286 + ], + [ + -75.968, + 45.279 + ] + ] + ], + [ + [ + [ + -75.964, + 45.37 + ], + [ + -75.96, + 45.363 + ], + [ + -75.951, + 45.361 + ], + [ + -75.942, + 45.363 + ], + [ + -75.938, + 45.37 + ], + [ + -75.942, + 45.376 + ], + [ + -75.951, + 45.379 + ], + [ + -75.96, + 45.376 + ], + [ + -75.964, + 45.37 + ] + ] + ], + [ + [ + [ + -75.95, + 44.835 + ], + [ + -75.947, + 44.828 + ], + [ + -75.938, + 44.826 + ], + [ + -75.929, + 44.828 + ], + [ + -75.925, + 44.835 + ], + [ + -75.929, + 44.841 + ], + [ + -75.938, + 44.844 + ], + [ + -75.947, + 44.841 + ], + [ + -75.95, + 44.835 + ] + ] + ], + [ + [ + [ + -75.944, + 45.683 + ], + [ + -75.94, + 45.676 + ], + [ + -75.931, + 45.674 + ], + [ + -75.922, + 45.676 + ], + [ + -75.918, + 45.683 + ], + [ + -75.922, + 45.689 + ], + [ + -75.931, + 45.692 + ], + [ + -75.94, + 45.689 + ], + [ + -75.944, + 45.683 + ] + ] + ], + [ + [ + [ + -75.941, + 45.294 + ], + [ + -75.937, + 45.288 + ], + [ + -75.928, + 45.285 + ], + [ + -75.919, + 45.288 + ], + [ + -75.915, + 45.294 + ], + [ + -75.91829411764705, + 45.29976470588235 + ], + [ + -75.916, + 45.299 + ], + [ + -75.91257142857143, + 45.30014285714285 + ], + [ + -75.914, + 45.298 + ], + [ + -75.91, + 45.291 + ], + [ + -75.90700000000004, + 45.29033333333334 + ], + [ + -75.9, + 45.288 + ], + [ + -75.895, + 45.28966666666666 + ], + [ + -75.89, + 45.288 + ], + [ + -75.88268, + 45.29044 + ], + [ + -75.88161538461539, + 45.288576923076924 + ], + [ + -75.882, + 45.288 + ], + [ + -75.878, + 45.282 + ], + [ + -75.869, + 45.279 + ], + [ + -75.86, + 45.282 + ], + [ + -75.856, + 45.288 + ], + [ + -75.858, + 45.291 + ], + [ + -75.861, + 45.297 + ], + [ + -75.86772, + 45.29924 + ], + [ + -75.865, + 45.304 + ], + [ + -75.8685, + 45.30925 + ], + [ + -75.868, + 45.31 + ], + [ + -75.87, + 45.313 + ], + [ + -75.874, + 45.32 + ], + [ + -75.883, + 45.322 + ], + [ + -75.892, + 45.32 + ], + [ + -75.895, + 45.313 + ], + [ + -75.892, + 45.307 + ], + [ + -75.8914, + 45.3068 + ], + [ + -75.89085714285714, + 45.30571428571428 + ], + [ + -75.89399999999996, + 45.304666666666655 + ], + [ + -75.901, + 45.307 + ], + [ + -75.90442857142857, + 45.30585714285715 + ], + [ + -75.903, + 45.308 + ], + [ + -75.907, + 45.315 + ], + [ + -75.90880000000001, + 45.3156 + ], + [ + -75.909, + 45.316 + ], + [ + -75.918, + 45.319 + ], + [ + -75.927, + 45.316 + ], + [ + -75.931, + 45.31 + ], + [ + -75.927, + 45.304 + ], + [ + -75.92594117647059, + 45.30364705882353 + ], + [ + -75.92521818181818, + 45.302381818181814 + ], + [ + -75.928, + 45.303 + ], + [ + -75.937, + 45.301 + ], + [ + -75.941, + 45.294 + ] + ] + ], + [ + [ + [ + -75.94, + 45.351 + ], + [ + -75.936, + 45.345 + ], + [ + -75.92952000000001, + 45.342839999999995 + ], + [ + -75.93, + 45.342 + ], + [ + -75.926, + 45.336 + ], + [ + -75.92211764705883, + 45.33470588235294 + ], + [ + -75.92, + 45.331 + ], + [ + -75.911, + 45.329 + ], + [ + -75.902, + 45.331 + ], + [ + -75.899, + 45.338 + ], + [ + -75.902, + 45.344 + ], + [ + -75.90588235294118, + 45.34529411764706 + ], + [ + -75.908, + 45.349 + ], + [ + -75.91438709677419, + 45.35041935483871 + ], + [ + -75.914, + 45.351 + ], + [ + -75.918, + 45.357 + ], + [ + -75.927, + 45.36 + ], + [ + -75.936, + 45.357 + ], + [ + -75.94, + 45.351 + ] + ] + ], + [ + [ + [ + -75.929, + 45.254 + ], + [ + -75.926, + 45.248 + ], + [ + -75.916, + 45.245 + ], + [ + -75.907, + 45.248 + ], + [ + -75.904, + 45.254 + ], + [ + -75.907, + 45.261 + ], + [ + -75.916, + 45.263 + ], + [ + -75.926, + 45.261 + ], + [ + -75.929, + 45.254 + ] + ] + ], + [ + [ + [ + -75.87, + 45.409 + ], + [ + -75.866, + 45.402 + ], + [ + -75.86498591549295, + 45.40177464788732 + ], + [ + -75.866, + 45.4 + ], + [ + -75.862, + 45.394 + ], + [ + -75.853, + 45.391 + ], + [ + -75.84590909090909, + 45.39336363636364 + ], + [ + -75.843, + 45.389 + ], + [ + -75.834, + 45.386 + ], + [ + -75.8305, + 45.38716666666667 + ], + [ + -75.83, + 45.387 + ], + [ + -75.821, + 45.39 + ], + [ + -75.817, + 45.396 + ], + [ + -75.821, + 45.402 + ], + [ + -75.83, + 45.405 + ], + [ + -75.826, + 45.411 + ], + [ + -75.83, + 45.417 + ], + [ + -75.839, + 45.42 + ], + [ + -75.848, + 45.417 + ], + [ + -75.84885714285714, + 45.415285714285716 + ], + [ + -75.857, + 45.418 + ], + [ + -75.866, + 45.415 + ], + [ + -75.87, + 45.409 + ] + ], + [ + [ + -75.84164705882353, + 45.40288235294118 + ], + [ + -75.8406, + 45.40253333333333 + ], + [ + -75.84135211267605, + 45.4023661971831 + ], + [ + -75.84164705882353, + 45.40288235294118 + ] + ] + ], + [ + [ + [ + -75.854, + 45.193 + ], + [ + -75.85, + 45.187 + ], + [ + -75.841, + 45.184 + ], + [ + -75.832, + 45.187 + ], + [ + -75.82860869565218, + 45.192086956521734 + ], + [ + -75.82, + 45.194 + ], + [ + -75.81873684210525, + 45.19694736842105 + ], + [ + -75.814, + 45.198 + ], + [ + -75.81, + 45.205 + ], + [ + -75.814, + 45.211 + ], + [ + -75.823, + 45.214 + ], + [ + -75.832, + 45.211 + ], + [ + -75.83371428571428, + 45.20842857142857 + ], + [ + -75.838, + 45.207 + ], + [ + -75.84142857142858, + 45.201857142857136 + ], + [ + -75.85, + 45.199 + ], + [ + -75.854, + 45.193 + ] + ] + ], + [ + [ + [ + -75.851, + 45.281 + ], + [ + -75.847, + 45.275 + ], + [ + -75.838, + 45.272 + ], + [ + -75.829, + 45.275 + ], + [ + -75.825, + 45.281 + ], + [ + -75.829, + 45.288 + ], + [ + -75.838, + 45.29 + ], + [ + -75.847, + 45.288 + ], + [ + -75.851, + 45.281 + ] + ] + ], + [ + [ + [ + -75.849, + 44.915 + ], + [ + -75.845, + 44.908 + ], + [ + -75.836, + 44.906 + ], + [ + -75.827, + 44.908 + ], + [ + -75.824, + 44.915 + ], + [ + -75.827, + 44.921 + ], + [ + -75.836, + 44.924 + ], + [ + -75.845, + 44.921 + ], + [ + -75.849, + 44.915 + ] + ] + ], + [ + [ + [ + -75.849, + 45.321 + ], + [ + -75.845, + 45.315 + ], + [ + -75.836, + 45.312 + ], + [ + -75.821, + 45.317 + ], + [ + -75.82042857142856, + 45.31785714285714 + ], + [ + -75.811, + 45.321 + ], + [ + -75.807, + 45.327 + ], + [ + -75.811, + 45.334 + ], + [ + -75.82, + 45.336 + ], + [ + -75.8205, + 45.33588888888889 + ], + [ + -75.821, + 45.336 + ], + [ + -75.83, + 45.334 + ], + [ + -75.83094117647059, + 45.332352941176474 + ], + [ + -75.832, + 45.332 + ], + [ + -75.83234782608695, + 45.33147826086957 + ], + [ + -75.839, + 45.33 + ], + [ + -75.83931578947369, + 45.32926315789474 + ], + [ + -75.845, + 45.328 + ], + [ + -75.849, + 45.321 + ] + ] + ], + [ + [ + [ + -75.848, + 45.352 + ], + [ + -75.845, + 45.346 + ], + [ + -75.836, + 45.343 + ], + [ + -75.826, + 45.346 + ], + [ + -75.823, + 45.352 + ], + [ + -75.826, + 45.359 + ], + [ + -75.836, + 45.361 + ], + [ + -75.845, + 45.359 + ], + [ + -75.848, + 45.352 + ] + ] + ], + [ + [ + [ + -75.828, + 45.442 + ], + [ + -75.824, + 45.436 + ], + [ + -75.815, + 45.433 + ], + [ + -75.806, + 45.436 + ], + [ + -75.803, + 45.442 + ], + [ + -75.806, + 45.449 + ], + [ + -75.815, + 45.451 + ], + [ + -75.824, + 45.449 + ], + [ + -75.828, + 45.442 + ] + ] + ], + [ + [ + [ + -75.823, + 45.503 + ], + [ + -75.82, + 45.497 + ], + [ + -75.811, + 45.494 + ], + [ + -75.801, + 45.497 + ], + [ + -75.798, + 45.503 + ], + [ + -75.801, + 45.51 + ], + [ + -75.811, + 45.512 + ], + [ + -75.82, + 45.51 + ], + [ + -75.823, + 45.503 + ] + ] + ], + [ + [ + [ + -75.822, + 45.354 + ], + [ + -75.818, + 45.347 + ], + [ + -75.809, + 45.345 + ], + [ + -75.80038028169014, + 45.34691549295775 + ], + [ + -75.799, + 45.344500000000004 + ], + [ + -75.801, + 45.341 + ], + [ + -75.797, + 45.335 + ], + [ + -75.788, + 45.332 + ], + [ + -75.779, + 45.335 + ], + [ + -75.77871428571429, + 45.33542857142857 + ], + [ + -75.777, + 45.336 + ], + [ + -75.77558064516128, + 45.33812903225807 + ], + [ + -75.775, + 45.338 + ], + [ + -75.76714084507043, + 45.339746478873245 + ], + [ + -75.765, + 45.336 + ], + [ + -75.76398591549295, + 45.33577464788733 + ], + [ + -75.765, + 45.334 + ], + [ + -75.761, + 45.328 + ], + [ + -75.752, + 45.325 + ], + [ + -75.743, + 45.328 + ], + [ + -75.739, + 45.334 + ], + [ + -75.743, + 45.341 + ], + [ + -75.74469565217392, + 45.3413768115942 + ], + [ + -75.744, + 45.343 + ], + [ + -75.747, + 45.349 + ], + [ + -75.756, + 45.352 + ], + [ + -75.76363636363637, + 45.34945454545454 + ], + [ + -75.766, + 45.353 + ], + [ + -75.775, + 45.356 + ], + [ + -75.78020000000001, + 45.35426666666667 + ], + [ + -75.7835, + 45.355 + ], + [ + -75.779, + 45.356 + ], + [ + -75.77629577464789, + 45.360732394366195 + ], + [ + -75.773, + 45.36 + ], + [ + -75.764, + 45.362 + ], + [ + -75.76067605633803, + 45.367816901408446 + ], + [ + -75.757, + 45.367 + ], + [ + -75.75474999999999, + 45.3675 + ], + [ + -75.74901408450704, + 45.36622535211268 + ], + [ + -75.752, + 45.361 + ], + [ + -75.74823076923077, + 45.35534615384615 + ], + [ + -75.749, + 45.354 + ], + [ + -75.745, + 45.348 + ], + [ + -75.743, + 45.344 + ], + [ + -75.74175, + 45.343583333333335 + ], + [ + -75.742, + 45.343 + ], + [ + -75.739, + 45.337 + ], + [ + -75.735625, + 45.335875 + ], + [ + -75.736, + 45.335 + ], + [ + -75.73371428571429, + 45.33042857142856 + ], + [ + -75.734, + 45.33 + ], + [ + -75.73261538461539, + 45.327576923076926 + ], + [ + -75.733, + 45.327 + ], + [ + -75.729, + 45.321 + ], + [ + -75.72, + 45.318 + ], + [ + -75.711, + 45.321 + ], + [ + -75.70751612903226, + 45.32622580645161 + ], + [ + -75.702, + 45.325 + ], + [ + -75.698, + 45.32588888888889 + ], + [ + -75.694, + 45.325 + ], + [ + -75.685, + 45.327 + ], + [ + -75.681, + 45.334 + ], + [ + -75.68227272727272, + 45.33590909090909 + ], + [ + -75.682, + 45.336 + ], + [ + -75.68016666666666, + 45.33875 + ], + [ + -75.679, + 45.337 + ], + [ + -75.67, + 45.334 + ], + [ + -75.661, + 45.337 + ], + [ + -75.657, + 45.343 + ], + [ + -75.65966666666667, + 45.347 + ], + [ + -75.657, + 45.351 + ], + [ + -75.655, + 45.348 + ], + [ + -75.646, + 45.345 + ], + [ + -75.6448, + 45.3454 + ], + [ + -75.643, + 45.345 + ], + [ + -75.6425, + 45.34511111111111 + ], + [ + -75.642, + 45.345 + ], + [ + -75.63677419354839, + 45.346161290322584 + ], + [ + -75.634, + 45.342 + ], + [ + -75.625, + 45.339 + ], + [ + -75.616, + 45.342 + ], + [ + -75.612, + 45.348 + ], + [ + -75.616, + 45.354 + ], + [ + -75.6195, + 45.35516666666666 + ], + [ + -75.611, + 45.358 + ], + [ + -75.607, + 45.364 + ], + [ + -75.611, + 45.371 + ], + [ + -75.61274193548387, + 45.37138709677419 + ], + [ + -75.611, + 45.374 + ], + [ + -75.615, + 45.38 + ], + [ + -75.6165, + 45.380500000000005 + ], + [ + -75.61390909090909, + 45.38136363636364 + ], + [ + -75.611, + 45.377 + ], + [ + -75.60909090909091, + 45.376363636363635 + ], + [ + -75.61, + 45.375 + ], + [ + -75.606, + 45.368 + ], + [ + -75.597, + 45.366 + ], + [ + -75.588, + 45.368 + ], + [ + -75.584, + 45.375 + ], + [ + -75.588, + 45.381 + ], + [ + -75.58990909090909, + 45.38163636363637 + ], + [ + -75.589, + 45.383 + ], + [ + -75.593, + 45.389 + ], + [ + -75.602, + 45.392 + ], + [ + -75.60671428571428, + 45.39042857142857 + ], + [ + -75.609, + 45.395 + ], + [ + -75.60906122448979, + 45.39514285714287 + ], + [ + -75.608, + 45.397 + ], + [ + -75.61018181818181, + 45.40027272727273 + ], + [ + -75.608, + 45.401 + ], + [ + -75.60495652173913, + 45.405565217391306 + ], + [ + -75.603, + 45.406 + ], + [ + -75.60252941176469, + 45.40682352941177 + ], + [ + -75.596, + 45.409 + ], + [ + -75.59527272727273, + 45.410090909090904 + ], + [ + -75.595, + 45.41 + ], + [ + -75.586, + 45.413 + ], + [ + -75.582, + 45.419 + ], + [ + -75.586, + 45.425 + ], + [ + -75.58666666666667, + 45.42522222222222 + ], + [ + -75.587, + 45.426 + ], + [ + -75.59300000000003, + 45.42733333333334 + ], + [ + -75.595, + 45.428 + ], + [ + -75.5954, + 45.42786666666667 + ], + [ + -75.596, + 45.428 + ], + [ + -75.605, + 45.426 + ], + [ + -75.60520000000001, + 45.42593333333333 + ], + [ + -75.60640000000001, + 45.4262 + ], + [ + -75.604, + 45.427 + ], + [ + -75.60371428571429, + 45.427428571428564 + ], + [ + -75.596, + 45.43 + ], + [ + -75.592, + 45.436 + ], + [ + -75.59374647887324, + 45.439056338028166 + ], + [ + -75.5886, + 45.4402 + ], + [ + -75.588, + 45.44 + ], + [ + -75.579, + 45.443 + ], + [ + -75.575, + 45.449 + ], + [ + -75.579, + 45.456 + ], + [ + -75.588, + 45.458 + ], + [ + -75.5934, + 45.4568 + ], + [ + -75.594, + 45.457 + ], + [ + -75.5945, + 45.456833333333336 + ], + [ + -75.595, + 45.457 + ], + [ + -75.604, + 45.454 + ], + [ + -75.608, + 45.448 + ], + [ + -75.60624, + 45.444919999999996 + ], + [ + -75.60799999999998, + 45.44433333333334 + ], + [ + -75.614, + 45.443 + ], + [ + -75.61433333333333, + 45.44222222222222 + ], + [ + -75.615, + 45.442 + ], + [ + -75.61524999999999, + 45.4415 + ], + [ + -75.61965217391305, + 45.44052173913043 + ], + [ + -75.616, + 45.446 + ], + [ + -75.62, + 45.453 + ], + [ + -75.629, + 45.455 + ], + [ + -75.638, + 45.453 + ], + [ + -75.6388, + 45.4516 + ], + [ + -75.64, + 45.452 + ], + [ + -75.64084000000001, + 45.451719999999995 + ], + [ + -75.641, + 45.452 + ], + [ + -75.65, + 45.454 + ], + [ + -75.659, + 45.452 + ], + [ + -75.66030434782608, + 45.448956521739134 + ], + [ + -75.661, + 45.45 + ], + [ + -75.67, + 45.452 + ], + [ + -75.679, + 45.45 + ], + [ + -75.68091304347827, + 45.44713043478261 + ], + [ + -75.686, + 45.446 + ], + [ + -75.689, + 45.439 + ], + [ + -75.68857142857142, + 45.43814285714286 + ], + [ + -75.689, + 45.438 + ], + [ + -75.68979999999999, + 45.436400000000006 + ], + [ + -75.694, + 45.435 + ], + [ + -75.698, + 45.429 + ], + [ + -75.69683636363636, + 45.42696363636363 + ], + [ + -75.697, + 45.427 + ], + [ + -75.706, + 45.425 + ], + [ + -75.70952941176469, + 45.41882352941177 + ], + [ + -75.715, + 45.417 + ], + [ + -75.719, + 45.411 + ], + [ + -75.7166923076923, + 45.407538461538465 + ], + [ + -75.717, + 45.407 + ], + [ + -75.7159090909091, + 45.40536363636364 + ], + [ + -75.717, + 45.405 + ], + [ + -75.721, + 45.412 + ], + [ + -75.73, + 45.414 + ], + [ + -75.739, + 45.412 + ], + [ + -75.7424909090909, + 45.40589090909091 + ], + [ + -75.751, + 45.404 + ], + [ + -75.75136363636365, + 45.403363636363636 + ], + [ + -75.753, + 45.403 + ], + [ + -75.75370588235293, + 45.40176470588236 + ], + [ + -75.762, + 45.399 + ], + [ + -75.766, + 45.393 + ], + [ + -75.762, + 45.386 + ], + [ + -75.758, + 45.385111111111115 + ], + [ + -75.763, + 45.384 + ], + [ + -75.76321818181819, + 45.383618181818186 + ], + [ + -75.766, + 45.383 + ], + [ + -75.76952, + 45.37684 + ], + [ + -75.773, + 45.378 + ], + [ + -75.77449999999999, + 45.377500000000005 + ], + [ + -75.782, + 45.38 + ], + [ + -75.791, + 45.377 + ], + [ + -75.79265217391304, + 45.37452173913044 + ], + [ + -75.795, + 45.374 + ], + [ + -75.799, + 45.367 + ], + [ + -75.79866666666668, + 45.366499999999995 + ], + [ + -75.801, + 45.363 + ], + [ + -75.797, + 45.356 + ], + [ + -75.79249999999999, + 45.355 + ], + [ + -75.79612903225807, + 45.354193548387094 + ], + [ + -75.8, + 45.36 + ], + [ + -75.809, + 45.363 + ], + [ + -75.818, + 45.36 + ], + [ + -75.822, + 45.354 + ] + ], + [ + [ + -75.74034375, + 45.38853125 + ], + [ + -75.74033333333333, + 45.388555555555556 + ], + [ + -75.738, + 45.38933333333333 + ], + [ + -75.735, + 45.39 + ], + [ + -75.73493548387097, + 45.390096774193545 + ], + [ + -75.73378947368421, + 45.389842105263156 + ], + [ + -75.74034375, + 45.38853125 + ] + ], + [ + [ + -75.7371090909091, + 45.37130909090909 + ], + [ + -75.73617073170732, + 45.372951219512196 + ], + [ + -75.733, + 45.372 + ], + [ + -75.724, + 45.375 + ], + [ + -75.721, + 45.381 + ], + [ + -75.724, + 45.388 + ], + [ + -75.72925000000001, + 45.38916666666667 + ], + [ + -75.721, + 45.391 + ], + [ + -75.71904081632653, + 45.39557142857143 + ], + [ + -75.717, + 45.392 + ], + [ + -75.708, + 45.39 + ], + [ + -75.699, + 45.392 + ], + [ + -75.69674545454545, + 45.395945454545455 + ], + [ + -75.692, + 45.397 + ], + [ + -75.68938181818181, + 45.40158181818182 + ], + [ + -75.683, + 45.403 + ], + [ + -75.68, + 45.41 + ], + [ + -75.683, + 45.416 + ], + [ + -75.68385714285714, + 45.416285714285706 + ], + [ + -75.6845, + 45.417249999999996 + ], + [ + -75.684, + 45.418 + ], + [ + -75.68516363636364, + 45.42003636363636 + ], + [ + -75.685, + 45.42 + ], + [ + -75.676, + 45.422 + ], + [ + -75.67510526315789, + 45.42408771929825 + ], + [ + -75.6722, + 45.424733333333336 + ], + [ + -75.67, + 45.424 + ], + [ + -75.669, + 45.42433333333333 + ], + [ + -75.668, + 45.424 + ], + [ + -75.65972000000001, + 45.42676 + ], + [ + -75.657, + 45.422 + ], + [ + -75.648, + 45.42 + ], + [ + -75.64683870967743, + 45.420258064516126 + ], + [ + -75.646, + 45.419 + ], + [ + -75.645, + 45.41866666666667 + ], + [ + -75.65, + 45.417 + ], + [ + -75.654, + 45.411 + ], + [ + -75.65, + 45.405 + ], + [ + -75.641, + 45.402 + ], + [ + -75.63854545454546, + 45.40281818181818 + ], + [ + -75.636, + 45.399 + ], + [ + -75.63327272727273, + 45.39809090909091 + ], + [ + -75.634, + 45.397 + ], + [ + -75.63342857142857, + 45.396 + ], + [ + -75.634, + 45.395 + ], + [ + -75.63181818181818, + 45.39172727272727 + ], + [ + -75.64, + 45.389 + ], + [ + -75.649, + 45.387 + ], + [ + -75.652, + 45.38 + ], + [ + -75.649, + 45.374 + ], + [ + -75.64, + 45.371 + ], + [ + -75.6359090909091, + 45.37236363636364 + ], + [ + -75.63335294117647, + 45.368529411764705 + ], + [ + -75.641, + 45.367 + ], + [ + -75.64273913043479, + 45.36294202898551 + ], + [ + -75.643, + 45.363 + ], + [ + -75.6448, + 45.3626 + ], + [ + -75.646, + 45.363 + ], + [ + -75.655, + 45.36 + ], + [ + -75.659, + 45.354 + ], + [ + -75.661, + 45.357 + ], + [ + -75.67, + 45.36 + ], + [ + -75.679, + 45.357 + ], + [ + -75.683, + 45.351 + ], + [ + -75.68033333333334, + 45.347 + ], + [ + -75.6806153846154, + 45.346576923076924 + ], + [ + -75.682, + 45.349 + ], + [ + -75.691, + 45.351 + ], + [ + -75.69373913043478, + 45.35039130434782 + ], + [ + -75.692, + 45.353 + ], + [ + -75.696, + 45.36 + ], + [ + -75.69884210526315, + 45.36063157894737 + ], + [ + -75.692, + 45.362 + ], + [ + -75.689, + 45.369 + ], + [ + -75.692, + 45.375 + ], + [ + -75.69424137931034, + 45.375672413793104 + ], + [ + -75.695, + 45.377 + ], + [ + -75.704, + 45.379 + ], + [ + -75.713, + 45.377 + ], + [ + -75.717, + 45.37 + ], + [ + -75.713, + 45.364 + ], + [ + -75.71166666666666, + 45.36355555555556 + ], + [ + -75.711, + 45.362 + ], + [ + -75.708, + 45.361333333333334 + ], + [ + -75.714, + 45.36 + ], + [ + -75.717, + 45.353 + ], + [ + -75.714, + 45.347 + ], + [ + -75.71244, + 45.34648 + ], + [ + -75.71342253521127, + 45.344760563380284 + ], + [ + -75.71867272727272, + 45.34592727272727 + ], + [ + -75.72315384615385, + 45.35376923076923 + ], + [ + -75.723, + 45.354 + ], + [ + -75.72330769230769, + 45.35453846153846 + ], + [ + -75.723, + 45.355 + ], + [ + -75.72466666666666, + 45.3575 + ], + [ + -75.721, + 45.363 + ], + [ + -75.725, + 45.37 + ], + [ + -75.734, + 45.372 + ], + [ + -75.7371090909091, + 45.37130909090909 + ] + ], + [ + [ + -75.63419999999999, + 45.43593333333334 + ], + [ + -75.631, + 45.437 + ], + [ + -75.63071428571429, + 45.437571428571424 + ], + [ + -75.629, + 45.437 + ], + [ + -75.62233333333333, + 45.43922222222222 + ], + [ + -75.62482608695652, + 45.43340579710145 + ], + [ + -75.629, + 45.43433333333334 + ], + [ + -75.62976470588235, + 45.43458823529412 + ], + [ + -75.63, + 45.435 + ], + [ + -75.63419999999999, + 45.43593333333334 + ] + ] + ], + [ + [ + [ + -75.822, + 45.413 + ], + [ + -75.818, + 45.406 + ], + [ + -75.809, + 45.404 + ], + [ + -75.8, + 45.406 + ], + [ + -75.796, + 45.413 + ], + [ + -75.79633333333334, + 45.4135 + ], + [ + -75.796, + 45.414 + ], + [ + -75.79626666666667, + 45.41446666666666 + ], + [ + -75.795, + 45.417 + ], + [ + -75.798, + 45.423 + ], + [ + -75.807, + 45.426 + ], + [ + -75.817, + 45.423 + ], + [ + -75.818, + 45.421 + ], + [ + -75.822, + 45.414 + ], + [ + -75.82166666666667, + 45.4135 + ], + [ + -75.822, + 45.413 + ] + ] + ], + [ + [ + [ + -75.821, + 45.386 + ], + [ + -75.817, + 45.38 + ], + [ + -75.808, + 45.377 + ], + [ + -75.8075, + 45.37716666666667 + ], + [ + -75.807, + 45.377 + ], + [ + -75.798, + 45.38 + ], + [ + -75.795, + 45.386 + ], + [ + -75.798, + 45.392 + ], + [ + -75.807, + 45.395 + ], + [ + -75.8075, + 45.39483333333334 + ], + [ + -75.808, + 45.395 + ], + [ + -75.817, + 45.392 + ], + [ + -75.821, + 45.386 + ] + ] + ], + [ + [ + [ + -75.815, + 45.269 + ], + [ + -75.811, + 45.263 + ], + [ + -75.802, + 45.26 + ], + [ + -75.793, + 45.263 + ], + [ + -75.79265217391304, + 45.26352173913044 + ], + [ + -75.792, + 45.262 + ], + [ + -75.782, + 45.26 + ], + [ + -75.773, + 45.262 + ], + [ + -75.77, + 45.269 + ], + [ + -75.773, + 45.275 + ], + [ + -75.782, + 45.278 + ], + [ + -75.792, + 45.275 + ], + [ + -75.79220000000001, + 45.2746 + ], + [ + -75.793, + 45.276 + ], + [ + -75.802, + 45.278 + ], + [ + -75.811, + 45.276 + ], + [ + -75.815, + 45.269 + ] + ] + ], + [ + [ + [ + -75.799, + 45.444 + ], + [ + -75.795, + 45.437 + ], + [ + -75.786, + 45.435 + ], + [ + -75.77863636363637, + 45.43663636363636 + ], + [ + -75.779, + 45.436 + ], + [ + -75.77553846153846, + 45.43080769230769 + ], + [ + -75.776, + 45.43 + ], + [ + -75.77, + 45.421 + ], + [ + -75.761, + 45.418 + ], + [ + -75.75718181818182, + 45.41927272727273 + ], + [ + -75.755, + 45.416 + ], + [ + -75.746, + 45.413 + ], + [ + -75.737, + 45.416 + ], + [ + -75.733, + 45.422 + ], + [ + -75.73328571428573, + 45.422428571428576 + ], + [ + -75.726, + 45.42 + ], + [ + -75.717, + 45.423 + ], + [ + -75.71534782608695, + 45.42547826086957 + ], + [ + -75.713, + 45.426 + ], + [ + -75.709, + 45.433 + ], + [ + -75.71190909090909, + 45.437363636363635 + ], + [ + -75.704, + 45.44 + ], + [ + -75.7, + 45.446 + ], + [ + -75.704, + 45.453 + ], + [ + -75.713, + 45.455 + ], + [ + -75.722, + 45.453 + ], + [ + -75.7225, + 45.452125 + ], + [ + -75.723, + 45.453 + ], + [ + -75.72398181818181, + 45.45321818181819 + ], + [ + -75.725, + 45.455 + ], + [ + -75.72964516129032, + 45.45603225806451 + ], + [ + -75.729, + 45.457 + ], + [ + -75.72935714285714, + 45.45762499999999 + ], + [ + -75.728, + 45.46 + ], + [ + -75.72927272727273, + 45.461909090909096 + ], + [ + -75.729, + 45.462 + ], + [ + -75.725, + 45.468 + ], + [ + -75.7251690140845, + 45.468295774647885 + ], + [ + -75.722, + 45.469 + ], + [ + -75.71969230769231, + 45.47303846153846 + ], + [ + -75.717, + 45.469 + ], + [ + -75.71281690140844, + 45.46807042253521 + ], + [ + -75.714, + 45.466 + ], + [ + -75.71192307692307, + 45.46288461538462 + ], + [ + -75.713, + 45.461 + ], + [ + -75.709, + 45.455 + ], + [ + -75.7, + 45.452 + ], + [ + -75.693, + 45.45433333333333 + ], + [ + -75.69, + 45.455 + ], + [ + -75.6882, + 45.4592 + ], + [ + -75.687, + 45.461 + ], + [ + -75.68724489795918, + 45.46142857142857 + ], + [ + -75.687, + 45.462 + ], + [ + -75.68857142857142, + 45.46514285714286 + ], + [ + -75.688, + 45.466 + ], + [ + -75.69173333333333, + 45.47253333333333 + ], + [ + -75.689, + 45.478 + ], + [ + -75.68985714285714, + 45.479714285714294 + ], + [ + -75.68954545454545, + 45.48018181818182 + ], + [ + -75.689, + 45.48 + ], + [ + -75.68709090909091, + 45.48063636363636 + ], + [ + -75.684, + 45.476 + ], + [ + -75.675, + 45.473 + ], + [ + -75.666, + 45.476 + ], + [ + -75.66587096774194, + 45.476193548387094 + ], + [ + -75.665, + 45.476 + ], + [ + -75.6584, + 45.47746666666667 + ], + [ + -75.651, + 45.475 + ], + [ + -75.648, + 45.476 + ], + [ + -75.645, + 45.475 + ], + [ + -75.642, + 45.476 + ], + [ + -75.639, + 45.475 + ], + [ + -75.63, + 45.478 + ], + [ + -75.626, + 45.484 + ], + [ + -75.62969230769231, + 45.490461538461545 + ], + [ + -75.628, + 45.493 + ], + [ + -75.63092307692308, + 45.49811538461538 + ], + [ + -75.629, + 45.501 + ], + [ + -75.633, + 45.508 + ], + [ + -75.642, + 45.51 + ], + [ + -75.651, + 45.508 + ], + [ + -75.655, + 45.501 + ], + [ + -75.65442857142857, + 45.500142857142855 + ], + [ + -75.657, + 45.501 + ], + [ + -75.66557142857144, + 45.49814285714285 + ], + [ + -75.663, + 45.502 + ], + [ + -75.66392307692307, + 45.50361538461539 + ], + [ + -75.663, + 45.505 + ], + [ + -75.667, + 45.512 + ], + [ + -75.676, + 45.514 + ], + [ + -75.685, + 45.512 + ], + [ + -75.689, + 45.505 + ], + [ + -75.68807692307692, + 45.50361538461539 + ], + [ + -75.689, + 45.502 + ], + [ + -75.68586956521739, + 45.49730434782609 + ], + [ + -75.689, + 45.498 + ], + [ + -75.698, + 45.496 + ], + [ + -75.70128571428572, + 45.490249999999996 + ], + [ + -75.704, + 45.495 + ], + [ + -75.713, + 45.497 + ], + [ + -75.7148, + 45.4966 + ], + [ + -75.719, + 45.498 + ], + [ + -75.72, + 45.49766666666667 + ], + [ + -75.724, + 45.499 + ], + [ + -75.733, + 45.496 + ], + [ + -75.73557142857143, + 45.492142857142866 + ], + [ + -75.737, + 45.495 + ], + [ + -75.747, + 45.498 + ], + [ + -75.756, + 45.495 + ], + [ + -75.76, + 45.488 + ], + [ + -75.756, + 45.482 + ], + [ + -75.74915999999999, + 45.47972 + ], + [ + -75.753, + 45.473 + ], + [ + -75.75119354838709, + 45.470290322580645 + ], + [ + -75.757, + 45.469 + ], + [ + -75.75791836734695, + 45.46685714285715 + ], + [ + -75.758, + 45.467 + ], + [ + -75.76294366197183, + 45.4680985915493 + ], + [ + -75.759, + 45.475 + ], + [ + -75.763, + 45.481 + ], + [ + -75.772, + 45.484 + ], + [ + -75.781, + 45.481 + ], + [ + -75.785, + 45.475 + ], + [ + -75.781, + 45.468 + ], + [ + -75.77605633802817, + 45.4669014084507 + ], + [ + -75.78, + 45.46 + ], + [ + -75.776, + 45.454 + ], + [ + -75.767, + 45.451 + ], + [ + -75.76372727272727, + 45.452090909090906 + ], + [ + -75.761, + 45.448 + ], + [ + -75.7567142857143, + 45.44657142857143 + ], + [ + -75.753, + 45.441 + ], + [ + -75.744, + 45.438 + ], + [ + -75.74040000000001, + 45.4392 + ], + [ + -75.738, + 45.435 + ], + [ + -75.73538709677419, + 45.43441935483871 + ], + [ + -75.739, + 45.429 + ], + [ + -75.7387142857143, + 45.42857142857143 + ], + [ + -75.746, + 45.431 + ], + [ + -75.75028571428572, + 45.42957142857142 + ], + [ + -75.75, + 45.43 + ], + [ + -75.75323076923077, + 45.43565384615384 + ], + [ + -75.753, + 45.436 + ], + [ + -75.757, + 45.443 + ], + [ + -75.766, + 45.445 + ], + [ + -75.77336363636364, + 45.443363636363635 + ], + [ + -75.773, + 45.444 + ], + [ + -75.777, + 45.451 + ], + [ + -75.786, + 45.453 + ], + [ + -75.795, + 45.451 + ], + [ + -75.799, + 45.444 + ] + ], + [ + [ + -75.73649999999999, + 45.48316666666667 + ], + [ + -75.73519999999999, + 45.486200000000004 + ], + [ + -75.735, + 45.48649999999999 + ], + [ + -75.73364000000001, + 45.48412 + ], + [ + -75.73649999999999, + 45.48316666666667 + ] + ], + [ + [ + -75.72095652173913, + 45.48043478260869 + ], + [ + -75.719, + 45.48 + ], + [ + -75.71801818181818, + 45.48021818181818 + ], + [ + -75.7193076923077, + 45.477961538461535 + ], + [ + -75.72095652173913, + 45.48043478260869 + ] + ] + ], + [ + [ + [ + -75.795, + 45.571 + ], + [ + -75.792, + 45.564 + ], + [ + -75.783, + 45.562 + ], + [ + -75.774, + 45.564 + ], + [ + -75.77, + 45.571 + ], + [ + -75.774, + 45.577 + ], + [ + -75.783, + 45.58 + ], + [ + -75.792, + 45.577 + ], + [ + -75.795, + 45.571 + ] + ] + ], + [ + [ + [ + -75.79, + 45.324 + ], + [ + -75.787, + 45.317 + ], + [ + -75.777, + 45.315 + ], + [ + -75.768, + 45.317 + ], + [ + -75.765, + 45.324 + ], + [ + -75.768, + 45.33 + ], + [ + -75.777, + 45.333 + ], + [ + -75.787, + 45.33 + ], + [ + -75.79, + 45.324 + ] + ] + ], + [ + [ + [ + -75.77, + 45.287 + ], + [ + -75.766, + 45.281 + ], + [ + -75.76560869565218, + 45.28091304347826 + ], + [ + -75.765, + 45.28 + ], + [ + -75.7570909090909, + 45.27736363636364 + ], + [ + -75.75857142857143, + 45.27514285714285 + ], + [ + -75.759, + 45.275 + ], + [ + -75.763, + 45.269 + ], + [ + -75.759, + 45.262 + ], + [ + -75.75, + 45.26 + ], + [ + -75.741, + 45.262 + ], + [ + -75.73942105263158, + 45.26568421052632 + ], + [ + -75.729, + 45.268 + ], + [ + -75.72788, + 45.269960000000005 + ], + [ + -75.719, + 45.267 + ], + [ + -75.71168, + 45.26944 + ], + [ + -75.708, + 45.263 + ], + [ + -75.699, + 45.261 + ], + [ + -75.69, + 45.263 + ], + [ + -75.686, + 45.27 + ], + [ + -75.69, + 45.276 + ], + [ + -75.69879999999998, + 45.278933333333335 + ], + [ + -75.694, + 45.28 + ], + [ + -75.69, + 45.287 + ], + [ + -75.694, + 45.293 + ], + [ + -75.703, + 45.296 + ], + [ + -75.712, + 45.293 + ], + [ + -75.71366666666667, + 45.2905 + ], + [ + -75.714, + 45.291 + ], + [ + -75.71523529411765, + 45.29141176470588 + ], + [ + -75.719, + 45.298 + ], + [ + -75.723, + 45.304 + ], + [ + -75.732, + 45.307 + ], + [ + -75.741, + 45.304 + ], + [ + -75.744, + 45.298 + ], + [ + -75.74316666666667, + 45.296055555555554 + ], + [ + -75.752, + 45.299 + ], + [ + -75.761, + 45.296 + ], + [ + -75.76169565217391, + 45.29495652173913 + ], + [ + -75.766, + 45.294 + ], + [ + -75.77, + 45.287 + ] + ], + [ + [ + -75.74614285714286, + 45.28171428571428 + ], + [ + -75.7454, + 45.2832 + ], + [ + -75.743, + 45.284 + ], + [ + -75.73966666666666, + 45.289 + ], + [ + -75.737, + 45.285 + ], + [ + -75.73576470588236, + 45.284588235294116 + ], + [ + -75.73482352941177, + 45.28294117647059 + ], + [ + -75.738, + 45.284 + ], + [ + -75.74549999999999, + 45.281499999999994 + ], + [ + -75.74614285714286, + 45.28171428571428 + ] + ], + [ + [ + -75.70808695652174, + 45.27913043478261 + ], + [ + -75.703, + 45.278 + ], + [ + -75.7, + 45.27866666666666 + ], + [ + -75.70636363636363, + 45.276545454545456 + ], + [ + -75.70808695652174, + 45.27913043478261 + ] + ] + ], + [ + [ + [ + -75.743, + 45.675 + ], + [ + -75.739, + 45.668 + ], + [ + -75.73, + 45.666 + ], + [ + -75.721, + 45.668 + ], + [ + -75.717, + 45.675 + ], + [ + -75.71718181818181, + 45.67527272727273 + ], + [ + -75.715, + 45.676 + ], + [ + -75.711, + 45.682 + ], + [ + -75.715, + 45.689 + ], + [ + -75.724, + 45.691 + ], + [ + -75.733, + 45.689 + ], + [ + -75.737, + 45.682 + ], + [ + -75.73681818181818, + 45.68172727272727 + ], + [ + -75.739, + 45.681 + ], + [ + -75.743, + 45.675 + ] + ] + ], + [ + [ + [ + -75.725, + 45.24 + ], + [ + -75.722, + 45.234 + ], + [ + -75.713, + 45.231 + ], + [ + -75.704, + 45.234 + ], + [ + -75.7, + 45.24 + ], + [ + -75.704, + 45.247 + ], + [ + -75.713, + 45.249 + ], + [ + -75.722, + 45.247 + ], + [ + -75.725, + 45.24 + ] + ] + ], + [ + [ + [ + -75.724, + 45.128 + ], + [ + -75.72, + 45.121 + ], + [ + -75.711, + 45.119 + ], + [ + -75.702, + 45.121 + ], + [ + -75.699, + 45.128 + ], + [ + -75.702, + 45.134 + ], + [ + -75.711, + 45.137 + ], + [ + -75.72, + 45.134 + ], + [ + -75.724, + 45.128 + ] + ] + ], + [ + [ + [ + -75.724, + 45.789 + ], + [ + -75.72, + 45.783 + ], + [ + -75.711, + 45.78 + ], + [ + -75.702, + 45.783 + ], + [ + -75.698, + 45.789 + ], + [ + -75.702, + 45.795 + ], + [ + -75.711, + 45.798 + ], + [ + -75.72, + 45.795 + ], + [ + -75.724, + 45.789 + ] + ] + ], + [ + [ + [ + -75.691, + 44.966 + ], + [ + -75.688, + 44.959 + ], + [ + -75.679, + 44.957 + ], + [ + -75.67, + 44.959 + ], + [ + -75.666, + 44.966 + ], + [ + -75.67, + 44.972 + ], + [ + -75.679, + 44.975 + ], + [ + -75.688, + 44.972 + ], + [ + -75.691, + 44.966 + ] + ] + ], + [ + [ + [ + -75.69, + 45.389 + ], + [ + -75.686, + 45.382 + ], + [ + -75.68092727272727, + 45.380872727272724 + ], + [ + -75.68053846153846, + 45.380192307692305 + ], + [ + -75.682, + 45.378 + ], + [ + -75.678, + 45.372 + ], + [ + -75.67733333333334, + 45.37177777777778 + ], + [ + -75.677, + 45.371 + ], + [ + -75.67554838709677, + 45.37067741935484 + ], + [ + -75.676, + 45.37 + ], + [ + -75.672, + 45.364 + ], + [ + -75.663, + 45.361 + ], + [ + -75.654, + 45.364 + ], + [ + -75.65, + 45.37 + ], + [ + -75.654, + 45.376 + ], + [ + -75.65454545454546, + 45.37618181818181 + ], + [ + -75.654, + 45.377 + ], + [ + -75.65564285714285, + 45.379875000000006 + ], + [ + -75.655, + 45.381 + ], + [ + -75.659, + 45.387 + ], + [ + -75.66416000000001, + 45.38872 + ], + [ + -75.664, + 45.389 + ], + [ + -75.668, + 45.395 + ], + [ + -75.677, + 45.398 + ], + [ + -75.686, + 45.395 + ], + [ + -75.69, + 45.389 + ] + ] + ], + [ + [ + [ + -75.688, + 45.234 + ], + [ + -75.684, + 45.228 + ], + [ + -75.675, + 45.225 + ], + [ + -75.666, + 45.228 + ], + [ + -75.662, + 45.234 + ], + [ + -75.666, + 45.24 + ], + [ + -75.675, + 45.243 + ], + [ + -75.684, + 45.24 + ], + [ + -75.688, + 45.234 + ] + ] + ], + [ + [ + [ + -75.666, + 45.021 + ], + [ + -75.662, + 45.015 + ], + [ + -75.66094117647059, + 45.01464705882353 + ], + [ + -75.66, + 45.013 + ], + [ + -75.651, + 45.011 + ], + [ + -75.642, + 45.013 + ], + [ + -75.638, + 45.02 + ], + [ + -75.63825806451614, + 45.02038709677419 + ], + [ + -75.631, + 45.022 + ], + [ + -75.63078181818182, + 45.02238181818182 + ], + [ + -75.628, + 45.023 + ], + [ + -75.625, + 45.03 + ], + [ + -75.628, + 45.036 + ], + [ + -75.637, + 45.039 + ], + [ + -75.649, + 45.035 + ], + [ + -75.65157142857143, + 45.031142857142854 + ], + [ + -75.658, + 45.029 + ], + [ + -75.65857142857143, + 45.02814285714286 + ], + [ + -75.662, + 45.027 + ], + [ + -75.666, + 45.021 + ] + ] + ], + [ + [ + [ + -75.659, + 45.149 + ], + [ + -75.656, + 45.142 + ], + [ + -75.647, + 45.14 + ], + [ + -75.638, + 45.142 + ], + [ + -75.634, + 45.149 + ], + [ + -75.638, + 45.155 + ], + [ + -75.647, + 45.158 + ], + [ + -75.656, + 45.155 + ], + [ + -75.659, + 45.149 + ] + ] + ], + [ + [ + [ + -75.65, + 45.199 + ], + [ + -75.646, + 45.192 + ], + [ + -75.637, + 45.19 + ], + [ + -75.628, + 45.192 + ], + [ + -75.625, + 45.199 + ], + [ + -75.628, + 45.205 + ], + [ + -75.637, + 45.208 + ], + [ + -75.646, + 45.205 + ], + [ + -75.65, + 45.199 + ] + ] + ], + [ + [ + [ + -75.63, + 45.596 + ], + [ + -75.626, + 45.589 + ], + [ + -75.617, + 45.587 + ], + [ + -75.608, + 45.589 + ], + [ + -75.604, + 45.596 + ], + [ + -75.608, + 45.602 + ], + [ + -75.617, + 45.605 + ], + [ + -75.626, + 45.602 + ], + [ + -75.63, + 45.596 + ] + ] + ], + [ + [ + [ + -75.622, + 45.144 + ], + [ + -75.619, + 45.138 + ], + [ + -75.61, + 45.135 + ], + [ + -75.601, + 45.138 + ], + [ + -75.60073913043477, + 45.13839130434783 + ], + [ + -75.598, + 45.139 + ], + [ + -75.594, + 45.146 + ], + [ + -75.598, + 45.152 + ], + [ + -75.607, + 45.155 + ], + [ + -75.616, + 45.152 + ], + [ + -75.6161875, + 45.151625 + ], + [ + -75.619, + 45.151 + ], + [ + -75.622, + 45.144 + ] + ] + ], + [ + [ + [ + -75.622, + 45.507 + ], + [ + -75.618, + 45.501 + ], + [ + -75.609, + 45.498 + ], + [ + -75.6, + 45.501 + ], + [ + -75.596, + 45.507 + ], + [ + -75.6, + 45.513 + ], + [ + -75.609, + 45.516 + ], + [ + -75.618, + 45.513 + ], + [ + -75.622, + 45.507 + ] + ] + ], + [ + [ + [ + -75.616, + 45.487 + ], + [ + -75.612, + 45.481 + ], + [ + -75.603, + 45.478 + ], + [ + -75.594, + 45.481 + ], + [ + -75.59373913043478, + 45.481391304347824 + ], + [ + -75.591, + 45.482 + ], + [ + -75.587, + 45.488 + ], + [ + -75.591, + 45.495 + ], + [ + -75.6, + 45.497 + ], + [ + -75.6005, + 45.49688888888889 + ], + [ + -75.601, + 45.497 + ], + [ + -75.61, + 45.495 + ], + [ + -75.61094117647059, + 45.49335294117647 + ], + [ + -75.612, + 45.493 + ], + [ + -75.616, + 45.487 + ] + ] + ], + [ + [ + [ + -75.612, + 45.331 + ], + [ + -75.60942857142857, + 45.325857142857146 + ], + [ + -75.61, + 45.325 + ], + [ + -75.606, + 45.318 + ], + [ + -75.60505263157894, + 45.31778947368421 + ], + [ + -75.603, + 45.313 + ], + [ + -75.594, + 45.311 + ], + [ + -75.585, + 45.313 + ], + [ + -75.581, + 45.32 + ], + [ + -75.58361538461538, + 45.32392307692307 + ], + [ + -75.583, + 45.325 + ], + [ + -75.587, + 45.331 + ], + [ + -75.591, + 45.338 + ], + [ + -75.6, + 45.34 + ], + [ + -75.609, + 45.338 + ], + [ + -75.612, + 45.331 + ] + ] + ], + [ + [ + [ + -75.607, + 45.27 + ], + [ + -75.604, + 45.263 + ], + [ + -75.595, + 45.261 + ], + [ + -75.586, + 45.263 + ], + [ + -75.582, + 45.27 + ], + [ + -75.586, + 45.276 + ], + [ + -75.595, + 45.279 + ], + [ + -75.604, + 45.276 + ], + [ + -75.607, + 45.27 + ] + ] + ], + [ + [ + [ + -75.593, + 45.297 + ], + [ + -75.59, + 45.291 + ], + [ + -75.581, + 45.288 + ], + [ + -75.572, + 45.291 + ], + [ + -75.568, + 45.297 + ], + [ + -75.572, + 45.303 + ], + [ + -75.581, + 45.306 + ], + [ + -75.59, + 45.303 + ], + [ + -75.593, + 45.297 + ] + ] + ], + [ + [ + [ + -75.584, + 45.281 + ], + [ + -75.58, + 45.275 + ], + [ + -75.571, + 45.272 + ], + [ + -75.562, + 45.275 + ], + [ + -75.558, + 45.281 + ], + [ + -75.562, + 45.288 + ], + [ + -75.571, + 45.29 + ], + [ + -75.58, + 45.288 + ], + [ + -75.584, + 45.281 + ] + ] + ], + [ + [ + [ + -75.584, + 45.498 + ], + [ + -75.58, + 45.492 + ], + [ + -75.571, + 45.489 + ], + [ + -75.562, + 45.492 + ], + [ + -75.558, + 45.498 + ], + [ + -75.562, + 45.505 + ], + [ + -75.571, + 45.507 + ], + [ + -75.58, + 45.505 + ], + [ + -75.584, + 45.498 + ] + ] + ], + [ + [ + [ + -75.577, + 45.432 + ], + [ + -75.573, + 45.425 + ], + [ + -75.564, + 45.423 + ], + [ + -75.555, + 45.425 + ], + [ + -75.551, + 45.432 + ], + [ + -75.555, + 45.438 + ], + [ + -75.564, + 45.441 + ], + [ + -75.573, + 45.438 + ], + [ + -75.577, + 45.432 + ] + ] + ], + [ + [ + [ + -75.561, + 45.462 + ], + [ + -75.558, + 45.455 + ], + [ + -75.548, + 45.453 + ], + [ + -75.54575, + 45.453500000000005 + ], + [ + -75.548, + 45.449 + ], + [ + -75.545, + 45.442 + ], + [ + -75.536, + 45.44 + ], + [ + -75.5342, + 45.4404 + ], + [ + -75.527, + 45.438 + ], + [ + -75.518, + 45.441 + ], + [ + -75.51527272727273, + 45.44509090909091 + ], + [ + -75.512, + 45.444 + ], + [ + -75.509, + 45.445 + ], + [ + -75.5, + 45.447 + ], + [ + -75.49952941176471, + 45.44782352941176 + ], + [ + -75.496, + 45.449 + ], + [ + -75.49582608695651, + 45.449260869565215 + ], + [ + -75.49439130434783, + 45.449579710144924 + ], + [ + -75.492, + 45.444 + ], + [ + -75.483, + 45.442 + ], + [ + -75.474, + 45.444 + ], + [ + -75.47, + 45.451 + ], + [ + -75.474, + 45.457 + ], + [ + -75.47657142857142, + 45.45785714285714 + ], + [ + -75.475, + 45.461 + ], + [ + -75.478, + 45.468 + ], + [ + -75.47865454545455, + 45.46814545454546 + ], + [ + -75.482, + 45.474 + ], + [ + -75.48500000000001, + 45.47466666666667 + ], + [ + -75.492, + 45.477 + ], + [ + -75.501, + 45.474 + ], + [ + -75.504, + 45.468 + ], + [ + -75.50373333333334, + 45.46746666666667 + ], + [ + -75.504, + 45.467 + ], + [ + -75.50272727272727, + 45.465090909090904 + ], + [ + -75.506, + 45.464 + ], + [ + -75.506125, + 45.46375 + ], + [ + -75.514, + 45.462 + ], + [ + -75.51447058823528, + 45.46117647058824 + ], + [ + -75.521, + 45.459 + ], + [ + -75.52372727272727, + 45.4549090909091 + ], + [ + -75.527, + 45.456 + ], + [ + -75.52850000000001, + 45.4555 + ], + [ + -75.5322, + 45.45673333333333 + ], + [ + -75.531, + 45.457 + ], + [ + -75.53066666666668, + 45.45777777777777 + ], + [ + -75.53, + 45.458 + ], + [ + -75.52947826086957, + 45.45878260869566 + ], + [ + -75.524, + 45.46 + ], + [ + -75.52268421052632, + 45.463070175438595 + ], + [ + -75.514, + 45.465 + ], + [ + -75.51211764705883, + 45.46829411764706 + ], + [ + -75.507, + 45.47 + ], + [ + -75.5065294117647, + 45.47094117647059 + ], + [ + -75.503, + 45.472 + ], + [ + -75.5, + 45.478 + ], + [ + -75.503, + 45.485 + ], + [ + -75.513, + 45.487 + ], + [ + -75.522, + 45.485 + ], + [ + -75.52288524590165, + 45.482934426229505 + ], + [ + -75.526, + 45.482 + ], + [ + -75.52615384615385, + 45.4816923076923 + ], + [ + -75.528, + 45.486 + ], + [ + -75.537, + 45.488 + ], + [ + -75.547, + 45.486 + ], + [ + -75.55, + 45.479 + ], + [ + -75.547, + 45.473 + ], + [ + -75.54359574468084, + 45.471978723404256 + ], + [ + -75.548, + 45.471 + ], + [ + -75.558, + 45.468 + ], + [ + -75.561, + 45.462 + ] + ] + ], + [ + [ + [ + -75.558, + 44.843 + ], + [ + -75.554, + 44.836 + ], + [ + -75.545, + 44.834 + ], + [ + -75.536, + 44.836 + ], + [ + -75.532, + 44.843 + ], + [ + -75.536, + 44.849 + ], + [ + -75.545, + 44.852 + ], + [ + -75.554, + 44.849 + ], + [ + -75.558, + 44.843 + ] + ] + ], + [ + [ + [ + -75.538, + 45.342 + ], + [ + -75.534, + 45.336 + ], + [ + -75.525, + 45.333 + ], + [ + -75.516, + 45.336 + ], + [ + -75.512, + 45.342 + ], + [ + -75.516, + 45.349 + ], + [ + -75.525, + 45.351 + ], + [ + -75.534, + 45.349 + ], + [ + -75.538, + 45.342 + ] + ] + ], + [ + [ + [ + -75.531, + 45.241 + ], + [ + -75.527, + 45.235 + ], + [ + -75.518, + 45.232 + ], + [ + -75.509, + 45.235 + ], + [ + -75.505, + 45.241 + ], + [ + -75.509, + 45.248 + ], + [ + -75.518, + 45.25 + ], + [ + -75.527, + 45.248 + ], + [ + -75.531, + 45.241 + ] + ] + ], + [ + [ + [ + -75.509, + 45.228 + ], + [ + -75.505, + 45.221 + ], + [ + -75.496, + 45.219 + ], + [ + -75.487, + 45.221 + ], + [ + -75.483, + 45.228 + ], + [ + -75.487, + 45.234 + ], + [ + -75.496, + 45.237 + ], + [ + -75.505, + 45.234 + ], + [ + -75.509, + 45.228 + ] + ] + ], + [ + [ + [ + -75.509, + 45.53 + ], + [ + -75.506, + 45.524 + ], + [ + -75.497, + 45.521 + ], + [ + -75.487, + 45.524 + ], + [ + -75.484, + 45.53 + ], + [ + -75.487, + 45.537 + ], + [ + -75.497, + 45.539 + ], + [ + -75.506, + 45.537 + ], + [ + -75.509, + 45.53 + ] + ] + ], + [ + [ + [ + -75.494, + 45.492 + ], + [ + -75.49, + 45.486 + ], + [ + -75.48957142857144, + 45.48585714285714 + ], + [ + -75.489, + 45.485 + ], + [ + -75.48, + 45.482 + ], + [ + -75.471, + 45.485 + ], + [ + -75.467, + 45.491 + ], + [ + -75.471, + 45.497 + ], + [ + -75.47142857142856, + 45.497142857142855 + ], + [ + -75.472, + 45.498 + ], + [ + -75.481, + 45.501 + ], + [ + -75.49, + 45.498 + ], + [ + -75.494, + 45.492 + ] + ] + ], + [ + [ + [ + -75.474, + 45.16 + ], + [ + -75.47, + 45.153 + ], + [ + -75.461, + 45.151 + ], + [ + -75.452, + 45.153 + ], + [ + -75.448, + 45.16 + ], + [ + -75.452, + 45.166 + ], + [ + -75.461, + 45.169 + ], + [ + -75.47, + 45.166 + ], + [ + -75.474, + 45.16 + ] + ] + ], + [ + [ + [ + -75.471, + 44.986 + ], + [ + -75.467, + 44.98 + ], + [ + -75.458, + 44.977 + ], + [ + -75.449, + 44.98 + ], + [ + -75.445, + 44.986 + ], + [ + -75.449, + 44.992 + ], + [ + -75.458, + 44.995 + ], + [ + -75.467, + 44.992 + ], + [ + -75.471, + 44.986 + ] + ] + ], + [ + [ + [ + -75.468, + 45.369 + ], + [ + -75.464, + 45.363 + ], + [ + -75.455, + 45.36 + ], + [ + -75.446, + 45.363 + ], + [ + -75.443, + 45.369 + ], + [ + -75.446, + 45.375 + ], + [ + -75.455, + 45.378 + ], + [ + -75.464, + 45.375 + ], + [ + -75.468, + 45.369 + ] + ] + ], + [ + [ + [ + -75.467, + 45.471 + ], + [ + -75.463, + 45.465 + ], + [ + -75.454, + 45.462 + ], + [ + -75.445, + 45.465 + ], + [ + -75.441, + 45.471 + ], + [ + -75.445, + 45.477 + ], + [ + -75.454, + 45.48 + ], + [ + -75.463, + 45.477 + ], + [ + -75.467, + 45.471 + ] + ] + ], + [ + [ + [ + -75.456, + 45.345 + ], + [ + -75.453, + 45.339 + ], + [ + -75.45214285714286, + 45.33871428571428 + ], + [ + -75.449, + 45.334 + ], + [ + -75.44, + 45.331 + ], + [ + -75.431, + 45.334 + ], + [ + -75.427, + 45.34 + ], + [ + -75.431, + 45.346 + ], + [ + -75.43185714285714, + 45.34628571428571 + ], + [ + -75.435, + 45.351 + ], + [ + -75.444, + 45.354 + ], + [ + -75.453, + 45.351 + ], + [ + -75.456, + 45.345 + ] + ] + ], + [ + [ + [ + -75.449, + 45.554 + ], + [ + -75.445, + 45.548 + ], + [ + -75.441, + 45.54666666666667 + ], + [ + -75.443, + 45.542 + ], + [ + -75.44, + 45.536 + ], + [ + -75.431, + 45.533 + ], + [ + -75.421, + 45.536 + ], + [ + -75.418, + 45.542 + ], + [ + -75.42016666666667, + 45.54705555555555 + ], + [ + -75.42, + 45.547 + ], + [ + -75.411, + 45.55 + ], + [ + -75.407, + 45.556 + ], + [ + -75.411, + 45.562 + ], + [ + -75.41276470588235, + 45.562588235294115 + ], + [ + -75.413, + 45.563 + ], + [ + -75.41600000000003, + 45.56366666666668 + ], + [ + -75.41614285714286, + 45.56371428571429 + ], + [ + -75.419, + 45.568 + ], + [ + -75.428, + 45.571 + ], + [ + -75.437, + 45.568 + ], + [ + -75.441, + 45.562 + ], + [ + -75.44094366197183, + 45.5619014084507 + ], + [ + -75.445, + 45.561 + ], + [ + -75.449, + 45.554 + ] + ] + ], + [ + [ + [ + -75.443, + 45.254 + ], + [ + -75.439, + 45.248 + ], + [ + -75.43, + 45.245 + ], + [ + -75.421, + 45.248 + ], + [ + -75.417, + 45.254 + ], + [ + -75.421, + 45.261 + ], + [ + -75.43, + 45.263 + ], + [ + -75.439, + 45.261 + ], + [ + -75.443, + 45.254 + ] + ] + ], + [ + [ + [ + -75.436, + 45.421 + ], + [ + -75.432, + 45.415 + ], + [ + -75.423, + 45.412 + ], + [ + -75.414, + 45.415 + ], + [ + -75.41, + 45.421 + ], + [ + -75.414, + 45.428 + ], + [ + -75.423, + 45.43 + ], + [ + -75.432, + 45.428 + ], + [ + -75.436, + 45.421 + ] + ] + ], + [ + [ + [ + -75.434, + 45.586 + ], + [ + -75.43, + 45.58 + ], + [ + -75.42241176470588, + 45.57747058823529 + ], + [ + -75.421, + 45.575 + ], + [ + -75.41982608695652, + 45.574739130434786 + ], + [ + -75.416, + 45.569 + ], + [ + -75.407, + 45.566 + ], + [ + -75.4028, + 45.5674 + ], + [ + -75.401, + 45.567 + ], + [ + -75.391, + 45.569 + ], + [ + -75.388, + 45.576 + ], + [ + -75.391, + 45.582 + ], + [ + -75.401, + 45.585 + ], + [ + -75.403, + 45.588 + ], + [ + -75.41058823529413, + 45.590529411764706 + ], + [ + -75.412, + 45.593 + ], + [ + -75.421, + 45.595 + ], + [ + -75.43, + 45.593 + ], + [ + -75.434, + 45.586 + ] + ] + ], + [ + [ + [ + -75.425, + 44.918 + ], + [ + -75.421, + 44.911 + ], + [ + -75.412, + 44.909 + ], + [ + -75.403, + 44.911 + ], + [ + -75.399, + 44.918 + ], + [ + -75.403, + 44.924 + ], + [ + -75.412, + 44.927 + ], + [ + -75.421, + 44.924 + ], + [ + -75.425, + 44.918 + ] + ] + ], + [ + [ + [ + -75.424, + 45.518 + ], + [ + -75.42, + 45.511 + ], + [ + -75.41950909090909, + 45.51089090909091 + ], + [ + -75.419, + 45.51 + ], + [ + -75.41, + 45.508 + ], + [ + -75.401, + 45.51 + ], + [ + -75.397, + 45.517 + ], + [ + -75.401, + 45.523 + ], + [ + -75.40142857142858, + 45.523142857142865 + ], + [ + -75.402, + 45.524 + ], + [ + -75.411, + 45.527 + ], + [ + -75.42, + 45.524 + ], + [ + -75.424, + 45.518 + ] + ] + ], + [ + [ + [ + -75.39, + 45.088 + ], + [ + -75.386, + 45.082 + ], + [ + -75.377, + 45.079 + ], + [ + -75.368, + 45.082 + ], + [ + -75.365, + 45.088 + ], + [ + -75.368, + 45.095 + ], + [ + -75.377, + 45.097 + ], + [ + -75.386, + 45.095 + ], + [ + -75.39, + 45.088 + ] + ] + ], + [ + [ + [ + -75.372, + 44.94 + ], + [ + -75.369, + 44.933 + ], + [ + -75.36, + 44.931 + ], + [ + -75.351, + 44.933 + ], + [ + -75.347, + 44.94 + ], + [ + -75.351, + 44.946 + ], + [ + -75.36, + 44.949 + ], + [ + -75.369, + 44.946 + ], + [ + -75.372, + 44.94 + ] + ] + ], + [ + [ + [ + -75.372, + 45.258 + ], + [ + -75.368, + 45.252 + ], + [ + -75.359, + 45.249 + ], + [ + -75.35, + 45.252 + ], + [ + -75.346, + 45.258 + ], + [ + -75.35, + 45.264 + ], + [ + -75.359, + 45.267 + ], + [ + -75.368, + 45.264 + ], + [ + -75.372, + 45.258 + ] + ] + ], + [ + [ + [ + -75.359, + 45.331 + ], + [ + -75.356, + 45.325 + ], + [ + -75.3554705882353, + 45.32482352941177 + ], + [ + -75.355, + 45.324 + ], + [ + -75.34899999999996, + 45.322666666666656 + ], + [ + -75.347, + 45.322 + ], + [ + -75.3466, + 45.32213333333333 + ], + [ + -75.346, + 45.322 + ], + [ + -75.337, + 45.324 + ], + [ + -75.333, + 45.331 + ], + [ + -75.335, + 45.334 + ], + [ + -75.331, + 45.34 + ], + [ + -75.335, + 45.347 + ], + [ + -75.344, + 45.349 + ], + [ + -75.353, + 45.347 + ], + [ + -75.357, + 45.34 + ], + [ + -75.35570967741936, + 45.33806451612903 + ], + [ + -75.356, + 45.338 + ], + [ + -75.359, + 45.331 + ] + ] + ], + [ + [ + [ + -75.357, + 45.442 + ], + [ + -75.353, + 45.435 + ], + [ + -75.344, + 45.433 + ], + [ + -75.335, + 45.435 + ], + [ + -75.332, + 45.442 + ], + [ + -75.335, + 45.448 + ], + [ + -75.344, + 45.451 + ], + [ + -75.353, + 45.448 + ], + [ + -75.357, + 45.442 + ] + ] + ], + [ + [ + [ + -75.354, + 45.076 + ], + [ + -75.35, + 45.069 + ], + [ + -75.341, + 45.067 + ], + [ + -75.332, + 45.069 + ], + [ + -75.328, + 45.076 + ], + [ + -75.332, + 45.082 + ], + [ + -75.341, + 45.085 + ], + [ + -75.35, + 45.082 + ], + [ + -75.354, + 45.076 + ] + ] + ], + [ + [ + [ + -75.316, + 45.268 + ], + [ + -75.312, + 45.261 + ], + [ + -75.303, + 45.259 + ], + [ + -75.285, + 45.263 + ], + [ + -75.281, + 45.27 + ], + [ + -75.285, + 45.276 + ], + [ + -75.294, + 45.279 + ], + [ + -75.3015, + 45.2765 + ], + [ + -75.303, + 45.277 + ], + [ + -75.312, + 45.274 + ], + [ + -75.316, + 45.268 + ] + ] + ], + [ + [ + [ + -75.316, + 45.546 + ], + [ + -75.3133846153846, + 45.54207692307692 + ], + [ + -75.314, + 45.541 + ], + [ + -75.31, + 45.535 + ], + [ + -75.301, + 45.532 + ], + [ + -75.292, + 45.535 + ], + [ + -75.29, + 45.538000000000004 + ], + [ + -75.287, + 45.539 + ], + [ + -75.283, + 45.545 + ], + [ + -75.2846, + 45.5478 + ], + [ + -75.283, + 45.551 + ], + [ + -75.286, + 45.558 + ], + [ + -75.296, + 45.56 + ], + [ + -75.305, + 45.558 + ], + [ + -75.30663157894737, + 45.55419298245614 + ], + [ + -75.312, + 45.553 + ], + [ + -75.316, + 45.546 + ] + ] + ], + [ + [ + [ + -75.306, + 45.032 + ], + [ + -75.302, + 45.026 + ], + [ + -75.293, + 45.023 + ], + [ + -75.284, + 45.026 + ], + [ + -75.281, + 45.032 + ], + [ + -75.284, + 45.038 + ], + [ + -75.293, + 45.041 + ], + [ + -75.302, + 45.038 + ], + [ + -75.306, + 45.032 + ] + ] + ], + [ + [ + [ + -75.284, + 45.554 + ], + [ + -75.281, + 45.547 + ], + [ + -75.272, + 45.545 + ], + [ + -75.263, + 45.547 + ], + [ + -75.259, + 45.554 + ], + [ + -75.263, + 45.56 + ], + [ + -75.272, + 45.563 + ], + [ + -75.281, + 45.56 + ], + [ + -75.284, + 45.554 + ] + ] + ], + [ + [ + [ + -75.265, + 45.33 + ], + [ + -75.261, + 45.323 + ], + [ + -75.25491549295775, + 45.32164788732394 + ], + [ + -75.257, + 45.318 + ], + [ + -75.253, + 45.312 + ], + [ + -75.244, + 45.309 + ], + [ + -75.235, + 45.312 + ], + [ + -75.231, + 45.318 + ], + [ + -75.235, + 45.325 + ], + [ + -75.24108450704226, + 45.326352112676055 + ], + [ + -75.239, + 45.33 + ], + [ + -75.243, + 45.336 + ], + [ + -75.252, + 45.339 + ], + [ + -75.261, + 45.336 + ], + [ + -75.265, + 45.33 + ] + ] + ], + [ + [ + [ + -75.262, + 45.559 + ], + [ + -75.258, + 45.553 + ], + [ + -75.249, + 45.55 + ], + [ + -75.24, + 45.553 + ], + [ + -75.236, + 45.559 + ], + [ + -75.24, + 45.565 + ], + [ + -75.249, + 45.568 + ], + [ + -75.258, + 45.565 + ], + [ + -75.262, + 45.559 + ] + ] + ], + [ + [ + [ + -75.258, + 45.41 + ], + [ + -75.254, + 45.404 + ], + [ + -75.245, + 45.401 + ], + [ + -75.236, + 45.404 + ], + [ + -75.232, + 45.41 + ], + [ + -75.236, + 45.417 + ], + [ + -75.245, + 45.419 + ], + [ + -75.254, + 45.417 + ], + [ + -75.258, + 45.41 + ] + ] + ], + [ + [ + [ + -75.257, + 44.975 + ], + [ + -75.254, + 44.969 + ], + [ + -75.245, + 44.966 + ], + [ + -75.236, + 44.969 + ], + [ + -75.232, + 44.975 + ], + [ + -75.236, + 44.982 + ], + [ + -75.245, + 44.984 + ], + [ + -75.254, + 44.982 + ], + [ + -75.257, + 44.975 + ] + ] + ], + [ + [ + [ + -75.254, + 45.597 + ], + [ + -75.25, + 45.591 + ], + [ + -75.241, + 45.588 + ], + [ + -75.232, + 45.591 + ], + [ + -75.228, + 45.597 + ], + [ + -75.2282857142857, + 45.5975 + ], + [ + -75.228, + 45.598 + ], + [ + -75.232, + 45.604 + ], + [ + -75.241, + 45.607 + ], + [ + -75.25, + 45.604 + ], + [ + -75.254, + 45.598 + ], + [ + -75.2537142857143, + 45.5975 + ], + [ + -75.254, + 45.597 + ] + ] + ], + [ + [ + [ + -75.243, + 45.103 + ], + [ + -75.24184615384615, + 45.10126923076923 + ], + [ + -75.242, + 45.101 + ], + [ + -75.238, + 45.095 + ], + [ + -75.229, + 45.092 + ], + [ + -75.22, + 45.095 + ], + [ + -75.216, + 45.101 + ], + [ + -75.22, + 45.108 + ], + [ + -75.2205625, + 45.108125 + ], + [ + -75.221, + 45.109 + ], + [ + -75.23, + 45.112 + ], + [ + -75.239, + 45.109 + ], + [ + -75.243, + 45.103 + ] + ] + ], + [ + [ + [ + -75.242, + 45.29 + ], + [ + -75.238, + 45.284 + ], + [ + -75.229, + 45.281 + ], + [ + -75.22200000000001, + 45.283333333333324 + ], + [ + -75.219, + 45.284 + ], + [ + -75.21719999999999, + 45.28820000000001 + ], + [ + -75.216, + 45.29 + ], + [ + -75.21624489795917, + 45.29042857142857 + ], + [ + -75.216, + 45.291 + ], + [ + -75.219, + 45.297 + ], + [ + -75.228, + 45.3 + ], + [ + -75.235, + 45.29766666666667 + ], + [ + -75.238, + 45.297 + ], + [ + -75.242, + 45.29 + ] + ] + ], + [ + [ + [ + -75.206, + 45.426 + ], + [ + -75.202, + 45.42 + ], + [ + -75.193, + 45.417 + ], + [ + -75.184, + 45.42 + ], + [ + -75.18, + 45.426 + ], + [ + -75.184, + 45.433 + ], + [ + -75.193, + 45.435 + ], + [ + -75.202, + 45.433 + ], + [ + -75.206, + 45.426 + ] + ] + ], + [ + [ + [ + -75.164, + 45.216 + ], + [ + -75.16, + 45.21 + ], + [ + -75.151, + 45.207 + ], + [ + -75.142, + 45.21 + ], + [ + -75.138, + 45.216 + ], + [ + -75.142, + 45.223 + ], + [ + -75.151, + 45.225 + ], + [ + -75.16, + 45.223 + ], + [ + -75.164, + 45.216 + ] + ] + ], + [ + [ + [ + -75.133, + 45.567 + ], + [ + -75.129, + 45.561 + ], + [ + -75.12, + 45.558 + ], + [ + -75.111, + 45.561 + ], + [ + -75.108, + 45.567 + ], + [ + -75.111, + 45.574 + ], + [ + -75.12, + 45.576 + ], + [ + -75.129, + 45.574 + ], + [ + -75.133, + 45.567 + ] + ] + ], + [ + [ + [ + -75.133, + 45.606 + ], + [ + -75.129, + 45.599 + ], + [ + -75.12, + 45.597 + ], + [ + -75.111, + 45.599 + ], + [ + -75.107, + 45.606 + ], + [ + -75.111, + 45.612 + ], + [ + -75.12, + 45.615 + ], + [ + -75.129, + 45.612 + ], + [ + -75.133, + 45.606 + ] + ] + ], + [ + [ + [ + -75.122, + 45.176 + ], + [ + -75.118, + 45.17 + ], + [ + -75.109, + 45.167 + ], + [ + -75.1, + 45.17 + ], + [ + -75.096, + 45.176 + ], + [ + -75.1, + 45.182 + ], + [ + -75.109, + 45.185 + ], + [ + -75.118, + 45.182 + ], + [ + -75.122, + 45.176 + ] + ] + ], + [ + [ + [ + -75.101, + 45.315 + ], + [ + -75.098, + 45.308 + ], + [ + -75.09447826086956, + 45.30721739130435 + ], + [ + -75.095, + 45.306 + ], + [ + -75.092, + 45.3 + ], + [ + -75.09152, + 45.299839999999996 + ], + [ + -75.092, + 45.299 + ], + [ + -75.088, + 45.293 + ], + [ + -75.079, + 45.29 + ], + [ + -75.07, + 45.293 + ], + [ + -75.066, + 45.299 + ], + [ + -75.06907692307692, + 45.30438461538461 + ], + [ + -75.068, + 45.306 + ], + [ + -75.072, + 45.313 + ], + [ + -75.07643478260869, + 45.31398550724637 + ], + [ + -75.076, + 45.315 + ], + [ + -75.079, + 45.321 + ], + [ + -75.089, + 45.324 + ], + [ + -75.098, + 45.321 + ], + [ + -75.101, + 45.315 + ] + ] + ], + [ + [ + [ + -75.09, + 45.146 + ], + [ + -75.086, + 45.14 + ], + [ + -75.077, + 45.137 + ], + [ + -75.068, + 45.14 + ], + [ + -75.065, + 45.146 + ], + [ + -75.068, + 45.153 + ], + [ + -75.077, + 45.155 + ], + [ + -75.086, + 45.153 + ], + [ + -75.09, + 45.146 + ] + ] + ], + [ + [ + [ + -75.07, + 45.731 + ], + [ + -75.066, + 45.725 + ], + [ + -75.057, + 45.722 + ], + [ + -75.048, + 45.725 + ], + [ + -75.044, + 45.731 + ], + [ + -75.048, + 45.737 + ], + [ + -75.057, + 45.74 + ], + [ + -75.066, + 45.737 + ], + [ + -75.07, + 45.731 + ] + ] + ], + [ + [ + [ + -75.029, + 45.617 + ], + [ + -75.026, + 45.611 + ], + [ + -75.017, + 45.608 + ], + [ + -75.01542105263158, + 45.60847368421052 + ], + [ + -75.014, + 45.608 + ], + [ + -75.005, + 45.611 + ], + [ + -75.001, + 45.617 + ], + [ + -75.005, + 45.624 + ], + [ + -75.014, + 45.626 + ], + [ + -75.01542105263158, + 45.625684210526316 + ], + [ + -75.017, + 45.626 + ], + [ + -75.026, + 45.624 + ], + [ + -75.029, + 45.617 + ] + ] + ], + [ + [ + [ + -75.011, + 45.535 + ], + [ + -75.007, + 45.529 + ], + [ + -74.998, + 45.526 + ], + [ + -74.9975, + 45.52616666666667 + ], + [ + -74.997, + 45.526 + ], + [ + -74.988, + 45.529 + ], + [ + -74.98514285714285, + 45.53328571428571 + ], + [ + -74.98, + 45.535 + ], + [ + -74.977, + 45.541 + ], + [ + -74.98, + 45.547 + ], + [ + -74.989, + 45.55 + ], + [ + -74.998, + 45.547 + ], + [ + -75.00052173913043, + 45.543217391304346 + ], + [ + -75.006, + 45.542 + ], + [ + -75.0064705882353, + 45.54117647058823 + ], + [ + -75.007, + 45.541 + ], + [ + -75.011, + 45.535 + ] + ] + ], + [ + [ + [ + -75.007, + 45.494 + ], + [ + -75.003, + 45.488 + ], + [ + -74.994, + 45.485 + ], + [ + -74.985, + 45.488 + ], + [ + -74.981, + 45.494 + ], + [ + -74.985, + 45.501 + ], + [ + -74.994, + 45.503 + ], + [ + -75.003, + 45.501 + ], + [ + -75.007, + 45.494 + ] + ] + ], + [ + [ + [ + -74.968, + 45.544 + ], + [ + -74.965, + 45.537 + ], + [ + -74.956, + 45.535 + ], + [ + -74.946, + 45.537 + ], + [ + -74.943, + 45.544 + ], + [ + -74.946, + 45.55 + ], + [ + -74.956, + 45.553 + ], + [ + -74.965, + 45.55 + ], + [ + -74.968, + 45.544 + ] + ] + ], + [ + [ + [ + -74.96, + 45.65 + ], + [ + -74.957, + 45.644 + ], + [ + -74.948, + 45.641 + ], + [ + -74.939, + 45.644 + ], + [ + -74.935, + 45.65 + ], + [ + -74.939, + 45.657 + ], + [ + -74.948, + 45.659 + ], + [ + -74.957, + 45.657 + ], + [ + -74.96, + 45.65 + ] + ] + ], + [ + [ + [ + -74.944, + 45.434 + ], + [ + -74.94, + 45.428 + ], + [ + -74.931, + 45.425 + ], + [ + -74.922, + 45.428 + ], + [ + -74.918, + 45.434 + ], + [ + -74.922, + 45.44 + ], + [ + -74.931, + 45.443 + ], + [ + -74.94, + 45.44 + ], + [ + -74.944, + 45.434 + ] + ] + ], + [ + [ + [ + -74.924, + 45.55 + ], + [ + -74.921, + 45.543 + ], + [ + -74.912, + 45.541 + ], + [ + -74.902, + 45.543 + ], + [ + -74.90178947368422, + 45.543491228070174 + ], + [ + -74.895, + 45.545 + ], + [ + -74.891, + 45.552 + ], + [ + -74.895, + 45.558 + ], + [ + -74.904, + 45.561 + ], + [ + -74.91094736842106, + 45.558684210526316 + ], + [ + -74.912, + 45.559 + ], + [ + -74.921, + 45.556 + ], + [ + -74.924, + 45.55 + ] + ] + ], + [ + [ + [ + -74.915, + 45.376 + ], + [ + -74.911, + 45.369 + ], + [ + -74.902, + 45.367 + ], + [ + -74.893, + 45.369 + ], + [ + -74.89, + 45.376 + ], + [ + -74.893, + 45.382 + ], + [ + -74.902, + 45.385 + ], + [ + -74.911, + 45.382 + ], + [ + -74.915, + 45.376 + ] + ] + ], + [ + [ + [ + -74.913, + 45.347 + ], + [ + -74.909, + 45.341 + ], + [ + -74.90852000000001, + 45.34084 + ], + [ + -74.909, + 45.34 + ], + [ + -74.905, + 45.334 + ], + [ + -74.896, + 45.331 + ], + [ + -74.887, + 45.334 + ], + [ + -74.884, + 45.34 + ], + [ + -74.887, + 45.347 + ], + [ + -74.891, + 45.353 + ], + [ + -74.9, + 45.356 + ], + [ + -74.909, + 45.353 + ], + [ + -74.913, + 45.347 + ] + ] + ], + [ + [ + [ + -74.894, + 45.558 + ], + [ + -74.89, + 45.552 + ], + [ + -74.881, + 45.549 + ], + [ + -74.872, + 45.552 + ], + [ + -74.87109090909091, + 45.553363636363635 + ], + [ + -74.87, + 45.553 + ], + [ + -74.861, + 45.556 + ], + [ + -74.857, + 45.562 + ], + [ + -74.861, + 45.568 + ], + [ + -74.87, + 45.571 + ], + [ + -74.879, + 45.568 + ], + [ + -74.87983870967741, + 45.56674193548387 + ], + [ + -74.881, + 45.567 + ], + [ + -74.89, + 45.565 + ], + [ + -74.894, + 45.558 + ] + ] + ] + ] + } +} diff --git a/src/dissolve/test/out/issue-1237.geojson b/src/dissolve/test/out/issue-1237.geojson new file mode 100644 index 0000000000..011300e3c4 --- /dev/null +++ b/src/dissolve/test/out/issue-1237.geojson @@ -0,0 +1,177 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -83.49609375, + 42.64052548480924 + ], + [ + -83.49540710449219, + 42.64052548480924 + ], + [ + -83.49540710449219, + 42.64103059165476 + ], + [ + -83.49609375, + 42.64103059165476 + ], + [ + -83.49609375, + 42.64052548480924 + ] + ] + ], + [ + [ + [ + -83.49609375, + 42.64456622475866 + ], + [ + -83.49540710449219, + 42.64456622475866 + ], + [ + -83.49540710449219, + 42.645576368740564 + ], + [ + -83.49609375, + 42.645576368740564 + ], + [ + -83.49609375, + 42.64456622475866 + ] + ] + ], + [ + [ + [ + -83.49609375, + 42.66880515319917 + ], + [ + -83.49540710449219, + 42.66880515319917 + ], + [ + -83.49540710449219, + 42.66931003040664 + ], + [ + -83.49609375, + 42.66931003040664 + ], + [ + -83.49609375, + 42.66880515319917 + ] + ] + ], + [ + [ + [ + -83.49540710449219, + 42.66830027189085 + ], + [ + -83.49403381347656, + 42.66830027189085 + ], + [ + -83.49403381347656, + 42.66880515319917 + ], + [ + -83.49540710449219, + 42.66880515319917 + ], + [ + -83.49540710449219, + 42.66830027189085 + ] + ] + ], + [ + [ + [ + -83.42674255371094, + 42.681930627802714 + ], + [ + -83.42605590820312, + 42.681930627802714 + ], + [ + -83.42605590820312, + 42.68243539838622 + ], + [ + -83.42674255371094, + 42.68243539838622 + ], + [ + -83.42674255371094, + 42.681930627802714 + ] + ] + ], + [ + [ + [ + -83.42262268066406, + 42.681930627802714 + ], + [ + -83.42124938964844, + 42.681930627802714 + ], + [ + -83.42124938964844, + 42.68243539838622 + ], + [ + -83.42262268066406, + 42.68243539838622 + ], + [ + -83.42262268066406, + 42.681930627802714 + ] + ] + ], + [ + [ + [ + -83.41850280761719, + 42.681930627802714 + ], + [ + -83.41781616210938, + 42.681930627802714 + ], + [ + -83.41781616210938, + 42.68243539838622 + ], + [ + -83.41850280761719, + 42.68243539838622 + ], + [ + -83.41850280761719, + 42.681930627802714 + ] + ] + ] + ] + } +} diff --git a/src/dissolve/test/out/polysByProperty.geojson b/src/dissolve/test/out/polysByProperty.geojson new file mode 100644 index 0000000000..88f1e17a66 --- /dev/null +++ b/src/dissolve/test/out/polysByProperty.geojson @@ -0,0 +1,154 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 0, + 1 + ], + [ + 0.4450683930362929, + 0.10986321392741416 + ], + [ + 0.23620605468749623, + 0.10986321392741416 + ], + [ + 0.23620605468749623, + -0.8901516807502449 + ], + [ + 1.2362060546874962, + -0.8901516807502449 + ], + [ + 1.2362060546874962, + 0 + ], + [ + 2, + 0 + ], + [ + 2, + 1 + ], + [ + 0, + 1 + ] + ], + [ + [ + 0.7659179283564485, + 0.10986321392741416 + ], + [ + 1, + 0.5 + ], + [ + 1, + 0.10986321392741416 + ], + [ + 0.7659179283564485, + 0.10986321392741416 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 0.851440429687502, + -1.647722051796948 + ], + [ + 1.516113281250002, + -1.647722051796948 + ], + [ + 1.516113281250002, + -1 + ], + [ + 2, + -1 + ], + [ + 2, + 0 + ], + [ + 1.516113281250002, + 0 + ], + [ + 1.516113281250002, + 1.4500404973607692 + ], + [ + 0.851440429687502, + 1.4500404973607692 + ], + [ + 0.851440429687502, + -1.647722051796948 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -0.252685546875, + 1.252341676699629 + ], + [ + 0.28564453125, + 1.252341676699629 + ], + [ + 0.28564453125, + 1.653212936926045 + ], + [ + -0.252685546875, + 1.653212936926045 + ], + [ + -0.252685546875, + 1.252341676699629 + ] + ] + ] + ] + } + } + ] +} diff --git a/src/dissolve/test/out/polysWithoutProperty.geojson b/src/dissolve/test/out/polysWithoutProperty.geojson new file mode 100644 index 0000000000..cccab41b7d --- /dev/null +++ b/src/dissolve/test/out/polysWithoutProperty.geojson @@ -0,0 +1,115 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -0.252685546875, + 1.252341676699629 + ], + [ + 0.28564453125, + 1.252341676699629 + ], + [ + 0.28564453125, + 1.653212936926045 + ], + [ + -0.252685546875, + 1.653212936926045 + ], + [ + -0.252685546875, + 1.252341676699629 + ] + ] + ], + [ + [ + [ + 0, + 1 + ], + [ + 0.4450683930362929, + 0.10986321392741416 + ], + [ + 0.23620605468749623, + 0.10986321392741416 + ], + [ + 0.23620605468749623, + -0.8901516807502449 + ], + [ + 0.851440429687502, + -0.8901516807502449 + ], + [ + 0.851440429687502, + -1.647722051796948 + ], + [ + 1.516113281250002, + -1.647722051796948 + ], + [ + 1.516113281250002, + -1 + ], + [ + 2, + -1 + ], + [ + 2, + 1 + ], + [ + 1.516113281250002, + 1 + ], + [ + 1.516113281250002, + 1.4500404973607692 + ], + [ + 0.851440429687502, + 1.4500404973607692 + ], + [ + 0.851440429687502, + 1 + ], + [ + 0, + 1 + ] + ], + [ + [ + 0.7659179283564485, + 0.10986321392741416 + ], + [ + 0.851440429687502, + 0.2524007161458367 + ], + [ + 0.851440429687502, + 0.10986321392741416 + ], + [ + 0.7659179283564485, + 0.10986321392741416 + ] + ] + ] + ] + } +} diff --git a/packages/turf-distance-weight/bench.js b/src/distance-weight/bench.js similarity index 100% rename from packages/turf-distance-weight/bench.js rename to src/distance-weight/bench.js diff --git a/src/distance-weight/index.d.ts b/src/distance-weight/index.d.ts new file mode 100644 index 0000000000..f81cdda3a0 --- /dev/null +++ b/src/distance-weight/index.d.ts @@ -0,0 +1,37 @@ +import { Feature, FeatureCollection, Point } from "../helpers"; +/** + * calcualte the Minkowski p-norm distance between two features. + * @param feature1 point feature + * @param feature2 point feature + * @param p p-norm 1=, feature2: Feature, p?: number): number; +/** + * + * + * @name distanceWeight + * @param {FeatureCollection} fc FeatureCollection. + * @param {Object} [options] option object. + * @param {number} [options.threshold=10000] If the distance between neighbor and + * target features is greater than threshold, the weight of that neighbor is 0. + * @param {number} [options.p=2] Minkowski p-norm distance parameter. + * 1: Manhattan distance. 2: Euclidean distance. 1=>} distance weight matrix. + * @example + * + * var bbox = [-65, 40, -63, 42]; + * var dataset = turf.randomPoint(100, { bbox: bbox }); + * var result = turf.distanceWeight(dataset); + */ +export default function distanceWeight(fc: FeatureCollection, options?: { + threshold?: number; + p?: number; + binary?: boolean; + alpha?: number; + standardization?: boolean; +}): number[][]; diff --git a/src/distance-weight/index.js b/src/distance-weight/index.js new file mode 100644 index 0000000000..46929cbc83 --- /dev/null +++ b/src/distance-weight/index.js @@ -0,0 +1,112 @@ +import centroid from '../centroid'; +import { getCoord } from '../invariant'; +import { featureEach } from '../meta'; + +/** + * calcualte the Minkowski p-norm distance between two features. + * @param {Point} feature1 point feature + * @param {Point} feature2 point feature + * @param {p} p p-norm 1=} fc FeatureCollection. + * @param {Object} [options] option object. + * @param {number} [options.threshold=10000] If the distance between neighbor and + * target features is greater than threshold, the weight of that neighbor is 0. + * @param {number} [options.p=2] Minkowski p-norm distance parameter. + * 1: Manhattan distance. 2: Euclidean distance. 1=>} distance weight matrix. + * @example + * + * var bbox = [-65, 40, -63, 42]; + * var dataset = turf.randomPoint(100, { bbox: bbox }); + * var result = turf.distanceWeight(dataset); + */ +export default function distanceWeight(fc, options) { + + options = options || {}; + const threshold = options.threshold || 10000; + const p = options.p || 2; + const binary = options.binary || false; + const alpha = options.alpha || -1; + const rowTransform = options.standardization || false; + + const features = []; + featureEach(fc, function (feature) { + features.push(centroid(feature)); + }); + + // computing the distance between the features + const weights = []; + for (let i = 0; i < features.length; i++) { + weights[i] = []; + } + + for (let i = 0; i < features.length; i++) { + for (let j = i; j < features.length; j++) { + if (i === j) { + weights[i][j] = 0; + } + const dis = pNormDistance(features[i], features[j], p); + weights[i][j] = dis; + weights[j][i] = dis; + } + } + + // binary or distance decay + for (let i = 0; i < features.length; i++) { + for (let j = 0; j < features.length; j++) { + const dis = weights[i][j]; + if (dis === 0) { + continue; + } + if (binary) { + if (dis <= threshold) { + weights[i][j] = 1.0; + } else { + weights[i][j] = 0.0; + } + } else { + if (dis <= threshold) { //eslint-disable-line + weights[i][j] = Math.pow(dis, alpha); + } else { + weights[i][j] = 0.0; + } + } + } + } + + if (rowTransform) { + for (let i = 0; i < features.length; i++) { + const rowSum = weights[i].reduce(function (sum, currentVal) { + return sum + currentVal; + }, 0); + for (let j = 0; j < features.length; j++) { + weights[i][j] = weights[i][j] / rowSum; + } + } + } + + return weights; + +} diff --git a/src/distance-weight/test.js b/src/distance-weight/test.js new file mode 100644 index 0000000000..c3397e51e1 --- /dev/null +++ b/src/distance-weight/test.js @@ -0,0 +1,97 @@ +const { point } = require('../helpers'); + +const test = require('tape'); +const glob = require('glob'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const distanceWeight = require('.').default; +const { pNormDistance } = require('.'); + +test('pNormDistance function', t => { + + t.equal(pNormDistance(point([2, 0]), point([0, 0]), 2), 2, '2-norm is ok'); + t.equal(pNormDistance(point([1, 1]), point([0, 0]), 1), 2, '1-norm is ok'); + t.end(); + +}); + +test('turf-distance-weight', t => { + + const columbusPath = path.join(__dirname, 'test', 'in', 'point.json'); + const columbusJson = load.sync(columbusPath); + + let result = distanceWeight(columbusJson, { + threshold: 1, + binary: false, + p: 1, + alpha: 1, + standardization: false + }); + t.equal(result[0][1], 0.8320121090670778, 'base arguments'); + + // test threshold + result = distanceWeight(columbusJson, { + threshold: 2, + binary: false, + p: 1, + alpha: 1 + }); + t.equal(result[0][1], 0.8320121090670778, 'change threshold'); + + // test binary + result = distanceWeight(columbusJson, { + threshold: 1, + binary: true, + p: 1, + alpha: 1 + }); + t.equal(result[0][1], 1, 'change binary'); + + // test p + result = distanceWeight(columbusJson, { + threshold: 1, + binary: false, + p: 2, + alpha: 1 + }); + t.equal(result[0][1], 0.5987182558007202, 'change p'); + + // test alpha + result = distanceWeight(columbusJson, { + threshold: 1, + binary: false, + p: 1, + alpha: -1 + }); + t.equal(result[0][1], 1.201905584188293, 'change alpha'); + + result = distanceWeight(columbusJson, { + threshold: 1, + binary: false, + p: 1, + alpha: 1, + standardization: true + }); + t.equal(result[0][1], 0.5311565480348293, 'standardization 1'); + + result = distanceWeight(columbusJson, { + threshold: 1, + binary: true, + p: 1, + alpha: 1, + standardization: true + }); + t.equal(result[0][1], 0.5, 'standardization 2'); + + + + // test default + result = distanceWeight(columbusJson); + t.equal(result[0][1], 1.6702346893742355, 'default arguments'); + + + t.end(); + + +}); diff --git a/packages/turf-distance-weight/test/in/columbus.json b/src/distance-weight/test/in/columbus.json similarity index 100% rename from packages/turf-distance-weight/test/in/columbus.json rename to src/distance-weight/test/in/columbus.json diff --git a/packages/turf-distance-weight/test/in/point.json b/src/distance-weight/test/in/point.json similarity index 100% rename from packages/turf-distance-weight/test/in/point.json rename to src/distance-weight/test/in/point.json diff --git a/packages/turf-distance/bench.js b/src/distance/bench.js similarity index 100% rename from packages/turf-distance/bench.js rename to src/distance/bench.js diff --git a/src/distance/index.js b/src/distance/index.js new file mode 100644 index 0000000000..c755eb9a8a --- /dev/null +++ b/src/distance/index.js @@ -0,0 +1,44 @@ +import { getCoord } from '../invariant'; +import { radiansToLength, degreesToRadians, checkIfOptionsExist } from '../helpers'; + +//http://en.wikipedia.org/wiki/Haversine_formula +//http://www.movable-type.co.uk/scripts/latlong.html + +/** + * Calculates the distance between two {@link Point|points} in degrees, radians, miles, or kilometers. + * This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature. + * + * @name distance + * @param {Coord} from origin point + * @param {Coord} to destination point + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers + * @returns {number} distance between the two points + * @example + * var from = turf.point([-75.343, 39.984]); + * var to = turf.point([-75.534, 39.123]); + * var options = {units: 'miles'}; + * + * var distance = turf.distance(from, to, options); + * + * //addToMap + * var addToMap = [from, to]; + * from.properties.distance = distance; + * to.properties.distance = distance; + */ +function distance(from, to, options) { + options = checkIfOptionsExist(options); + var coordinates1 = getCoord(from); + var coordinates2 = getCoord(to); + var dLat = degreesToRadians((coordinates2[1] - coordinates1[1])); + var dLon = degreesToRadians((coordinates2[0] - coordinates1[0])); + var lat1 = degreesToRadians(coordinates1[1]); + var lat2 = degreesToRadians(coordinates2[1]); + + var a = Math.pow(Math.sin(dLat / 2), 2) + + Math.pow(Math.sin(dLon / 2), 2) * Math.cos(lat1) * Math.cos(lat2); + + return radiansToLength(2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)), options.units); +} + +export default distance; diff --git a/src/distance/test.js b/src/distance/test.js new file mode 100644 index 0000000000..399c7ebb5d --- /dev/null +++ b/src/distance/test.js @@ -0,0 +1,50 @@ +const fs = require('fs'); +const path = require('path'); +const test = require('tape'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { point } = require('../helpers'); +const distance = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('distance', t => { + fixtures.forEach(fixture => { + const name = fixture.name; + const geojson = fixture.geojson; + const pt1 = geojson.features[0]; + const pt2 = geojson.features[1]; + const distances = { + miles: distance(pt1, pt2, {units: 'miles'}), + nauticalmiles: distance(pt1, pt2, {units: 'nauticalmiles'}), + kilometers: distance(pt1, pt2, {units: 'kilometers'}), + radians: distance(pt1, pt2, {units: 'radians'}), + degrees: distance(pt1, pt2, {units: 'degrees'}) + }; + if (process.env.REGEN) write.sync(directories.out + name + '.json', distances); + t.deepEqual(distances, load.sync(directories.out + name + '.json'), name); + }); + t.end(); +}); + +// https://github.com/Turfjs/turf/issues/758 +test('distance -- Issue #758', t => { + t.equal(Math.round(distance(point([-180, -90]), point([180, -90]))), 0, 'should be 0'); + t.end(); +}); + +test('distance -- throws', t => { + t.throws(() => distance(point([0, 0]), point([10, 10]), {units: 'foo'}), /units is invalid/); + t.end(); +}); diff --git a/packages/turf-distance/test/in/points.geojson b/src/distance/test/in/points.geojson similarity index 100% rename from packages/turf-distance/test/in/points.geojson rename to src/distance/test/in/points.geojson diff --git a/packages/turf-distance/test/out/points.json b/src/distance/test/out/points.json similarity index 81% rename from packages/turf-distance/test/out/points.json rename to src/distance/test/out/points.json index 92f32a28cf..e75c92f6c8 100644 --- a/packages/turf-distance/test/out/points.json +++ b/src/distance/test/out/points.json @@ -3,5 +3,5 @@ "nauticalmiles": 52.44558379572265, "kilometers": 97.12922118967835, "radians": 0.015245501024842149, - "degrees": 0.8724834600465156 + "degrees": 0.8735028652858263 } diff --git a/packages/turf-ellipse/bench.js b/src/ellipse/bench.js similarity index 100% rename from packages/turf-ellipse/bench.js rename to src/ellipse/bench.js diff --git a/packages/turf-ellipse/index.d.ts b/src/ellipse/index.d.ts similarity index 100% rename from packages/turf-ellipse/index.d.ts rename to src/ellipse/index.d.ts diff --git a/src/ellipse/index.js b/src/ellipse/index.js new file mode 100644 index 0000000000..d58de3b83e --- /dev/null +++ b/src/ellipse/index.js @@ -0,0 +1,92 @@ +import { degreesToRadians, polygon, isObject, isNumber } from '../helpers'; +import rhumbDestination from '../rhumb-destination'; +import transformRotate from '../transform-rotate'; +import { getCoord } from '../invariant'; + +/** + * Takes a {@link Point} and calculates the ellipse polygon given two semi-axes expressed in variable units and steps for precision. + * + * @param {Coord} center center point + * @param {number} xSemiAxis semi (major) axis of the ellipse along the x-axis + * @param {number} ySemiAxis semi (minor) axis of the ellipse along the y-axis + * @param {Object} [options={}] Optional parameters + * @param {number} [options.angle=0] angle of rotation (along the vertical axis), from North in decimal degrees, negative clockwise + * @param {Coord} [options.pivot='origin'] point around which the rotation will be performed + * @param {number} [options.steps=64] number of steps + * @param {string} [options.units='kilometers'] unit of measurement for axes + * @param {Object} [options.properties={}] properties + * @returns {Feature} ellipse polygon + * @example + * var center = [-75, 40]; + * var xSemiAxis = 5; + * var ySemiAxis = 2; + * var ellipse = turf.ellipse(center, xSemiAxis, ySemiAxis); + * + * //addToMap + * var addToMap = [turf.point(center), ellipse] + */ +function ellipse(center, xSemiAxis, ySemiAxis, options) { + // Optional params + options = options || {}; + var steps = options.steps || 64; + var units = options.units || 'kilometers'; + var angle = options.angle || 0; + var pivot = options.pivot || center; + var properties = options.properties || center.properties || {}; + + // validation + if (!center) throw new Error('center is required'); + if (!xSemiAxis) throw new Error('xSemiAxis is required'); + if (!ySemiAxis) throw new Error('ySemiAxis is required'); + if (!isObject(options)) throw new Error('options must be an object'); + if (!isNumber(steps)) throw new Error('steps must be a number'); + if (!isNumber(angle)) throw new Error('angle must be a number'); + + var centerCoords = getCoord(center); + if (units === 'degrees') { + var angleRad = degreesToRadians(angle); + } else { + xSemiAxis = rhumbDestination(center, xSemiAxis, 90, {units: units}); + ySemiAxis = rhumbDestination(center, ySemiAxis, 0, {units: units}); + xSemiAxis = getCoord(xSemiAxis)[0] - centerCoords[0]; + ySemiAxis = getCoord(ySemiAxis)[1] - centerCoords[1]; + } + + var coordinates = []; + for (var i = 0; i < steps; i += 1) { + var stepAngle = i * -360 / steps; + var x = ((xSemiAxis * ySemiAxis) / Math.sqrt(Math.pow(ySemiAxis, 2) + (Math.pow(xSemiAxis, 2) * Math.pow(getTanDeg(stepAngle), 2)))); + var y = ((xSemiAxis * ySemiAxis) / Math.sqrt(Math.pow(xSemiAxis, 2) + (Math.pow(ySemiAxis, 2) / Math.pow(getTanDeg(stepAngle), 2)))); + + if (stepAngle < -90 && stepAngle >= -270) x = -x; + if (stepAngle < -180 && stepAngle >= -360) y = -y; + if (units === 'degrees') { + var newx = x * Math.cos(angleRad) + y * Math.sin(angleRad); + var newy = y * Math.cos(angleRad) - x * Math.sin(angleRad); + x = newx; + y = newy; + } + + coordinates.push([x + centerCoords[0], y + centerCoords[1]]); + } + coordinates.push(coordinates[0]); + if (units === 'degrees') { + return polygon([coordinates], properties); + } else { + return transformRotate(polygon([coordinates], properties), angle, { pivot: pivot }); + } +} + +/** + * Get Tan Degrees + * + * @private + * @param {number} deg Degrees + * @returns {number} Tan Degrees + */ +function getTanDeg(deg) { + var rad = deg * Math.PI / 180; + return Math.tan(rad); +} + +export default ellipse; diff --git a/src/ellipse/test.js b/src/ellipse/test.js new file mode 100644 index 0000000000..0e597c9042 --- /dev/null +++ b/src/ellipse/test.js @@ -0,0 +1,102 @@ +import test from 'tape'; +import glob from 'glob'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import circle from '../circle'; +import truncate from '../truncate'; +import geojsonhint from '@mapbox/geojsonhint'; +import bboxPolygon from '../bbox-polygon'; +import rhumbDestination from '../rhumb-destination'; +// import destination from '../destination'; +import { featureCollection } from '../helpers'; + +import ellipse from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +test('turf-ellipse', t => { + glob.sync(directories.in + '*.geojson').forEach(filepath => { + // Define params + const {name} = path.parse(filepath); + const geojson = load.sync(filepath); + const center = geojson.geometry.coordinates; + let {xSemiAxis, ySemiAxis, steps, angle, units} = geojson.properties; + angle = angle || 0; + const options = {steps, angle, units}; + const maxAxis = Math.max(xSemiAxis, ySemiAxis); + + // Styled results + const maxDestination0 = rhumbDestination(center, maxAxis, angle, {units}); + const maxDestination90 = rhumbDestination(center, maxAxis, angle + 90, {units}); + const maxDestination180 = rhumbDestination(center, maxAxis, angle + 180, {units}); + const maxDestination270 = rhumbDestination(center, maxAxis, angle + 270, {units}); + + const xDestination0 = rhumbDestination(center, xSemiAxis, angle, {units}); + const xDestination90 = rhumbDestination(center, xSemiAxis, angle + 90, {units}); + const xDestination180 = rhumbDestination(center, xSemiAxis, angle + 180, {units}); + const xDestination270 = rhumbDestination(center, xSemiAxis, angle + 270, {units}); + + const yDestination0 = rhumbDestination(center, ySemiAxis, angle, {units}); + const yDestination90 = rhumbDestination(center, ySemiAxis, angle + 90, {units}); + const yDestination180 = rhumbDestination(center, ySemiAxis, angle + 180, {units}); + const yDestination270 = rhumbDestination(center, ySemiAxis, angle + 270, {units}); + + const bboxX = colorize(bboxPolygon([ + xDestination270.geometry.coordinates[0], + yDestination180.geometry.coordinates[1], + xDestination90.geometry.coordinates[0], + yDestination0.geometry.coordinates[1], + ]), '#FFF'); + const bboxY = colorize(bboxPolygon([ + yDestination270.geometry.coordinates[0], + xDestination180.geometry.coordinates[1], + yDestination90.geometry.coordinates[0], + xDestination0.geometry.coordinates[1], + ]), '#666'); + const bboxMax = colorize(bboxPolygon([ + maxDestination270.geometry.coordinates[0], + maxDestination180.geometry.coordinates[1], + maxDestination90.geometry.coordinates[0], + maxDestination0.geometry.coordinates[1], + ]), '#000'); + + const results = featureCollection([ + bboxX, + bboxY, + bboxMax, + geojson, + truncate(colorize(circle(center, maxAxis, options), '#F00')), + truncate(colorize(ellipse(center, xSemiAxis, ySemiAxis, options), '#00F')), + truncate(colorize(ellipse(center, xSemiAxis, ySemiAxis, {steps, angle: angle + 90, units}), '#0F0')), + ]); + + // Save to file + if (process.env.REGEN) write.sync(directories.out + base, result); + t.deepEqual(result, load.sync(directories.out + base), name); + }); + t.end(); +}); + +test('turf-ellipse -- with coordinates', t => { + t.assert(ellipse([-100, 75], 5, 1)); + t.end(); +}); + +test('turf-ellipse -- validate geojson', t => { + const E = ellipse([0, 0], 10, 20); + geojsonhint.hint(E).forEach(hint => t.fail(hint.message)); + t.end(); +}); + +function colorize(feature, color) { + color = color || '#F00'; + feature.properties['stroke-width'] = 6; + feature.properties.stroke = color; + feature.properties.fill = color; + feature.properties['fill-opacity'] = 0; + return feature; +} diff --git a/packages/turf-ellipse/test/in/anti-meridian-degrees.json b/src/ellipse/test/in/anti-meridian-degrees.json similarity index 100% rename from packages/turf-ellipse/test/in/anti-meridian-degrees.json rename to src/ellipse/test/in/anti-meridian-degrees.json diff --git a/packages/turf-ellipse/test/in/anti-meridian.json b/src/ellipse/test/in/anti-meridian.json similarity index 100% rename from packages/turf-ellipse/test/in/anti-meridian.json rename to src/ellipse/test/in/anti-meridian.json diff --git a/packages/turf-ellipse/test/in/northern-latitudes-degrees.json b/src/ellipse/test/in/northern-latitudes-degrees.json similarity index 100% rename from packages/turf-ellipse/test/in/northern-latitudes-degrees.json rename to src/ellipse/test/in/northern-latitudes-degrees.json diff --git a/packages/turf-ellipse/test/in/northern-latitudes.json b/src/ellipse/test/in/northern-latitudes.json similarity index 100% rename from packages/turf-ellipse/test/in/northern-latitudes.json rename to src/ellipse/test/in/northern-latitudes.json diff --git a/packages/turf-ellipse/test/in/rotation-degrees.json b/src/ellipse/test/in/rotation-degrees.json similarity index 100% rename from packages/turf-ellipse/test/in/rotation-degrees.json rename to src/ellipse/test/in/rotation-degrees.json diff --git a/packages/turf-ellipse/test/in/rotation.json b/src/ellipse/test/in/rotation.json similarity index 100% rename from packages/turf-ellipse/test/in/rotation.json rename to src/ellipse/test/in/rotation.json diff --git a/packages/turf-ellipse/test/in/simple-degrees.json b/src/ellipse/test/in/simple-degrees.json similarity index 100% rename from packages/turf-ellipse/test/in/simple-degrees.json rename to src/ellipse/test/in/simple-degrees.json diff --git a/packages/turf-ellipse/test/in/simple.json b/src/ellipse/test/in/simple.json similarity index 100% rename from packages/turf-ellipse/test/in/simple.json rename to src/ellipse/test/in/simple.json diff --git a/packages/turf-ellipse/test/out/anti-meridian-degrees.json b/src/ellipse/test/out/anti-meridian-degrees.json similarity index 100% rename from packages/turf-ellipse/test/out/anti-meridian-degrees.json rename to src/ellipse/test/out/anti-meridian-degrees.json diff --git a/packages/turf-ellipse/test/out/anti-meridian.json b/src/ellipse/test/out/anti-meridian.json similarity index 100% rename from packages/turf-ellipse/test/out/anti-meridian.json rename to src/ellipse/test/out/anti-meridian.json diff --git a/packages/turf-ellipse/test/out/northern-latitudes-degrees.json b/src/ellipse/test/out/northern-latitudes-degrees.json similarity index 100% rename from packages/turf-ellipse/test/out/northern-latitudes-degrees.json rename to src/ellipse/test/out/northern-latitudes-degrees.json diff --git a/packages/turf-ellipse/test/out/northern-latitudes.json b/src/ellipse/test/out/northern-latitudes.json similarity index 100% rename from packages/turf-ellipse/test/out/northern-latitudes.json rename to src/ellipse/test/out/northern-latitudes.json diff --git a/packages/turf-ellipse/test/out/rotation-degrees.json b/src/ellipse/test/out/rotation-degrees.json similarity index 100% rename from packages/turf-ellipse/test/out/rotation-degrees.json rename to src/ellipse/test/out/rotation-degrees.json diff --git a/packages/turf-ellipse/test/out/rotation.json b/src/ellipse/test/out/rotation.json similarity index 100% rename from packages/turf-ellipse/test/out/rotation.json rename to src/ellipse/test/out/rotation.json diff --git a/packages/turf-ellipse/test/out/simple-degrees.json b/src/ellipse/test/out/simple-degrees.json similarity index 100% rename from packages/turf-ellipse/test/out/simple-degrees.json rename to src/ellipse/test/out/simple-degrees.json diff --git a/packages/turf-ellipse/test/out/simple.json b/src/ellipse/test/out/simple.json similarity index 100% rename from packages/turf-ellipse/test/out/simple.json rename to src/ellipse/test/out/simple.json diff --git a/packages/turf-envelope/bench.js b/src/envelope/bench.js similarity index 100% rename from packages/turf-envelope/bench.js rename to src/envelope/bench.js diff --git a/src/envelope/index.d.ts b/src/envelope/index.d.ts new file mode 100644 index 0000000000..4de25ca8c1 --- /dev/null +++ b/src/envelope/index.d.ts @@ -0,0 +1,8 @@ +import { Feature, AllGeoJSON, Polygon } from '../helpers' + +/** + * http://turfjs.org/docs/#envelope + */ +export default function envelope( + features: AllGeoJSON +): Feature; diff --git a/src/envelope/index.js b/src/envelope/index.js new file mode 100644 index 0000000000..bfbc8b21fd --- /dev/null +++ b/src/envelope/index.js @@ -0,0 +1,26 @@ +import bbox from '../bbox'; +import bboxPolygon from '../bbox-polygon'; + +/** + * Takes any number of features and returns a rectangular {@link Polygon} that encompasses all vertices. + * + * @name envelope + * @param {GeoJSON} geojson input features + * @returns {Feature} a rectangular Polygon feature that encompasses all vertices + * @example + * var features = turf.featureCollection([ + * turf.point([-75.343, 39.984], {"name": "Location A"}), + * turf.point([-75.833, 39.284], {"name": "Location B"}), + * turf.point([-75.534, 39.123], {"name": "Location C"}) + * ]); + * + * var enveloped = turf.envelope(features); + * + * //addToMap + * var addToMap = [features, enveloped]; + */ +function envelope(geojson) { + return bboxPolygon(bbox(geojson)); +} + +export default envelope; diff --git a/packages/turf-envelope/test.js b/src/envelope/test.js similarity index 100% rename from packages/turf-envelope/test.js rename to src/envelope/test.js diff --git a/packages/turf-envelope/test/in/feature-collection.geojson b/src/envelope/test/in/feature-collection.geojson similarity index 100% rename from packages/turf-envelope/test/in/feature-collection.geojson rename to src/envelope/test/in/feature-collection.geojson diff --git a/packages/turf-explode/bench.js b/src/explode/bench.js similarity index 100% rename from packages/turf-explode/bench.js rename to src/explode/bench.js diff --git a/packages/turf-explode/index.d.ts b/src/explode/index.d.ts similarity index 100% rename from packages/turf-explode/index.d.ts rename to src/explode/index.d.ts diff --git a/src/explode/index.js b/src/explode/index.js new file mode 100644 index 0000000000..41ce130893 --- /dev/null +++ b/src/explode/index.js @@ -0,0 +1,35 @@ +import { coordEach, featureEach } from '../meta'; +import { point, featureCollection } from '../helpers'; + +/** + * Takes a feature or set of features and returns all positions as {@link Point|points}. + * + * @name explode + * @param {GeoJSON} geojson input features + * @returns {FeatureCollection} points representing the exploded input features + * @throws {Error} if it encounters an unknown geometry type + * @example + * var polygon = turf.polygon([[[-81, 41], [-88, 36], [-84, 31], [-80, 33], [-77, 39], [-81, 41]]]); + * + * var explode = turf.explode(polygon); + * + * //addToMap + * var addToMap = [polygon, explode] + */ +function explode(geojson) { + const points = []; + if (geojson.type === 'FeatureCollection') { + featureEach(geojson, function (feature) { + coordEach(feature, function (coord) { + points.push(point(coord, feature.properties)); + }); + }); + } else { + coordEach(geojson, function (coord) { + points.push(point(coord, geojson.properties)); + }); + } + return featureCollection(points); +} + +export default explode; diff --git a/packages/turf-explode/test.js b/src/explode/test.js similarity index 100% rename from packages/turf-explode/test.js rename to src/explode/test.js diff --git a/packages/turf-explode/test/in/geometrycollection-0-0.json b/src/explode/test/in/geometrycollection-0-0.json similarity index 100% rename from packages/turf-explode/test/in/geometrycollection-0-0.json rename to src/explode/test/in/geometrycollection-0-0.json diff --git a/packages/turf-explode/test/in/geometrycollection-xyz-0-6.json b/src/explode/test/in/geometrycollection-xyz-0-6.json similarity index 100% rename from packages/turf-explode/test/in/geometrycollection-xyz-0-6.json rename to src/explode/test/in/geometrycollection-xyz-0-6.json diff --git a/packages/turf-explode/test/in/multilinestring-0-5.json b/src/explode/test/in/multilinestring-0-5.json similarity index 100% rename from packages/turf-explode/test/in/multilinestring-0-5.json rename to src/explode/test/in/multilinestring-0-5.json diff --git a/packages/turf-explode/test/in/multilinestring-xyz-0-11.json b/src/explode/test/in/multilinestring-xyz-0-11.json similarity index 100% rename from packages/turf-explode/test/in/multilinestring-xyz-0-11.json rename to src/explode/test/in/multilinestring-xyz-0-11.json diff --git a/packages/turf-explode/test/in/multipoint-0-3.json b/src/explode/test/in/multipoint-0-3.json similarity index 100% rename from packages/turf-explode/test/in/multipoint-0-3.json rename to src/explode/test/in/multipoint-0-3.json diff --git a/packages/turf-explode/test/in/multipoint-xyz-0-9.json b/src/explode/test/in/multipoint-xyz-0-9.json similarity index 100% rename from packages/turf-explode/test/in/multipoint-xyz-0-9.json rename to src/explode/test/in/multipoint-xyz-0-9.json diff --git a/packages/turf-explode/test/in/multipolygon-0-4.json b/src/explode/test/in/multipolygon-0-4.json similarity index 100% rename from packages/turf-explode/test/in/multipolygon-0-4.json rename to src/explode/test/in/multipolygon-0-4.json diff --git a/packages/turf-explode/test/in/multipolygon-xyz-0-10.json b/src/explode/test/in/multipolygon-xyz-0-10.json similarity index 100% rename from packages/turf-explode/test/in/multipolygon-xyz-0-10.json rename to src/explode/test/in/multipolygon-xyz-0-10.json diff --git a/packages/turf-explode/test/in/one-1-0.json b/src/explode/test/in/one-1-0.json similarity index 100% rename from packages/turf-explode/test/in/one-1-0.json rename to src/explode/test/in/one-1-0.json diff --git a/packages/turf-explode/test/in/one-2-0.json b/src/explode/test/in/one-2-0.json similarity index 100% rename from packages/turf-explode/test/in/one-2-0.json rename to src/explode/test/in/one-2-0.json diff --git a/packages/turf-explode/test/in/point-0-2.json b/src/explode/test/in/point-0-2.json similarity index 100% rename from packages/turf-explode/test/in/point-0-2.json rename to src/explode/test/in/point-0-2.json diff --git a/packages/turf-explode/test/in/point-xyz-0-8.json b/src/explode/test/in/point-xyz-0-8.json similarity index 100% rename from packages/turf-explode/test/in/point-xyz-0-8.json rename to src/explode/test/in/point-xyz-0-8.json diff --git a/packages/turf-explode/test/in/polygon-0-1.json b/src/explode/test/in/polygon-0-1.json similarity index 100% rename from packages/turf-explode/test/in/polygon-0-1.json rename to src/explode/test/in/polygon-0-1.json diff --git a/packages/turf-explode/test/in/polygon-with-properties.json b/src/explode/test/in/polygon-with-properties.json similarity index 100% rename from packages/turf-explode/test/in/polygon-with-properties.json rename to src/explode/test/in/polygon-with-properties.json diff --git a/packages/turf-explode/test/in/polygon-xyz-0-7.json b/src/explode/test/in/polygon-xyz-0-7.json similarity index 100% rename from packages/turf-explode/test/in/polygon-xyz-0-7.json rename to src/explode/test/in/polygon-xyz-0-7.json diff --git a/packages/turf-explode/test/out/geometrycollection-0-0.json b/src/explode/test/out/geometrycollection-0-0.json similarity index 100% rename from packages/turf-explode/test/out/geometrycollection-0-0.json rename to src/explode/test/out/geometrycollection-0-0.json diff --git a/packages/turf-explode/test/out/geometrycollection-xyz-0-6.json b/src/explode/test/out/geometrycollection-xyz-0-6.json similarity index 100% rename from packages/turf-explode/test/out/geometrycollection-xyz-0-6.json rename to src/explode/test/out/geometrycollection-xyz-0-6.json diff --git a/packages/turf-explode/test/out/multilinestring-0-5.json b/src/explode/test/out/multilinestring-0-5.json similarity index 100% rename from packages/turf-explode/test/out/multilinestring-0-5.json rename to src/explode/test/out/multilinestring-0-5.json diff --git a/packages/turf-explode/test/out/multilinestring-xyz-0-11.json b/src/explode/test/out/multilinestring-xyz-0-11.json similarity index 100% rename from packages/turf-explode/test/out/multilinestring-xyz-0-11.json rename to src/explode/test/out/multilinestring-xyz-0-11.json diff --git a/packages/turf-explode/test/out/multipoint-0-3.json b/src/explode/test/out/multipoint-0-3.json similarity index 100% rename from packages/turf-explode/test/out/multipoint-0-3.json rename to src/explode/test/out/multipoint-0-3.json diff --git a/packages/turf-explode/test/out/multipoint-xyz-0-9.json b/src/explode/test/out/multipoint-xyz-0-9.json similarity index 100% rename from packages/turf-explode/test/out/multipoint-xyz-0-9.json rename to src/explode/test/out/multipoint-xyz-0-9.json diff --git a/packages/turf-explode/test/out/multipolygon-0-4.json b/src/explode/test/out/multipolygon-0-4.json similarity index 100% rename from packages/turf-explode/test/out/multipolygon-0-4.json rename to src/explode/test/out/multipolygon-0-4.json diff --git a/packages/turf-explode/test/out/multipolygon-xyz-0-10.json b/src/explode/test/out/multipolygon-xyz-0-10.json similarity index 100% rename from packages/turf-explode/test/out/multipolygon-xyz-0-10.json rename to src/explode/test/out/multipolygon-xyz-0-10.json diff --git a/packages/turf-explode/test/out/one-1-0.json b/src/explode/test/out/one-1-0.json similarity index 100% rename from packages/turf-explode/test/out/one-1-0.json rename to src/explode/test/out/one-1-0.json diff --git a/packages/turf-explode/test/out/one-2-0.json b/src/explode/test/out/one-2-0.json similarity index 100% rename from packages/turf-explode/test/out/one-2-0.json rename to src/explode/test/out/one-2-0.json diff --git a/packages/turf-explode/test/out/point-0-2.json b/src/explode/test/out/point-0-2.json similarity index 100% rename from packages/turf-explode/test/out/point-0-2.json rename to src/explode/test/out/point-0-2.json diff --git a/packages/turf-explode/test/out/point-xyz-0-8.json b/src/explode/test/out/point-xyz-0-8.json similarity index 100% rename from packages/turf-explode/test/out/point-xyz-0-8.json rename to src/explode/test/out/point-xyz-0-8.json diff --git a/packages/turf-explode/test/out/polygon-0-1.json b/src/explode/test/out/polygon-0-1.json similarity index 100% rename from packages/turf-explode/test/out/polygon-0-1.json rename to src/explode/test/out/polygon-0-1.json diff --git a/packages/turf-explode/test/out/polygon-with-properties.json b/src/explode/test/out/polygon-with-properties.json similarity index 100% rename from packages/turf-explode/test/out/polygon-with-properties.json rename to src/explode/test/out/polygon-with-properties.json diff --git a/packages/turf-explode/test/out/polygon-xyz-0-7.json b/src/explode/test/out/polygon-xyz-0-7.json similarity index 100% rename from packages/turf-explode/test/out/polygon-xyz-0-7.json rename to src/explode/test/out/polygon-xyz-0-7.json diff --git a/packages/turf-flatten/bench.js b/src/flatten/bench.js similarity index 100% rename from packages/turf-flatten/bench.js rename to src/flatten/bench.js diff --git a/src/flatten/index.d.ts b/src/flatten/index.d.ts new file mode 100644 index 0000000000..abf4026f8d --- /dev/null +++ b/src/flatten/index.d.ts @@ -0,0 +1,21 @@ +import { + Point, + MultiPoint, + LineString, + MultiLineString, + Polygon, + MultiPolygon, + Feature, + FeatureCollection, + AllGeoJSON +} from '../helpers' + +/** + * http://turfjs.org/docs/#flatten + */ +declare function flatten(geojson: Feature | FeatureCollection | T): FeatureCollection; +declare function flatten(geojson: Feature | FeatureCollection | T): FeatureCollection; +declare function flatten(geojson: Feature | FeatureCollection | T): FeatureCollection; +declare function flatten(geojson: AllGeoJSON): FeatureCollection; + +export default flatten; diff --git a/src/flatten/index.js b/src/flatten/index.js new file mode 100644 index 0000000000..cf889c2fbb --- /dev/null +++ b/src/flatten/index.js @@ -0,0 +1,32 @@ +import { flattenEach } from '../meta'; +import { featureCollection } from '../helpers'; + +/** + * Flattens any {@link GeoJSON} to a {@link FeatureCollection} inspired by [geojson-flatten](https://github.com/tmcw/geojson-flatten). + * + * @name flatten + * @param {GeoJSON} geojson any valid GeoJSON Object + * @returns {FeatureCollection} all Multi-Geometries are flattened into single Features + * @example + * var multiGeometry = turf.multiPolygon([ + * [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]], + * [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], + * [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]] + * ]); + * + * var flatten = turf.flatten(multiGeometry); + * + * //addToMap + * var addToMap = [flatten] + */ +function flatten(geojson) { + if (!geojson) throw new Error('geojson is required'); + + var results = []; + flattenEach(geojson, function (feature) { + results.push(feature); + }); + return featureCollection(results); +} + +export default flatten; diff --git a/packages/turf-flatten/test.js b/src/flatten/test.js similarity index 100% rename from packages/turf-flatten/test.js rename to src/flatten/test.js diff --git a/packages/turf-flatten/test/in/FeatureCollection.geojson b/src/flatten/test/in/FeatureCollection.geojson similarity index 100% rename from packages/turf-flatten/test/in/FeatureCollection.geojson rename to src/flatten/test/in/FeatureCollection.geojson diff --git a/packages/turf-flatten/test/in/GeometryCollection.geojson b/src/flatten/test/in/GeometryCollection.geojson similarity index 100% rename from packages/turf-flatten/test/in/GeometryCollection.geojson rename to src/flatten/test/in/GeometryCollection.geojson diff --git a/packages/turf-flatten/test/in/GeometryObject.geojson b/src/flatten/test/in/GeometryObject.geojson similarity index 100% rename from packages/turf-flatten/test/in/GeometryObject.geojson rename to src/flatten/test/in/GeometryObject.geojson diff --git a/packages/turf-flatten/test/in/MultiLineString.geojson b/src/flatten/test/in/MultiLineString.geojson similarity index 100% rename from packages/turf-flatten/test/in/MultiLineString.geojson rename to src/flatten/test/in/MultiLineString.geojson diff --git a/packages/turf-flatten/test/in/MultiPoint.geojson b/src/flatten/test/in/MultiPoint.geojson similarity index 100% rename from packages/turf-flatten/test/in/MultiPoint.geojson rename to src/flatten/test/in/MultiPoint.geojson diff --git a/packages/turf-flatten/test/in/MultiPolygon.geojson b/src/flatten/test/in/MultiPolygon.geojson similarity index 100% rename from packages/turf-flatten/test/in/MultiPolygon.geojson rename to src/flatten/test/in/MultiPolygon.geojson diff --git a/packages/turf-flatten/test/in/Polygon.geojson b/src/flatten/test/in/Polygon.geojson similarity index 100% rename from packages/turf-flatten/test/in/Polygon.geojson rename to src/flatten/test/in/Polygon.geojson diff --git a/packages/turf-flatten/test/out/FeatureCollection.geojson b/src/flatten/test/out/FeatureCollection.geojson similarity index 100% rename from packages/turf-flatten/test/out/FeatureCollection.geojson rename to src/flatten/test/out/FeatureCollection.geojson diff --git a/packages/turf-flatten/test/out/GeometryCollection.geojson b/src/flatten/test/out/GeometryCollection.geojson similarity index 100% rename from packages/turf-flatten/test/out/GeometryCollection.geojson rename to src/flatten/test/out/GeometryCollection.geojson diff --git a/packages/turf-flatten/test/out/GeometryObject.geojson b/src/flatten/test/out/GeometryObject.geojson similarity index 100% rename from packages/turf-flatten/test/out/GeometryObject.geojson rename to src/flatten/test/out/GeometryObject.geojson diff --git a/packages/turf-flatten/test/out/MultiLineString.geojson b/src/flatten/test/out/MultiLineString.geojson similarity index 100% rename from packages/turf-flatten/test/out/MultiLineString.geojson rename to src/flatten/test/out/MultiLineString.geojson diff --git a/packages/turf-flatten/test/out/MultiPoint.geojson b/src/flatten/test/out/MultiPoint.geojson similarity index 100% rename from packages/turf-flatten/test/out/MultiPoint.geojson rename to src/flatten/test/out/MultiPoint.geojson diff --git a/packages/turf-flatten/test/out/MultiPolygon.geojson b/src/flatten/test/out/MultiPolygon.geojson similarity index 100% rename from packages/turf-flatten/test/out/MultiPolygon.geojson rename to src/flatten/test/out/MultiPolygon.geojson diff --git a/packages/turf-flatten/test/out/Polygon.geojson b/src/flatten/test/out/Polygon.geojson similarity index 100% rename from packages/turf-flatten/test/out/Polygon.geojson rename to src/flatten/test/out/Polygon.geojson diff --git a/packages/turf-flip/bench.js b/src/flip/bench.js similarity index 100% rename from packages/turf-flip/bench.js rename to src/flip/bench.js diff --git a/packages/turf-flip/index.d.ts b/src/flip/index.d.ts similarity index 100% rename from packages/turf-flip/index.d.ts rename to src/flip/index.d.ts diff --git a/src/flip/index.js b/src/flip/index.js new file mode 100644 index 0000000000..b508179eb6 --- /dev/null +++ b/src/flip/index.js @@ -0,0 +1,42 @@ +import { coordEach } from '../meta'; +import { isObject } from '../helpers'; +import clone from '../clone'; + +/** + * Takes input features and flips all of their coordinates from `[x, y]` to `[y, x]`. + * + * @name flip + * @param {GeoJSON} geojson input features + * @param {Object} [options={}] Optional parameters + * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) + * @returns {GeoJSON} a feature or set of features of the same type as `input` with flipped coordinates + * @example + * var serbia = turf.point([20.566406, 43.421008]); + * + * var saudiArabia = turf.flip(serbia); + * + * //addToMap + * var addToMap = [serbia, saudiArabia]; + */ +function flip(geojson, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var mutate = options.mutate; + + if (!geojson) throw new Error('geojson is required'); + // ensure that we don't modify features in-place and changes to the + // output do not change the previous feature, including changes to nested + // properties. + if (mutate === false || mutate === undefined) geojson = clone(geojson); + + coordEach(geojson, function (coord) { + var x = coord[0]; + var y = coord[1]; + coord[0] = y; + coord[1] = x; + }); + return geojson; +} + +export default flip; \ No newline at end of file diff --git a/src/flip/test.js b/src/flip/test.js new file mode 100644 index 0000000000..5af37ce8d7 --- /dev/null +++ b/src/flip/test.js @@ -0,0 +1,42 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import { point } from '../helpers'; +import flip from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-flip', t => { + fixtures.forEach(fixture => { + const name = fixture.name; + const filename = fixture.filename; + const geojson = fixture.geojson; + const results = flip(geojson); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(load.sync(directories.out + filename), results, name); + }); + t.end(); +}); + +test('turf-flip - handle input mutation', t => { + const geojson = point([120, 40]); + flip(geojson); + t.deepEqual(geojson, point([120, 40]), 'does not mutate input'); + flip(geojson, {mutate: true}); + t.deepEqual(geojson, point([40, 120]), 'does mutate input'); + t.end(); +}); diff --git a/packages/turf-flip/test/in/feature-collection-points.geojson b/src/flip/test/in/feature-collection-points.geojson similarity index 100% rename from packages/turf-flip/test/in/feature-collection-points.geojson rename to src/flip/test/in/feature-collection-points.geojson diff --git a/packages/turf-flip/test/in/linestring.geojson b/src/flip/test/in/linestring.geojson similarity index 100% rename from packages/turf-flip/test/in/linestring.geojson rename to src/flip/test/in/linestring.geojson diff --git a/packages/turf-flip/test/in/point-with-elevation.geojson b/src/flip/test/in/point-with-elevation.geojson similarity index 100% rename from packages/turf-flip/test/in/point-with-elevation.geojson rename to src/flip/test/in/point-with-elevation.geojson diff --git a/packages/turf-flip/test/in/polygon.geojson b/src/flip/test/in/polygon.geojson similarity index 100% rename from packages/turf-flip/test/in/polygon.geojson rename to src/flip/test/in/polygon.geojson diff --git a/packages/turf-flip/test/out/feature-collection-points.geojson b/src/flip/test/out/feature-collection-points.geojson similarity index 100% rename from packages/turf-flip/test/out/feature-collection-points.geojson rename to src/flip/test/out/feature-collection-points.geojson diff --git a/packages/turf-flip/test/out/linestring.geojson b/src/flip/test/out/linestring.geojson similarity index 100% rename from packages/turf-flip/test/out/linestring.geojson rename to src/flip/test/out/linestring.geojson diff --git a/packages/turf-flip/test/out/point-with-elevation.geojson b/src/flip/test/out/point-with-elevation.geojson similarity index 100% rename from packages/turf-flip/test/out/point-with-elevation.geojson rename to src/flip/test/out/point-with-elevation.geojson diff --git a/packages/turf-flip/test/out/polygon.geojson b/src/flip/test/out/polygon.geojson similarity index 100% rename from packages/turf-flip/test/out/polygon.geojson rename to src/flip/test/out/polygon.geojson diff --git a/src/great-circle/bench.js b/src/great-circle/bench.js new file mode 100644 index 0000000000..c337fc5757 --- /dev/null +++ b/src/great-circle/bench.js @@ -0,0 +1,14 @@ +import Benchmark from 'benchmark'; +import { point } from '../helpers'; +import greatCircle from './'; + +const point1 = point([-75, 45]); +const point2 = point([30, 45]); + +const suite = new Benchmark.Suite('turf-great-circle'); + +suite + .add('greatCircle', () => { greatCircle(point1, point2); }) + .on('cycle', e => console.log(String(e.target))) + .on('complete', () => {}) + .run(); diff --git a/src/great-circle/index.d.ts b/src/great-circle/index.d.ts new file mode 100644 index 0000000000..8830eab3fe --- /dev/null +++ b/src/great-circle/index.d.ts @@ -0,0 +1,14 @@ +import { LineString, Feature, Coord, Properties } from '../helpers' + +/** + * http://turfjs.org/docs/#greatcircle + */ +export default function greatCircle( + start: Coord, + end: Coord, + options?: { + properties?: Properties, + npoints?: number, + offset?: number + } +): Feature; diff --git a/src/great-circle/index.js b/src/great-circle/index.js new file mode 100644 index 0000000000..e5d12c345a --- /dev/null +++ b/src/great-circle/index.js @@ -0,0 +1,48 @@ +import { getCoord } from '../invariant'; +import { GreatCircle } from './lib/arc'; + +/** + * Calculate great circles routes as {@link LineString} + * + * @name greatCircle + * @param {Coord} start source point feature + * @param {Coord} end destination point feature + * @param {Object} [options={}] Optional parameters + * @param {Object} [options.properties={}] line feature properties + * @param {number} [options.npoints=100] number of points + * @param {number} [options.offset=10] offset controls the likelyhood that lines will + * be split which cross the dateline. The higher the number the more likely. + * @returns {Feature} great circle line feature + * @example + * var start = turf.point([-122, 48]); + * var end = turf.point([-77, 39]); + * + * var greatCircle = turf.greatCircle(start, end, {'name': 'Seattle to DC'}); + * + * //addToMap + * var addToMap = [start, end, greatCircle] + */ +function greatCircle(start, end, options) { + // Optional parameters + options = options || {}; + if (typeof options !== 'object') throw new Error('options is invalid'); + var properties = options.properties; + var npoints = options.npoints; + var offset = options.offset; + + start = getCoord(start); + end = getCoord(end); + properties = properties || {}; + npoints = npoints || 100; + offset = offset || 10; + + var generator = new GreatCircle({x: start[0], y: start[1]}, {x: end[0], y: end[1]}, properties); + + /* eslint-disable */ + var line = generator.Arc(npoints, {offset: offset}); + /* eslint-enable */ + + return line.json(); +} + +export default greatCircle; \ No newline at end of file diff --git a/packages/turf-great-circle/lib/arc.js b/src/great-circle/lib/arc.js similarity index 100% rename from packages/turf-great-circle/lib/arc.js rename to src/great-circle/lib/arc.js diff --git a/src/great-circle/test.js b/src/great-circle/test.js new file mode 100644 index 0000000000..2b80fc623d --- /dev/null +++ b/src/great-circle/test.js @@ -0,0 +1,37 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import truncate from '../truncate'; +import { featureCollection } from '../helpers'; +import greatCircle from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(path.join(directories.in, filename)) + }; +}); + +test('turf-great-circle', t => { + fixtures.forEach(fixture => { + const name = fixture.name; + const filename = fixture.filename; + const geojson = fixture.geojson; + const start = geojson.features[0]; + const end = geojson.features[1]; + const line = truncate(greatCircle(start, end)); + const results = featureCollection([line, start, end]); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEquals(results, load.sync(directories.out + filename), name); + }); + t.end(); +}); diff --git a/packages/turf-great-circle/test/in/basic.geojson b/src/great-circle/test/in/basic.geojson similarity index 100% rename from packages/turf-great-circle/test/in/basic.geojson rename to src/great-circle/test/in/basic.geojson diff --git a/packages/turf-great-circle/test/out/basic.geojson b/src/great-circle/test/out/basic.geojson similarity index 100% rename from packages/turf-great-circle/test/out/basic.geojson rename to src/great-circle/test/out/basic.geojson diff --git a/packages/turf-helpers/bench.js b/src/helpers/bench.js similarity index 100% rename from packages/turf-helpers/bench.js rename to src/helpers/bench.js diff --git a/src/helpers/index.d.ts b/src/helpers/index.d.ts new file mode 100644 index 0000000000..d055a14cec --- /dev/null +++ b/src/helpers/index.d.ts @@ -0,0 +1,480 @@ +import { BBox, CollectionTypes, Feature, FeatureCollection, GeoJSONObject, Geometries, Geometry, GeometryCollection, GeometryObject, GeometryTypes, Id, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, Position, Properties, Types } from "./lib/geojson"; +export { Id, Properties, BBox, Position, Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryObject, GeoJSONObject, GeometryCollection, Geometry, GeometryTypes, Types, CollectionTypes, Geometries, Feature, FeatureCollection }; +export declare type Coord = Feature | Point | Position; +export declare type Units = "meters" | "millimeters" | "centimeters" | "kilometers" | "acres" | "miles" | "nauticalmiles" | "inches" | "yards" | "feet" | "radians" | "degrees"; +export declare type Grid = "point" | "square" | "hex" | "triangle"; +export declare type Corners = "sw" | "se" | "nw" | "ne" | "center" | "centroid"; +export declare type Lines = LineString | MultiLineString | Polygon | MultiPolygon; +export declare type AllGeoJSON = Feature | FeatureCollection | Geometry | GeometryCollection; +/** + * @module helpers + */ +/** + * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth. + * + * @memberof helpers + * @type {number} + */ +export declare let earthRadius: number; +/** + * Unit of measurement factors using a spherical (non-ellipsoid) earth radius. + * + * @memberof helpers + * @type {Object} + */ +export declare let factors: { + [key: string]: number; +}; +/** + * Area of measurement factors based on 1 square meter. + * + * @memberof helpers + * @type {Object} + */ +export declare let areaFactors: any; +/** + * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}. + * + * @name feature + * @param {Geometry} geometry input geometry + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} a GeoJSON Feature + * @example + * var geometry = { + * "type": "Point", + * "coordinates": [110, 50] + * }; + * + * var feature = turf.feature(geometry); + * + * //=feature + */ +export declare function feature(geom: G, properties?: P, options?: { + bbox?: BBox; + id?: Id; +}): Feature; +/** + * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates. + * For GeometryCollection type use `helpers.geometryCollection` + * + * @name geometry + * @param {string} type Geometry Type + * @param {Array} coordinates Coordinates + * @param {Object} [options={}] Optional Parameters + * @returns {Geometry} a GeoJSON Geometry + * @example + * var type = "Point"; + * var coordinates = [110, 50]; + * var geometry = turf.geometry(type, coordinates); + * // => geometry + */ +export declare function geometry(type: "Point" | "LineString" | "Polygon" | "MultiPoint" | "MultiLineString" | "MultiPolygon", coordinates: any[], options?: {}): Point | LineString | Polygon | MultiPoint | MultiLineString | MultiPolygon; +/** + * Creates a {@link Point} {@link Feature} from a Position. + * + * @name point + * @param {Array} coordinates longitude, latitude position (each in decimal degrees) + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} a Point feature + * @example + * var point = turf.point([-75.343, 39.984]); + * + * //=point + */ +export declare function point

(coordinates: Position, properties?: P, options?: { + bbox?: BBox; + id?: Id; +}): Feature; +/** + * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates. + * + * @name points + * @param {Array>} coordinates an array of Points + * @param {Object} [properties={}] Translate these properties to each Feature + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] + * associated with the FeatureCollection + * @param {string|number} [options.id] Identifier associated with the FeatureCollection + * @returns {FeatureCollection} Point Feature + * @example + * var points = turf.points([ + * [-75, 39], + * [-80, 45], + * [-78, 50] + * ]); + * + * //=points + */ +export declare function points

(coordinates: Position[], properties?: P, options?: { + bbox?: BBox; + id?: Id; +}): FeatureCollection; +/** + * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings. + * + * @name polygon + * @param {Array>>} coordinates an array of LinearRings + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} Polygon Feature + * @example + * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' }); + * + * //=polygon + */ +export declare function polygon

(coordinates: Position[][], properties?: P, options?: { + bbox?: BBox; + id?: Id; +}): Feature; +/** + * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates. + * + * @name polygons + * @param {Array>>>} coordinates an array of Polygon coordinates + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the FeatureCollection + * @returns {FeatureCollection} Polygon FeatureCollection + * @example + * var polygons = turf.polygons([ + * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], + * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]], + * ]); + * + * //=polygons + */ +export declare function polygons

(coordinates: Position[][][], properties?: P, options?: { + bbox?: BBox; + id?: Id; +}): FeatureCollection; +/** + * Creates a {@link LineString} {@link Feature} from an Array of Positions. + * + * @name lineString + * @param {Array>} coordinates an array of Positions + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} LineString Feature + * @example + * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'}); + * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'}); + * + * //=linestring1 + * //=linestring2 + */ +export declare function lineString

(coordinates: Position[], properties?: P, options?: { + bbox?: BBox; + id?: Id; +}): Feature; +/** + * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates. + * + * @name lineStrings + * @param {Array>>} coordinates an array of LinearRings + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] + * associated with the FeatureCollection + * @param {string|number} [options.id] Identifier associated with the FeatureCollection + * @returns {FeatureCollection} LineString FeatureCollection + * @example + * var linestrings = turf.lineStrings([ + * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]], + * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]] + * ]); + * + * //=linestrings + */ +export declare function lineStrings

(coordinates: Position[][], properties?: P, options?: { + bbox?: BBox; + id?: Id; +}): FeatureCollection; +/** + * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}. + * + * @name featureCollection + * @param {Feature[]} features input features + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {FeatureCollection} FeatureCollection of Features + * @example + * var locationA = turf.point([-75.343, 39.984], {name: 'Location A'}); + * var locationB = turf.point([-75.833, 39.284], {name: 'Location B'}); + * var locationC = turf.point([-75.534, 39.123], {name: 'Location C'}); + * + * var collection = turf.featureCollection([ + * locationA, + * locationB, + * locationC + * ]); + * + * //=collection + */ +export declare function featureCollection(features: Array>, options?: { + bbox?: BBox; + id?: Id; +}): FeatureCollection; +/** + * Creates a {@link Feature} based on a + * coordinate array. Properties can be added optionally. + * + * @name multiLineString + * @param {Array>>} coordinates an array of LineStrings + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} a MultiLineString feature + * @throws {Error} if no coordinates are passed + * @example + * var multiLine = turf.multiLineString([[[0,0],[10,10]]]); + * + * //=multiLine + */ +export declare function multiLineString

(coordinates: Position[][], properties?: P, options?: { + bbox?: BBox; + id?: Id; +}): Feature; +/** + * Creates a {@link Feature} based on a + * coordinate array. Properties can be added optionally. + * + * @name multiPoint + * @param {Array>} coordinates an array of Positions + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} a MultiPoint feature + * @throws {Error} if no coordinates are passed + * @example + * var multiPt = turf.multiPoint([[0,0],[10,10]]); + * + * //=multiPt + */ +export declare function multiPoint

(coordinates: Position[], properties?: P, options?: { + bbox?: BBox; + id?: Id; +}): Feature; +/** + * Creates a {@link Feature} based on a + * coordinate array. Properties can be added optionally. + * + * @name multiPolygon + * @param {Array>>>} coordinates an array of Polygons + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} a multipolygon feature + * @throws {Error} if no coordinates are passed + * @example + * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]); + * + * //=multiPoly + * + */ +export declare function multiPolygon

(coordinates: Position[][][], properties?: P, options?: { + bbox?: BBox; + id?: Id; +}): Feature; +/** + * Creates a {@link Feature} based on a + * coordinate array. Properties can be added optionally. + * + * @name geometryCollection + * @param {Array} geometries an array of GeoJSON Geometries + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} a GeoJSON GeometryCollection Feature + * @example + * var pt = turf.geometry("Point", [100, 0]); + * var line = turf.geometry("LineString", [[101, 0], [102, 1]]); + * var collection = turf.geometryCollection([pt, line]); + * + * // => collection + */ +export declare function geometryCollection

(geometries: Array, properties?: P, options?: { + bbox?: BBox; + id?: Id; +}): Feature; +/** + * Round number to precision + * + * @param {number} num Number + * @param {number} [precision=0] Precision + * @returns {number} rounded number + * @example + * turf.round(120.4321) + * //=120 + * + * turf.round(120.4321, 2) + * //=120.43 + */ +export declare function round(num: number, precision?: number): number; +/** + * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit. + * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet + * + * @name radiansToLength + * @param {number} radians in radians across the sphere + * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers inches, yards, metres, + * meters, kilometres, kilometers. + * @returns {number} distance + */ +export declare function radiansToLength(radians: number, units?: Units): number; +/** + * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians + * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet + * + * @name lengthToRadians + * @param {number} distance in real units + * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers inches, yards, metres, + * meters, kilometres, kilometers. + * @returns {number} radians + */ +export declare function lengthToRadians(distance: number, units?: Units): number; +/** + * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees + * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet + * + * @name lengthToDegrees + * @param {number} distance in real units + * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers inches, yards, metres, + * meters, kilometres, kilometers. + * @returns {number} degrees + */ +export declare function lengthToDegrees(distance: number, units?: Units): number; +/** + * Converts any bearing angle from the north line direction (positive clockwise) + * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line + * + * @name bearingToAzimuth + * @param {number} bearing angle, between -180 and +180 degrees + * @returns {number} angle between 0 and 360 degrees + */ +export declare function bearingToAzimuth(bearing: number): number; +/** + * Converts an angle in radians to degrees + * + * @name radiansToDegrees + * @param {number} radians angle in radians + * @returns {number} degrees between 0 and 360 degrees + */ +export declare function radiansToDegrees(radians: number): number; +/** + * Converts an angle in degrees to radians + * + * @name degreesToRadians + * @param {number} degrees angle between 0 and 360 degrees + * @returns {number} angle in radians + */ +export declare function degreesToRadians(degrees: number): number; +/** + * Converts a length to the requested unit. + * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet + * + * @param {number} length to be converted + * @param {Units} [originalUnit="kilometers"] of the length + * @param {Units} [finalUnit="kilometers"] returned unit + * @returns {number} the converted length + */ +export declare function convertLength(length: number, originalUnit?: Units, finalUnit?: Units): number; +/** + * Converts a area to the requested unit. + * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches + * @param {number} area to be converted + * @param {Units} [originalUnit="meters"] of the distance + * @param {Units} [finalUnit="kilometers"] returned unit + * @returns {number} the converted distance + */ +export declare function convertArea(area: number, originalUnit?: Units, finalUnit?: Units): number; +/** + * isNumber + * + * @param {*} num Number to validate + * @returns {boolean} true/false + * @example + * turf.isNumber(123) + * //=true + * turf.isNumber('foo') + * //=false + */ +export declare function isNumber(num: any): boolean; +/** + * isObject + * + * @param {*} input variable to validate + * @returns {boolean} true/false + * @example + * turf.isObject({elevation: 10}) + * //=true + * turf.isObject('foo') + * //=false + */ +export declare function isObject(input: any): boolean; +/** + * Validate BBox + * + * @private + * @param {Array} bbox BBox to validate + * @returns {void} + * @throws Error if BBox is not valid + * @example + * validateBBox([-180, -40, 110, 50]) + * //=OK + * validateBBox([-180, -40]) + * //=Error + * validateBBox('Foo') + * //=Error + * validateBBox(5) + * //=Error + * validateBBox(null) + * //=Error + * validateBBox(undefined) + * //=Error + */ +export declare function validateBBox(bbox: any): void; +/** + * Validate Id + * + * @private + * @param {string|number} id Id to validate + * @returns {void} + * @throws Error if Id is not valid + * @example + * validateId([-180, -40, 110, 50]) + * //=Error + * validateId([-180, -40]) + * //=Error + * validateId('Foo') + * //=OK + * validateId(5) + * //=OK + * validateId(null) + * //=Error + * validateId(undefined) + * //=Error + */ +export declare function validateId(id: any): void; +export declare function radians2degrees(): void; +export declare function degrees2radians(): void; +export declare function distanceToDegrees(): void; +export declare function distanceToRadians(): void; +export declare function radiansToDistance(): void; +export declare function bearingToAngle(): void; +export declare function convertDistance(): void; diff --git a/src/helpers/index.js b/src/helpers/index.js new file mode 100644 index 0000000000..10e5dc6447 --- /dev/null +++ b/src/helpers/index.js @@ -0,0 +1,687 @@ +/** + * @module helpers + */ + +/** + * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth. + * + * @memberof helpers + * @type {number} + */ +export const earthRadius = 6371008.8; + +/** + * Unit of measurement factors using a spherical (non-ellipsoid) earth radius. + * + * @memberof helpers + * @type {Object} + */ +export const factors = { + centimeters: earthRadius * 100, + centimetres: earthRadius * 100, + degrees: 180 / Math.PI, // See https://github.com/Turfjs/turf/issues/1406 + feet: earthRadius * 3.28084, + inches: earthRadius * 39.370, + kilometers: earthRadius / 1000, + kilometres: earthRadius / 1000, + meters: earthRadius, + metres: earthRadius, + miles: earthRadius / 1609.344, + millimeters: earthRadius * 1000, + millimetres: earthRadius * 1000, + nauticalmiles: earthRadius / 1852, + radians: 1, + yards: earthRadius / 1.0936, +}; + +/** + * Area of measurement factors based on 1 square meter. + * + * @memberof helpers + * @type {Object} + */ +export const areaFactors = { + acres: 0.000247105, + centimeters: 10000, + centimetres: 10000, + feet: 10.763910417, + inches: 1550.003100006, + kilometers: 0.000001, + kilometres: 0.000001, + meters: 1, + metres: 1, + miles: 3.86e-7, + millimeters: 1000000, + millimetres: 1000000, + yards: 1.195990046, +}; + +/** + * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}. + * + * @name feature + * @param {Geometry} geometry input geometry + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} a GeoJSON Feature + * @example + * var geometry = { + * 'type': 'Point', + * 'coordinates': [110, 50] + * }; + * + * var feature = turf.feature(geometry); + * + * //=feature + */ +export function feature(geometry, properties, options) { + options = checkIfOptionsExist(options); + const feat = {type: 'Feature'}; + if (options.id === 0 || options.id) { feat.id = options.id; } + if (options.bbox) { feat.bbox = options.bbox; } + feat.properties = properties || {}; + feat.geometry = geometry; + return feat; +} + +/** + * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates. + * For GeometryCollection type use `helpers.geometryCollection` + * + * @name geometry + * @param {string} type Geometry Type + * @param {Array} coordinates Coordinates + * @returns {Geometry} a GeoJSON Geometry + * @example + * var type = 'Point'; + * var coordinates = [110, 50]; + * var geometry = turf.geometry(type, coordinates); + * // => geometry + */ +export function geometry(type, coordinates) { + switch (type) { + case 'Point': return point(coordinates).geometry; + case 'LineString': return lineString(coordinates).geometry; + case 'Polygon': return polygon(coordinates).geometry; + case 'MultiPoint': return multiPoint(coordinates).geometry; + case 'MultiLineString': return multiLineString(coordinates).geometry; + case 'MultiPolygon': return multiPolygon(coordinates).geometry; + default: throw new Error(type + ' is invalid'); + } +} + +/** + * Creates a {@link Point} {@link Feature} from a Position. + * + * @name point + * @param {Array} coordinates longitude, latitude position (each in decimal degrees) + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} a Point feature + * @example + * var point = turf.point([-75.343, 39.984]); + * + * //=point + */ +export function point(coordinates, properties, options) { + options = checkIfOptionsExist(options); + const geom = { + type: 'Point', + coordinates, + }; + return feature(geom, properties, options); +} + +/** + * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates. + * + * @name points + * @param {Array>} coordinates an array of Points + * @param {Object} [properties={}] Translate these properties to each Feature + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] + * associated with the FeatureCollection + * @param {string|number} [options.id] Identifier associated with the FeatureCollection + * @returns {FeatureCollection} Point Feature + * @example + * var points = turf.points([ + * [-75, 39], + * [-80, 45], + * [-78, 50] + * ]); + * + * //=points + */ +export function points(coordinates, properties, options) { + options = checkIfOptionsExist(options); + return featureCollection(coordinates.map((coords) => { + return point(coords, properties); + }), options); +} + +/** + * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings. + * + * @name polygon + * @param {Array>>} coordinates an array of LinearRings + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} Polygon Feature + * @example + * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' }); + * + * //=polygon + */ +export function polygon(coordinates, properties, options) { + options = checkIfOptionsExist(options); + for (const ring of coordinates) { + if (ring.length < 4) { + throw new Error('Each LinearRing of a Polygon must have 4 or more Positions.'); + } + for (let j = 0; j < ring[ring.length - 1].length; j++) { + // Check if first point of Polygon contains two numbers + if (ring[ring.length - 1][j] !== ring[0][j]) { + throw new Error('First and last Position are not equivalent.'); + } + } + } + const geom = { + type: 'Polygon', + coordinates, + }; + return feature(geom, properties, options); +} + +/** + * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates. + * + * @name polygons + * @param {Array>>>} coordinates an array of Polygon coordinates + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the FeatureCollection + * @returns {FeatureCollection} Polygon FeatureCollection + * @example + * var polygons = turf.polygons([ + * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], + * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]], + * ]); + * + * //=polygons + */ +export function polygons(coordinates, properties, options) { + options = checkIfOptionsExist(options); + return featureCollection(coordinates.map((coords) => { + return polygon(coords, properties); + }), options); +} + +/** + * Creates a {@link LineString} {@link Feature} from an Array of Positions. + * + * @name lineString + * @param {Array>} coordinates an array of Positions + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} LineString Feature + * @example + * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'}); + * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'}); + * + * //=linestring1 + * //=linestring2 + */ +export function lineString(coordinates, properties, options) { + options = checkIfOptionsExist(options); + if (coordinates.length < 2) { throw new Error('coordinates must be an array of two or more positions'); } + const geom = { + type: 'LineString', + coordinates, + }; + return feature(geom, properties, options); +} + +/** + * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates. + * + * @name lineStrings + * @param {Array>>} coordinates an array of LinearRings + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] + * associated with the FeatureCollection + * @param {string|number} [options.id] Identifier associated with the FeatureCollection + * @returns {FeatureCollection} LineString FeatureCollection + * @example + * var linestrings = turf.lineStrings([ + * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]], + * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]] + * ]); + * + * //=linestrings + */ +export function lineStrings(coordinates, properties, options) { + options = checkIfOptionsExist(options); + return featureCollection(coordinates.map((coords) => { + return lineString(coords, properties); + }), options); +} + +/** + * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}. + * + * @name featureCollection + * @param {Feature[]} features input features + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {FeatureCollection} FeatureCollection of Features + * @example + * var locationA = turf.point([-75.343, 39.984], {name: 'Location A'}); + * var locationB = turf.point([-75.833, 39.284], {name: 'Location B'}); + * var locationC = turf.point([-75.534, 39.123], {name: 'Location C'}); + * + * var collection = turf.featureCollection([ + * locationA, + * locationB, + * locationC + * ]); + * + * //=collection + */ +export function featureCollection(features, options) { + options = checkIfOptionsExist(options); + const fc = {type: 'FeatureCollection'}; + if (options.id) { fc.id = options.id; } + if (options.bbox) { fc.bbox = options.bbox; } + fc.features = features; + return fc; +} + +/** + * Creates a {@link Feature} based on a + * coordinate array. Properties can be added optionally. + * + * @name multiLineString + * @param {Array>>} coordinates an array of LineStrings + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} a MultiLineString feature + * @throws {Error} if no coordinates are passed + * @example + * var multiLine = turf.multiLineString([[[0,0],[10,10]]]); + * + * //=multiLine + */ +export function multiLineString(coordinates, properties, options) { + options = checkIfOptionsExist(options); + const geom = { + type: 'MultiLineString', + coordinates, + }; + return feature(geom, properties, options); +} + +/** + * Creates a {@link Feature} based on a + * coordinate array. Properties can be added optionally. + * + * @name multiPoint + * @param {Array>} coordinates an array of Positions + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} a MultiPoint feature + * @throws {Error} if no coordinates are passed + * @example + * var multiPt = turf.multiPoint([[0,0],[10,10]]); + * + * //=multiPt + */ +export function multiPoint(coordinates, properties, options) { + options = checkIfOptionsExist(options); + const geom = { + type: 'MultiPoint', + coordinates, + }; + return feature(geom, properties, options); +} + +/** + * Creates a {@link Feature} based on a + * coordinate array. Properties can be added optionally. + * + * @name multiPolygon + * @param {Array>>>} coordinates an array of Polygons + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} a multipolygon feature + * @throws {Error} if no coordinates are passed + * @example + * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]); + * + * //=multiPoly + * + */ +export function multiPolygon(coordinates, properties, options) { + options = checkIfOptionsExist(options); + const geom = { + type: 'MultiPolygon', + coordinates, + }; + return feature(geom, properties, options); +} + +/** + * Creates a {@link Feature} based on a + * coordinate array. Properties can be added optionally. + * + * @name geometryCollection + * @param {Array} geometries an array of GeoJSON Geometries + * @param {Object} [properties={}] an Object of key-value pairs to add as properties + * @param {Object} [options={}] Optional Parameters + * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature + * @param {string|number} [options.id] Identifier associated with the Feature + * @returns {Feature} a GeoJSON GeometryCollection Feature + * @example + * var pt = turf.geometry('Point', [100, 0]); + * var line = turf.geometry('LineString', [[101, 0], [102, 1]]); + * var collection = turf.geometryCollection([pt, line]); + * + * // => collection + */ +export function geometryCollection(geometries, properties, options) { + options = checkIfOptionsExist(options); + const geom = { + type: 'GeometryCollection', + geometries, + }; + return feature(geom, properties, options); +} + +/** + * Round number to precision + * + * @param {number} num Number + * @param {number} [precision=0] Precision + * @returns {number} rounded number + * @example + * turf.round(120.4321) + * //=120 + * + * turf.round(120.4321, 2) + * //=120.43 + */ +export function round(num, precision) { + if (precision && !(precision >= 0)) { throw new Error('precision must be a positive number'); } + const multiplier = Math.pow(10, precision || 0); + return Math.round(num * multiplier) / multiplier; +} + +/** + * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit. + * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet + * + * @name radiansToLength + * @param {number} radians in radians across the sphere + * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, + * meters, kilometres, kilometers. + * @returns {number} distance + */ +export function radiansToLength(radians, units) { + if (radians === undefined || radians === null) throw new Error('radians is required'); + if (units && typeof units !== 'string') throw new Error('units must be a string'); + + var factor = factors[units || 'kilometers']; + if (!factor) { throw new Error(units + ' units is invalid'); } + return radians * factor; +} + +/** + * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians + * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet + * + * @name lengthToRadians + * @param {number} distance in real units + * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, + * meters, kilometres, kilometers. + * @returns {number} radians + */ +export function lengthToRadians(distance, units) { + if (distance === undefined || distance === null) throw new Error('distance is required'); + if (units && typeof units !== 'string') throw new Error('units must be a string'); + + var factor = factors[units || 'kilometers']; + if (!factor) { throw new Error(units + ' units is invalid'); } + return distance / factor; +} + +/** + * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees + * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet + * + * @name lengthToDegrees + * @param {number} distance in real units + * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, + * meters, kilometres, kilometers. + * @returns {number} degrees + */ +export function lengthToDegrees(distance, units) { + if (units === null) units = 'kilometers'; + return radiansToDegrees(lengthToRadians(distance, units)); +} + +/** + * Converts any bearing angle from the north line direction (positive clockwise) + * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line + * + * @name bearingToAzimuth + * @param {number} bearing angle, between -180 and +180 degrees + * @returns {number} angle between 0 and 360 degrees + */ +export function bearingToAzimuth(bearing) { + if (bearing === null || bearing === undefined) throw new Error('bearing is required'); + + let angle = bearing % 360; + if (angle < 0) { angle += 360; } + return angle; +} + +/** + * Converts an angle in radians to degrees + * + * @name radiansToDegrees + * @param {number} radians angle in radians + * @returns {number} degrees between 0 and 360 degrees + */ +export function radiansToDegrees(radians) { + if (radians === null || radians === undefined) throw new Error('radians is required'); + + const degrees = radians % (2 * Math.PI); + return degrees * 180 / Math.PI; +} + +/** + * Converts an angle in degrees to radians + * + * @name degreesToRadians + * @param {number} degrees angle between 0 and 360 degrees + * @returns {number} angle in radians + */ +export function degreesToRadians(degrees) { + if (degrees === null || degrees === undefined) throw new Error('degrees is required'); + + const radians = degrees % 360; + return radians * Math.PI / 180; +} + +/** + * Converts a length to the requested unit. + * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet + * + * @param {number} length to be converted + * @param {Units} [originalUnit='kilometers'] of the length + * @param {Units} [finalUnit='kilometers'] returned unit + * @returns {number} the converted length + */ +export function convertLength(length, originalUnit, finalUnit) { + if (length === null || length === undefined) throw new Error('length is required'); + + return radiansToLength(lengthToRadians(length, originalUnit), finalUnit || 'kilometers'); +} + +/** + * Converts a area to the requested unit. + * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches + * @param {number} area to be converted + * @param {Units} [originalUnit='meters'] of the distance + * @param {Units} [finalUnit='kilometers'] returned unit + * @returns {number} the converted distance + */ +export function convertArea(area, originalUnit, finalUnit) { + if (area === null || area === undefined) throw new Error('area is required'); + if (!(area >= 0)) throw new Error('area must be a positive number'); + + var startFactor = areaFactors[originalUnit || 'meters']; + if (!startFactor) throw new Error('invalid original units'); + + var finalFactor = areaFactors[finalUnit || 'kilometers']; + if (!finalFactor) throw new Error('invalid final units'); + + return (area / startFactor) * finalFactor; +} + +/** + * isNumber + * + * @param {*} num Number to validate + * @returns {boolean} true/false + * @example + * turf.isNumber(123) + * //=true + * turf.isNumber('foo') + * //=false + */ +export function isNumber(num) { + return !isNaN(num) && num !== null && !Array.isArray(num); +} + +/** + * isObject + * + * @param {*} input variable to validate + * @returns {boolean} true/false + * @example + * turf.isObject({elevation: 10}) + * //=true + * turf.isObject('foo') + * //=false + */ +export function isObject(input) { + return (!!input) && (input.constructor === Object); +} + +/** + * Validate BBox + * + * @private + * @param {Array} bbox BBox to validate + * @returns {void} + * @throws Error if BBox is not valid + * @example + * validateBBox([-180, -40, 110, 50]) + * //=OK + * validateBBox([-180, -40]) + * //=Error + * validateBBox('Foo') + * //=Error + * validateBBox(5) + * //=Error + * validateBBox(null) + * //=Error + * validateBBox(undefined) + * //=Error + */ +export function validateBBox(bbox) { + if (!bbox) { throw new Error('bbox is required'); } + if (!Array.isArray(bbox)) { throw new Error('bbox must be an Array'); } + if (bbox.length !== 4 && bbox.length !== 6) { throw new Error('bbox must be an Array of 4 or 6 numbers'); } + bbox.forEach((num) => { + if (!isNumber(num)) { throw new Error('bbox must only contain numbers'); } + }); +} + +/** + * Validate Id + * + * @private + * @param {string|number} id Id to validate + * @returns {void} + * @throws Error if Id is not valid + * @example + * validateId([-180, -40, 110, 50]) + * //=Error + * validateId([-180, -40]) + * //=Error + * validateId('Foo') + * //=OK + * validateId(5) + * //=OK + * validateId(null) + * //=Error + * validateId(undefined) + * //=Error + */ +export function validateId(id) { + if (!id) { throw new Error('id is required'); } + if (['string', 'number'].indexOf(typeof id) === -1) { throw new Error('id must be a number or a string'); } +} + +export function checkIfOptionsExist(options) { + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + return options; +} + +// Deprecated methods +export function radians2degrees() { + throw new Error('method has been renamed to `radiansToDegrees`'); +} + +export function degrees2radians() { + throw new Error('method has been renamed to `degreesToRadians`'); +} + +export function distanceToDegrees() { + throw new Error('method has been renamed to `lengthToDegrees`'); +} + +export function distanceToRadians() { + throw new Error('method has been renamed to `lengthToRadians`'); +} + +export function radiansToDistance() { + throw new Error('method has been renamed to `radiansToLength`'); +} + +export function bearingToAngle() { + throw new Error('method has been renamed to `bearingToAzimuth`'); +} + +export function convertDistance() { + throw new Error('method has been renamed to `convertLength`'); +} diff --git a/src/helpers/test.js b/src/helpers/test.js new file mode 100644 index 0000000000..7b0096c9f3 --- /dev/null +++ b/src/helpers/test.js @@ -0,0 +1,509 @@ +const test = require('tape'); +const { + point, polygon, lineString, + feature, featureCollection, geometryCollection, + multiLineString, multiPoint, multiPolygon, + radiansToLength, lengthToRadians, lengthToDegrees, radiansToDegrees, degreesToRadians, + bearingToAzimuth, convertLength, convertArea, + round, isObject, isNumber, earthRadius +} = require('./'); +const turf = require('./'); + +test('point', t => { + const ptArray = point([5, 10], {name: 'test point'}); + + t.ok(ptArray); + t.equal(ptArray.geometry.coordinates[0], 5); + t.equal(ptArray.geometry.coordinates[1], 10); + t.equal(ptArray.properties.name, 'test point'); + + // t.throws(() => { + // point('hey', 'invalid'); + // }, 'numbers required'); + + const noProps = point([0, 0]); + t.deepEqual(noProps.properties, {}, 'no props becomes {}'); + + t.end(); +}); + +test('polygon', t => { + const poly = polygon([[[5, 10], [20, 40], [40, 0], [5, 10]]], {name: 'test polygon'}); + t.ok(poly); + t.equal(poly.geometry.coordinates[0][0][0], 5); + t.equal(poly.geometry.coordinates[0][1][0], 20); + t.equal(poly.geometry.coordinates[0][2][0], 40); + t.equal(poly.properties.name, 'test polygon'); + t.equal(poly.geometry.type, 'Polygon'); + t.throws(() => { + t.equal(polygon([[[20.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]]).message); + }, /First and last Position are not equivalent/, 'invalid ring - not wrapped'); + t.throws(() => { + t.equal(polygon([[[20.0, 0.0], [101.0, 0.0]]]).message); + }, /Each LinearRing of a Polygon must have 4 or more Positions/, 'invalid ring - too few positions'); + const noProperties = polygon([[[5, 10], [20, 40], [40, 0], [5, 10]]]); + t.deepEqual(noProperties.properties, {}); + t.end(); +}); + +test('lineString', t => { + const line = lineString([[5, 10], [20, 40]], {name: 'test line'}); + t.ok(line, 'creates a linestring'); + t.equal(line.geometry.coordinates[0][0], 5); + t.equal(line.geometry.coordinates[1][0], 20); + t.equal(line.properties.name, 'test line'); + t.deepEqual(lineString([[5, 10], [20, 40]]).properties, {}, 'no properties case'); + + t.throws(() => lineString(), 'error on no coordinates'); + t.throws(() => lineString([[5, 10]]), 'coordinates must be an array of two or more positions'); + t.throws(() => lineString([['xyz', 10]]), 'coordinates must contain numbers'); + t.throws(() => lineString([[5, 'xyz']]), 'coordinates must contain numbers'); + t.end(); +}); + +test('featureCollection', t => { + const p1 = point([0, 0], {name: 'first point'}); + const p2 = point([0, 10]); + const p3 = point([10, 10]); + const p4 = point([10, 0]); + const fc = featureCollection([p1, p2, p3, p4]); + t.ok(fc); + t.equal(fc.features.length, 4); + t.equal(fc.features[0].properties.name, 'first point'); + t.equal(fc.type, 'FeatureCollection'); + t.equal(fc.features[1].geometry.type, 'Point'); + t.equal(fc.features[1].geometry.coordinates[0], 0); + t.equal(fc.features[1].geometry.coordinates[1], 10); + // t.throws(() => featureCollection(fc), /features must be an Array/); + // t.throws(() => featureCollection(p1), /features must be an Array/); + t.end(); +}); + +test('multilinestring', t => { + t.deepEqual(multiLineString([[[0, 0], [10, 10]], [[5, 0], [15, 8]]]), { + type: 'Feature', + properties: {}, + geometry: { + type: 'MultiLineString', + coordinates: [[[0, 0], [10, 10]], [[5, 0], [15, 8]]] + } + }, 'takes coordinates'); + + t.deepEqual(multiLineString([[[0, 0], [10, 10]], [[5, 0], [15, 8]]], {test: 23}), { + type: 'Feature', + properties: { + test: 23 + }, + geometry: { + type: 'MultiLineString', + coordinates: [[[0, 0], [10, 10]], [[5, 0], [15, 8]]] + } + }, 'takes properties'); + + + // t.throws(() => { + // multiLineString(); + // }, 'throws error with no coordinates'); + + t.end(); +}); + + +test('multiPoint', t => { + t.deepEqual(multiPoint([[0, 0], [10, 10]]), { + type: 'Feature', + properties: {}, + geometry: { + type: 'MultiPoint', + coordinates: [ + [0, 0], + [10, 10] + ] + } + }, 'takes coordinates'); + + t.deepEqual(multiPoint([[0, 0], [10, 10]], {test: 23}), { + type: 'Feature', + properties: { + test: 23 + }, + geometry: { + type: 'MultiPoint', + coordinates: [ + [0, 0], + [10, 10] + ] + } + }, 'takes properties'); + + + // t.throws(() => { + // multiPoint(); + // }, 'throws error with no coordinates'); + + t.end(); +}); + +test('feature', t => { + const pt = { + type: 'Point', + coordinates: [ + 67.5, + 32.84267363195431 + ] + }; + const line = { + type: 'LineString', + coordinates: [ + [ + 82.96875, + 58.99531118795094 + ], + [ + 72.7734375, + 55.57834467218206 + ], + [ + 84.0234375, + 55.57834467218206 + ] + ] + }; + const polygon = { + type: 'Polygon', + coordinates: [ + [ + [ + 85.78125, + -3.513421045640032 + ], + [ + 85.78125, + 13.581920900545844 + ], + [ + 92.46093749999999, + 13.581920900545844 + ], + [ + 92.46093749999999, + -3.513421045640032 + ], + [ + 85.78125, + -3.513421045640032 + ] + ] + ] + }; + t.end(); +}); + +test('multipolygon', t =>{ + t.deepEqual(multiPolygon([[[[94, 57], [78, 49], [94, 43], [94, 57]]], [[[93, 19], [63, 7], [79, 0], [93, 19]]]]), { + type: 'Feature', + properties: {}, + geometry: { + type: 'MultiPolygon', + coordinates: [[[[94, 57], [78, 49], [94, 43], [94, 57]]], [[[93, 19], [63, 7], [79, 0], [93, 19]]]] + } + }, 'takes coordinates'); + + t.deepEqual(multiPolygon([[[[94, 57], [78, 49], [94, 43], [94, 57]]], [[[93, 19], [63, 7], [79, 0], [93, 19]]]], {test: 23}), { + type: 'Feature', + properties: { + test: 23 + }, + geometry: { + type: 'MultiPolygon', + coordinates: [[[[94, 57], [78, 49], [94, 43], [94, 57]]], [[[93, 19], [63, 7], [79, 0], [93, 19]]]] + } + }, 'takes properties'); + + + // t.throws(() => { + // multiPolygon(); + // }, 'throws error with no coordinates'); + + t.end(); +}); + +test('geometrycollection', t => { + const pt = { + type: 'Point', + coordinates: [100, 0] + }; + const line = { + type: 'LineString', + coordinates: [[101, 0], [102, 1]] + }; + const gc = geometryCollection([pt, line]); + + t.deepEqual(gc, { + type: 'Feature', + properties: {}, + geometry: { + type: 'GeometryCollection', + geometries: [ + { + type: 'Point', + coordinates: [100, 0] + }, + { + type: 'LineString', + coordinates: [[101, 0], [102, 1]] + } + ] + } + }, 'creates a GeometryCollection'); + + const gcWithProps = geometryCollection([pt, line], {a: 23}); + t.deepEqual(gcWithProps, { + type: 'Feature', + properties: {a: 23}, + geometry: { + type: 'GeometryCollection', + geometries: [ + { + type: 'Point', + coordinates: [100, 0] + }, + { + type: 'LineString', + coordinates: [[101, 0], [102, 1]] + } + ] + } + }, 'creates a GeometryCollection with properties'); + + t.end(); +}); + +test('radiansToLength', t => { + t.equal(radiansToLength(1, 'radians'), 1); + t.equal(radiansToLength(1, 'kilometers'), earthRadius / 1000); + t.equal(radiansToLength(1, 'miles'), earthRadius / 1609.344); + // t.throws(() => radiansToLength(1, 'foo'), 'invalid units'); + t.end(); +}); + +test('lengthToRadians', t => { + t.equal(lengthToRadians(1, 'radians'), 1); + t.equal(lengthToRadians(earthRadius / 1000, 'kilometers'), 1); + t.equal(lengthToRadians(earthRadius / 1609.344, 'miles'), 1); + // t.throws(() => lengthToRadians(1, 'foo'), 'invalid units'); + t.end(); +}); + +test('lengthToDegrees', t => { + t.equal(lengthToDegrees(1, 'radians'), 57.29577951308232); + t.equal(lengthToDegrees(100, 'kilometers'), 0.899320363724538); + t.equal(lengthToDegrees(10, 'miles'), 0.1447315831437903); + // t.throws(() => lengthToRadians(1, 'foo'), 'invalid units'); + t.end(); +}); + +test('radiansToDegrees', t => { + t.equal(round(radiansToDegrees(Math.PI / 3), 6), 60, 'radiance conversion PI/3'); + t.equal(radiansToDegrees(3.5 * Math.PI), 270, 'radiance conversion 3.5PI'); + t.equal(radiansToDegrees(-Math.PI), -180, 'radiance conversion -PI'); + t.end(); +}); + +test('radiansToDegrees', t => { + t.equal(degreesToRadians(60), Math.PI / 3, 'degrees conversion 60'); + t.equal(degreesToRadians(270), 1.5 * Math.PI, 'degrees conversion 270'); + t.equal(degreesToRadians(-180), -Math.PI, 'degrees conversion -180'); + t.end(); +}); + +test('bearingToAzimuth', t => { + t.equal(bearingToAzimuth(40), 40); + t.equal(bearingToAzimuth(-105), 255); + t.equal(bearingToAzimuth(410), 50); + t.equal(bearingToAzimuth(-200), 160); + t.equal(bearingToAzimuth(-395), 325); + t.end(); +}); + +test('round', t => { + t.equal(round(125.123), 125); + t.equal(round(123.123, 1), 123.1); + t.equal(round(123.5), 124); + t.throws(() => round(34.5, 'precision'), 'invalid precision'); + t.throws(() => round(34.5, -5), 'invalid precision'); + t.end(); +}); + +test('convertLength', t => { + t.equal(convertLength(1000, 'meters'), 1); + t.equal(convertLength(1, 'kilometers', 'miles'), 0.621371192237334); + t.equal(convertLength(1, 'miles', 'kilometers'), 1.609344); + t.equal(convertLength(1, 'nauticalmiles'), 1.852); + t.equal(convertLength(1, 'meters', 'centimeters'), 100.00000000000001); + t.throws(() => convertLength(1, 'foo'), 'invalid units'); + t.end(); +}); + +test('convertArea', t => { + t.equal(convertArea(1000), 0.001); + t.equal(convertArea(1, 'kilometres', 'miles'), 0.386); + t.equal(convertArea(1, 'miles', 'kilometers'), 2.5906735751295336); + t.equal(convertArea(1, 'meters', 'centimetres'), 10000); + t.equal(convertArea(100, 'metres', 'acres'), 0.0247105); + t.equal(convertArea(100, undefined, 'yards'), 119.59900459999999); + t.equal(convertArea(100, 'metres', 'feet'), 1076.3910417); + t.equal(convertArea(100000, 'feet', undefined), 0.009290303999749462); + t.throws(() => convertLength(1, 'foo'), 'invalid original units'); + t.throws(() => convertLength(1, 'meters', 'foo'), 'invalid final units'); + + t.end(); +}); + +// https://github.com/Turfjs/turf/issues/853 +// https://github.com/Turfjs/turf/pull/866#discussion_r129873661 +test('null geometries', t => { + t.equal(feature(null).geometry, null, 'feature'); + t.equal(featureCollection([feature(null)]).features[0].geometry, null, 'featureCollection'); + t.equal(geometryCollection([feature(null).geometry]).geometry.geometries[0], null, 'geometryCollection'); + t.equal(geometryCollection([]).geometry.geometries.length, 0, 'geometryCollection -- empty'); + t.end(); +}); + +test('turf-helpers -- Handle Id & BBox properties', t => { + const id = 12345; + const bbox = [10, 30, 10, 30]; + const pt = point([10, 30], {}, {bbox, id}); + const ptId0 = point([10, 30], {}, {bbox, id: 0}); + const fc = featureCollection([pt], {bbox, id}); + t.equal(pt.id, id, 'feature id'); + t.equal(ptId0.id, 0, 'feature id = 0'); // issue #1180 + t.equal(pt.bbox, bbox, 'feature bbox'); + t.equal(fc.id, id, 'featureCollection id'); + t.equal(fc.bbox, bbox, 'featureCollection bbox'); + // t.throws(() => point([10, 30], {}, {bbox: [0], id}), 'throws invalid bbox'); + // t.throws(() => point([10, 30], {}, {bbox, id: {invalid: 'id'}}), 'throws invalid id'); + // t.throws(() => featureCollection([pt], {bbox: [0], id}), 'throws invalid bbox'); + // t.throws(() => featureCollection([pt], {bbox: [0], id: {invalid: 'id'}}), 'throws invalid id'); + t.end(); +}); + +test('turf-helpers -- isNumber', t => { + // t.throws(() => point(['foo', 'bar']), /coordinates must contain numbers/, 'coordinates must contain numbers'); + // t.throws(() => lineString([['foo', 'bar'], ['hello', 'world']]), /coordinates must contain numbers/, 'coordinates must contain numbers'); + // t.throws(() => polygon([[['foo', 'bar'], ['hello', 'world'], ['world', 'hello'], ['foo', 'bar']]]), /coordinates must contain numbers/, 'coordinates must contain numbers'); + + // true + t.true(isNumber(123)); + t.true(isNumber(1.23)); + t.true(isNumber(-1.23)); + t.true(isNumber(-123)); + t.true(isNumber('123')); + t.true(isNumber(+'123')); + t.true(isNumber('1e10000')); + t.true(isNumber(1e10000)); + t.true(isNumber(Infinity)); + t.true(isNumber(-Infinity)); + + // false + t.false(isNumber(+'ciao')); + t.false(isNumber('foo')); + t.false(isNumber('10px')); + t.false(isNumber(NaN)); + t.false(isNumber(undefined)); + t.false(isNumber(null)); + t.false(isNumber({a: 1})); + t.false(isNumber({})); + t.false(isNumber([1, 2, 3])); + t.false(isNumber([])); + t.false(isNumber(isNumber)); + t.end(); +}); + +test('turf-helpers -- isObject', t => { + // true + t.true(isObject({a: 1})); + t.true(isObject({})); + t.true(point([0, 1])); + + // false + t.false(isObject(123)); + t.false(isObject(Infinity)); + t.false(isObject(-123)); + t.false(isObject('foo')); + t.false(isObject(NaN)); + t.false(isObject(undefined)); + t.false(isObject(null)); + t.false(isObject([1, 2, 3])); + t.false(isObject([])); + t.false(isObject(isNumber)); + t.end(); +}); + +test('turf-helpers -- points', t => { + const points = turf.points([ + [-75, 39], + [-80, 45], + [-78, 50] + ], {foo: 'bar'}, {id: 'hello'}); + + t.equal(points.features.length, 3); + t.equal(points.id, 'hello'); + t.equal(points.features[0].properties.foo, 'bar'); + t.end(); +}); + +test('turf-helpers -- lineStrings', t => { + var linestrings = turf.lineStrings([ + [[-24, 63], [-23, 60], [-25, 65], [-20, 69]], + [[-14, 43], [-13, 40], [-15, 45], [-10, 49]] + ], {foo: 'bar'}, {id: 'hello'}); + + t.equal(linestrings.features.length, 2); + t.equal(linestrings.id, 'hello'); + t.equal(linestrings.features[0].properties.foo, 'bar'); + t.end(); +}); + +test('turf-helpers -- polygons', t => { + var polygons = turf.polygons([ + [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], + [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]], + ], {foo: 'bar'}, {id: 'hello'}); + + t.equal(polygons.features.length, 2); + t.equal(polygons.id, 'hello'); + t.equal(polygons.features[0].properties.foo, 'bar'); + t.end(); +}); + +test('turf-helpers -- Issue #1284 - Prevent mutating Properties', t => { + // https://github.com/Turfjs/turf/issues/1284 + const coord = [110, 45]; + const properties = {foo: 'bar'} + + // Create initial Feature + const pt = feature(coord, properties); + t.deepEqual(pt.properties, {foo: 'bar'}) + t.deepEqual(properties, {foo: 'bar'}) + + // Mutate Original Properties + properties.foo = 'barbar'; + + // Initial Point's Properties ~should~ be mutated + // https://github.com/Turfjs/turf/commit/39c6c9ec29986cc540960b3e2680e9e0a65168a1#r28018260 + t.deepEqual(pt.properties, {foo: 'barbar'}) + t.deepEqual(properties, {foo: 'barbar'}) + + // Include this test case if initial point should ~not~ have it's properties mutated + t.skip(pt.properties, {foo: 'bar'}) + + // Create Mutated Point + const ptMutate = feature(coord, properties); + t.deepEqual(ptMutate.properties, {foo: 'barbar'}) + t.deepEqual(properties, {foo: 'barbar'}) + + // New Features should contain empty properties {} + t.deepEqual(feature(coord).properties, {}); + t.end(); +}); diff --git a/packages/turf-hex-grid/bench.js b/src/hex-grid/bench.js similarity index 100% rename from packages/turf-hex-grid/bench.js rename to src/hex-grid/bench.js diff --git a/src/hex-grid/index.d.ts b/src/hex-grid/index.d.ts new file mode 100644 index 0000000000..e32c1c6325 --- /dev/null +++ b/src/hex-grid/index.d.ts @@ -0,0 +1,15 @@ +import { Units, BBox, Polygon, MultiPolygon, Feature, FeatureCollection, Point, Properties } from '@turf/helpers'; + +/** + * http://turfjs.org/docs/#hexgrid + */ +export default function hexGrid

( + bbox: BBox, + cellSide: number, + options?: { + units?: Units, + triangles?: boolean, + properties?: P, + mask?: Feature | Polygon | MultiPolygon; + } +): FeatureCollection; \ No newline at end of file diff --git a/src/hex-grid/index.js b/src/hex-grid/index.js new file mode 100644 index 0000000000..7be5a61a74 --- /dev/null +++ b/src/hex-grid/index.js @@ -0,0 +1,201 @@ +import distance from '../distance'; +import intersect from '../intersect'; +import {getType} from '../invariant'; +import {polygon, featureCollection, isObject, isNumber} from '../helpers'; + +/** + * Takes a bounding box and the diameter of the cell and returns a {@link FeatureCollection} of flat-topped + * hexagons or triangles ({@link Polygon} features) aligned in an "odd-q" vertical grid as + * described in [Hexagonal Grids](http://www.redblobgames.com/grids/hexagons/). + * + * @name hexGrid + * @param {BBox} bbox extent in [minX, minY, maxX, maxY] order + * @param {number} cellSide length of the side of the the hexagons or triangles, in units. It will also coincide with the + * radius of the circumcircle of the hexagons. + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] used in calculating cell size, can be degrees, radians, miles, or kilometers + * @param {Object} [options.properties={}] passed to each hexagon or triangle of the grid + * @param {Feature} [options.mask] if passed a Polygon or MultiPolygon, the grid Points will be created only inside it + * @param {boolean} [options.triangles=false] whether to return as triangles instead of hexagons + * @returns {FeatureCollection} a hexagonal grid + * @example + * var bbox = [-96,31,-84,40]; + * var cellSide = 50; + * var options = {units: 'miles'}; + * + * var hexgrid = turf.hexGrid(bbox, cellSide, options); + * + * //addToMap + * var addToMap = [hexgrid]; + */ +function hexGrid(bbox, cellSide, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + // var units = options.units; + const clonedProperties = JSON.stringify(options.properties || {}) + var triangles = options.triangles; + var mask = options.mask; + + // validation + if (cellSide === null || cellSide === undefined) throw new Error('cellSide is required'); + if (!isNumber(cellSide)) throw new Error('cellSide is invalid'); + if (!bbox) throw new Error('bbox is required'); + if (!Array.isArray(bbox)) throw new Error('bbox must be array'); + if (bbox.length !== 4) throw new Error('bbox must contain 4 numbers'); + if (mask && ['Polygon', 'MultiPolygon'].indexOf(getType(mask)) === -1) throw new Error('options.mask must be a (Multi)Polygon'); + + var west = bbox[0]; + var south = bbox[1]; + var east = bbox[2]; + var north = bbox[3]; + var centerY = (south + north) / 2; + var centerX = (west + east) / 2; + + // https://github.com/Turfjs/turf/issues/758 + var xFraction = cellSide * 2 / (distance([west, centerY], [east, centerY], options)); + var cellWidth = xFraction * (east - west); + var yFraction = cellSide * 2 / (distance([centerX, south], [centerX, north], options)); + var cellHeight = yFraction * (north - south); + var radius = cellWidth / 2; + + var hex_width = radius * 2; + var hex_height = Math.sqrt(3) / 2 * cellHeight; + + var box_width = east - west; + var box_height = north - south; + + var x_interval = 3 / 4 * hex_width; + var y_interval = hex_height; + + // adjust box_width so all hexagons will be inside the bbox + var x_span = (box_width - hex_width) / (hex_width - radius / 2); + var x_count = Math.floor(x_span); + + var x_adjust = ((x_count * x_interval - radius / 2) - box_width) / 2 - radius / 2 + x_interval / 2; + + // adjust box_height so all hexagons will be inside the bbox + var y_count = Math.floor((box_height - hex_height) / hex_height); + + var y_adjust = (box_height - y_count * hex_height) / 2; + + var hasOffsetY = y_count * hex_height - box_height > hex_height / 2; + if (hasOffsetY) { + y_adjust -= hex_height / 4; + } + + // Precompute cosines and sines of angles used in hexagon creation for performance gain + var cosines = []; + var sines = []; + for (var i = 0; i < 6; i++) { + var angle = 2 * Math.PI / 6 * i; + cosines.push(Math.cos(angle)); + sines.push(Math.sin(angle)); + } + + var results = []; + for (var x = 0; x <= x_count; x++) { + for (var y = 0; y <= y_count; y++) { + + var isOdd = x % 2 === 1; + if (y === 0 && isOdd) continue; + if (y === 0 && hasOffsetY) continue; + + var center_x = x * x_interval + west - x_adjust; + var center_y = y * y_interval + south + y_adjust; + + if (isOdd) { + center_y -= hex_height / 2; + } + + if (triangles === true) { + hexTriangles( + [center_x, center_y], + cellWidth / 2, + cellHeight / 2, + JSON.parse(clonedProperties), + cosines, + sines).forEach(function (triangle) { + if (mask) { + if (intersect(mask, triangle)) results.push(triangle); + } else { + results.push(triangle); + } + }); + } else { + var hex = hexagon( + [center_x, center_y], + cellWidth / 2, + cellHeight / 2, + JSON.parse(clonedProperties), + cosines, + sines + ); + if (mask) { + if (intersect(mask, hex)) results.push(hex); + } else { + results.push(hex); + } + } + } + } + + return featureCollection(results); +} + +/** + * Creates hexagon + * + * @private + * @param {Array} center of the hexagon + * @param {number} rx half hexagon width + * @param {number} ry half hexagon height + * @param {Object} properties passed to each hexagon + * @param {Array} cosines precomputed + * @param {Array} sines precomputed + * @returns {Feature} hexagon + */ +function hexagon(center, rx, ry, properties, cosines, sines) { + var vertices = []; + for (var i = 0; i < 6; i++) { + var x = center[0] + rx * cosines[i]; + var y = center[1] + ry * sines[i]; + vertices.push([x, y]); + } + //first and last vertex must be the same + vertices.push(vertices[0].slice()); + return polygon([vertices], properties); +} + +/** + * Creates triangles composing an hexagon + * + * @private + * @param {Array} center of the hexagon + * @param {number} rx half triangle width + * @param {number} ry half triangle height + * @param {Object} properties passed to each triangle + * @param {Array} cosines precomputed + * @param {Array} sines precomputed + * @returns {Array>} triangles + */ +function hexTriangles(center, rx, ry, properties, cosines, sines) { + var triangles = []; + for (var i = 0; i < 6; i++) { + var vertices = []; + vertices.push(center); + vertices.push([ + center[0] + rx * cosines[i], + center[1] + ry * sines[i] + ]); + vertices.push([ + center[0] + rx * cosines[(i + 1) % 6], + center[1] + ry * sines[(i + 1) % 6] + ]); + vertices.push(center); + triangles.push(polygon([vertices], properties)); + } + return triangles; +} + +export default hexGrid; diff --git a/src/hex-grid/test.js b/src/hex-grid/test.js new file mode 100644 index 0000000000..fd144b0b72 --- /dev/null +++ b/src/hex-grid/test.js @@ -0,0 +1,103 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const truncate = require('../truncate').default; +const bboxPoly = require('../bbox-polygon').default; +const hexGrid = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + json: load.sync(directories.in + filename) + }; +}); + +test('hex-grid', t => { + fixtures.forEach(({name, json, filename}) => { + const {bbox, cellSide} = json; + const options = json; + + const result = truncate(hexGrid(bbox, cellSide, options)); + const poly = bboxPoly(bbox); + t.assert(poly.bbox); + poly.properties = { + stroke: '#F00', + 'stroke-width': 6, + 'fill-opacity': 0 + }; + result.features.push(poly); + if (options.mask) { + options.mask.properties = { + "stroke": "#00F", + "stroke-width": 6, + "fill-opacity": 0 + }; + result.features.push(options.mask); + } + + if (process.env.REGEN) write.sync(directories.out + name + '.geojson', result); + t.deepEqual(result, load.sync(directories.out + name + '.geojson'), name); + }); + t.end(); +}); + + +test('grid tiles count', t => { + const bbox1 = require(directories.in + 'bbox1.json').bbox; + t.equal(hexGrid(bbox1, 50, {units: 'miles'}).features.length, 52); + t.equal(hexGrid(bbox1, 50, {units: 'miles', triangles: true}).features.length, 312); + + t.end(); +}); + +test('Property mutation', t => { + const bbox1 = require(directories.in + 'bbox1.json').bbox; + const grid = hexGrid(bbox1, 50, {units: 'miles', properties: {foo: 'bar'}}) + t.equal(grid.features[0].properties.foo, 'bar'); + t.equal(grid.features[1].properties.foo, 'bar'); + + grid.features[0].properties.foo = 'baz' + t.equal(grid.features[0].properties.foo, 'baz'); + t.equal(grid.features[1].properties.foo, 'bar'); + t.end(); +}); + + +test('longitude (13141439571036224) - issue #758', t => { + const bbox = [-179, -90, 179, 90]; + const grid = hexGrid(bbox, 250, {units: 'kilometers'}); + + const coords = []; + grid.features.forEach(feature => feature.geometry.coordinates[0].forEach(coord => coords.push(coord))); + + for (const coord of coords) { + const lng = coord[0]; + const lat = coord[1]; + if (lng > 1000 || lng < -1000) { + t.fail(`longitude is +- 1000 [${lng},${lat}]`); + break; + } + } + t.end(); +}); + +test('hex-grid -- throw', t => { + const bbox = [0, 0, 1, 1]; + // Types handled by Typescript + // t.throws(() => hexGrid(null, 0), /bbox is required/, 'missing bbox'); + // t.throws(() => hexGrid('string', 0), /bbox must be array/, 'invalid bbox'); + // t.throws(() => hexGrid([0, 2], 1), /bbox must contain 4 numbers/, 'invalid bbox'); + // t.throws(() => hexGrid(bbox, null), /cellSide is required/, 'missing cellSide'); + // t.throws(() => hexGrid(bbox, 'string'), /cellSide is invalid/, 'invalid cellSide'); + // t.throws(() => hexGrid(bbox, 1, 'string'), /options is invalid/, 'invalid options'); + t.end(); +}); + diff --git a/packages/turf-hex-grid/test/in/bbox1-triangles.json b/src/hex-grid/test/in/bbox1-triangles.json similarity index 100% rename from packages/turf-hex-grid/test/in/bbox1-triangles.json rename to src/hex-grid/test/in/bbox1-triangles.json diff --git a/packages/turf-hex-grid/test/in/bbox1.json b/src/hex-grid/test/in/bbox1.json similarity index 100% rename from packages/turf-hex-grid/test/in/bbox1.json rename to src/hex-grid/test/in/bbox1.json diff --git a/packages/turf-hex-grid/test/in/big-bbox.json b/src/hex-grid/test/in/big-bbox.json similarity index 100% rename from packages/turf-hex-grid/test/in/big-bbox.json rename to src/hex-grid/test/in/big-bbox.json diff --git a/packages/turf-hex-grid/test/in/fiji-10-miles.json b/src/hex-grid/test/in/fiji-10-miles.json similarity index 100% rename from packages/turf-hex-grid/test/in/fiji-10-miles.json rename to src/hex-grid/test/in/fiji-10-miles.json diff --git a/packages/turf-hex-grid/test/in/london-20-miles.json b/src/hex-grid/test/in/london-20-miles.json similarity index 100% rename from packages/turf-hex-grid/test/in/london-20-miles.json rename to src/hex-grid/test/in/london-20-miles.json diff --git a/packages/turf-hex-grid/test/in/piedemont-mask.json b/src/hex-grid/test/in/piedemont-mask.json similarity index 100% rename from packages/turf-hex-grid/test/in/piedemont-mask.json rename to src/hex-grid/test/in/piedemont-mask.json diff --git a/packages/turf-hex-grid/test/in/properties.json b/src/hex-grid/test/in/properties.json similarity index 100% rename from packages/turf-hex-grid/test/in/properties.json rename to src/hex-grid/test/in/properties.json diff --git a/packages/turf-hex-grid/test/in/resolute.json b/src/hex-grid/test/in/resolute.json similarity index 100% rename from packages/turf-hex-grid/test/in/resolute.json rename to src/hex-grid/test/in/resolute.json diff --git a/packages/turf-hex-grid/test/out/bbox1-triangles.geojson b/src/hex-grid/test/out/bbox1-triangles.geojson similarity index 100% rename from packages/turf-hex-grid/test/out/bbox1-triangles.geojson rename to src/hex-grid/test/out/bbox1-triangles.geojson diff --git a/packages/turf-hex-grid/test/out/bbox1.geojson b/src/hex-grid/test/out/bbox1.geojson similarity index 100% rename from packages/turf-hex-grid/test/out/bbox1.geojson rename to src/hex-grid/test/out/bbox1.geojson diff --git a/packages/turf-hex-grid/test/out/big-bbox.geojson b/src/hex-grid/test/out/big-bbox.geojson similarity index 100% rename from packages/turf-hex-grid/test/out/big-bbox.geojson rename to src/hex-grid/test/out/big-bbox.geojson diff --git a/packages/turf-hex-grid/test/out/fiji-10-miles.geojson b/src/hex-grid/test/out/fiji-10-miles.geojson similarity index 100% rename from packages/turf-hex-grid/test/out/fiji-10-miles.geojson rename to src/hex-grid/test/out/fiji-10-miles.geojson diff --git a/packages/turf-hex-grid/test/out/london-20-miles.geojson b/src/hex-grid/test/out/london-20-miles.geojson similarity index 100% rename from packages/turf-hex-grid/test/out/london-20-miles.geojson rename to src/hex-grid/test/out/london-20-miles.geojson diff --git a/packages/turf-hex-grid/test/out/piedemont-mask.geojson b/src/hex-grid/test/out/piedemont-mask.geojson similarity index 100% rename from packages/turf-hex-grid/test/out/piedemont-mask.geojson rename to src/hex-grid/test/out/piedemont-mask.geojson diff --git a/packages/turf-hex-grid/test/out/properties.geojson b/src/hex-grid/test/out/properties.geojson similarity index 100% rename from packages/turf-hex-grid/test/out/properties.geojson rename to src/hex-grid/test/out/properties.geojson diff --git a/packages/turf-hex-grid/test/out/resolute.geojson b/src/hex-grid/test/out/resolute.geojson similarity index 100% rename from packages/turf-hex-grid/test/out/resolute.geojson rename to src/hex-grid/test/out/resolute.geojson diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000000..eb0762329e --- /dev/null +++ b/src/index.js @@ -0,0 +1,142 @@ +/** + * Turf is a modular geospatial analysis engine written in JavaScript. It performs geospatial + * processing tasks with GeoJSON data and can be run on a server or in a browser. + * + * @module turf + * @summary Geospatial analysis for JavaScript + */ +export {default as isolines} from './isolines'; +export {default as convex} from './convex'; +export {default as pointsWithinPolygon} from './points-within-polygon'; +export {default as concave} from './concave'; +export {default as collect} from './collect'; +export {default as flip} from './flip'; +export {default as simplify} from './simplify'; +export {default as bezierSpline} from './bezier-spline'; +export {default as tag} from './tag'; +export {default as sample} from './sample'; +export {default as envelope} from './envelope'; +export {default as square} from './square'; +export {default as circle} from './circle'; +export {default as midpoint} from './midpoint'; +export {default as center} from './center'; +export {default as centerOfMass} from './center-of-mass'; +export {default as centroid} from './centroid'; +export {default as combine} from './combine'; +export {default as distance} from './distance'; +export {default as explode} from './explode'; +export {default as bbox} from './bbox'; +export {default as tesselate} from './tesselate'; +export {default as bboxPolygon} from './bbox-polygon'; +export {default as booleanPointInPolygon} from './boolean-point-in-polygon'; +export {default as nearestPoint} from './nearest-point'; +export {default as nearestPointOnLine} from './nearest-point-on-line'; +export {default as nearestPointToLine} from './nearest-point-to-line'; +export {default as planepoint} from './planepoint'; +export {default as tin} from './tin'; +export {default as bearing} from './bearing'; +export {default as destination} from './destination'; +export {default as kinks} from './kinks'; +export {default as pointOnFeature} from './point-on-feature'; +export {default as area} from './area'; +export {default as along} from './along'; +export {default as length} from './length'; +export {default as lineSlice} from './line-slice'; +export {default as lineSliceAlong} from './line-slice-along'; +export {default as pointGrid} from './point-grid'; +export {default as truncate} from './truncate'; +export {default as flatten} from './flatten'; +export {default as lineIntersect} from './line-intersect'; +export {default as lineChunk} from './line-chunk'; +export {default as unkinkPolygon} from './unkink-polygon'; +export {default as greatCircle} from './great-circle'; +export {default as lineSegment} from './line-segment'; +export {default as lineSplit} from './line-split'; +export {default as lineArc} from './line-arc'; +export {default as polygonToLine} from './polygon-to-line'; +export {default as lineToPolygon} from './line-to-polygon'; +export {default as bboxClip} from './bbox-clip'; +export {default as lineOverlap} from './line-overlap'; +export {default as sector} from './sector'; +export {default as rhumbBearing} from './rhumb-bearing'; +export {default as rhumbDistance} from './rhumb-distance'; +export {default as rhumbDestination} from './rhumb-destination'; +export {default as polygonTangents} from './polygon-tangents'; +export {default as rewind} from './rewind'; +// export {default as isobands} from './isobands'; // NEEDS LOTS OF WORK +export {default as transformRotate} from './transform-rotate'; +export {default as transformScale} from './transform-scale'; +export {default as transformTranslate} from './transform-translate'; +export {default as lineOffset} from './line-offset'; +export {default as polygonize} from './polygonize'; +export {default as booleanDisjoint} from './boolean-disjoint'; +export {default as booleanContains} from './boolean-contains'; +export {default as booleanCrosses} from './boolean-crosses'; +export {default as booleanClockwise} from './boolean-clockwise'; +export {default as booleanOverlap} from './boolean-overlap'; +export {default as booleanPointOnLine} from './boolean-point-on-line'; +export {default as booleanEqual} from './boolean-equal'; +export {default as booleanWithin} from './boolean-within'; +export {default as clone} from './clone'; +export {default as cleanCoords} from './clean-coords'; +export {default as clustersDbscan} from './clusters-dbscan'; +export {default as clustersKmeans} from './clusters-kmeans'; +export {default as pointToLineDistance} from './point-to-line-distance'; +export {default as booleanParallel} from './boolean-parallel'; +export {default as shortestPath} from './shortest-path'; +export {default as voronoi} from './voronoi'; +export {default as ellipse} from './ellipse'; +export {default as centerMean} from './center-mean'; +export {default as centerMedian} from './center-median'; +export {default as standardDeviationalEllipse} from './standard-deviational-ellipse'; +export {default as angle} from './angle'; +export {default as polygonSmooth} from './polygon-smooth'; +export {default as moranIndex} from './moran-index'; +export {default as distanceWeight} from './distance-weight'; +export * from './projection'; +export * from './random'; +export * from './clusters'; +export * from './helpers'; +export * from './invariant'; +export * from './meta'; +import * as projection from './projection'; +import * as random from './random'; +import * as clusters from './clusters'; +import * as helpers from './helpers'; +import * as invariant from './invariant'; +import * as meta from './meta'; +export {projection, random, clusters, helpers, invariant, meta}; +export {default as difference} from './difference'; +export {default as union} from './union'; +export {default as intersect} from './intersect'; +export {default as dissolve} from './dissolve'; +export {default as hexGrid} from './hex-grid'; +export {default as mask} from './mask'; +export {default as rectangleGrid} from './rectangle-grid'; +export {default as squareGrid} from './square-grid'; +export {default as triangleGrid} from './triangle-grid'; +export {default as interpolate} from './interpolate'; + +// JSTS Modules +// export {default as buffer} from './buffer'; + +// Renamed modules (Backwards compatitble with v4.0) +// https://github.com/Turfjs/turf/issues/860 +export {default as pointOnSurface} from './point-on-feature'; +export {default as polygonToLineString} from './polygon-to-line'; +export {default as lineStringToPolygon} from './line-to-polygon'; +export {default as inside} from './boolean-point-in-polygon'; +export {default as within} from './points-within-polygon'; +export {default as bezier} from './bezier-spline'; +export {default as nearest} from './nearest-point'; +export {default as pointOnLine} from './nearest-point-on-line'; +export {default as lineDistance} from './length'; +export { + radiansToDegrees as radians2degrees, + degreesToRadians as degrees2radians, + lengthToDegrees as distanceToDegrees, + lengthToRadians as distanceToRadians, + radiansToLength as radiansToDistance, + bearingToAzimuth as bearingToAngle, + convertLength as convertDistance +} from './helpers'; diff --git a/packages/turf-interpolate/bench.js b/src/interpolate/bench.js similarity index 100% rename from packages/turf-interpolate/bench.js rename to src/interpolate/bench.js diff --git a/src/interpolate/index.d.ts b/src/interpolate/index.d.ts new file mode 100644 index 0000000000..2c28999010 --- /dev/null +++ b/src/interpolate/index.d.ts @@ -0,0 +1,25 @@ +import { Point, Polygon, Units, FeatureCollection, Grid } from '../helpers'; + +/** + * http://turfjs.org/docs/#interpolate + */ +export default function interpolate( + points: FeatureCollection, + cellSize: number, + options?: { + gridType?: 'point', + property?: string, + units?: Units, + weight?: number + } +): FeatureCollection; +export default function interpolate( + points: FeatureCollection, + cellSize: number, + options?: { + gridType?: Grid, + property?: string, + units?: Units, + weight?: number + } +): FeatureCollection; diff --git a/src/interpolate/index.js b/src/interpolate/index.js new file mode 100644 index 0000000000..fe5adc9a96 --- /dev/null +++ b/src/interpolate/index.js @@ -0,0 +1,105 @@ +import bbox from '../bbox'; +import hexGrid from '../hex-grid'; +import pointGrid from '../point-grid'; +import distance from '../distance'; +import centroid from '../centroid'; +import squareGrid from '../square-grid'; +import triangleGrid from '../triangle-grid'; +import clone from '../clone'; +import { featureCollection } from '../helpers'; +import { featureEach } from '../meta'; +import { collectionOf } from '../invariant'; + +/** + * Takes a set of points and estimates their 'property' values on a grid using the [Inverse Distance Weighting (IDW) method](https://en.wikipedia.org/wiki/Inverse_distance_weighting). + * + * @name interpolate + * @param {FeatureCollection} points with known value + * @param {number} cellSize the distance across each grid point + * @param {Object} [options={}] Optional parameters + * @param {string} [options.gridType='square'] defines the output format based on a Grid Type (options: 'square' | 'point' | 'hex' | 'triangle') + * @param {string} [options.property='elevation'] the property name in `points` from which z-values will be pulled, zValue fallbacks to 3rd coordinate if no property exists. + * @param {string} [options.units='kilometers'] used in calculating cellSize, can be degrees, radians, miles, or kilometers + * @param {number} [options.weight=1] exponent regulating the distance-decay weighting + * @returns {FeatureCollection} grid of points or polygons with interpolated 'property' + * @example + * var points = turf.randomPoint(30, {bbox: [50, 30, 70, 50]}); + * + * // add a random property to each point + * turf.featureEach(points, function(point) { + * point.properties.solRad = Math.random() * 50; + * }); + * var options = {gridType: 'points', property: 'solRad', units: 'miles'}; + * var grid = turf.interpolate(points, 100, options); + * + * //addToMap + * var addToMap = [grid]; + */ +function interpolate(points, cellSize, options) { + // Optional parameters + options = options || {}; + if (typeof options !== 'object') throw new Error('options is invalid'); + var gridType = options.gridType; + var property = options.property; + var weight = options.weight; + + // validation + if (!points) throw new Error('points is required'); + collectionOf(points, 'Point', 'input must contain Points'); + if (!cellSize) throw new Error('cellSize is required'); + if (weight !== undefined && typeof weight !== 'number') throw new Error('weight must be a number'); + + // default values + property = property || 'elevation'; + gridType = gridType || 'square'; + weight = weight || 1; + + var box = bbox(points); + var grid; + switch (gridType) { + case 'point': + case 'points': + grid = pointGrid(box, cellSize, options); + break; + case 'square': + case 'squares': + grid = squareGrid(box, cellSize, options); + break; + case 'hex': + case 'hexes': + grid = hexGrid(box, cellSize, options); + break; + case 'triangle': + case 'triangles': + grid = triangleGrid(box, cellSize, options); + break; + default: + throw new Error('invalid gridType'); + } + var results = []; + featureEach(grid, function (gridFeature) { + var zw = 0; + var sw = 0; + // calculate the distance from each input point to the grid points + featureEach(points, function (point) { + var gridPoint = (gridType === 'point') ? gridFeature : centroid(gridFeature); + var d = distance(gridPoint, point, options); + var zValue; + // property has priority for zValue, fallbacks to 3rd coordinate from geometry + if (property !== undefined) zValue = point.properties[property]; + if (zValue === undefined) zValue = point.geometry.coordinates[2]; + if (zValue === undefined) throw new Error('zValue is missing'); + if (d === 0) zw = zValue; + var w = 1.0 / Math.pow(d, weight); + sw += w; + zw += w * zValue; + }); + // write interpolated value for each grid point + var newFeature = clone(gridFeature); + newFeature.properties[property] = zw / sw; + results.push(newFeature); + }); + return featureCollection(results); +} + +export default interpolate; diff --git a/src/interpolate/test.js b/src/interpolate/test.js new file mode 100644 index 0000000000..8be9cddd7b --- /dev/null +++ b/src/interpolate/test.js @@ -0,0 +1,105 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import truncate from '../truncate'; +import { brightness } from 'chromatism'; +import { round, featureCollection, point } from '../helpers'; +import { featureEach, propEach } from '../meta'; +import interpolate from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +var fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); +// fixtures = fixtures.filter(fixture => fixture.name === 'points-random') + +test('turf-interpolate', t => { + for (const {filename, name, geojson} of fixtures) { + const options = geojson.properties; + const cellSize = options.cellSize; + const property = options.property || 'elevation'; + + // Truncate coordinates & elevation (property) to 6 precision + let result = truncate(interpolate(geojson, cellSize, options)); + propEach(result, (properties, featureIndex) => { + properties[property] = round(properties[property]); + }); + result = colorize(result, property, name); + + if (process.env.REGEN) write.sync(directories.out + filename, result); + t.deepEquals(result, load.sync(directories.out + filename), name); + } + t.end(); +}); + +test('turf-interpolate -- throws errors', t => { + const cellSize = 1; + const property = 'elevation'; + const weight = 0.5; + const units = 'miles'; + const gridType = 'point'; + const points = featureCollection([ + point([1, 2], {elevation: 200}), + point([2, 1], {elevation: 300}), + point([1.5, 1.5], {elevation: 400}) + ]); + + t.assert(interpolate(points, cellSize, {gridType: gridType, units: units, weight: weight}).features.length); + t.throws(() => interpolate(points, undefined), /cellSize is required/, 'cellSize is required'); + t.throws(() => interpolate(undefined, cellSize), /points is required/, 'points is required'); + t.throws(() => interpolate(points, cellSize, {gridType: 'foo'}), /invalid gridType/, 'invalid gridType'); + t.throws(() => interpolate(points, cellSize, {units: 'foo'}), 'invalid units'); + t.throws(() => interpolate(points, cellSize, {weight: 'foo'}), /weight must be a number/, 'weight must be a number'); + t.throws(() => interpolate(points, cellSize, {property: 'foo'}), /zValue is missing/, 'zValue is missing'); + t.end(); +}); + +test('turf-interpolate -- zValue from 3rd coordinate', t => { + const cellSize = 1; + const points = featureCollection([ + point([1, 2, 200]), + point([2, 1, 300]), + point([1.5, 1.5, 400]) + ]); + t.assert(interpolate(points, cellSize).features.length, 'zValue from 3rd coordinate'); + t.end(); +}); + +// style result +function colorize(grid, property, name) { + property = property || 'elevation'; + let max = -Infinity; + let min = Infinity; + propEach(grid, properties => { + const value = properties[property]; + if (value > max) max = value; + if (value < min) min = value; + }); + const delta = (max - min); + if (delta === 0) throw new Error(name + ' delta is invalid'); + + featureEach(grid, feature => { + const value = feature.properties[property]; + const percent = round((value - min - delta / 2) / delta * 100); + // darker corresponds to higher values + const color = brightness(-percent, '#0086FF').hex; + if (feature.geometry.type === 'Point') feature.properties['marker-color'] = color; + else { + feature.properties['stroke'] = color; + feature.properties['fill'] = color; + feature.properties['fill-opacity'] = 0.85; + } + }); + + return grid; +} diff --git a/packages/turf-interpolate/test/in/data-1km.geojson b/src/interpolate/test/in/data-1km.geojson similarity index 100% rename from packages/turf-interpolate/test/in/data-1km.geojson rename to src/interpolate/test/in/data-1km.geojson diff --git a/packages/turf-interpolate/test/in/data-500m.geojson b/src/interpolate/test/in/data-500m.geojson similarity index 100% rename from packages/turf-interpolate/test/in/data-500m.geojson rename to src/interpolate/test/in/data-500m.geojson diff --git a/packages/turf-interpolate/test/in/data-weight-2.geojson b/src/interpolate/test/in/data-weight-2.geojson similarity index 100% rename from packages/turf-interpolate/test/in/data-weight-2.geojson rename to src/interpolate/test/in/data-weight-2.geojson diff --git a/packages/turf-interpolate/test/in/hex-zValue.geojson b/src/interpolate/test/in/hex-zValue.geojson similarity index 100% rename from packages/turf-interpolate/test/in/hex-zValue.geojson rename to src/interpolate/test/in/hex-zValue.geojson diff --git a/packages/turf-interpolate/test/in/points-random.geojson b/src/interpolate/test/in/points-random.geojson similarity index 100% rename from packages/turf-interpolate/test/in/points-random.geojson rename to src/interpolate/test/in/points-random.geojson diff --git a/packages/turf-interpolate/test/in/points1-weight-3.geojson b/src/interpolate/test/in/points1-weight-3.geojson similarity index 100% rename from packages/turf-interpolate/test/in/points1-weight-3.geojson rename to src/interpolate/test/in/points1-weight-3.geojson diff --git a/packages/turf-interpolate/test/in/points1.geojson b/src/interpolate/test/in/points1.geojson similarity index 100% rename from packages/turf-interpolate/test/in/points1.geojson rename to src/interpolate/test/in/points1.geojson diff --git a/packages/turf-interpolate/test/in/triangle-zValue.geojson b/src/interpolate/test/in/triangle-zValue.geojson similarity index 100% rename from packages/turf-interpolate/test/in/triangle-zValue.geojson rename to src/interpolate/test/in/triangle-zValue.geojson diff --git a/packages/turf-interpolate/test/out/data-1km.geojson b/src/interpolate/test/out/data-1km.geojson similarity index 97% rename from packages/turf-interpolate/test/out/data-1km.geojson rename to src/interpolate/test/out/data-1km.geojson index ec4c8dea73..a56c53fc2c 100644 --- a/packages/turf-interpolate/test/out/data-1km.geojson +++ b/src/interpolate/test/out/data-1km.geojson @@ -4,7 +4,7 @@ { "type": "Feature", "properties": { - "value": 17, + "value": 18, "stroke": "#ebf5ff", "fill": "#ebf5ff", "fill-opacity": 0.85 @@ -41,8 +41,8 @@ "type": "Feature", "properties": { "value": 19, - "stroke": "#c2e2ff", - "fill": "#c2e2ff", + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -77,8 +77,8 @@ "type": "Feature", "properties": { "value": 20, - "stroke": "#add8ff", - "fill": "#add8ff", + "stroke": "#c2e2ff", + "fill": "#c2e2ff", "fill-opacity": 0.85 }, "geometry": { @@ -113,8 +113,8 @@ "type": "Feature", "properties": { "value": 20, - "stroke": "#add8ff", - "fill": "#add8ff", + "stroke": "#c2e2ff", + "fill": "#c2e2ff", "fill-opacity": 0.85 }, "geometry": { @@ -149,8 +149,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#99ceff", - "fill": "#99ceff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -185,8 +185,8 @@ "type": "Feature", "properties": { "value": 22, - "stroke": "#85c4ff", - "fill": "#85c4ff", + "stroke": "#99ceff", + "fill": "#99ceff", "fill-opacity": 0.85 }, "geometry": { @@ -221,8 +221,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#5cb1ff", - "fill": "#5cb1ff", + "stroke": "#70bbff", + "fill": "#70bbff", "fill-opacity": 0.85 }, "geometry": { @@ -257,8 +257,8 @@ "type": "Feature", "properties": { "value": 25, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -293,8 +293,8 @@ "type": "Feature", "properties": { "value": 26, - "stroke": "#339dff", - "fill": "#339dff", + "stroke": "#47a7ff", + "fill": "#47a7ff", "fill-opacity": 0.85 }, "geometry": { @@ -329,8 +329,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#1f94ff", - "fill": "#1f94ff", + "stroke": "#339dff", + "fill": "#339dff", "fill-opacity": 0.85 }, "geometry": { @@ -365,8 +365,8 @@ "type": "Feature", "properties": { "value": 18, - "stroke": "#d6ebff", - "fill": "#d6ebff", + "stroke": "#ebf5ff", + "fill": "#ebf5ff", "fill-opacity": 0.85 }, "geometry": { @@ -401,8 +401,8 @@ "type": "Feature", "properties": { "value": 19, - "stroke": "#c2e2ff", - "fill": "#c2e2ff", + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -437,8 +437,8 @@ "type": "Feature", "properties": { "value": 19, - "stroke": "#c2e2ff", - "fill": "#c2e2ff", + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -473,8 +473,8 @@ "type": "Feature", "properties": { "value": 19, - "stroke": "#c2e2ff", - "fill": "#c2e2ff", + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -509,8 +509,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#99ceff", - "fill": "#99ceff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -545,8 +545,8 @@ "type": "Feature", "properties": { "value": 22, - "stroke": "#85c4ff", - "fill": "#85c4ff", + "stroke": "#99ceff", + "fill": "#99ceff", "fill-opacity": 0.85 }, "geometry": { @@ -580,7 +580,7 @@ { "type": "Feature", "properties": { - "value": 23, + "value": 24, "stroke": "#70bbff", "fill": "#70bbff", "fill-opacity": 0.85 @@ -617,8 +617,8 @@ "type": "Feature", "properties": { "value": 25, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -653,8 +653,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#1f94ff", - "fill": "#1f94ff", + "stroke": "#339dff", + "fill": "#339dff", "fill-opacity": 0.85 }, "geometry": { @@ -689,8 +689,8 @@ "type": "Feature", "properties": { "value": 28, - "stroke": "#0a8aff", - "fill": "#0a8aff", + "stroke": "#1f94ff", + "fill": "#1f94ff", "fill-opacity": 0.85 }, "geometry": { @@ -725,8 +725,8 @@ "type": "Feature", "properties": { "value": 19, - "stroke": "#c2e2ff", - "fill": "#c2e2ff", + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -761,8 +761,8 @@ "type": "Feature", "properties": { "value": 19, - "stroke": "#c2e2ff", - "fill": "#c2e2ff", + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -797,8 +797,8 @@ "type": "Feature", "properties": { "value": 18, - "stroke": "#d6ebff", - "fill": "#d6ebff", + "stroke": "#ebf5ff", + "fill": "#ebf5ff", "fill-opacity": 0.85 }, "geometry": { @@ -833,8 +833,8 @@ "type": "Feature", "properties": { "value": 17, - "stroke": "#ebf5ff", - "fill": "#ebf5ff", + "stroke": "#ffffff", + "fill": "#ffffff", "fill-opacity": 0.85 }, "geometry": { @@ -869,8 +869,8 @@ "type": "Feature", "properties": { "value": 20, - "stroke": "#add8ff", - "fill": "#add8ff", + "stroke": "#c2e2ff", + "fill": "#c2e2ff", "fill-opacity": 0.85 }, "geometry": { @@ -905,8 +905,8 @@ "type": "Feature", "properties": { "value": 22, - "stroke": "#85c4ff", - "fill": "#85c4ff", + "stroke": "#99ceff", + "fill": "#99ceff", "fill-opacity": 0.85 }, "geometry": { @@ -941,8 +941,8 @@ "type": "Feature", "properties": { "value": 23, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -977,8 +977,8 @@ "type": "Feature", "properties": { "value": 25, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -1012,7 +1012,7 @@ { "type": "Feature", "properties": { - "value": 27, + "value": 28, "stroke": "#1f94ff", "fill": "#1f94ff", "fill-opacity": 0.85 @@ -1048,7 +1048,7 @@ { "type": "Feature", "properties": { - "value": 29, + "value": 30, "stroke": "#0080f5", "fill": "#0080f5", "fill-opacity": 0.85 @@ -1084,7 +1084,7 @@ { "type": "Feature", "properties": { - "value": 19, + "value": 20, "stroke": "#c2e2ff", "fill": "#c2e2ff", "fill-opacity": 0.85 @@ -1121,8 +1121,8 @@ "type": "Feature", "properties": { "value": 19, - "stroke": "#c2e2ff", - "fill": "#c2e2ff", + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -1157,8 +1157,8 @@ "type": "Feature", "properties": { "value": 18, - "stroke": "#d6ebff", - "fill": "#d6ebff", + "stroke": "#ebf5ff", + "fill": "#ebf5ff", "fill-opacity": 0.85 }, "geometry": { @@ -1192,7 +1192,7 @@ { "type": "Feature", "properties": { - "value": 16, + "value": 17, "stroke": "#ffffff", "fill": "#ffffff", "fill-opacity": 0.85 @@ -1228,7 +1228,7 @@ { "type": "Feature", "properties": { - "value": 19, + "value": 20, "stroke": "#c2e2ff", "fill": "#c2e2ff", "fill-opacity": 0.85 @@ -1265,8 +1265,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#99ceff", - "fill": "#99ceff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -1301,8 +1301,8 @@ "type": "Feature", "properties": { "value": 23, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -1336,7 +1336,7 @@ { "type": "Feature", "properties": { - "value": 25, + "value": 26, "stroke": "#47a7ff", "fill": "#47a7ff", "fill-opacity": 0.85 @@ -1372,7 +1372,7 @@ { "type": "Feature", "properties": { - "value": 28, + "value": 29, "stroke": "#0a8aff", "fill": "#0a8aff", "fill-opacity": 0.85 @@ -1408,7 +1408,7 @@ { "type": "Feature", "properties": { - "value": 31, + "value": 32, "stroke": "#006acc", "fill": "#006acc", "fill-opacity": 0.85 @@ -1445,8 +1445,8 @@ "type": "Feature", "properties": { "value": 20, - "stroke": "#add8ff", - "fill": "#add8ff", + "stroke": "#c2e2ff", + "fill": "#c2e2ff", "fill-opacity": 0.85 }, "geometry": { @@ -1481,8 +1481,8 @@ "type": "Feature", "properties": { "value": 20, - "stroke": "#add8ff", - "fill": "#add8ff", + "stroke": "#c2e2ff", + "fill": "#c2e2ff", "fill-opacity": 0.85 }, "geometry": { @@ -1517,8 +1517,8 @@ "type": "Feature", "properties": { "value": 19, - "stroke": "#c2e2ff", - "fill": "#c2e2ff", + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -1553,8 +1553,8 @@ "type": "Feature", "properties": { "value": 19, - "stroke": "#c2e2ff", - "fill": "#c2e2ff", + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -1589,8 +1589,8 @@ "type": "Feature", "properties": { "value": 20, - "stroke": "#add8ff", - "fill": "#add8ff", + "stroke": "#c2e2ff", + "fill": "#c2e2ff", "fill-opacity": 0.85 }, "geometry": { @@ -1625,8 +1625,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#99ceff", - "fill": "#99ceff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -1661,8 +1661,8 @@ "type": "Feature", "properties": { "value": 20, - "stroke": "#add8ff", - "fill": "#add8ff", + "stroke": "#c2e2ff", + "fill": "#c2e2ff", "fill-opacity": 0.85 }, "geometry": { @@ -1696,7 +1696,7 @@ { "type": "Feature", "properties": { - "value": 25, + "value": 26, "stroke": "#47a7ff", "fill": "#47a7ff", "fill-opacity": 0.85 @@ -1732,7 +1732,7 @@ { "type": "Feature", "properties": { - "value": 30, + "value": 31, "stroke": "#0075e0", "fill": "#0075e0", "fill-opacity": 0.85 @@ -1768,7 +1768,7 @@ { "type": "Feature", "properties": { - "value": 34, + "value": 35, "stroke": "#004a8f", "fill": "#004a8f", "fill-opacity": 0.85 @@ -1805,8 +1805,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#99ceff", - "fill": "#99ceff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -1841,8 +1841,8 @@ "type": "Feature", "properties": { "value": 20, - "stroke": "#add8ff", - "fill": "#add8ff", + "stroke": "#c2e2ff", + "fill": "#c2e2ff", "fill-opacity": 0.85 }, "geometry": { @@ -1877,8 +1877,8 @@ "type": "Feature", "properties": { "value": 20, - "stroke": "#add8ff", - "fill": "#add8ff", + "stroke": "#c2e2ff", + "fill": "#c2e2ff", "fill-opacity": 0.85 }, "geometry": { @@ -1913,8 +1913,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#99ceff", - "fill": "#99ceff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -1949,8 +1949,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#99ceff", - "fill": "#99ceff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -1985,8 +1985,8 @@ "type": "Feature", "properties": { "value": 22, - "stroke": "#85c4ff", - "fill": "#85c4ff", + "stroke": "#99ceff", + "fill": "#99ceff", "fill-opacity": 0.85 }, "geometry": { @@ -2021,8 +2021,8 @@ "type": "Feature", "properties": { "value": 23, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -2057,8 +2057,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#1f94ff", - "fill": "#1f94ff", + "stroke": "#339dff", + "fill": "#339dff", "fill-opacity": 0.85 }, "geometry": { @@ -2092,7 +2092,7 @@ { "type": "Feature", "properties": { - "value": 32, + "value": 33, "stroke": "#0060b8", "fill": "#0060b8", "fill-opacity": 0.85 @@ -2128,7 +2128,7 @@ { "type": "Feature", "properties": { - "value": 39, + "value": 40, "stroke": "#001529", "fill": "#001529", "fill-opacity": 0.85 @@ -2165,8 +2165,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#99ceff", - "fill": "#99ceff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -2201,8 +2201,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#99ceff", - "fill": "#99ceff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -2237,8 +2237,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#99ceff", - "fill": "#99ceff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -2273,8 +2273,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#99ceff", - "fill": "#99ceff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -2309,8 +2309,8 @@ "type": "Feature", "properties": { "value": 22, - "stroke": "#85c4ff", - "fill": "#85c4ff", + "stroke": "#99ceff", + "fill": "#99ceff", "fill-opacity": 0.85 }, "geometry": { @@ -2345,8 +2345,8 @@ "type": "Feature", "properties": { "value": 23, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -2380,7 +2380,7 @@ { "type": "Feature", "properties": { - "value": 24, + "value": 25, "stroke": "#5cb1ff", "fill": "#5cb1ff", "fill-opacity": 0.85 @@ -2417,8 +2417,8 @@ "type": "Feature", "properties": { "value": 28, - "stroke": "#0a8aff", - "fill": "#0a8aff", + "stroke": "#1f94ff", + "fill": "#1f94ff", "fill-opacity": 0.85 }, "geometry": { @@ -2453,8 +2453,8 @@ "type": "Feature", "properties": { "value": 33, - "stroke": "#0055a3", - "fill": "#0055a3", + "stroke": "#0060b8", + "fill": "#0060b8", "fill-opacity": 0.85 }, "geometry": { @@ -2488,7 +2488,7 @@ { "type": "Feature", "properties": { - "value": 41, + "value": 42, "stroke": "#000000", "fill": "#000000", "fill-opacity": 0.85 @@ -2525,8 +2525,8 @@ "type": "Feature", "properties": { "value": 22, - "stroke": "#85c4ff", - "fill": "#85c4ff", + "stroke": "#99ceff", + "fill": "#99ceff", "fill-opacity": 0.85 }, "geometry": { @@ -2561,8 +2561,8 @@ "type": "Feature", "properties": { "value": 22, - "stroke": "#85c4ff", - "fill": "#85c4ff", + "stroke": "#99ceff", + "fill": "#99ceff", "fill-opacity": 0.85 }, "geometry": { @@ -2597,8 +2597,8 @@ "type": "Feature", "properties": { "value": 22, - "stroke": "#85c4ff", - "fill": "#85c4ff", + "stroke": "#99ceff", + "fill": "#99ceff", "fill-opacity": 0.85 }, "geometry": { @@ -2633,8 +2633,8 @@ "type": "Feature", "properties": { "value": 22, - "stroke": "#85c4ff", - "fill": "#85c4ff", + "stroke": "#99ceff", + "fill": "#99ceff", "fill-opacity": 0.85 }, "geometry": { @@ -2669,8 +2669,8 @@ "type": "Feature", "properties": { "value": 22, - "stroke": "#85c4ff", - "fill": "#85c4ff", + "stroke": "#99ceff", + "fill": "#99ceff", "fill-opacity": 0.85 }, "geometry": { @@ -2705,8 +2705,8 @@ "type": "Feature", "properties": { "value": 22, - "stroke": "#85c4ff", - "fill": "#85c4ff", + "stroke": "#99ceff", + "fill": "#99ceff", "fill-opacity": 0.85 }, "geometry": { @@ -2740,7 +2740,7 @@ { "type": "Feature", "properties": { - "value": 24, + "value": 25, "stroke": "#5cb1ff", "fill": "#5cb1ff", "fill-opacity": 0.85 @@ -2777,8 +2777,8 @@ "type": "Feature", "properties": { "value": 28, - "stroke": "#0a8aff", - "fill": "#0a8aff", + "stroke": "#1f94ff", + "fill": "#1f94ff", "fill-opacity": 0.85 }, "geometry": { @@ -2813,8 +2813,8 @@ "type": "Feature", "properties": { "value": 32, - "stroke": "#0060b8", - "fill": "#0060b8", + "stroke": "#006acc", + "fill": "#006acc", "fill-opacity": 0.85 }, "geometry": { @@ -2849,8 +2849,8 @@ "type": "Feature", "properties": { "value": 37, - "stroke": "#002b52", - "fill": "#002b52", + "stroke": "#003566", + "fill": "#003566", "fill-opacity": 0.85 }, "geometry": { @@ -2885,8 +2885,8 @@ "type": "Feature", "properties": { "value": 22, - "stroke": "#85c4ff", - "fill": "#85c4ff", + "stroke": "#99ceff", + "fill": "#99ceff", "fill-opacity": 0.85 }, "geometry": { @@ -2921,8 +2921,8 @@ "type": "Feature", "properties": { "value": 22, - "stroke": "#85c4ff", - "fill": "#85c4ff", + "stroke": "#99ceff", + "fill": "#99ceff", "fill-opacity": 0.85 }, "geometry": { @@ -2957,8 +2957,8 @@ "type": "Feature", "properties": { "value": 22, - "stroke": "#85c4ff", - "fill": "#85c4ff", + "stroke": "#99ceff", + "fill": "#99ceff", "fill-opacity": 0.85 }, "geometry": { @@ -2993,8 +2993,8 @@ "type": "Feature", "properties": { "value": 22, - "stroke": "#85c4ff", - "fill": "#85c4ff", + "stroke": "#99ceff", + "fill": "#99ceff", "fill-opacity": 0.85 }, "geometry": { @@ -3029,8 +3029,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#99ceff", - "fill": "#99ceff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -3064,9 +3064,9 @@ { "type": "Feature", "properties": { - "value": 20, - "stroke": "#add8ff", - "fill": "#add8ff", + "value": 19, + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -3101,8 +3101,8 @@ "type": "Feature", "properties": { "value": 23, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -3137,8 +3137,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#1f94ff", - "fill": "#1f94ff", + "stroke": "#339dff", + "fill": "#339dff", "fill-opacity": 0.85 }, "geometry": { @@ -3173,8 +3173,8 @@ "type": "Feature", "properties": { "value": 30, - "stroke": "#0075e0", - "fill": "#0075e0", + "stroke": "#0080f5", + "fill": "#0080f5", "fill-opacity": 0.85 }, "geometry": { @@ -3209,8 +3209,8 @@ "type": "Feature", "properties": { "value": 33, - "stroke": "#0055a3", - "fill": "#0055a3", + "stroke": "#0060b8", + "fill": "#0060b8", "fill-opacity": 0.85 }, "geometry": { diff --git a/packages/turf-interpolate/test/out/data-500m.geojson b/src/interpolate/test/out/data-500m.geojson similarity index 94% rename from packages/turf-interpolate/test/out/data-500m.geojson rename to src/interpolate/test/out/data-500m.geojson index 3e7b1adddb..1ae7e573b8 100644 --- a/packages/turf-interpolate/test/out/data-500m.geojson +++ b/src/interpolate/test/out/data-500m.geojson @@ -40,9 +40,9 @@ { "type": "Feature", "properties": { - "value": 17, - "stroke": "#e0f0ff", - "fill": "#e0f0ff", + "value": 18, + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -293,8 +293,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -329,8 +329,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -473,8 +473,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -509,8 +509,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -545,8 +545,8 @@ "type": "Feature", "properties": { "value": 25, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#75bdff", + "fill": "#75bdff", "fill-opacity": 0.85 }, "geometry": { @@ -581,8 +581,8 @@ "type": "Feature", "properties": { "value": 25, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#75bdff", + "fill": "#75bdff", "fill-opacity": 0.85 }, "geometry": { @@ -617,8 +617,8 @@ "type": "Feature", "properties": { "value": 26, - "stroke": "#61b3ff", - "fill": "#61b3ff", + "stroke": "#66b6ff", + "fill": "#66b6ff", "fill-opacity": 0.85 }, "geometry": { @@ -653,8 +653,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -689,8 +689,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -725,8 +725,8 @@ "type": "Feature", "properties": { "value": 28, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "stroke": "#4daaff", + "fill": "#4daaff", "fill-opacity": 0.85 }, "geometry": { @@ -761,8 +761,8 @@ "type": "Feature", "properties": { "value": 17, - "stroke": "#e0f0ff", - "fill": "#e0f0ff", + "stroke": "#e5f3ff", + "fill": "#e5f3ff", "fill-opacity": 0.85 }, "geometry": { @@ -1049,8 +1049,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -1085,8 +1085,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -1229,8 +1229,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -1265,8 +1265,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -1301,8 +1301,8 @@ "type": "Feature", "properties": { "value": 25, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#75bdff", + "fill": "#75bdff", "fill-opacity": 0.85 }, "geometry": { @@ -1337,8 +1337,8 @@ "type": "Feature", "properties": { "value": 26, - "stroke": "#61b3ff", - "fill": "#61b3ff", + "stroke": "#66b6ff", + "fill": "#66b6ff", "fill-opacity": 0.85 }, "geometry": { @@ -1373,8 +1373,8 @@ "type": "Feature", "properties": { "value": 26, - "stroke": "#61b3ff", - "fill": "#61b3ff", + "stroke": "#66b6ff", + "fill": "#66b6ff", "fill-opacity": 0.85 }, "geometry": { @@ -1409,8 +1409,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -1444,9 +1444,9 @@ { "type": "Feature", "properties": { - "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "value": 28, + "stroke": "#4daaff", + "fill": "#4daaff", "fill-opacity": 0.85 }, "geometry": { @@ -1481,8 +1481,8 @@ "type": "Feature", "properties": { "value": 28, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "stroke": "#4daaff", + "fill": "#4daaff", "fill-opacity": 0.85 }, "geometry": { @@ -1841,8 +1841,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -1877,8 +1877,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -1985,8 +1985,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -2021,8 +2021,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -2057,8 +2057,8 @@ "type": "Feature", "properties": { "value": 25, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#75bdff", + "fill": "#75bdff", "fill-opacity": 0.85 }, "geometry": { @@ -2093,8 +2093,8 @@ "type": "Feature", "properties": { "value": 26, - "stroke": "#61b3ff", - "fill": "#61b3ff", + "stroke": "#66b6ff", + "fill": "#66b6ff", "fill-opacity": 0.85 }, "geometry": { @@ -2129,8 +2129,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -2165,8 +2165,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -2201,8 +2201,8 @@ "type": "Feature", "properties": { "value": 28, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "stroke": "#4daaff", + "fill": "#4daaff", "fill-opacity": 0.85 }, "geometry": { @@ -2236,9 +2236,9 @@ { "type": "Feature", "properties": { - "value": 28, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "value": 29, + "stroke": "#3da2ff", + "fill": "#3da2ff", "fill-opacity": 0.85 }, "geometry": { @@ -2633,8 +2633,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -2740,9 +2740,9 @@ { "type": "Feature", "properties": { - "value": 23, - "stroke": "#8fc9ff", - "fill": "#8fc9ff", + "value": 24, + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -2777,8 +2777,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -2813,8 +2813,8 @@ "type": "Feature", "properties": { "value": 25, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#75bdff", + "fill": "#75bdff", "fill-opacity": 0.85 }, "geometry": { @@ -2849,8 +2849,8 @@ "type": "Feature", "properties": { "value": 26, - "stroke": "#61b3ff", - "fill": "#61b3ff", + "stroke": "#66b6ff", + "fill": "#66b6ff", "fill-opacity": 0.85 }, "geometry": { @@ -2885,8 +2885,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -2921,8 +2921,8 @@ "type": "Feature", "properties": { "value": 28, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "stroke": "#4daaff", + "fill": "#4daaff", "fill-opacity": 0.85 }, "geometry": { @@ -2956,9 +2956,9 @@ { "type": "Feature", "properties": { - "value": 28, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "value": 29, + "stroke": "#3da2ff", + "fill": "#3da2ff", "fill-opacity": 0.85 }, "geometry": { @@ -2993,8 +2993,8 @@ "type": "Feature", "properties": { "value": 29, - "stroke": "#38a0ff", - "fill": "#38a0ff", + "stroke": "#3da2ff", + "fill": "#3da2ff", "fill-opacity": 0.85 }, "geometry": { @@ -3389,8 +3389,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -3533,8 +3533,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -3569,8 +3569,8 @@ "type": "Feature", "properties": { "value": 25, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#75bdff", + "fill": "#75bdff", "fill-opacity": 0.85 }, "geometry": { @@ -3605,8 +3605,8 @@ "type": "Feature", "properties": { "value": 26, - "stroke": "#61b3ff", - "fill": "#61b3ff", + "stroke": "#66b6ff", + "fill": "#66b6ff", "fill-opacity": 0.85 }, "geometry": { @@ -3641,8 +3641,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -3677,8 +3677,8 @@ "type": "Feature", "properties": { "value": 28, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "stroke": "#4daaff", + "fill": "#4daaff", "fill-opacity": 0.85 }, "geometry": { @@ -3713,8 +3713,8 @@ "type": "Feature", "properties": { "value": 29, - "stroke": "#38a0ff", - "fill": "#38a0ff", + "stroke": "#3da2ff", + "fill": "#3da2ff", "fill-opacity": 0.85 }, "geometry": { @@ -3749,8 +3749,8 @@ "type": "Feature", "properties": { "value": 30, - "stroke": "#2999ff", - "fill": "#2999ff", + "stroke": "#2e9bff", + "fill": "#2e9bff", "fill-opacity": 0.85 }, "geometry": { @@ -3965,8 +3965,8 @@ "type": "Feature", "properties": { "value": 17, - "stroke": "#e0f0ff", - "fill": "#e0f0ff", + "stroke": "#e5f3ff", + "fill": "#e5f3ff", "fill-opacity": 0.85 }, "geometry": { @@ -4108,9 +4108,9 @@ { "type": "Feature", "properties": { - "value": 19, - "stroke": "#c7e4ff", - "fill": "#c7e4ff", + "value": 20, + "stroke": "#b8ddff", + "fill": "#b8ddff", "fill-opacity": 0.85 }, "geometry": { @@ -4145,8 +4145,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -4180,9 +4180,9 @@ { "type": "Feature", "properties": { - "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "value": 22, + "stroke": "#9ed1ff", + "fill": "#9ed1ff", "fill-opacity": 0.85 }, "geometry": { @@ -4289,8 +4289,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -4325,8 +4325,8 @@ "type": "Feature", "properties": { "value": 25, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#75bdff", + "fill": "#75bdff", "fill-opacity": 0.85 }, "geometry": { @@ -4361,8 +4361,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -4397,8 +4397,8 @@ "type": "Feature", "properties": { "value": 28, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "stroke": "#4daaff", + "fill": "#4daaff", "fill-opacity": 0.85 }, "geometry": { @@ -4433,8 +4433,8 @@ "type": "Feature", "properties": { "value": 29, - "stroke": "#38a0ff", - "fill": "#38a0ff", + "stroke": "#3da2ff", + "fill": "#3da2ff", "fill-opacity": 0.85 }, "geometry": { @@ -4469,8 +4469,8 @@ "type": "Feature", "properties": { "value": 30, - "stroke": "#2999ff", - "fill": "#2999ff", + "stroke": "#2e9bff", + "fill": "#2e9bff", "fill-opacity": 0.85 }, "geometry": { @@ -4505,8 +4505,8 @@ "type": "Feature", "properties": { "value": 31, - "stroke": "#1f94ff", - "fill": "#1f94ff", + "stroke": "#2496ff", + "fill": "#2496ff", "fill-opacity": 0.85 }, "geometry": { @@ -4721,8 +4721,8 @@ "type": "Feature", "properties": { "value": 17, - "stroke": "#e0f0ff", - "fill": "#e0f0ff", + "stroke": "#e5f3ff", + "fill": "#e5f3ff", "fill-opacity": 0.85 }, "geometry": { @@ -4864,9 +4864,9 @@ { "type": "Feature", "properties": { - "value": 19, - "stroke": "#c7e4ff", - "fill": "#c7e4ff", + "value": 20, + "stroke": "#b8ddff", + "fill": "#b8ddff", "fill-opacity": 0.85 }, "geometry": { @@ -4900,9 +4900,9 @@ { "type": "Feature", "properties": { - "value": 20, - "stroke": "#b8ddff", - "fill": "#b8ddff", + "value": 21, + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -4937,8 +4937,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -5045,8 +5045,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -5080,9 +5080,9 @@ { "type": "Feature", "properties": { - "value": 25, - "stroke": "#70bbff", - "fill": "#70bbff", + "value": 26, + "stroke": "#66b6ff", + "fill": "#66b6ff", "fill-opacity": 0.85 }, "geometry": { @@ -5117,8 +5117,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -5153,8 +5153,8 @@ "type": "Feature", "properties": { "value": 28, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "stroke": "#4daaff", + "fill": "#4daaff", "fill-opacity": 0.85 }, "geometry": { @@ -5189,8 +5189,8 @@ "type": "Feature", "properties": { "value": 30, - "stroke": "#2999ff", - "fill": "#2999ff", + "stroke": "#2e9bff", + "fill": "#2e9bff", "fill-opacity": 0.85 }, "geometry": { @@ -5225,8 +5225,8 @@ "type": "Feature", "properties": { "value": 31, - "stroke": "#1f94ff", - "fill": "#1f94ff", + "stroke": "#2496ff", + "fill": "#2496ff", "fill-opacity": 0.85 }, "geometry": { @@ -5261,8 +5261,8 @@ "type": "Feature", "properties": { "value": 32, - "stroke": "#0f8cff", - "fill": "#0f8cff", + "stroke": "#148fff", + "fill": "#148fff", "fill-opacity": 0.85 }, "geometry": { @@ -5513,8 +5513,8 @@ "type": "Feature", "properties": { "value": 17, - "stroke": "#e0f0ff", - "fill": "#e0f0ff", + "stroke": "#e5f3ff", + "fill": "#e5f3ff", "fill-opacity": 0.85 }, "geometry": { @@ -5548,9 +5548,9 @@ { "type": "Feature", "properties": { - "value": 17, - "stroke": "#e0f0ff", - "fill": "#e0f0ff", + "value": 18, + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -5656,9 +5656,9 @@ { "type": "Feature", "properties": { - "value": 20, - "stroke": "#b8ddff", - "fill": "#b8ddff", + "value": 21, + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -5693,8 +5693,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -5729,8 +5729,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -5801,8 +5801,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -5836,9 +5836,9 @@ { "type": "Feature", "properties": { - "value": 25, - "stroke": "#70bbff", - "fill": "#70bbff", + "value": 26, + "stroke": "#66b6ff", + "fill": "#66b6ff", "fill-opacity": 0.85 }, "geometry": { @@ -5873,8 +5873,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -5909,8 +5909,8 @@ "type": "Feature", "properties": { "value": 29, - "stroke": "#38a0ff", - "fill": "#38a0ff", + "stroke": "#3da2ff", + "fill": "#3da2ff", "fill-opacity": 0.85 }, "geometry": { @@ -5945,8 +5945,8 @@ "type": "Feature", "properties": { "value": 31, - "stroke": "#1f94ff", - "fill": "#1f94ff", + "stroke": "#2496ff", + "fill": "#2496ff", "fill-opacity": 0.85 }, "geometry": { @@ -5981,8 +5981,8 @@ "type": "Feature", "properties": { "value": 32, - "stroke": "#0f8cff", - "fill": "#0f8cff", + "stroke": "#148fff", + "fill": "#148fff", "fill-opacity": 0.85 }, "geometry": { @@ -6016,9 +6016,9 @@ { "type": "Feature", "properties": { - "value": 33, - "stroke": "#0085ff", - "fill": "#0085ff", + "value": 34, + "stroke": "#0082fa", + "fill": "#0082fa", "fill-opacity": 0.85 }, "geometry": { @@ -6160,9 +6160,9 @@ { "type": "Feature", "properties": { - "value": 19, - "stroke": "#c7e4ff", - "fill": "#c7e4ff", + "value": 20, + "stroke": "#b8ddff", + "fill": "#b8ddff", "fill-opacity": 0.85 }, "geometry": { @@ -6340,9 +6340,9 @@ { "type": "Feature", "properties": { - "value": 19, - "stroke": "#c7e4ff", - "fill": "#c7e4ff", + "value": 20, + "stroke": "#b8ddff", + "fill": "#b8ddff", "fill-opacity": 0.85 }, "geometry": { @@ -6413,8 +6413,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -6449,8 +6449,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -6521,8 +6521,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -6556,9 +6556,9 @@ { "type": "Feature", "properties": { - "value": 23, - "stroke": "#8fc9ff", - "fill": "#8fc9ff", + "value": 24, + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -6593,8 +6593,8 @@ "type": "Feature", "properties": { "value": 26, - "stroke": "#61b3ff", - "fill": "#61b3ff", + "stroke": "#66b6ff", + "fill": "#66b6ff", "fill-opacity": 0.85 }, "geometry": { @@ -6629,8 +6629,8 @@ "type": "Feature", "properties": { "value": 28, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "stroke": "#4daaff", + "fill": "#4daaff", "fill-opacity": 0.85 }, "geometry": { @@ -6665,8 +6665,8 @@ "type": "Feature", "properties": { "value": 30, - "stroke": "#2999ff", - "fill": "#2999ff", + "stroke": "#2e9bff", + "fill": "#2e9bff", "fill-opacity": 0.85 }, "geometry": { @@ -6701,8 +6701,8 @@ "type": "Feature", "properties": { "value": 32, - "stroke": "#0f8cff", - "fill": "#0f8cff", + "stroke": "#148fff", + "fill": "#148fff", "fill-opacity": 0.85 }, "geometry": { @@ -6737,8 +6737,8 @@ "type": "Feature", "properties": { "value": 34, - "stroke": "#007df0", - "fill": "#007df0", + "stroke": "#0082fa", + "fill": "#0082fa", "fill-opacity": 0.85 }, "geometry": { @@ -6772,9 +6772,9 @@ { "type": "Feature", "properties": { - "value": 35, - "stroke": "#0075e0", - "fill": "#0075e0", + "value": 36, + "stroke": "#0072db", + "fill": "#0072db", "fill-opacity": 0.85 }, "geometry": { @@ -7133,8 +7133,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -7169,8 +7169,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -7205,8 +7205,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -7312,9 +7312,9 @@ { "type": "Feature", "properties": { - "value": 23, - "stroke": "#8fc9ff", - "fill": "#8fc9ff", + "value": 24, + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -7349,8 +7349,8 @@ "type": "Feature", "properties": { "value": 26, - "stroke": "#61b3ff", - "fill": "#61b3ff", + "stroke": "#66b6ff", + "fill": "#66b6ff", "fill-opacity": 0.85 }, "geometry": { @@ -7384,9 +7384,9 @@ { "type": "Feature", "properties": { - "value": 28, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "value": 29, + "stroke": "#3da2ff", + "fill": "#3da2ff", "fill-opacity": 0.85 }, "geometry": { @@ -7421,8 +7421,8 @@ "type": "Feature", "properties": { "value": 31, - "stroke": "#1f94ff", - "fill": "#1f94ff", + "stroke": "#2496ff", + "fill": "#2496ff", "fill-opacity": 0.85 }, "geometry": { @@ -7456,9 +7456,9 @@ { "type": "Feature", "properties": { - "value": 33, - "stroke": "#0085ff", - "fill": "#0085ff", + "value": 34, + "stroke": "#0082fa", + "fill": "#0082fa", "fill-opacity": 0.85 }, "geometry": { @@ -7493,8 +7493,8 @@ "type": "Feature", "properties": { "value": 36, - "stroke": "#0070d6", - "fill": "#0070d6", + "stroke": "#0072db", + "fill": "#0072db", "fill-opacity": 0.85 }, "geometry": { @@ -7529,8 +7529,8 @@ "type": "Feature", "properties": { "value": 38, - "stroke": "#0060b8", - "fill": "#0060b8", + "stroke": "#0065c2", + "fill": "#0065c2", "fill-opacity": 0.85 }, "geometry": { @@ -7565,8 +7565,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -7853,8 +7853,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -7889,8 +7889,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -7925,8 +7925,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -7961,8 +7961,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -7996,9 +7996,9 @@ { "type": "Feature", "properties": { - "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "value": 22, + "stroke": "#9ed1ff", + "fill": "#9ed1ff", "fill-opacity": 0.85 }, "geometry": { @@ -8032,9 +8032,9 @@ { "type": "Feature", "properties": { - "value": 22, - "stroke": "#9ed1ff", - "fill": "#9ed1ff", + "value": 23, + "stroke": "#8fc9ff", + "fill": "#8fc9ff", "fill-opacity": 0.85 }, "geometry": { @@ -8068,9 +8068,9 @@ { "type": "Feature", "properties": { - "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "value": 25, + "stroke": "#75bdff", + "fill": "#75bdff", "fill-opacity": 0.85 }, "geometry": { @@ -8105,8 +8105,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -8141,8 +8141,8 @@ "type": "Feature", "properties": { "value": 29, - "stroke": "#38a0ff", - "fill": "#38a0ff", + "stroke": "#3da2ff", + "fill": "#3da2ff", "fill-opacity": 0.85 }, "geometry": { @@ -8177,8 +8177,8 @@ "type": "Feature", "properties": { "value": 32, - "stroke": "#0f8cff", - "fill": "#0f8cff", + "stroke": "#148fff", + "fill": "#148fff", "fill-opacity": 0.85 }, "geometry": { @@ -8213,8 +8213,8 @@ "type": "Feature", "properties": { "value": 35, - "stroke": "#0075e0", - "fill": "#0075e0", + "stroke": "#007aeb", + "fill": "#007aeb", "fill-opacity": 0.85 }, "geometry": { @@ -8248,9 +8248,9 @@ { "type": "Feature", "properties": { - "value": 38, - "stroke": "#0060b8", - "fill": "#0060b8", + "value": 39, + "stroke": "#005db3", + "fill": "#005db3", "fill-opacity": 0.85 }, "geometry": { @@ -8285,8 +8285,8 @@ "type": "Feature", "properties": { "value": 42, - "stroke": "#004280", - "fill": "#004280", + "stroke": "#00488a", + "fill": "#00488a", "fill-opacity": 0.85 }, "geometry": { @@ -8321,8 +8321,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -8357,8 +8357,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -8393,8 +8393,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -8429,8 +8429,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -8465,8 +8465,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -8501,8 +8501,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -8537,8 +8537,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -8573,8 +8573,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -8609,8 +8609,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -8645,8 +8645,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -8789,8 +8789,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -8825,8 +8825,8 @@ "type": "Feature", "properties": { "value": 25, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#75bdff", + "fill": "#75bdff", "fill-opacity": 0.85 }, "geometry": { @@ -8860,9 +8860,9 @@ { "type": "Feature", "properties": { - "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "value": 28, + "stroke": "#4daaff", + "fill": "#4daaff", "fill-opacity": 0.85 }, "geometry": { @@ -8897,8 +8897,8 @@ "type": "Feature", "properties": { "value": 30, - "stroke": "#2999ff", - "fill": "#2999ff", + "stroke": "#2e9bff", + "fill": "#2e9bff", "fill-opacity": 0.85 }, "geometry": { @@ -8933,8 +8933,8 @@ "type": "Feature", "properties": { "value": 33, - "stroke": "#0085ff", - "fill": "#0085ff", + "stroke": "#0587ff", + "fill": "#0587ff", "fill-opacity": 0.85 }, "geometry": { @@ -8968,9 +8968,9 @@ { "type": "Feature", "properties": { - "value": 36, - "stroke": "#0070d6", - "fill": "#0070d6", + "value": 37, + "stroke": "#006dd1", + "fill": "#006dd1", "fill-opacity": 0.85 }, "geometry": { @@ -9005,8 +9005,8 @@ "type": "Feature", "properties": { "value": 41, - "stroke": "#004a8f", - "fill": "#004a8f", + "stroke": "#005099", + "fill": "#005099", "fill-opacity": 0.85 }, "geometry": { @@ -9040,7 +9040,7 @@ { "type": "Feature", "properties": { - "value": 47, + "value": 48, "stroke": "#001d38", "fill": "#001d38", "fill-opacity": 0.85 @@ -9077,8 +9077,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -9113,8 +9113,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -9149,8 +9149,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -9185,8 +9185,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -9221,8 +9221,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -9257,8 +9257,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -9293,8 +9293,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -9329,8 +9329,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -9365,8 +9365,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -9544,9 +9544,9 @@ { "type": "Feature", "properties": { - "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "value": 25, + "stroke": "#75bdff", + "fill": "#75bdff", "fill-opacity": 0.85 }, "geometry": { @@ -9581,8 +9581,8 @@ "type": "Feature", "properties": { "value": 26, - "stroke": "#61b3ff", - "fill": "#61b3ff", + "stroke": "#66b6ff", + "fill": "#66b6ff", "fill-opacity": 0.85 }, "geometry": { @@ -9617,8 +9617,8 @@ "type": "Feature", "properties": { "value": 28, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "stroke": "#4daaff", + "fill": "#4daaff", "fill-opacity": 0.85 }, "geometry": { @@ -9653,8 +9653,8 @@ "type": "Feature", "properties": { "value": 30, - "stroke": "#2999ff", - "fill": "#2999ff", + "stroke": "#2e9bff", + "fill": "#2e9bff", "fill-opacity": 0.85 }, "geometry": { @@ -9689,8 +9689,8 @@ "type": "Feature", "properties": { "value": 33, - "stroke": "#0085ff", - "fill": "#0085ff", + "stroke": "#0587ff", + "fill": "#0587ff", "fill-opacity": 0.85 }, "geometry": { @@ -9725,8 +9725,8 @@ "type": "Feature", "properties": { "value": 37, - "stroke": "#0068c7", - "fill": "#0068c7", + "stroke": "#006dd1", + "fill": "#006dd1", "fill-opacity": 0.85 }, "geometry": { @@ -9761,8 +9761,8 @@ "type": "Feature", "properties": { "value": 42, - "stroke": "#004280", - "fill": "#004280", + "stroke": "#00488a", + "fill": "#00488a", "fill-opacity": 0.85 }, "geometry": { @@ -9796,7 +9796,7 @@ { "type": "Feature", "properties": { - "value": 51, + "value": 52, "stroke": "#000000", "fill": "#000000", "fill-opacity": 0.85 @@ -9833,8 +9833,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -9869,8 +9869,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -9905,8 +9905,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -9941,8 +9941,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -9977,8 +9977,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -10013,8 +10013,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -10049,8 +10049,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -10085,8 +10085,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -10265,8 +10265,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -10301,8 +10301,8 @@ "type": "Feature", "properties": { "value": 25, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#75bdff", + "fill": "#75bdff", "fill-opacity": 0.85 }, "geometry": { @@ -10337,8 +10337,8 @@ "type": "Feature", "properties": { "value": 26, - "stroke": "#61b3ff", - "fill": "#61b3ff", + "stroke": "#66b6ff", + "fill": "#66b6ff", "fill-opacity": 0.85 }, "geometry": { @@ -10373,8 +10373,8 @@ "type": "Feature", "properties": { "value": 28, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "stroke": "#4daaff", + "fill": "#4daaff", "fill-opacity": 0.85 }, "geometry": { @@ -10409,8 +10409,8 @@ "type": "Feature", "properties": { "value": 30, - "stroke": "#2999ff", - "fill": "#2999ff", + "stroke": "#2e9bff", + "fill": "#2e9bff", "fill-opacity": 0.85 }, "geometry": { @@ -10445,8 +10445,8 @@ "type": "Feature", "properties": { "value": 33, - "stroke": "#0085ff", - "fill": "#0085ff", + "stroke": "#0587ff", + "fill": "#0587ff", "fill-opacity": 0.85 }, "geometry": { @@ -10480,9 +10480,9 @@ { "type": "Feature", "properties": { - "value": 36, - "stroke": "#0070d6", - "fill": "#0070d6", + "value": 37, + "stroke": "#006dd1", + "fill": "#006dd1", "fill-opacity": 0.85 }, "geometry": { @@ -10517,8 +10517,8 @@ "type": "Feature", "properties": { "value": 41, - "stroke": "#004a8f", - "fill": "#004a8f", + "stroke": "#005099", + "fill": "#005099", "fill-opacity": 0.85 }, "geometry": { @@ -10553,8 +10553,8 @@ "type": "Feature", "properties": { "value": 46, - "stroke": "#002547", - "fill": "#002547", + "stroke": "#002b52", + "fill": "#002b52", "fill-opacity": 0.85 }, "geometry": { @@ -10588,9 +10588,9 @@ { "type": "Feature", "properties": { - "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "value": 22, + "stroke": "#9ed1ff", + "fill": "#9ed1ff", "fill-opacity": 0.85 }, "geometry": { @@ -10625,8 +10625,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -10661,8 +10661,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -10697,8 +10697,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -10733,8 +10733,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -10769,8 +10769,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -10804,9 +10804,9 @@ { "type": "Feature", "properties": { - "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "value": 22, + "stroke": "#9ed1ff", + "fill": "#9ed1ff", "fill-opacity": 0.85 }, "geometry": { @@ -11020,9 +11020,9 @@ { "type": "Feature", "properties": { - "value": 23, - "stroke": "#8fc9ff", - "fill": "#8fc9ff", + "value": 24, + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -11057,8 +11057,8 @@ "type": "Feature", "properties": { "value": 25, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#75bdff", + "fill": "#75bdff", "fill-opacity": 0.85 }, "geometry": { @@ -11093,8 +11093,8 @@ "type": "Feature", "properties": { "value": 26, - "stroke": "#61b3ff", - "fill": "#61b3ff", + "stroke": "#66b6ff", + "fill": "#66b6ff", "fill-opacity": 0.85 }, "geometry": { @@ -11129,8 +11129,8 @@ "type": "Feature", "properties": { "value": 28, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "stroke": "#4daaff", + "fill": "#4daaff", "fill-opacity": 0.85 }, "geometry": { @@ -11165,8 +11165,8 @@ "type": "Feature", "properties": { "value": 30, - "stroke": "#2999ff", - "fill": "#2999ff", + "stroke": "#2e9bff", + "fill": "#2e9bff", "fill-opacity": 0.85 }, "geometry": { @@ -11201,8 +11201,8 @@ "type": "Feature", "properties": { "value": 32, - "stroke": "#0f8cff", - "fill": "#0f8cff", + "stroke": "#148fff", + "fill": "#148fff", "fill-opacity": 0.85 }, "geometry": { @@ -11237,8 +11237,8 @@ "type": "Feature", "properties": { "value": 35, - "stroke": "#0075e0", - "fill": "#0075e0", + "stroke": "#007aeb", + "fill": "#007aeb", "fill-opacity": 0.85 }, "geometry": { @@ -11273,8 +11273,8 @@ "type": "Feature", "properties": { "value": 38, - "stroke": "#0060b8", - "fill": "#0060b8", + "stroke": "#0065c2", + "fill": "#0065c2", "fill-opacity": 0.85 }, "geometry": { @@ -11309,8 +11309,8 @@ "type": "Feature", "properties": { "value": 41, - "stroke": "#004a8f", - "fill": "#004a8f", + "stroke": "#005099", + "fill": "#005099", "fill-opacity": 0.85 }, "geometry": { @@ -11813,8 +11813,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -11849,8 +11849,8 @@ "type": "Feature", "properties": { "value": 26, - "stroke": "#61b3ff", - "fill": "#61b3ff", + "stroke": "#66b6ff", + "fill": "#66b6ff", "fill-opacity": 0.85 }, "geometry": { @@ -11884,9 +11884,9 @@ { "type": "Feature", "properties": { - "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "value": 28, + "stroke": "#4daaff", + "fill": "#4daaff", "fill-opacity": 0.85 }, "geometry": { @@ -11920,9 +11920,9 @@ { "type": "Feature", "properties": { - "value": 29, - "stroke": "#38a0ff", - "fill": "#38a0ff", + "value": 30, + "stroke": "#2e9bff", + "fill": "#2e9bff", "fill-opacity": 0.85 }, "geometry": { @@ -11956,9 +11956,9 @@ { "type": "Feature", "properties": { - "value": 31, - "stroke": "#1f94ff", - "fill": "#1f94ff", + "value": 32, + "stroke": "#148fff", + "fill": "#148fff", "fill-opacity": 0.85 }, "geometry": { @@ -11993,8 +11993,8 @@ "type": "Feature", "properties": { "value": 34, - "stroke": "#007df0", - "fill": "#007df0", + "stroke": "#0082fa", + "fill": "#0082fa", "fill-opacity": 0.85 }, "geometry": { @@ -12029,8 +12029,8 @@ "type": "Feature", "properties": { "value": 36, - "stroke": "#0070d6", - "fill": "#0070d6", + "stroke": "#0072db", + "fill": "#0072db", "fill-opacity": 0.85 }, "geometry": { @@ -12065,8 +12065,8 @@ "type": "Feature", "properties": { "value": 38, - "stroke": "#0060b8", - "fill": "#0060b8", + "stroke": "#0065c2", + "fill": "#0065c2", "fill-opacity": 0.85 }, "geometry": { @@ -12389,8 +12389,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -12425,8 +12425,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -12461,8 +12461,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -12497,8 +12497,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -12569,8 +12569,8 @@ "type": "Feature", "properties": { "value": 24, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -12605,8 +12605,8 @@ "type": "Feature", "properties": { "value": 25, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#75bdff", + "fill": "#75bdff", "fill-opacity": 0.85 }, "geometry": { @@ -12641,8 +12641,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -12677,8 +12677,8 @@ "type": "Feature", "properties": { "value": 29, - "stroke": "#38a0ff", - "fill": "#38a0ff", + "stroke": "#3da2ff", + "fill": "#3da2ff", "fill-opacity": 0.85 }, "geometry": { @@ -12713,8 +12713,8 @@ "type": "Feature", "properties": { "value": 31, - "stroke": "#1f94ff", - "fill": "#1f94ff", + "stroke": "#2496ff", + "fill": "#2496ff", "fill-opacity": 0.85 }, "geometry": { @@ -12749,8 +12749,8 @@ "type": "Feature", "properties": { "value": 32, - "stroke": "#0f8cff", - "fill": "#0f8cff", + "stroke": "#148fff", + "fill": "#148fff", "fill-opacity": 0.85 }, "geometry": { @@ -12785,8 +12785,8 @@ "type": "Feature", "properties": { "value": 34, - "stroke": "#007df0", - "fill": "#007df0", + "stroke": "#0082fa", + "fill": "#0082fa", "fill-opacity": 0.85 }, "geometry": { @@ -12821,8 +12821,8 @@ "type": "Feature", "properties": { "value": 36, - "stroke": "#0070d6", - "fill": "#0070d6", + "stroke": "#0072db", + "fill": "#0072db", "fill-opacity": 0.85 }, "geometry": { @@ -13145,8 +13145,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -13181,8 +13181,8 @@ "type": "Feature", "properties": { "value": 21, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -13252,9 +13252,9 @@ { "type": "Feature", "properties": { - "value": 18, - "stroke": "#d6ebff", - "fill": "#d6ebff", + "value": 17, + "stroke": "#e5f3ff", + "fill": "#e5f3ff", "fill-opacity": 0.85 }, "geometry": { @@ -13288,9 +13288,9 @@ { "type": "Feature", "properties": { - "value": 20, - "stroke": "#b8ddff", - "fill": "#b8ddff", + "value": 21, + "stroke": "#add8ff", + "fill": "#add8ff", "fill-opacity": 0.85 }, "geometry": { @@ -13361,8 +13361,8 @@ "type": "Feature", "properties": { "value": 25, - "stroke": "#70bbff", - "fill": "#70bbff", + "stroke": "#75bdff", + "fill": "#75bdff", "fill-opacity": 0.85 }, "geometry": { @@ -13397,8 +13397,8 @@ "type": "Feature", "properties": { "value": 27, - "stroke": "#57aeff", - "fill": "#57aeff", + "stroke": "#5cb1ff", + "fill": "#5cb1ff", "fill-opacity": 0.85 }, "geometry": { @@ -13433,8 +13433,8 @@ "type": "Feature", "properties": { "value": 28, - "stroke": "#47a7ff", - "fill": "#47a7ff", + "stroke": "#4daaff", + "fill": "#4daaff", "fill-opacity": 0.85 }, "geometry": { @@ -13469,8 +13469,8 @@ "type": "Feature", "properties": { "value": 30, - "stroke": "#2999ff", - "fill": "#2999ff", + "stroke": "#2e9bff", + "fill": "#2e9bff", "fill-opacity": 0.85 }, "geometry": { @@ -13505,8 +13505,8 @@ "type": "Feature", "properties": { "value": 31, - "stroke": "#1f94ff", - "fill": "#1f94ff", + "stroke": "#2496ff", + "fill": "#2496ff", "fill-opacity": 0.85 }, "geometry": { @@ -13541,8 +13541,8 @@ "type": "Feature", "properties": { "value": 33, - "stroke": "#0085ff", - "fill": "#0085ff", + "stroke": "#0587ff", + "fill": "#0587ff", "fill-opacity": 0.85 }, "geometry": { @@ -13577,8 +13577,8 @@ "type": "Feature", "properties": { "value": 34, - "stroke": "#007df0", - "fill": "#007df0", + "stroke": "#0082fa", + "fill": "#0082fa", "fill-opacity": 0.85 }, "geometry": { diff --git a/packages/turf-interpolate/test/out/data-weight-2.geojson b/src/interpolate/test/out/data-weight-2.geojson similarity index 92% rename from packages/turf-interpolate/test/out/data-weight-2.geojson rename to src/interpolate/test/out/data-weight-2.geojson index 22a414f43c..0a64bd52a4 100644 --- a/packages/turf-interpolate/test/out/data-weight-2.geojson +++ b/src/interpolate/test/out/data-weight-2.geojson @@ -5,8 +5,8 @@ "type": "Feature", "properties": { "value": 8, - "stroke": "#e5f3ff", - "fill": "#e5f3ff", + "stroke": "#ebf5ff", + "fill": "#ebf5ff", "fill-opacity": 0.85 }, "geometry": { @@ -41,8 +41,8 @@ "type": "Feature", "properties": { "value": 8, - "stroke": "#e5f3ff", - "fill": "#e5f3ff", + "stroke": "#ebf5ff", + "fill": "#ebf5ff", "fill-opacity": 0.85 }, "geometry": { @@ -112,7 +112,7 @@ { "type": "Feature", "properties": { - "value": 14, + "value": 15, "stroke": "#b8ddff", "fill": "#b8ddff", "fill-opacity": 0.85 @@ -148,9 +148,9 @@ { "type": "Feature", "properties": { - "value": 21, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "value": 22, + "stroke": "#85c4ff", + "fill": "#85c4ff", "fill-opacity": 0.85 }, "geometry": { @@ -184,9 +184,9 @@ { "type": "Feature", "properties": { - "value": 31, - "stroke": "#2e9bff", - "fill": "#2e9bff", + "value": 32, + "stroke": "#38a0ff", + "fill": "#38a0ff", "fill-opacity": 0.85 }, "geometry": { @@ -221,8 +221,8 @@ "type": "Feature", "properties": { "value": 8, - "stroke": "#e5f3ff", - "fill": "#e5f3ff", + "stroke": "#ebf5ff", + "fill": "#ebf5ff", "fill-opacity": 0.85 }, "geometry": { @@ -293,8 +293,8 @@ "type": "Feature", "properties": { "value": 6, - "stroke": "#f5faff", - "fill": "#f5faff", + "stroke": "#fafdff", + "fill": "#fafdff", "fill-opacity": 0.85 }, "geometry": { @@ -329,8 +329,8 @@ "type": "Feature", "properties": { "value": 13, - "stroke": "#bddfff", - "fill": "#bddfff", + "stroke": "#c7e4ff", + "fill": "#c7e4ff", "fill-opacity": 0.85 }, "geometry": { @@ -364,7 +364,7 @@ { "type": "Feature", "properties": { - "value": 20, + "value": 21, "stroke": "#8ac7ff", "fill": "#8ac7ff", "fill-opacity": 0.85 @@ -400,9 +400,9 @@ { "type": "Feature", "properties": { - "value": 36, - "stroke": "#0a8aff", - "fill": "#0a8aff", + "value": 39, + "stroke": "#0587ff", + "fill": "#0587ff", "fill-opacity": 0.85 }, "geometry": { @@ -437,8 +437,8 @@ "type": "Feature", "properties": { "value": 10, - "stroke": "#d6ebff", - "fill": "#d6ebff", + "stroke": "#dbeeff", + "fill": "#dbeeff", "fill-opacity": 0.85 }, "geometry": { @@ -472,9 +472,9 @@ { "type": "Feature", "properties": { - "value": 7, - "stroke": "#f0f8ff", - "fill": "#f0f8ff", + "value": 8, + "stroke": "#ebf5ff", + "fill": "#ebf5ff", "fill-opacity": 0.85 }, "geometry": { @@ -508,9 +508,9 @@ { "type": "Feature", "properties": { - "value": 9, - "stroke": "#e0f0ff", - "fill": "#e0f0ff", + "value": 10, + "stroke": "#dbeeff", + "fill": "#dbeeff", "fill-opacity": 0.85 }, "geometry": { @@ -580,9 +580,9 @@ { "type": "Feature", "properties": { - "value": 16, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "value": 18, + "stroke": "#9ed1ff", + "fill": "#9ed1ff", "fill-opacity": 0.85 }, "geometry": { @@ -616,9 +616,9 @@ { "type": "Feature", "properties": { - "value": 49, - "stroke": "#00529e", - "fill": "#00529e", + "value": 55, + "stroke": "#004d94", + "fill": "#004d94", "fill-opacity": 0.85 }, "geometry": { @@ -653,8 +653,8 @@ "type": "Feature", "properties": { "value": 12, - "stroke": "#c7e4ff", - "fill": "#c7e4ff", + "stroke": "#cce7ff", + "fill": "#cce7ff", "fill-opacity": 0.85 }, "geometry": { @@ -689,8 +689,8 @@ "type": "Feature", "properties": { "value": 12, - "stroke": "#c7e4ff", - "fill": "#c7e4ff", + "stroke": "#cce7ff", + "fill": "#cce7ff", "fill-opacity": 0.85 }, "geometry": { @@ -725,8 +725,8 @@ "type": "Feature", "properties": { "value": 13, - "stroke": "#bddfff", - "fill": "#bddfff", + "stroke": "#c7e4ff", + "fill": "#c7e4ff", "fill-opacity": 0.85 }, "geometry": { @@ -760,7 +760,7 @@ { "type": "Feature", "properties": { - "value": 14, + "value": 15, "stroke": "#b8ddff", "fill": "#b8ddff", "fill-opacity": 0.85 @@ -796,9 +796,9 @@ { "type": "Feature", "properties": { - "value": 24, - "stroke": "#66b6ff", - "fill": "#66b6ff", + "value": 28, + "stroke": "#57aeff", + "fill": "#57aeff", "fill-opacity": 0.85 }, "geometry": { @@ -832,7 +832,7 @@ { "type": "Feature", "properties": { - "value": 69, + "value": 75, "stroke": "#000000", "fill": "#000000", "fill-opacity": 0.85 @@ -869,8 +869,8 @@ "type": "Feature", "properties": { "value": 14, - "stroke": "#b8ddff", - "fill": "#b8ddff", + "stroke": "#bddfff", + "fill": "#bddfff", "fill-opacity": 0.85 }, "geometry": { @@ -905,8 +905,8 @@ "type": "Feature", "properties": { "value": 13, - "stroke": "#bddfff", - "fill": "#bddfff", + "stroke": "#c7e4ff", + "fill": "#c7e4ff", "fill-opacity": 0.85 }, "geometry": { @@ -940,9 +940,9 @@ { "type": "Feature", "properties": { - "value": 12, - "stroke": "#c7e4ff", - "fill": "#c7e4ff", + "value": 11, + "stroke": "#d1e9ff", + "fill": "#d1e9ff", "fill-opacity": 0.85 }, "geometry": { @@ -977,8 +977,8 @@ "type": "Feature", "properties": { "value": 12, - "stroke": "#c7e4ff", - "fill": "#c7e4ff", + "stroke": "#cce7ff", + "fill": "#cce7ff", "fill-opacity": 0.85 }, "geometry": { @@ -1012,9 +1012,9 @@ { "type": "Feature", "properties": { - "value": 26, - "stroke": "#57aeff", - "fill": "#57aeff", + "value": 27, + "stroke": "#61b3ff", + "fill": "#61b3ff", "fill-opacity": 0.85 }, "geometry": { @@ -1048,9 +1048,9 @@ { "type": "Feature", "properties": { - "value": 61, - "stroke": "#00203d", - "fill": "#00203d", + "value": 62, + "stroke": "#003361", + "fill": "#003361", "fill-opacity": 0.85 }, "geometry": { diff --git a/packages/turf-interpolate/test/out/hex-zValue.geojson b/src/interpolate/test/out/hex-zValue.geojson similarity index 100% rename from packages/turf-interpolate/test/out/hex-zValue.geojson rename to src/interpolate/test/out/hex-zValue.geojson diff --git a/packages/turf-interpolate/test/out/points-random.geojson b/src/interpolate/test/out/points-random.geojson similarity index 100% rename from packages/turf-interpolate/test/out/points-random.geojson rename to src/interpolate/test/out/points-random.geojson diff --git a/packages/turf-interpolate/test/out/points1-weight-3.geojson b/src/interpolate/test/out/points1-weight-3.geojson similarity index 100% rename from packages/turf-interpolate/test/out/points1-weight-3.geojson rename to src/interpolate/test/out/points1-weight-3.geojson diff --git a/packages/turf-interpolate/test/out/points1.geojson b/src/interpolate/test/out/points1.geojson similarity index 100% rename from packages/turf-interpolate/test/out/points1.geojson rename to src/interpolate/test/out/points1.geojson diff --git a/packages/turf-interpolate/test/out/triangle-zValue.geojson b/src/interpolate/test/out/triangle-zValue.geojson similarity index 99% rename from packages/turf-interpolate/test/out/triangle-zValue.geojson rename to src/interpolate/test/out/triangle-zValue.geojson index 9cd56eddb8..2541d6d671 100644 --- a/packages/turf-interpolate/test/out/triangle-zValue.geojson +++ b/src/interpolate/test/out/triangle-zValue.geojson @@ -68,9 +68,9 @@ { "type": "Feature", "properties": { - "elevation": 5, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "elevation": 6, + "stroke": "#57aeff", + "fill": "#57aeff", "fill-opacity": 0.85 }, "geometry": { @@ -1700,9 +1700,9 @@ { "type": "Feature", "properties": { - "elevation": 4, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "elevation": 5, + "stroke": "#80c2ff", + "fill": "#80c2ff", "fill-opacity": 0.85 }, "geometry": { @@ -1796,9 +1796,9 @@ { "type": "Feature", "properties": { - "elevation": 4, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "elevation": 3, + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -3236,9 +3236,9 @@ { "type": "Feature", "properties": { - "elevation": 4, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "elevation": 5, + "stroke": "#80c2ff", + "fill": "#80c2ff", "fill-opacity": 0.85 }, "geometry": { @@ -4772,9 +4772,9 @@ { "type": "Feature", "properties": { - "elevation": 4, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "elevation": 5, + "stroke": "#80c2ff", + "fill": "#80c2ff", "fill-opacity": 0.85 }, "geometry": { @@ -4900,9 +4900,9 @@ { "type": "Feature", "properties": { - "elevation": 3, - "stroke": "#d6ebff", - "fill": "#d6ebff", + "elevation": 4, + "stroke": "#a8d6ff", + "fill": "#a8d6ff", "fill-opacity": 0.85 }, "geometry": { @@ -5092,9 +5092,9 @@ { "type": "Feature", "properties": { - "elevation": 2, - "stroke": "#ffffff", - "fill": "#ffffff", + "elevation": 3, + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -5668,9 +5668,9 @@ { "type": "Feature", "properties": { - "elevation": 3, - "stroke": "#d6ebff", - "fill": "#d6ebff", + "elevation": 4, + "stroke": "#a8d6ff", + "fill": "#a8d6ff", "fill-opacity": 0.85 }, "geometry": { @@ -5828,9 +5828,9 @@ { "type": "Feature", "properties": { - "elevation": 4, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "elevation": 5, + "stroke": "#80c2ff", + "fill": "#80c2ff", "fill-opacity": 0.85 }, "geometry": { @@ -5860,9 +5860,9 @@ { "type": "Feature", "properties": { - "elevation": 4, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "elevation": 5, + "stroke": "#80c2ff", + "fill": "#80c2ff", "fill-opacity": 0.85 }, "geometry": { @@ -5892,9 +5892,9 @@ { "type": "Feature", "properties": { - "elevation": 8, - "stroke": "#0085ff", - "fill": "#0085ff", + "elevation": 9, + "stroke": "#0070d6", + "fill": "#0070d6", "fill-opacity": 0.85 }, "geometry": { @@ -5924,9 +5924,9 @@ { "type": "Feature", "properties": { - "elevation": 8, - "stroke": "#0085ff", - "fill": "#0085ff", + "elevation": 9, + "stroke": "#0070d6", + "fill": "#0070d6", "fill-opacity": 0.85 }, "geometry": { @@ -6116,9 +6116,9 @@ { "type": "Feature", "properties": { - "elevation": 7, - "stroke": "#2999ff", - "fill": "#2999ff", + "elevation": 6, + "stroke": "#57aeff", + "fill": "#57aeff", "fill-opacity": 0.85 }, "geometry": { @@ -6756,9 +6756,9 @@ { "type": "Feature", "properties": { - "elevation": 2, - "stroke": "#ffffff", - "fill": "#ffffff", + "elevation": 3, + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -6788,9 +6788,9 @@ { "type": "Feature", "properties": { - "elevation": 2, - "stroke": "#ffffff", - "fill": "#ffffff", + "elevation": 3, + "stroke": "#d6ebff", + "fill": "#d6ebff", "fill-opacity": 0.85 }, "geometry": { @@ -7396,9 +7396,9 @@ { "type": "Feature", "properties": { - "elevation": 9, - "stroke": "#0070d6", - "fill": "#0070d6", + "elevation": 10, + "stroke": "#0058a8", + "fill": "#0058a8", "fill-opacity": 0.85 }, "geometry": { @@ -7588,9 +7588,9 @@ { "type": "Feature", "properties": { - "elevation": 7, - "stroke": "#2999ff", - "fill": "#2999ff", + "elevation": 8, + "stroke": "#0085ff", + "fill": "#0085ff", "fill-opacity": 0.85 }, "geometry": { @@ -7716,9 +7716,9 @@ { "type": "Feature", "properties": { - "elevation": 6, - "stroke": "#57aeff", - "fill": "#57aeff", + "elevation": 7, + "stroke": "#2999ff", + "fill": "#2999ff", "fill-opacity": 0.85 }, "geometry": { @@ -7844,9 +7844,9 @@ { "type": "Feature", "properties": { - "elevation": 5, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "elevation": 6, + "stroke": "#57aeff", + "fill": "#57aeff", "fill-opacity": 0.85 }, "geometry": { @@ -8196,9 +8196,9 @@ { "type": "Feature", "properties": { - "elevation": 3, - "stroke": "#d6ebff", - "fill": "#d6ebff", + "elevation": 4, + "stroke": "#a8d6ff", + "fill": "#a8d6ff", "fill-opacity": 0.85 }, "geometry": { @@ -8260,9 +8260,9 @@ { "type": "Feature", "properties": { - "elevation": 3, - "stroke": "#d6ebff", - "fill": "#d6ebff", + "elevation": 4, + "stroke": "#a8d6ff", + "fill": "#a8d6ff", "fill-opacity": 0.85 }, "geometry": { @@ -8324,9 +8324,9 @@ { "type": "Feature", "properties": { - "elevation": 3, - "stroke": "#d6ebff", - "fill": "#d6ebff", + "elevation": 4, + "stroke": "#a8d6ff", + "fill": "#a8d6ff", "fill-opacity": 0.85 }, "geometry": { @@ -8484,9 +8484,9 @@ { "type": "Feature", "properties": { - "elevation": 4, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "elevation": 5, + "stroke": "#80c2ff", + "fill": "#80c2ff", "fill-opacity": 0.85 }, "geometry": { @@ -8516,9 +8516,9 @@ { "type": "Feature", "properties": { - "elevation": 4, - "stroke": "#a8d6ff", - "fill": "#a8d6ff", + "elevation": 5, + "stroke": "#80c2ff", + "fill": "#80c2ff", "fill-opacity": 0.85 }, "geometry": { @@ -8804,9 +8804,9 @@ { "type": "Feature", "properties": { - "elevation": 5, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "elevation": 6, + "stroke": "#57aeff", + "fill": "#57aeff", "fill-opacity": 0.85 }, "geometry": { @@ -9412,9 +9412,9 @@ { "type": "Feature", "properties": { - "elevation": 6, - "stroke": "#57aeff", - "fill": "#57aeff", + "elevation": 7, + "stroke": "#2999ff", + "fill": "#2999ff", "fill-opacity": 0.85 }, "geometry": { @@ -9764,9 +9764,9 @@ { "type": "Feature", "properties": { - "elevation": 5, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "elevation": 6, + "stroke": "#57aeff", + "fill": "#57aeff", "fill-opacity": 0.85 }, "geometry": { @@ -9796,9 +9796,9 @@ { "type": "Feature", "properties": { - "elevation": 5, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "elevation": 6, + "stroke": "#57aeff", + "fill": "#57aeff", "fill-opacity": 0.85 }, "geometry": { @@ -9892,9 +9892,9 @@ { "type": "Feature", "properties": { - "elevation": 5, - "stroke": "#80c2ff", - "fill": "#80c2ff", + "elevation": 6, + "stroke": "#57aeff", + "fill": "#57aeff", "fill-opacity": 0.85 }, "geometry": { @@ -10884,9 +10884,9 @@ { "type": "Feature", "properties": { - "elevation": 7, - "stroke": "#2999ff", - "fill": "#2999ff", + "elevation": 8, + "stroke": "#0085ff", + "fill": "#0085ff", "fill-opacity": 0.85 }, "geometry": { @@ -10948,9 +10948,9 @@ { "type": "Feature", "properties": { - "elevation": 7, - "stroke": "#2999ff", - "fill": "#2999ff", + "elevation": 8, + "stroke": "#0085ff", + "fill": "#0085ff", "fill-opacity": 0.85 }, "geometry": { @@ -11172,9 +11172,9 @@ { "type": "Feature", "properties": { - "elevation": 7, - "stroke": "#2999ff", - "fill": "#2999ff", + "elevation": 8, + "stroke": "#0085ff", + "fill": "#0085ff", "fill-opacity": 0.85 }, "geometry": { @@ -11396,9 +11396,9 @@ { "type": "Feature", "properties": { - "elevation": 6, - "stroke": "#57aeff", - "fill": "#57aeff", + "elevation": 7, + "stroke": "#2999ff", + "fill": "#2999ff", "fill-opacity": 0.85 }, "geometry": { @@ -11940,9 +11940,9 @@ { "type": "Feature", "properties": { - "elevation": 10, - "stroke": "#0058a8", - "fill": "#0058a8", + "elevation": 11, + "stroke": "#004280", + "fill": "#004280", "fill-opacity": 0.85 }, "geometry": { @@ -12612,9 +12612,9 @@ { "type": "Feature", "properties": { - "elevation": 8, - "stroke": "#0085ff", - "fill": "#0085ff", + "elevation": 9, + "stroke": "#0070d6", + "fill": "#0070d6", "fill-opacity": 0.85 }, "geometry": { @@ -13412,9 +13412,9 @@ { "type": "Feature", "properties": { - "elevation": 11, - "stroke": "#004280", - "fill": "#004280", + "elevation": 12, + "stroke": "#002d57", + "fill": "#002d57", "fill-opacity": 0.85 }, "geometry": { @@ -14916,9 +14916,9 @@ { "type": "Feature", "properties": { - "elevation": 11, - "stroke": "#004280", - "fill": "#004280", + "elevation": 12, + "stroke": "#002d57", + "fill": "#002d57", "fill-opacity": 0.85 }, "geometry": { @@ -17348,9 +17348,9 @@ { "type": "Feature", "properties": { - "elevation": 8, - "stroke": "#0085ff", - "fill": "#0085ff", + "elevation": 7, + "stroke": "#2999ff", + "fill": "#2999ff", "fill-opacity": 0.85 }, "geometry": { @@ -18852,9 +18852,9 @@ { "type": "Feature", "properties": { - "elevation": 7, - "stroke": "#2999ff", - "fill": "#2999ff", + "elevation": 8, + "stroke": "#0085ff", + "fill": "#0085ff", "fill-opacity": 0.85 }, "geometry": { @@ -20228,9 +20228,9 @@ { "type": "Feature", "properties": { - "elevation": 9, - "stroke": "#0070d6", - "fill": "#0070d6", + "elevation": 10, + "stroke": "#0058a8", + "fill": "#0058a8", "fill-opacity": 0.85 }, "geometry": { @@ -20260,9 +20260,9 @@ { "type": "Feature", "properties": { - "elevation": 9, - "stroke": "#0070d6", - "fill": "#0070d6", + "elevation": 10, + "stroke": "#0058a8", + "fill": "#0058a8", "fill-opacity": 0.85 }, "geometry": { @@ -20900,9 +20900,9 @@ { "type": "Feature", "properties": { - "elevation": 12, - "stroke": "#002d57", - "fill": "#002d57", + "elevation": 13, + "stroke": "#001529", + "fill": "#001529", "fill-opacity": 0.85 }, "geometry": { @@ -21700,9 +21700,9 @@ { "type": "Feature", "properties": { - "elevation": 10, - "stroke": "#0058a8", - "fill": "#0058a8", + "elevation": 11, + "stroke": "#004280", + "fill": "#004280", "fill-opacity": 0.85 }, "geometry": { @@ -21860,9 +21860,9 @@ { "type": "Feature", "properties": { - "elevation": 7, - "stroke": "#2999ff", - "fill": "#2999ff", + "elevation": 6, + "stroke": "#57aeff", + "fill": "#57aeff", "fill-opacity": 0.85 }, "geometry": { @@ -22468,9 +22468,9 @@ { "type": "Feature", "properties": { - "elevation": 11, - "stroke": "#004280", - "fill": "#004280", + "elevation": 10, + "stroke": "#0058a8", + "fill": "#0058a8", "fill-opacity": 0.85 }, "geometry": { @@ -23812,9 +23812,9 @@ { "type": "Feature", "properties": { - "elevation": 14, - "stroke": "#000000", - "fill": "#000000", + "elevation": 13, + "stroke": "#001529", + "fill": "#001529", "fill-opacity": 0.85 }, "geometry": { @@ -24100,9 +24100,9 @@ { "type": "Feature", "properties": { - "elevation": 9, - "stroke": "#0070d6", - "fill": "#0070d6", + "elevation": 10, + "stroke": "#0058a8", + "fill": "#0058a8", "fill-opacity": 0.85 }, "geometry": { @@ -24804,9 +24804,9 @@ { "type": "Feature", "properties": { - "elevation": 9, - "stroke": "#0070d6", - "fill": "#0070d6", + "elevation": 8, + "stroke": "#0085ff", + "fill": "#0085ff", "fill-opacity": 0.85 }, "geometry": { @@ -25284,9 +25284,9 @@ { "type": "Feature", "properties": { - "elevation": 14, - "stroke": "#000000", - "fill": "#000000", + "elevation": 13, + "stroke": "#001529", + "fill": "#001529", "fill-opacity": 0.85 }, "geometry": { @@ -25412,9 +25412,9 @@ { "type": "Feature", "properties": { - "elevation": 12, - "stroke": "#002d57", - "fill": "#002d57", + "elevation": 11, + "stroke": "#004280", + "fill": "#004280", "fill-opacity": 0.85 }, "geometry": { @@ -26276,9 +26276,9 @@ { "type": "Feature", "properties": { - "elevation": 9, - "stroke": "#0070d6", - "fill": "#0070d6", + "elevation": 10, + "stroke": "#0058a8", + "fill": "#0058a8", "fill-opacity": 0.85 }, "geometry": { diff --git a/src/intersect/bench.js b/src/intersect/bench.js new file mode 100644 index 0000000000..e4d38f9146 --- /dev/null +++ b/src/intersect/bench.js @@ -0,0 +1,21 @@ +const path = require('path'); +const load = require('load-json-file'); +const Benchmark = require('benchmark'); +const intersect = require('./').default; + +// Fixtures +const armenia = load.sync(path.join(__dirname, 'test', 'in', 'armenia.geojson')); +const simple = load.sync(path.join(__dirname, 'test', 'in', 'Intersect1.geojson')); + +/** + * Benchmark Results + * + * turf-intersect#simple x 11,529 ops/sec ±15.12% (90 runs sampled) + * turf-intersect#armenia x 8,011 ops/sec ±1.83% (88 runs sampled) + */ +new Benchmark.Suite('turf-intersect') + .add('turf-intersect#simple', () => intersect(simple.features[0], simple.features[1])) + .add('turf-intersect#armenia', () => intersect(armenia.features[0], armenia.features[1])) + .on('cycle', e => console.log(String(e.target))) + .on('complete', () => {}) + .run(); diff --git a/src/intersect/index.d.ts b/src/intersect/index.d.ts new file mode 100644 index 0000000000..7a1e6be01b --- /dev/null +++ b/src/intersect/index.d.ts @@ -0,0 +1,40 @@ +import { Feature, MultiPolygon, Polygon, Properties } from "../helpers"; +/** + * Takes two {@link Polygon|polygon} or {@link MultiPolygon|multi-polygon} geometries and + * finds their polygonal intersection. If they don't intersect, returns null. + * + * @name intersect + * @param {Feature} poly1 the first polygon or multipolygon + * @param {Feature} poly2 the second polygon or multipolygon + * @param {Object} [options={}] Optional Parameters + * @param {Object} [options.properties={}] Translate GeoJSON Properties to Feature + * @returns {Feature|null} returns a feature representing the area they share (either a {@link Polygon} or + * {@link MultiPolygon}). If they do not share any area, returns `null`. + * @example + * var poly1 = turf.polygon([[ + * [-122.801742, 45.48565], + * [-122.801742, 45.60491], + * [-122.584762, 45.60491], + * [-122.584762, 45.48565], + * [-122.801742, 45.48565] + * ]]); + * + * var poly2 = turf.polygon([[ + * [-122.520217, 45.535693], + * [-122.64038, 45.553967], + * [-122.720031, 45.526554], + * [-122.669906, 45.507309], + * [-122.723464, 45.446643], + * [-122.532577, 45.408574], + * [-122.487258, 45.477466], + * [-122.520217, 45.535693] + * ]]); + * + * var intersection = turf.intersect(poly1, poly2); + * + * //addToMap + * var addToMap = [poly1, poly2, intersection]; + */ +export default function intersect

(poly1: Feature | Polygon | MultiPolygon, poly2: Feature | Polygon | MultiPolygon, options?: { + properties?: P; +}): Feature | null; diff --git a/src/intersect/index.js b/src/intersect/index.js new file mode 100644 index 0000000000..1aab1e0194 --- /dev/null +++ b/src/intersect/index.js @@ -0,0 +1,51 @@ +import { multiPolygon, polygon, checkIfOptionsExist } from '../helpers'; +import { getGeom } from '../invariant'; +import polygonClipping from 'polygon-clipping'; + +/** + * Takes two {@link Polygon|polygon} or {@link MultiPolygon|multi-polygon} geometries and + * finds their polygonal intersection. If they don't intersect, returns null. + * + * @name intersect + * @param {Feature} poly1 the first polygon or multipolygon + * @param {Feature} poly2 the second polygon or multipolygon + * @param {Object} [options={}] Optional Parameters + * @param {Object} [options.properties={}] Translate GeoJSON Properties to Feature + * @returns {Feature|null} returns a feature representing the area they share (either a {@link Polygon} or + * {@link MultiPolygon}). If they do not share any area, returns `null`. + * @example + * var poly1 = turf.polygon([[ + * [-122.801742, 45.48565], + * [-122.801742, 45.60491], + * [-122.584762, 45.60491], + * [-122.584762, 45.48565], + * [-122.801742, 45.48565] + * ]]); + * + * var poly2 = turf.polygon([[ + * [-122.520217, 45.535693], + * [-122.64038, 45.553967], + * [-122.720031, 45.526554], + * [-122.669906, 45.507309], + * [-122.723464, 45.446643], + * [-122.532577, 45.408574], + * [-122.487258, 45.477466], + * [-122.520217, 45.535693] + * ]]); + * + * var intersection = turf.intersect(poly1, poly2); + * + * //addToMap + * var addToMap = [poly1, poly2, intersection]; + */ +export default function intersect(poly1, poly2, options) { + options = checkIfOptionsExist(options); + const properties = options.properties || {}; + + const geom1 = getGeom(poly1); + const geom2 = getGeom(poly2); + + const intersection = polygonClipping.intersection(geom1.coordinates, geom2.coordinates); + if (intersection.length === 0) return null; + return multiPolygon(intersection, properties); +} diff --git a/src/intersect/test.js b/src/intersect/test.js new file mode 100644 index 0000000000..2fab41b280 --- /dev/null +++ b/src/intersect/test.js @@ -0,0 +1,38 @@ +const path = require('path'); +const glob = require('glob'); +const test = require('tape'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { featureCollection } = require('../helpers'); +const intersect = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +test('turf-intersect', t => { + glob.sync(directories.in + '*.geojson').forEach(filepath => { + const { name, base } = path.parse(filepath); + const [polygon1, polygon2] = load.sync(filepath).features; + + if (name.includes('skip')) return t.skip(name); + + // Red Polygon1 + polygon1.properties = Object.assign(polygon1.properties || {}, {'fill-opacity': 0.5, fill: '#F00'}); + // Blue Polygon2 + polygon2.properties = Object.assign(polygon2.properties || {}, {'fill-opacity': 0.5, fill: '#00F'}); + + const results = featureCollection([polygon1, polygon2]); + const result = intersect(polygon1, polygon2); + if (result) { + // Green Polygon + result.properties = {'fill-opacity': 1, fill: '#0F0'}; + results.features.push(result); + } + + if (process.env.REGEN) write.sync(directories.out + base, results); + t.deepEqual(results, load.sync(directories.out + base), name); + }); + t.end(); +}); diff --git a/packages/turf-intersect/test/in/Intersect1.geojson b/src/intersect/test/in/Intersect1.geojson similarity index 100% rename from packages/turf-intersect/test/in/Intersect1.geojson rename to src/intersect/test/in/Intersect1.geojson diff --git a/packages/turf-intersect/test/in/Intersect2.geojson b/src/intersect/test/in/Intersect2.geojson similarity index 100% rename from packages/turf-intersect/test/in/Intersect2.geojson rename to src/intersect/test/in/Intersect2.geojson diff --git a/packages/turf-intersect/test/in/armenia.geojson b/src/intersect/test/in/armenia.geojson similarity index 100% rename from packages/turf-intersect/test/in/armenia.geojson rename to src/intersect/test/in/armenia.geojson diff --git a/packages/turf-intersect/test/in/issue-1004.geojson b/src/intersect/test/in/issue-1004.geojson similarity index 100% rename from packages/turf-intersect/test/in/issue-1004.geojson rename to src/intersect/test/in/issue-1004.geojson diff --git a/packages/turf-intersect/test/in/issue-1394.geojson b/src/intersect/test/in/issue-1394.geojson similarity index 100% rename from packages/turf-intersect/test/in/issue-1394.geojson rename to src/intersect/test/in/issue-1394.geojson diff --git a/packages/turf-intersect/test/in/issue-412.geojson b/src/intersect/test/in/issue-412.geojson similarity index 100% rename from packages/turf-intersect/test/in/issue-412.geojson rename to src/intersect/test/in/issue-412.geojson diff --git a/packages/turf-intersect/test/in/issue-702.geojson b/src/intersect/test/in/issue-702.geojson similarity index 100% rename from packages/turf-intersect/test/in/issue-702.geojson rename to src/intersect/test/in/issue-702.geojson diff --git a/packages/turf-intersect/test/in/issue-820.geojson b/src/intersect/test/in/issue-820.geojson similarity index 100% rename from packages/turf-intersect/test/in/issue-820.geojson rename to src/intersect/test/in/issue-820.geojson diff --git a/packages/turf-intersect/test/in/linestring.geojson b/src/intersect/test/in/linestring.geojson similarity index 100% rename from packages/turf-intersect/test/in/linestring.geojson rename to src/intersect/test/in/linestring.geojson diff --git a/packages/turf-intersect/test/in/multilinestring.geojson b/src/intersect/test/in/multilinestring.geojson similarity index 100% rename from packages/turf-intersect/test/in/multilinestring.geojson rename to src/intersect/test/in/multilinestring.geojson diff --git a/packages/turf-intersect/test/in/multipoint.geojson b/src/intersect/test/in/multipoint.geojson similarity index 100% rename from packages/turf-intersect/test/in/multipoint.geojson rename to src/intersect/test/in/multipoint.geojson diff --git a/packages/turf-intersect/test/in/multipolygon-input.geojson b/src/intersect/test/in/multipolygon-input.geojson similarity index 100% rename from packages/turf-intersect/test/in/multipolygon-input.geojson rename to src/intersect/test/in/multipolygon-input.geojson diff --git a/packages/turf-intersect/test/in/no-overlap.geojson b/src/intersect/test/in/no-overlap.geojson similarity index 100% rename from packages/turf-intersect/test/in/no-overlap.geojson rename to src/intersect/test/in/no-overlap.geojson diff --git a/packages/turf-intersect/test/in/output-multipolygon.geojson b/src/intersect/test/in/output-multipolygon.geojson similarity index 100% rename from packages/turf-intersect/test/in/output-multipolygon.geojson rename to src/intersect/test/in/output-multipolygon.geojson diff --git a/packages/turf-intersect/test/in/point.geojson b/src/intersect/test/in/point.geojson similarity index 100% rename from packages/turf-intersect/test/in/point.geojson rename to src/intersect/test/in/point.geojson diff --git a/packages/turf-intersect/test/in/skip-issue-1132-line.geojson b/src/intersect/test/in/skip-issue-1132-line.geojson similarity index 95% rename from packages/turf-intersect/test/in/skip-issue-1132-line.geojson rename to src/intersect/test/in/skip-issue-1132-line.geojson index fb0bfda3e8..1a47ede6a6 100644 --- a/packages/turf-intersect/test/in/skip-issue-1132-line.geojson +++ b/src/intersect/test/in/skip-issue-1132-line.geojson @@ -1,285 +1,285 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.13018281184321, - 42.728620766896256 - ], - [ - -76.13060123644954, - 42.728597123463544 - ], - [ - -76.13064415179377, - 42.72858136117006 - ], - [ - -76.13070852481015, - 42.728565598872564 - ], - [ - -76.13075144015438, - 42.728565598872564 - ], - [ - -76.1307728978265, - 42.72855771772231 - ], - [ - -76.13080508433468, - 42.72854983657106 - ], - [ - -76.13083727084286, - 42.72854983657106 - ], - [ - -76.1309016438592, - 42.72854983657106 - ], - [ - -76.13093383036738, - 42.72854195541882 - ], - [ - -76.13094455920346, - 42.72854195541882 - ], - [ - -76.13096601687558, - 42.72853407426555 - ], - [ - -76.1309874745477, - 42.72853407426555 - ], - [ - -76.13105184756404, - 42.72853407426555 - ], - [ - -76.13168484889155, - 42.728376450990226 - ], - [ - -76.13169557772763, - 42.728376450990226 - ], - [ - -76.13169557772763, - 42.728376450990226 - ], - [ - -76.13170630656367, - 42.72836068864066 - ], - [ - -76.13171703539975, - 42.728352807464404 - ], - [ - -76.13173849307186, - 42.728329163929544 - ], - [ - -76.13173849307186, - 42.728329163929544 - ], - [ - -76.13174922190792, - 42.72831340156796 - ], - [ - -76.13200671397334, - 42.72798239104955 - ], - [ - -76.13204962931759, - 42.727903578761016 - ], - [ - -76.13204962931759, - 42.727887816291286 - ], - [ - -76.13216764651425, - 42.72746222809471 - ], - [ - -76.13216764651425, - 42.727430702926966 - ], - [ - -76.13218910418637, - 42.72737553384482 - ], - [ - -76.13218910418637, - 42.727344008633 - ], - [ - -76.13218910418637, - 42.7273282460211 - ], - [ - -76.1322320195306, - 42.72697358619405 - ], - [ - -76.1322320195306, - 42.726910535345894 - ], - [ - -76.1322320195306, - 42.72688689126127 - ], - [ - -76.1322320195306, - 42.72688689126127 - ], - [ - -76.13222129069455, - 42.726642568526074 - ], - [ - -76.13222129069455, - 42.726642568526074 - ], - [ - -76.13219983302243, - 42.72652434750228 - ], - [ - -76.13218910418637, - 42.726516466092676 - ], - [ - -76.13218910418637, - 42.726484940444266 - ], - [ - -76.1321783753503, - 42.72647705902966 - ], - [ - -76.1321783753503, - 42.72647705902966 - ], - [ - -76.1321783753503, - 42.72646129619747 - ], - [ - -76.13204962931759, - 42.72615392016877 - ], - [ - -76.13203890048152, - 42.7261460387121 - ], - [ - -76.13203890048152, - 42.72613027579578 - ], - [ - -76.13202817164547, - 42.7261223943361 - ], - [ - -76.1320174428094, - 42.726114512875455 - ], - [ - -76.13178140841609, - 42.72585442411173 - ], - [ - -76.13178140841609, - 42.72585442411173 - ], - [ - -76.13173849307186, - 42.7258307796246 - ], - [ - -76.13172776423579, - 42.725822898126864 - ], - [ - -76.13125569544917, - 42.72568891251251 - ], - [ - -76.13125569544917, - 42.72568891251251 - ], - [ - -76.13120205126889, - 42.72568891251251 - ], - [ - -76.13120205126889, - 42.72568891251251 - ], - [ - -76.13118059359677, - 42.72568891251251 - ], - [ - -76.13086945735103, - 42.7257283200762 - ], - [ - -76.13086945735103, - 42.7257283200762 - ], - [ - -76.13084799967892, - 42.72573620158593 - ], - [ - -76.13067633830195, - 42.72581501662816 - ], - [ - -76.13066560946591, - 42.725822898126864 - ], - [ - -76.13066560946591, - 42.725822898126864 - ], - [ - -76.13018281184321, - 42.728620766896256 - ] - ] - ] - }, - "properties": null - }, - { - "type": "Feature", - "geometry": { - "type": "LineString", - "coordinates": [ - [ - -76.13127651893724, - 42.726809124054114 - ], - [ - -76.13147387880517, - 42.726826941348634 - ] - ] - }, - "properties": null - } - ] +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -76.13018281184321, + 42.728620766896256 + ], + [ + -76.13060123644954, + 42.728597123463544 + ], + [ + -76.13064415179377, + 42.72858136117006 + ], + [ + -76.13070852481015, + 42.728565598872564 + ], + [ + -76.13075144015438, + 42.728565598872564 + ], + [ + -76.1307728978265, + 42.72855771772231 + ], + [ + -76.13080508433468, + 42.72854983657106 + ], + [ + -76.13083727084286, + 42.72854983657106 + ], + [ + -76.1309016438592, + 42.72854983657106 + ], + [ + -76.13093383036738, + 42.72854195541882 + ], + [ + -76.13094455920346, + 42.72854195541882 + ], + [ + -76.13096601687558, + 42.72853407426555 + ], + [ + -76.1309874745477, + 42.72853407426555 + ], + [ + -76.13105184756404, + 42.72853407426555 + ], + [ + -76.13168484889155, + 42.728376450990226 + ], + [ + -76.13169557772763, + 42.728376450990226 + ], + [ + -76.13169557772763, + 42.728376450990226 + ], + [ + -76.13170630656367, + 42.72836068864066 + ], + [ + -76.13171703539975, + 42.728352807464404 + ], + [ + -76.13173849307186, + 42.728329163929544 + ], + [ + -76.13173849307186, + 42.728329163929544 + ], + [ + -76.13174922190792, + 42.72831340156796 + ], + [ + -76.13200671397334, + 42.72798239104955 + ], + [ + -76.13204962931759, + 42.727903578761016 + ], + [ + -76.13204962931759, + 42.727887816291286 + ], + [ + -76.13216764651425, + 42.72746222809471 + ], + [ + -76.13216764651425, + 42.727430702926966 + ], + [ + -76.13218910418637, + 42.72737553384482 + ], + [ + -76.13218910418637, + 42.727344008633 + ], + [ + -76.13218910418637, + 42.7273282460211 + ], + [ + -76.1322320195306, + 42.72697358619405 + ], + [ + -76.1322320195306, + 42.726910535345894 + ], + [ + -76.1322320195306, + 42.72688689126127 + ], + [ + -76.1322320195306, + 42.72688689126127 + ], + [ + -76.13222129069455, + 42.726642568526074 + ], + [ + -76.13222129069455, + 42.726642568526074 + ], + [ + -76.13219983302243, + 42.72652434750228 + ], + [ + -76.13218910418637, + 42.726516466092676 + ], + [ + -76.13218910418637, + 42.726484940444266 + ], + [ + -76.1321783753503, + 42.72647705902966 + ], + [ + -76.1321783753503, + 42.72647705902966 + ], + [ + -76.1321783753503, + 42.72646129619747 + ], + [ + -76.13204962931759, + 42.72615392016877 + ], + [ + -76.13203890048152, + 42.7261460387121 + ], + [ + -76.13203890048152, + 42.72613027579578 + ], + [ + -76.13202817164547, + 42.7261223943361 + ], + [ + -76.1320174428094, + 42.726114512875455 + ], + [ + -76.13178140841609, + 42.72585442411173 + ], + [ + -76.13178140841609, + 42.72585442411173 + ], + [ + -76.13173849307186, + 42.7258307796246 + ], + [ + -76.13172776423579, + 42.725822898126864 + ], + [ + -76.13125569544917, + 42.72568891251251 + ], + [ + -76.13125569544917, + 42.72568891251251 + ], + [ + -76.13120205126889, + 42.72568891251251 + ], + [ + -76.13120205126889, + 42.72568891251251 + ], + [ + -76.13118059359677, + 42.72568891251251 + ], + [ + -76.13086945735103, + 42.7257283200762 + ], + [ + -76.13086945735103, + 42.7257283200762 + ], + [ + -76.13084799967892, + 42.72573620158593 + ], + [ + -76.13067633830195, + 42.72581501662816 + ], + [ + -76.13066560946591, + 42.725822898126864 + ], + [ + -76.13066560946591, + 42.725822898126864 + ], + [ + -76.13018281184321, + 42.728620766896256 + ] + ] + ] + }, + "properties": null + }, + { + "type": "Feature", + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -76.13127651893724, + 42.726809124054114 + ], + [ + -76.13147387880517, + 42.726826941348634 + ] + ] + }, + "properties": null + } + ] } \ No newline at end of file diff --git a/packages/turf-intersect/test/in/skip-issue-1132-point.geojson b/src/intersect/test/in/skip-issue-1132-point.geojson similarity index 95% rename from packages/turf-intersect/test/in/skip-issue-1132-point.geojson rename to src/intersect/test/in/skip-issue-1132-point.geojson index ec53a5b6e6..f01134e889 100644 --- a/packages/turf-intersect/test/in/skip-issue-1132-point.geojson +++ b/src/intersect/test/in/skip-issue-1132-point.geojson @@ -1,279 +1,279 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [ - -76.13018281184321, - 42.728620766896256 - ], - [ - -76.13060123644954, - 42.728597123463544 - ], - [ - -76.13064415179377, - 42.72858136117006 - ], - [ - -76.13070852481015, - 42.728565598872564 - ], - [ - -76.13075144015438, - 42.728565598872564 - ], - [ - -76.1307728978265, - 42.72855771772231 - ], - [ - -76.13080508433468, - 42.72854983657106 - ], - [ - -76.13083727084286, - 42.72854983657106 - ], - [ - -76.1309016438592, - 42.72854983657106 - ], - [ - -76.13093383036738, - 42.72854195541882 - ], - [ - -76.13094455920346, - 42.72854195541882 - ], - [ - -76.13096601687558, - 42.72853407426555 - ], - [ - -76.1309874745477, - 42.72853407426555 - ], - [ - -76.13105184756404, - 42.72853407426555 - ], - [ - -76.13168484889155, - 42.728376450990226 - ], - [ - -76.13169557772763, - 42.728376450990226 - ], - [ - -76.13169557772763, - 42.728376450990226 - ], - [ - -76.13170630656367, - 42.72836068864066 - ], - [ - -76.13171703539975, - 42.728352807464404 - ], - [ - -76.13173849307186, - 42.728329163929544 - ], - [ - -76.13173849307186, - 42.728329163929544 - ], - [ - -76.13174922190792, - 42.72831340156796 - ], - [ - -76.13200671397334, - 42.72798239104955 - ], - [ - -76.13204962931759, - 42.727903578761016 - ], - [ - -76.13204962931759, - 42.727887816291286 - ], - [ - -76.13216764651425, - 42.72746222809471 - ], - [ - -76.13216764651425, - 42.727430702926966 - ], - [ - -76.13218910418637, - 42.72737553384482 - ], - [ - -76.13218910418637, - 42.727344008633 - ], - [ - -76.13218910418637, - 42.7273282460211 - ], - [ - -76.1322320195306, - 42.72697358619405 - ], - [ - -76.1322320195306, - 42.726910535345894 - ], - [ - -76.1322320195306, - 42.72688689126127 - ], - [ - -76.1322320195306, - 42.72688689126127 - ], - [ - -76.13222129069455, - 42.726642568526074 - ], - [ - -76.13222129069455, - 42.726642568526074 - ], - [ - -76.13219983302243, - 42.72652434750228 - ], - [ - -76.13218910418637, - 42.726516466092676 - ], - [ - -76.13218910418637, - 42.726484940444266 - ], - [ - -76.1321783753503, - 42.72647705902966 - ], - [ - -76.1321783753503, - 42.72647705902966 - ], - [ - -76.1321783753503, - 42.72646129619747 - ], - [ - -76.13204962931759, - 42.72615392016877 - ], - [ - -76.13203890048152, - 42.7261460387121 - ], - [ - -76.13203890048152, - 42.72613027579578 - ], - [ - -76.13202817164547, - 42.7261223943361 - ], - [ - -76.1320174428094, - 42.726114512875455 - ], - [ - -76.13178140841609, - 42.72585442411173 - ], - [ - -76.13178140841609, - 42.72585442411173 - ], - [ - -76.13173849307186, - 42.7258307796246 - ], - [ - -76.13172776423579, - 42.725822898126864 - ], - [ - -76.13125569544917, - 42.72568891251251 - ], - [ - -76.13125569544917, - 42.72568891251251 - ], - [ - -76.13120205126889, - 42.72568891251251 - ], - [ - -76.13120205126889, - 42.72568891251251 - ], - [ - -76.13118059359677, - 42.72568891251251 - ], - [ - -76.13086945735103, - 42.7257283200762 - ], - [ - -76.13086945735103, - 42.7257283200762 - ], - [ - -76.13084799967892, - 42.72573620158593 - ], - [ - -76.13067633830195, - 42.72581501662816 - ], - [ - -76.13066560946591, - 42.725822898126864 - ], - [ - -76.13066560946591, - 42.725822898126864 - ], - [ - -76.13018281184321, - 42.728620766896256 - ] - ] - ] - }, - "properties": null - }, - { - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -76.13147387880517, - 42.726826941348634 - ] - }, - "properties": null - } - ] +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -76.13018281184321, + 42.728620766896256 + ], + [ + -76.13060123644954, + 42.728597123463544 + ], + [ + -76.13064415179377, + 42.72858136117006 + ], + [ + -76.13070852481015, + 42.728565598872564 + ], + [ + -76.13075144015438, + 42.728565598872564 + ], + [ + -76.1307728978265, + 42.72855771772231 + ], + [ + -76.13080508433468, + 42.72854983657106 + ], + [ + -76.13083727084286, + 42.72854983657106 + ], + [ + -76.1309016438592, + 42.72854983657106 + ], + [ + -76.13093383036738, + 42.72854195541882 + ], + [ + -76.13094455920346, + 42.72854195541882 + ], + [ + -76.13096601687558, + 42.72853407426555 + ], + [ + -76.1309874745477, + 42.72853407426555 + ], + [ + -76.13105184756404, + 42.72853407426555 + ], + [ + -76.13168484889155, + 42.728376450990226 + ], + [ + -76.13169557772763, + 42.728376450990226 + ], + [ + -76.13169557772763, + 42.728376450990226 + ], + [ + -76.13170630656367, + 42.72836068864066 + ], + [ + -76.13171703539975, + 42.728352807464404 + ], + [ + -76.13173849307186, + 42.728329163929544 + ], + [ + -76.13173849307186, + 42.728329163929544 + ], + [ + -76.13174922190792, + 42.72831340156796 + ], + [ + -76.13200671397334, + 42.72798239104955 + ], + [ + -76.13204962931759, + 42.727903578761016 + ], + [ + -76.13204962931759, + 42.727887816291286 + ], + [ + -76.13216764651425, + 42.72746222809471 + ], + [ + -76.13216764651425, + 42.727430702926966 + ], + [ + -76.13218910418637, + 42.72737553384482 + ], + [ + -76.13218910418637, + 42.727344008633 + ], + [ + -76.13218910418637, + 42.7273282460211 + ], + [ + -76.1322320195306, + 42.72697358619405 + ], + [ + -76.1322320195306, + 42.726910535345894 + ], + [ + -76.1322320195306, + 42.72688689126127 + ], + [ + -76.1322320195306, + 42.72688689126127 + ], + [ + -76.13222129069455, + 42.726642568526074 + ], + [ + -76.13222129069455, + 42.726642568526074 + ], + [ + -76.13219983302243, + 42.72652434750228 + ], + [ + -76.13218910418637, + 42.726516466092676 + ], + [ + -76.13218910418637, + 42.726484940444266 + ], + [ + -76.1321783753503, + 42.72647705902966 + ], + [ + -76.1321783753503, + 42.72647705902966 + ], + [ + -76.1321783753503, + 42.72646129619747 + ], + [ + -76.13204962931759, + 42.72615392016877 + ], + [ + -76.13203890048152, + 42.7261460387121 + ], + [ + -76.13203890048152, + 42.72613027579578 + ], + [ + -76.13202817164547, + 42.7261223943361 + ], + [ + -76.1320174428094, + 42.726114512875455 + ], + [ + -76.13178140841609, + 42.72585442411173 + ], + [ + -76.13178140841609, + 42.72585442411173 + ], + [ + -76.13173849307186, + 42.7258307796246 + ], + [ + -76.13172776423579, + 42.725822898126864 + ], + [ + -76.13125569544917, + 42.72568891251251 + ], + [ + -76.13125569544917, + 42.72568891251251 + ], + [ + -76.13120205126889, + 42.72568891251251 + ], + [ + -76.13120205126889, + 42.72568891251251 + ], + [ + -76.13118059359677, + 42.72568891251251 + ], + [ + -76.13086945735103, + 42.7257283200762 + ], + [ + -76.13086945735103, + 42.7257283200762 + ], + [ + -76.13084799967892, + 42.72573620158593 + ], + [ + -76.13067633830195, + 42.72581501662816 + ], + [ + -76.13066560946591, + 42.725822898126864 + ], + [ + -76.13066560946591, + 42.725822898126864 + ], + [ + -76.13018281184321, + 42.728620766896256 + ] + ] + ] + }, + "properties": null + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + -76.13147387880517, + 42.726826941348634 + ] + }, + "properties": null + } + ] } \ No newline at end of file diff --git a/src/intersect/test/out/Intersect1.geojson b/src/intersect/test/out/Intersect1.geojson new file mode 100644 index 0000000000..130f1473df --- /dev/null +++ b/src/intersect/test/out/Intersect1.geojson @@ -0,0 +1,141 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "fill-opacity": 0.5, + "fill": "#F00" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -79.88571166992188, + 32.887659962078956 + ], + [ + -80.09788513183594, + 32.927436533285565 + ], + [ + -80.15350341796875, + 32.82825010814964 + ], + [ + -80.00312805175781, + 32.69428812316933 + ], + [ + -79.89395141601562, + 32.75551989829049 + ], + [ + -79.88571166992188, + 32.887659962078956 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "fill-opacity": 0.5, + "fill": "#00F" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -79.92141723632812, + 32.953944317478246 + ], + [ + -79.97428894042969, + 32.83690450361482 + ], + [ + -79.97360229492188, + 32.76071688548088 + ], + [ + -79.93034362792969, + 32.76475877693074 + ], + [ + -79.93789672851562, + 32.74108223150125 + ], + [ + -79.80537414550781, + 32.7231762754146 + ], + [ + -79.81773376464844, + 32.923402043498875 + ], + [ + -79.92141723632812, + 32.953944317478246 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "fill-opacity": 1, + "fill": "#0F0" + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -79.97428894042969, + 32.83690450361482 + ], + [ + -79.97360229492188, + 32.76071688548088 + ], + [ + -79.93034362792969, + 32.76475877693074 + ], + [ + -79.93789672851562, + 32.74108223150125 + ], + [ + -79.92322780260464, + 32.73910022106017 + ], + [ + -79.89395141601562, + 32.75551989829049 + ], + [ + -79.88571166992188, + 32.887659962078956 + ], + [ + -79.94623496447946, + 32.89900638172028 + ], + [ + -79.97428894042969, + 32.83690450361482 + ] + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-intersect/test/out/Intersect2.geojson b/src/intersect/test/out/Intersect2.geojson similarity index 75% rename from packages/turf-intersect/test/out/Intersect2.geojson rename to src/intersect/test/out/Intersect2.geojson index e9b3830fe2..3bffc9508f 100644 --- a/packages/turf-intersect/test/out/Intersect2.geojson +++ b/src/intersect/test/out/Intersect2.geojson @@ -96,36 +96,38 @@ "fill": "#0F0" }, "geometry": { - "type": "Polygon", + "type": "MultiPolygon", "coordinates": [ [ [ - -80.068359375, - 32.88189375925038 - ], - [ - -80.01686096191406, - 32.87266705436184 - ], - [ - -80.0066252126598, - 32.84617770697059 - ], - [ - -79.99351501464844, - 32.84440429734253 - ], - [ - -79.98184204101562, - 32.90495631913751 - ], - [ - -80.0050160405751, - 32.91295307720083 - ], - [ - -80.068359375, - 32.88189375925038 + [ + -80.068359375, + 32.88189375925038 + ], + [ + -80.01686096191406, + 32.87266705436184 + ], + [ + -80.0066252126598, + 32.84617770697059 + ], + [ + -79.99351501464844, + 32.84440429734253 + ], + [ + -79.98184204101562, + 32.90495631913751 + ], + [ + -80.0050160405751, + 32.91295307720083 + ], + [ + -80.068359375, + 32.88189375925038 + ] ] ] ] diff --git a/packages/turf-intersect/test/out/armenia.geojson b/src/intersect/test/out/armenia.geojson similarity index 79% rename from packages/turf-intersect/test/out/armenia.geojson rename to src/intersect/test/out/armenia.geojson index 72fd37f1cc..5c63ca942e 100644 --- a/packages/turf-intersect/test/out/armenia.geojson +++ b/src/intersect/test/out/armenia.geojson @@ -138,40 +138,42 @@ "fill": "#0F0" }, "geometry": { - "type": "Polygon", + "type": "MultiPolygon", "coordinates": [ [ [ - 45.1318359375, - 40.1452892956766 - ], - [ - 45.82712793551521, - 40.1452892956766 - ], - [ - 45.891907, - 40.218476 - ], - [ - 45.359175, - 40.561504 - ], - [ - 45.560351, - 40.81229 - ], - [ - 45.179496, - 40.985354 - ], - [ - 45.1318359375, - 41.04585112545618 - ], - [ - 45.1318359375, - 40.1452892956766 + [ + 45.1318359375, + 40.1452892956766 + ], + [ + 45.82712793551521, + 40.1452892956766 + ], + [ + 45.891907, + 40.218476 + ], + [ + 45.359175, + 40.561504 + ], + [ + 45.560351, + 40.81229 + ], + [ + 45.179496, + 40.985354 + ], + [ + 45.1318359375, + 41.04585112545618 + ], + [ + 45.1318359375, + 40.1452892956766 + ] ] ] ] diff --git a/packages/turf-intersect/test/out/issue-1004.geojson b/src/intersect/test/out/issue-1004.geojson similarity index 93% rename from packages/turf-intersect/test/out/issue-1004.geojson rename to src/intersect/test/out/issue-1004.geojson index 4cce750119..96b9731622 100644 --- a/packages/turf-intersect/test/out/issue-1004.geojson +++ b/src/intersect/test/out/issue-1004.geojson @@ -408,32 +408,34 @@ "fill": "#0F0" }, "geometry": { - "type": "Polygon", + "type": "MultiPolygon", "coordinates": [ [ [ - -114.757217, - 32.619867791666415 - ], - [ - -114.757213, - 32.61975337499965 - ], - [ - -114.757213, - 32.61992600000001 - ], - [ - -114.757215, - 32.619925 - ], - [ - -114.757217, - 32.619925 - ], - [ - -114.757217, - 32.619867791666415 + [ + -114.757217, + 32.619867791666415 + ], + [ + -114.757213, + 32.61975337499965 + ], + [ + -114.757213, + 32.61992600000001 + ], + [ + -114.757215, + 32.619925 + ], + [ + -114.757217, + 32.619925 + ], + [ + -114.757217, + 32.619867791666415 + ] ] ] ] diff --git a/packages/turf-intersect/test/out/issue-1132-line.geojson b/src/intersect/test/out/issue-1132-line.geojson similarity index 100% rename from packages/turf-intersect/test/out/issue-1132-line.geojson rename to src/intersect/test/out/issue-1132-line.geojson diff --git a/packages/turf-intersect/test/out/issue-1394.geojson b/src/intersect/test/out/issue-1394.geojson similarity index 93% rename from packages/turf-intersect/test/out/issue-1394.geojson rename to src/intersect/test/out/issue-1394.geojson index 92c858fa29..5894c1a044 100644 --- a/packages/turf-intersect/test/out/issue-1394.geojson +++ b/src/intersect/test/out/issue-1394.geojson @@ -276,24 +276,26 @@ "fill": "#0F0" }, "geometry": { - "type": "Polygon", + "type": "MultiPolygon", "coordinates": [ [ [ - -85.42358073, - 41.76885781 - ], - [ - -85.42357713028528, - 41.76878899545362 - ], - [ - -85.42357713, - 41.768789 - ], - [ - -85.42358073, - 41.76885781 + [ + -85.42358073, + 41.76885781 + ], + [ + -85.42357713028528, + 41.76878899545362 + ], + [ + -85.42357713, + 41.768789 + ], + [ + -85.42358073, + 41.76885781 + ] ] ] ] diff --git a/src/intersect/test/out/issue-412.geojson b/src/intersect/test/out/issue-412.geojson new file mode 100644 index 0000000000..aa38517e47 --- /dev/null +++ b/src/intersect/test/out/issue-412.geojson @@ -0,0 +1,101 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 11.076136797048882, + 9.856269774244707 + ], + [ + 11.262359619140625, + 9.85386305739084 + ], + [ + 11.083831787109375, + 9.85386305739084 + ], + [ + 11.076136797048882, + 9.856269774244707 + ] + ] + ] + }, + "properties": { + "fill-opacity": 0.5, + "fill": "#F00" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 11.62078857421875, + 10.306812602471467 + ], + [ + 11.162109375, + 9.848450887107404 + ], + [ + 11.072845458984375, + 9.85656910923582 + ], + [ + 11.62078857421875, + 10.306812602471467 + ] + ] + ] + }, + "properties": { + "fill-opacity": 0.5, + "fill": "#00F" + } + }, + { + "type": "Feature", + "properties": { + "fill-opacity": 1, + "fill": "#0F0" + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 11.076136797048882, + 9.856269774244707 + ], + [ + 11.102599853580067, + 9.85386305739084 + ], + [ + 11.167525294018606, + 9.85386305739084 + ], + [ + 11.1687361088318, + 9.855073034114678 + ], + [ + 11.076136797048882, + 9.856269774244707 + ] + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-intersect/test/out/issue-702.geojson b/src/intersect/test/out/issue-702.geojson similarity index 100% rename from packages/turf-intersect/test/out/issue-702.geojson rename to src/intersect/test/out/issue-702.geojson diff --git a/packages/turf-intersect/test/out/issue-820.geojson b/src/intersect/test/out/issue-820.geojson similarity index 100% rename from packages/turf-intersect/test/out/issue-820.geojson rename to src/intersect/test/out/issue-820.geojson diff --git a/packages/turf-intersect/test/out/jsts/Intersect1.geojson b/src/intersect/test/out/jsts/Intersect1.geojson similarity index 100% rename from packages/turf-intersect/test/out/jsts/Intersect1.geojson rename to src/intersect/test/out/jsts/Intersect1.geojson diff --git a/packages/turf-intersect/test/out/jsts/Intersect2.geojson b/src/intersect/test/out/jsts/Intersect2.geojson similarity index 100% rename from packages/turf-intersect/test/out/jsts/Intersect2.geojson rename to src/intersect/test/out/jsts/Intersect2.geojson diff --git a/packages/turf-intersect/test/out/jsts/armenia.geojson b/src/intersect/test/out/jsts/armenia.geojson similarity index 100% rename from packages/turf-intersect/test/out/jsts/armenia.geojson rename to src/intersect/test/out/jsts/armenia.geojson diff --git a/packages/turf-intersect/test/out/jsts/issue-1004.geojson b/src/intersect/test/out/jsts/issue-1004.geojson similarity index 100% rename from packages/turf-intersect/test/out/jsts/issue-1004.geojson rename to src/intersect/test/out/jsts/issue-1004.geojson diff --git a/packages/turf-intersect/test/out/jsts/issue-1132-line.geojson b/src/intersect/test/out/jsts/issue-1132-line.geojson similarity index 100% rename from packages/turf-intersect/test/out/jsts/issue-1132-line.geojson rename to src/intersect/test/out/jsts/issue-1132-line.geojson diff --git a/packages/turf-intersect/test/out/jsts/issue-1132-point.geojson b/src/intersect/test/out/jsts/issue-1132-point.geojson similarity index 100% rename from packages/turf-intersect/test/out/jsts/issue-1132-point.geojson rename to src/intersect/test/out/jsts/issue-1132-point.geojson diff --git a/packages/turf-intersect/test/out/jsts/issue-412.geojson b/src/intersect/test/out/jsts/issue-412.geojson similarity index 100% rename from packages/turf-intersect/test/out/jsts/issue-412.geojson rename to src/intersect/test/out/jsts/issue-412.geojson diff --git a/packages/turf-intersect/test/out/jsts/issue-820.geojson b/src/intersect/test/out/jsts/issue-820.geojson similarity index 100% rename from packages/turf-intersect/test/out/jsts/issue-820.geojson rename to src/intersect/test/out/jsts/issue-820.geojson diff --git a/packages/turf-intersect/test/out/jsts/linestring.geojson b/src/intersect/test/out/jsts/linestring.geojson similarity index 100% rename from packages/turf-intersect/test/out/jsts/linestring.geojson rename to src/intersect/test/out/jsts/linestring.geojson diff --git a/packages/turf-intersect/test/out/jsts/multilinestring.geojson b/src/intersect/test/out/jsts/multilinestring.geojson similarity index 100% rename from packages/turf-intersect/test/out/jsts/multilinestring.geojson rename to src/intersect/test/out/jsts/multilinestring.geojson diff --git a/packages/turf-intersect/test/out/jsts/multipoint.geojson b/src/intersect/test/out/jsts/multipoint.geojson similarity index 100% rename from packages/turf-intersect/test/out/jsts/multipoint.geojson rename to src/intersect/test/out/jsts/multipoint.geojson diff --git a/packages/turf-intersect/test/out/jsts/no-overlap.geojson b/src/intersect/test/out/jsts/no-overlap.geojson similarity index 100% rename from packages/turf-intersect/test/out/jsts/no-overlap.geojson rename to src/intersect/test/out/jsts/no-overlap.geojson diff --git a/packages/turf-intersect/test/out/jsts/point.geojson b/src/intersect/test/out/jsts/point.geojson similarity index 100% rename from packages/turf-intersect/test/out/jsts/point.geojson rename to src/intersect/test/out/jsts/point.geojson diff --git a/packages/turf-intersect/test/out/linestring.geojson b/src/intersect/test/out/linestring.geojson similarity index 100% rename from packages/turf-intersect/test/out/linestring.geojson rename to src/intersect/test/out/linestring.geojson diff --git a/packages/turf-intersect/test/out/multilinestring.geojson b/src/intersect/test/out/multilinestring.geojson similarity index 100% rename from packages/turf-intersect/test/out/multilinestring.geojson rename to src/intersect/test/out/multilinestring.geojson diff --git a/packages/turf-intersect/test/out/multipoint.geojson b/src/intersect/test/out/multipoint.geojson similarity index 100% rename from packages/turf-intersect/test/out/multipoint.geojson rename to src/intersect/test/out/multipoint.geojson diff --git a/packages/turf-intersect/test/out/multipolygon-input.geojson b/src/intersect/test/out/multipolygon-input.geojson similarity index 100% rename from packages/turf-intersect/test/out/multipolygon-input.geojson rename to src/intersect/test/out/multipolygon-input.geojson diff --git a/packages/turf-intersect/test/out/no-overlap.geojson b/src/intersect/test/out/no-overlap.geojson similarity index 100% rename from packages/turf-intersect/test/out/no-overlap.geojson rename to src/intersect/test/out/no-overlap.geojson diff --git a/packages/turf-intersect/test/out/output-multipolygon.geojson b/src/intersect/test/out/output-multipolygon.geojson similarity index 100% rename from packages/turf-intersect/test/out/output-multipolygon.geojson rename to src/intersect/test/out/output-multipolygon.geojson diff --git a/packages/turf-intersect/test/out/point.geojson b/src/intersect/test/out/point.geojson similarity index 100% rename from packages/turf-intersect/test/out/point.geojson rename to src/intersect/test/out/point.geojson diff --git a/src/invariant/bench.js b/src/invariant/bench.js new file mode 100644 index 0000000000..21ec228360 --- /dev/null +++ b/src/invariant/bench.js @@ -0,0 +1,32 @@ +const Benchmark = require('benchmark'); +const helpers = require('../helpers'); +const invariant = require('./'); + +const pt = helpers.point([-75, 40]); +const line = helpers.lineString([[-75, 40], [-70, 50]]); +const poly = helpers.polygon([[[-75, 40], [-80, 50], [-70, 50], [-75, 40]]]); +const fc = helpers.points([ + [-75, 40], + [20, 50] +]); + +const suite = new Benchmark.Suite('turf-invariant'); + +/** + * Benchmark Results + * + * getCoord -- pt x 60,659,161 ops/sec ±1.34% (89 runs sampled) + * getCoords -- line x 63,252,327 ops/sec ±1.19% (81 runs sampled) + * getCoords -- poly x 62,053,169 ops/sec ±1.49% (85 runs sampled) + * collectionOf -- fc x 24,204,462 ops/sec ±2.00% (81 runs sampled) + * getType -- pt x 59,544,117 ops/sec ±1.14% (87 runs sampled) + */ +suite + .add('getCoord -- pt', () => invariant.getCoord(pt)) + .add('getCoords -- line', () => invariant.getCoords(line)) + .add('getCoords -- poly', () => invariant.getCoords(poly)) + .add('collectionOf -- fc', () => invariant.collectionOf(fc, 'Point', 'bench')) + .add('getType -- pt', () => invariant.getType(pt)) + .on('cycle', e => console.log(String(e.target))) + .on('complete', () => {}) + .run(); diff --git a/packages/turf-invariant/index.d.ts b/src/invariant/index.d.ts similarity index 100% rename from packages/turf-invariant/index.d.ts rename to src/invariant/index.d.ts diff --git a/src/invariant/index.js b/src/invariant/index.js new file mode 100644 index 0000000000..c5232c9c7a --- /dev/null +++ b/src/invariant/index.js @@ -0,0 +1,187 @@ +import { isNumber } from '../helpers'; + +/** + * Unwrap a coordinate from a Point Feature, Geometry or a single coordinate. + * + * @name getCoord + * @param {Array|Geometry|Feature} coord GeoJSON Point or an Array of numbers + * @returns {Array} coordinates + * @example + * var pt = turf.point([10, 10]); + * + * var coord = turf.getCoord(pt); + * //= [10, 10] + */ +export function getCoord(coord) { + if (!coord) { throw new Error('coord is required'); } + + if (!Array.isArray(coord)) { + if (coord.type === 'Feature' && coord.geometry !== null && coord.geometry.type === 'Point') { + return coord.geometry.coordinates; + } + if (coord.type === 'Point') { + return coord.coordinates; + } + } + if (Array.isArray(coord) && coord.length >= 2 && !Array.isArray(coord[0]) && !Array.isArray(coord[1])) { + return coord; + } + + throw new Error('coord must be GeoJSON Point or an Array of numbers'); +} + +/** + * Unwrap coordinates from a Feature, Geometry Object or an Array + * + * @name getCoords + * @param {Array|Geometry|Feature} coords Feature, Geometry Object or an Array + * @returns {Array} coordinates + * @example + * var poly = turf.polygon([[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]]); + * + * var coords = turf.getCoords(poly); + * //= [[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]] + */ +export function getCoords(coords) { + if (Array.isArray(coords)) { return coords; } + + // Feature + if (coords.type === 'Feature') { + if (coords.geometry !== null) { return coords.geometry.coordinates; } + } else { + // Geometry + if (coords.coordinates) { return coords.coordinates; } + } + + throw new Error('coords must be GeoJSON Feature, Geometry Object or an Array'); +} + +/** + * Checks if coordinates contains a number + * + * @name containsNumber + * @param {Array} coordinates GeoJSON Coordinates + * @returns {boolean} true if Array contains a number + */ +export function containsNumber(coordinates) { + if (coordinates.length > 1 && isNumber(coordinates[0]) && isNumber(coordinates[1])) { + return true; + } + + if (Array.isArray(coordinates[0]) && coordinates[0].length) { + return containsNumber(coordinates[0]); + } + throw new Error('coordinates must only contain numbers'); +} + +/** + * Enforce expectations about types of GeoJSON objects for Turf. + * + * @name geojsonType + * @param {GeoJSON} value any GeoJSON object + * @param {string} type expected GeoJSON type + * @param {string} name name of calling function + * @throws {Error} if value is not the expected type. + */ +export function geojsonType(value, type, name) { + if (!type || !name) { throw new Error('type and name required'); } + + if (!value || value.type !== type) { + throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + value.type); + } +} + +/** + * Enforce expectations about types of {@link Feature} inputs for Turf. + * Internally this uses {@link geojsonType} to judge geometry types. + * + * @name featureOf + * @param {Feature} feature a feature with an expected geometry type + * @param {string} type expected GeoJSON type + * @param {string} name name of calling function + * @throws {Error} error if value is not the expected type. + */ +export function featureOf(feature, type, name) { + if (!feature) { throw new Error('No feature passed'); } + if (!name) { throw new Error('.featureOf() requires a name'); } + if (!feature || feature.type !== 'Feature' || !feature.geometry) { + throw new Error('Invalid input to ' + name + ', Feature with geometry required'); + } + if (!feature.geometry || feature.geometry.type !== type) { + throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + feature.geometry.type); + } +} + +/** + * Enforce expectations about types of {@link FeatureCollection} inputs for Turf. + * Internally this uses {@link geojsonType} to judge geometry types. + * + * @name collectionOf + * @param {FeatureCollection} featureCollection a FeatureCollection for which features will be judged + * @param {string} type expected GeoJSON type + * @param {string} name name of calling function + * @throws {Error} if value is not the expected type. + */ +export function collectionOf(featureCollection, type, name) { + if (!featureCollection) { throw new Error('No featureCollection passed'); } + if (!name) { throw new Error('.collectionOf() requires a name'); } + if (!featureCollection || featureCollection.type !== 'FeatureCollection') { + throw new Error('Invalid input to ' + name + ', FeatureCollection required'); + } + for (const feature of featureCollection.features) { + if (!feature || feature.type !== 'Feature' || !feature.geometry) { + throw new Error('Invalid input to ' + name + ', Feature with geometry required'); + } + if (!feature.geometry || feature.geometry.type !== type) { + throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + feature.geometry.type); + } + } +} + +/** + * Get Geometry from Feature or Geometry Object + * + * @param {Feature|Geometry} geojson GeoJSON Feature or Geometry Object + * @returns {Geometry|null} GeoJSON Geometry Object + * @throws {Error} if geojson is not a Feature or Geometry Object + * @example + * var point = { + * 'type': 'Feature', + * 'properties': {}, + * 'geometry': { + * 'type': 'Point', + * 'coordinates': [110, 40] + * } + * } + * var geom = turf.getGeom(point) + * //={'type': 'Point', 'coordinates': [110, 40]} + */ +export function getGeom(geojson){ + if (geojson.type === 'Feature') { return geojson.geometry; } + return geojson; +} + +/** + * Get GeoJSON object's type, Geometry type is prioritize. + * + * @param {GeoJSON} geojson GeoJSON object + * @param {string} [name='geojson'] name of the variable to display in error message + * @returns {string} GeoJSON type + * @example + * var point = { + * 'type': 'Feature', + * 'properties': {}, + * 'geometry': { + * 'type': 'Point', + * 'coordinates': [110, 40] + * } + * } + * var geom = turf.getType(point) + * //='Point' + */ +export function getType(geojson, name) { + if (geojson.type === 'FeatureCollection') { return 'FeatureCollection'; } + if (geojson.type === 'GeometryCollection') { return 'GeometryCollection'; } + if (geojson.type === 'Feature' && geojson.geometry !== null) { return geojson.geometry.type; } + return geojson.type; +} diff --git a/src/invariant/test.js b/src/invariant/test.js new file mode 100644 index 0000000000..17ead629a6 --- /dev/null +++ b/src/invariant/test.js @@ -0,0 +1,227 @@ +const test = require('tape'); +const helpers = require('../helpers'); +const invariant = require('./'); + +test('invariant -- containsNumber', t => { + t.equals(invariant.containsNumber([1, 1]), true); + t.equals(invariant.containsNumber([[1, 1], [1, 1]]), true); + t.equals(invariant.containsNumber([[[1, 1], [1, 1]], [1, 1]]), true); + + //# Ensure recursive call handles Max callstack exceeded + t.throws(() => { + invariant.containsNumber(['foo', 1]); + }, /coordinates must only contain numbers/, 'Must only contain numbers'); + t.end(); +}); + +test('invariant -- geojsonType', t => { + t.throws(() => { + invariant.geojsonType(); + }, /type and name required/, '.geojsonType() name requirement'); + + t.throws(() => { + invariant.geojsonType({}, undefined, 'myfn'); + }, /type and name required/, 'invalid types'); + + t.throws(() => { + invariant.geojsonType({ + type: 'Point', + coordinates: [0, 0] + }, 'Polygon', 'myfn'); + }, /Invalid input to myfn: must be a Polygon, given Point/, 'invalid geometry type'); + + t.doesNotThrow(() => { + invariant.geojsonType({ + type: 'Point', + coordinates: [0, 0] + }, 'Point', 'myfn'); + }, 'valid geometry'); + + t.end(); +}); + +test('invariant -- featureOf', t => { + t.throws(() => { + invariant.featureOf({ + type: 'Feature', + geometry: { + type: 'Point', + coordinates: [0, 0] + }, + properties: {} + }, 'Polygon'); + }, /requires a name/, 'requires a name'); + + t.throws(() => { + invariant.featureOf({}, 'Polygon', 'foo'); + }, /Feature with geometry required/, 'requires a feature'); + + t.throws(() => { + invariant.featureOf({ + type: 'Feature', + geometry: { + type: 'Point', + coordinates: [0, 0] + }, + properties: {} + }, 'Polygon', 'myfn'); + }, /Invalid input to myfn: must be a Polygon, given Point/, 'invalid geometry type'); + + t.doesNotThrow(() => { + invariant.featureOf({ + type: 'Feature', + geometry: { + type: 'Point', + coordinates: [0, 0] + }, + properties: {} + }, 'Point', 'myfn'); + }, 'valid geometry type'); + + t.end(); +}); + +test('invariant -- collectionOf', t => { + t.throws(() => { + invariant.collectionOf({ + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + geometry: { + type: 'Point', + coordinates: [0, 0] + }, + properties: {} + } + ] + }, 'Polygon', 'myfn'); + }, /Invalid input to myfn: must be a Polygon, given Point/, 'invalid geometry type'); + + t.throws(() => { + invariant.collectionOf({}, 'Polygon'); + }, /requires a name/, 'requires a name'); + + t.throws(() => { + invariant.collectionOf({}, 'Polygon', 'foo'); + }, /FeatureCollection required/, 'requires a featurecollection'); + + t.doesNotThrow(() => { + invariant.collectionOf({ + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + geometry: { + type: 'Point', + coordinates: [0, 0] + }, + properties: {} + } + ] + }, 'Point', 'myfn'); + }, 'valid geometry type'); + + t.end(); +}); + +test('invariant -- getCoord', t => { + t.throws(() => invariant.getCoord(helpers.lineString([[1, 2], [3, 4]]))); + t.throws(() => invariant.getCoord(helpers.polygon([[[-75, 40], [-80, 50], [-70, 50], [-75, 40]]]))); + + t.deepEqual(invariant.getCoord({ + type: 'Point', + coordinates: [1, 2] + }), [1, 2]); + + t.deepEqual(invariant.getCoord(helpers.point([1, 2])), [1, 2]); + t.end(); +}); + +test('invariant -- getCoord', t => { + t.throws(() => invariant.getCoord({ + type: 'LineString', + coordinates: [[1, 2], [3, 4]] + })); + + t.throws(() => invariant.getCoord(false), 'false should throw Error'); + t.throws(() => invariant.getCoord(null), 'null should throw Error'); + t.throws(() => invariant.getCoord(helpers.lineString([[1, 2], [3, 4]])), 'LineString is not a Point'); + t.throws(() => invariant.getCoord([10]), 'Single number Array should throw Error'); + // t.throws(() => invariant.getCoord(['A', 'B']), 'Array of String should throw Error'); + // t.throws(() => invariant.getCoord([1, 'foo']), 'Mixed Array should throw Error'); + + t.deepEqual(invariant.getCoord({ + type: 'Point', + coordinates: [1, 2] + }), [1, 2]); + + t.deepEqual(invariant.getCoord(helpers.point([1, 2])), [1, 2]); + t.deepEqual(invariant.getCoord([1, 2]), [1, 2]); + t.end(); +}); + +test('invariant -- getCoords', t => { + t.throws(() => invariant.getCoords({ + type: 'LineString', + coordinates: null + })); + + t.throws(() => invariant.getCoords(false)); + t.throws(() => invariant.getCoords(null)); + t.throws(() => containsNumber(invariant.getCoords(['A', 'B', 'C']))); + t.throws(() => containsNumber(invariant.getCoords([1, 'foo', 'bar']))); + + t.deepEqual(invariant.getCoords({ + type: 'LineString', + coordinates: [[1, 2], [3, 4]] + }), [[1, 2], [3, 4]]); + + t.deepEqual(invariant.getCoords(helpers.point([1, 2])), [1, 2]); + t.deepEqual(invariant.getCoords(helpers.lineString([[1, 2], [3, 4]])), [[1, 2], [3, 4]]); + t.deepEqual(invariant.getCoords([1, 2]), [1, 2]); + t.end(); +}); + +test('invariant -- getGeom', t => { + const pt = helpers.point([1, 1]); + const line = helpers.lineString([[0, 1], [1, 1]]); + const collection = helpers.featureCollection([pt, line]); + const geomCollection = helpers.geometryCollection([pt.geometry, line.geometry]); + + t.deepEqual(invariant.getGeom(pt), pt.geometry, 'Point'); + t.deepEqual(invariant.getGeom(line.geometry), line.geometry, 'LineString'); + t.deepEqual(invariant.getGeom(geomCollection), geomCollection.geometry, 'GeometryCollection'); + t.deepEqual(invariant.getGeom(geomCollection.geometry), geomCollection.geometry, 'GeometryCollection'); + // t.throws(() => invariant.getGeom(collection), 'featureCollection not valid'); + t.end(); +}); + +test('invariant -- getType', t => { + const pt = helpers.point([1, 1]); + const line = helpers.lineString([[0, 1], [1, 1]]); + const collection = helpers.featureCollection([pt, line]); + const geomCollection = helpers.geometryCollection([pt.geometry, line.geometry]); + + t.deepEqual(invariant.getType(pt), 'Point'); + t.deepEqual(invariant.getType(line.geometry), 'LineString'); + t.deepEqual(invariant.getType(geomCollection), 'GeometryCollection'); + t.deepEqual(invariant.getType(collection), 'FeatureCollection'); + // t.throws(() => invariant.getType(null), /geojson is required/, 'geojson is required'); + t.end(); +}); + +// https://github.com/Turfjs/turf/issues/853 +test('null geometries', t => { + const nullFeature = { + type: 'Feature', + properties: {}, + geometry: null + }; + // t.throws(() => invariant.getGeom(null), /geojson is required/, 'getGeom => geojson is required'); + t.throws(() => invariant.getCoords(nullFeature), /coords must be GeoJSON Feature, Geometry Object or an Array/, 'getCoords => coords must be GeoJSON Feature, Geometry Object or an Array'); + t.throws(() => invariant.getCoord(nullFeature), /coord must be GeoJSON Point or an Array of numbers/, 'getCoord => coord must be GeoJSON Point or an Array of numbers'); + + // t.equal(invariant.getGeom(nullFeature), null, 'getGeom => null'); + t.end(); +}); diff --git a/packages/turf-isobands/bench.js b/src/isobands/bench.js similarity index 100% rename from packages/turf-isobands/bench.js rename to src/isobands/bench.js diff --git a/src/isobands/index.d.ts b/src/isobands/index.d.ts new file mode 100644 index 0000000000..861bde28a8 --- /dev/null +++ b/src/isobands/index.d.ts @@ -0,0 +1,14 @@ +import { Point, MultiPolygon, FeatureCollection, Feature, Properties } from '../helpers' + +/** + * http://turfjs.org/docs/#isobands + */ +export default function isobands( + points: FeatureCollection, + breaks: number[], + options?: { + zProperty?: string; + commonProperties?: Properties; + breaksProperties?: Properties[]; + } +): FeatureCollection; diff --git a/src/isobands/index.js b/src/isobands/index.js new file mode 100644 index 0000000000..a853b19e9e --- /dev/null +++ b/src/isobands/index.js @@ -0,0 +1,248 @@ +import bbox from '../bbox'; +import area from '../area'; +import booleanPointInPolygon from '../boolean-point-in-polygon'; +import explode from '../explode'; +import { collectionOf } from '../invariant'; +import { polygon, multiPolygon, featureCollection, isObject } from '../helpers'; +import gridToMatrix from './lib/grid-to-matrix'; +import isoBands from './lib/marchingsquares-isobands'; + +/** + * Takes a grid {@link FeatureCollection} of {@link Point} features with z-values and an array of + * value breaks and generates filled contour isobands. + * + * @name isobands + * @param {FeatureCollection} pointGrid input points + * @param {Array} breaks where to draw contours + * @param {Object} [options={}] options on output + * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled + * @param {Object} [options.commonProperties={}] GeoJSON properties passed to ALL isobands + * @param {Array} [options.breaksProperties=[]] GeoJSON properties passed, in order, to the correspondent isoband (order defined by breaks) + * @returns {FeatureCollection} a FeatureCollection of {@link MultiPolygon} features representing isobands + */ +function isobands(pointGrid, breaks, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var zProperty = options.zProperty || 'elevation'; + var commonProperties = options.commonProperties || {}; + var breaksProperties = options.breaksProperties || []; + + // Validation + collectionOf(pointGrid, 'Point', 'Input must contain Points'); + if (!breaks) throw new Error('breaks is required'); + if (!Array.isArray(breaks)) throw new Error('breaks is not an Array'); + if (!isObject(commonProperties)) throw new Error('commonProperties is not an Object'); + if (!Array.isArray(breaksProperties)) throw new Error('breaksProperties is not an Array'); + + // Isoband methods + var matrix = gridToMatrix(pointGrid, {zProperty: zProperty, flip: true}); + var contours = createContourLines(matrix, breaks, zProperty); + contours = rescaleContours(contours, matrix, pointGrid); + + var multipolygons = contours.map(function (contour, index) { + if (breaksProperties[index] && !isObject(breaksProperties[index])) { + throw new Error('Each mappedProperty is required to be an Object'); + } + // collect all properties + var contourProperties = Object.assign( + {}, + commonProperties, + breaksProperties[index] + ); + contourProperties[zProperty] = contour[zProperty]; + var multiP = multiPolygon(contour.groupedRings, contourProperties); + return multiP; + }); + + return featureCollection(multipolygons); +} + +/** + * Creates the contours lines (featuresCollection of polygon features) from the 2D data grid + * + * Marchingsquares process the grid data as a 3D representation of a function on a 2D plane, therefore it + * assumes the points (x-y coordinates) are one 'unit' distance. The result of the IsoBands function needs to be + * rescaled, with turfjs, to the original area and proportions on the map + * + * @private + * @param {Array>} matrix Grid Data + * @param {Array} breaks Breaks + * @param {string} [property='elevation'] Property + * @returns {Array} contours + */ +function createContourLines(matrix, breaks, property) { + + var contours = []; + for (var i = 1; i < breaks.length; i++) { + var lowerBand = +breaks[i - 1]; // make sure the breaks value is a number + var upperBand = +breaks[i]; + + var isobandsCoords = isoBands(matrix, lowerBand, upperBand - lowerBand); + // as per GeoJson rules for creating a Polygon, make sure the first element + // in the array of LinearRings represents the exterior ring (i.e. biggest area), + // and any subsequent elements represent interior rings (i.e. smaller area); + // this avoids rendering issues of the MultiPolygons on the map + var nestedRings = orderByArea(isobandsCoords); + var groupedRings = groupNestedRings(nestedRings); + var obj = {}; + obj['groupedRings'] = groupedRings; + obj[property] = lowerBand + '-' + upperBand; + contours.push(obj); + } + return contours; +} + +/** + * Transform isobands of 2D grid to polygons for the map + * + * @private + * @param {Array} contours Contours + * @param {Array>} matrix Grid Data + * @param {Object} points Points by Latitude + * @returns {Array} contours + */ +function rescaleContours(contours, matrix, points) { + + // get dimensions (on the map) of the original grid + var gridBbox = bbox(points); // [ minX, minY, maxX, maxY ] + var originalWidth = gridBbox[2] - gridBbox[0]; + var originalHeigth = gridBbox[3] - gridBbox[1]; + + // get origin, which is the first point of the last row on the rectangular data on the map + var x0 = gridBbox[0]; + var y0 = gridBbox[1]; + // get number of cells per side + var matrixWidth = matrix[0].length - 1; + var matrixHeight = matrix.length - 1; + // calculate the scaling factor between matrix and rectangular grid on the map + var scaleX = originalWidth / matrixWidth; + var scaleY = originalHeigth / matrixHeight; + + var resize = function (point) { + point[0] = point[0] * scaleX + x0; + point[1] = point[1] * scaleY + y0; + }; + + // resize and shift each point/line of the isobands + contours.forEach(function (contour) { + contour.groupedRings.forEach(function (lineRingSet) { + lineRingSet.forEach(function (lineRing) { + lineRing.forEach(resize); + }); + }); + }); + return contours; +} + + +/* utility functions */ + + +/** + * Returns an array of coordinates (of LinearRings) in descending order by area + * + * @private + * @param {Array} ringsCoords array of closed LineString + * @returns {Array} array of the input LineString ordered by area + */ +function orderByArea(ringsCoords) { + var ringsWithArea = []; + var areas = []; + ringsCoords.forEach(function (coords) { + // var poly = polygon([points]); + var ringArea = area(polygon([coords])); + // create an array of areas value + areas.push(ringArea); + // associate each lineRing with its area + ringsWithArea.push({ring: coords, area: ringArea}); + }); + areas.sort(function (a, b) { // bigger --> smaller + return b - a; + }); + // create a new array of linearRings coordinates ordered by their area + var orderedByArea = []; + areas.forEach(function (area) { + for (var lr = 0; lr < ringsWithArea.length; lr++) { + if (ringsWithArea[lr].area === area) { + orderedByArea.push(ringsWithArea[lr].ring); + ringsWithArea.splice(lr, 1); + break; + } + } + }); + return orderedByArea; +} + +/** + * Returns an array of arrays of coordinates, each representing + * a set of (coordinates of) nested LinearRings, + * i.e. the first ring contains all the others + * + * @private + * @param {Array} orderedLinearRings array of coordinates (of LinearRings) in descending order by area + * @returns {Array} Array of coordinates of nested LinearRings + */ +function groupNestedRings(orderedLinearRings) { + // create a list of the (coordinates of) LinearRings + var lrList = orderedLinearRings.map(function (lr) { + return {lrCoordinates: lr, grouped: false}; + }); + var groupedLinearRingsCoords = []; + while (!allGrouped(lrList)) { + for (var i = 0; i < lrList.length; i++) { + if (!lrList[i].grouped) { + // create new group starting with the larger not already grouped ring + var group = []; + group.push(lrList[i].lrCoordinates); + lrList[i].grouped = true; + var outerMostPoly = polygon([lrList[i].lrCoordinates]); + // group all the rings contained by the outermost ring + for (var j = i + 1; j < lrList.length; j++) { + if (!lrList[j].grouped) { + var lrPoly = polygon([lrList[j].lrCoordinates]); + if (isInside(lrPoly, outerMostPoly)) { + group.push(lrList[j].lrCoordinates); + lrList[j].grouped = true; + } + } + } + // insert the new group + groupedLinearRingsCoords.push(group); + } + } + } + return groupedLinearRingsCoords; +} + +/** + * @private + * @param {Polygon} testPolygon polygon of interest + * @param {Polygon} targetPolygon polygon you want to compare with + * @returns {boolean} true if test-Polygon is inside target-Polygon + */ +function isInside(testPolygon, targetPolygon) { + var points = explode(testPolygon); + for (var i = 0; i < points.features.length; i++) { + if (!booleanPointInPolygon(points.features[i], targetPolygon)) { + return false; + } + } + return true; +} + +/** + * @private + * @param {Array} list list of objects which might contain the 'group' attribute + * @returns {boolean} true if all the objects in the list are marked as grouped + */ +function allGrouped(list) { + for (var i = 0; i < list.length; i++) { + if (list[i].grouped === false) { + return false; + } + } + return true; +} + +export default isobands; diff --git a/src/isobands/lib/grid-to-matrix.js b/src/isobands/lib/grid-to-matrix.js new file mode 100644 index 0000000000..b69ae72c7e --- /dev/null +++ b/src/isobands/lib/grid-to-matrix.js @@ -0,0 +1,104 @@ +import { getCoords, collectionOf } from '../../invariant'; +import { featureEach } from '../../meta'; +import { isObject } from '../../helpers'; + +/** + * Takes a {@link Point} grid and returns a correspondent matrix {Array>} + * of the 'property' values + * + * @name gridToMatrix + * @param {FeatureCollection} grid of points + * @param {Object} [options={}] Optional parameters + * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled + * @param {boolean} [options.flip=false] returns the matrix upside-down + * @param {boolean} [options.flags=false] flags, adding a `matrixPosition` array field ([row, column]) to its properties, + * the grid points with coordinates on the matrix + * @returns {Array>} matrix of property values + * @example + * var extent = [-70.823364, -33.553984, -70.473175, -33.302986]; + * var cellSize = 3; + * var grid = turf.pointGrid(extent, cellSize); + * // add a random property to each point between 0 and 60 + * for (var i = 0; i < grid.features.length; i++) { + * grid.features[i].properties.elevation = (Math.random() * 60); + * } + * gridToMatrix(grid); + * //= [ + * [ 1, 13, 10, 9, 10, 13, 18], + * [34, 8, 5, 4, 5, 8, 13], + * [10, 5, 2, 1, 2, 5, 4], + * [ 0, 4, 56, 19, 1, 4, 9], + * [10, 5, 2, 1, 2, 5, 10], + * [57, 8, 5, 4, 5, 0, 57], + * [ 3, 13, 10, 9, 5, 13, 18], + * [18, 13, 10, 9, 78, 13, 18] + * ] + */ +export default function gridToMatrix(grid, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var zProperty = options.zProperty || 'elevation'; + var flip = options.flip; + var flags = options.flags; + + // validation + collectionOf(grid, 'Point', 'input must contain Points'); + + var pointsMatrix = sortPointsByLatLng(grid, flip); + + var matrix = []; + // create property matrix from sorted points + // looping order matters here + for (var r = 0; r < pointsMatrix.length; r++) { + var pointRow = pointsMatrix[r]; + var row = []; + for (var c = 0; c < pointRow.length; c++) { + var point = pointRow[c]; + // Check if zProperty exist + if (point.properties[zProperty]) row.push(point.properties[zProperty]); + else row.push(0); + // add flags + if (flags === true) point.properties.matrixPosition = [r, c]; + } + matrix.push(row); + } + + return matrix; +} + +/** + * Sorts points by latitude and longitude, creating a 2-dimensional array of points + * + * @private + * @param {FeatureCollection} points GeoJSON Point features + * @param {boolean} [flip=false] returns the matrix upside-down + * @returns {Array>} points ordered by latitude and longitude + */ +function sortPointsByLatLng(points, flip) { + var pointsByLatitude = {}; + + // divide points by rows with the same latitude + featureEach(points, function (point) { + var lat = getCoords(point)[1]; + if (!pointsByLatitude[lat]) pointsByLatitude[lat] = []; + pointsByLatitude[lat].push(point); + }); + + // sort points (with the same latitude) by longitude + var orderedRowsByLatitude = Object.keys(pointsByLatitude).map(function (lat) { + var row = pointsByLatitude[lat]; + var rowOrderedByLongitude = row.sort(function (a, b) { + return getCoords(a)[0] - getCoords(b)[0]; + }); + return rowOrderedByLongitude; + }); + + // sort rows (of points with the same latitude) by latitude + var pointMatrix = orderedRowsByLatitude.sort(function (a, b) { + if (flip) return getCoords(a[0])[1] - getCoords(b[0])[1]; + else return getCoords(b[0])[1] - getCoords(a[0])[1]; + }); + + return pointMatrix; +} diff --git a/packages/turf-isobands/lib/marchingsquares-isobands.js b/src/isobands/lib/marchingsquares-isobands.js similarity index 100% rename from packages/turf-isobands/lib/marchingsquares-isobands.js rename to src/isobands/lib/marchingsquares-isobands.js diff --git a/src/isobands/lib/matrix-to-grid.js b/src/isobands/lib/matrix-to-grid.js new file mode 100644 index 0000000000..4d7473bdb9 --- /dev/null +++ b/src/isobands/lib/matrix-to-grid.js @@ -0,0 +1,78 @@ +import { isObject, featureCollection, point } from '../../helpers'; +import rhumbDestination from '../../rhumb-destination'; + +/** + * Takes a {@link Point} grid and returns a correspondent matrix {Array>} + * of the 'property' values + * + * @name matrixToGrid + * @param {Array>} matrix of numbers + * @param {Point|Array} origin position of the first bottom-left (South-West) point of the grid + * @param {number} cellSize the distance across each cell + * @param {Object} [options={}] optional parameters + * @param {string} [options.zProperty='elevation'] the grid points property name associated with the matrix value + * @param {Object} [options.properties={}] GeoJSON properties passed to all the points + * @param {string} [options.units='kilometers'] used in calculating cellSize, can be miles, or kilometers + * @returns {FeatureCollection} grid of points + * + * @example + * var matrixToGrid = require('matrix-to-grid'); + * var matrix = [ + * [ 1, 13, 20, 9, 10, 13, 18], + * [34, 8, 0, 4, 5, 8, 13], + * [10, 5, 2, 1, 2, 5, 24], + * [ 0, 4, 56, 19, 0, 4, 9], + * [10, 5, 2, 12, 2, 5, 10], + * [57, 8, 5, 4, 5, 0, 57], + * [ 3, 13, 0, 9, 5, 13, 35], + * [18, 13, 10, 9, 78, 13, 18] + * ]; + * var origin = [-70.823364, -33.553984] + * matrixToGrid(matrix, origin, 10); + * //= pointGrid + */ +export default function matrixToGrid(matrix, origin, cellSize, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var zProperty = options.zProperty || 'elevation'; + var properties = options.properties; + var units = options.units; + + // validation + if (!matrix || !Array.isArray(matrix)) throw new Error('matrix is required'); + if (!origin) throw new Error('origin is required'); + if (Array.isArray(origin)) { + origin = point(origin); // Convert coordinates array to point + } + // all matrix array have to be of the same size + var matrixCols = matrix[0].length; + var matrixRows = matrix.length; + for (var row = 1; row < matrixRows; row++) { + if (matrix[row].length !== matrixCols) throw new Error('matrix requires all rows of equal size'); + } + + var points = []; + for (var r = 0; r < matrixRows; r++) { + // create first point in the row + var first = rhumbDestination(origin, cellSize * r, 0, { units: units }); + first.properties[zProperty] = matrix[matrixRows - 1 - r][0]; + for (var prop in properties) { + first.properties[prop] = properties[prop]; + } + points.push(first); + for (var c = 1; c < matrixCols; c++) { + // create the other points in the same row + var pt = rhumbDestination(first, cellSize * c, 90, { units: units }); + for (var prop2 in properties) { + pt.properties[prop2] = properties[prop2]; + } + // add matrix property + var val = matrix[matrixRows - 1 - r][c]; + pt.properties[zProperty] = val; + points.push(pt); + } + } + var grid = featureCollection(points); + return grid; +} diff --git a/src/isobands/test.js b/src/isobands/test.js new file mode 100644 index 0000000000..687a987d5f --- /dev/null +++ b/src/isobands/test.js @@ -0,0 +1,61 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import envelope from '../envelope'; +import pointGrid from '../point-grid'; +import truncate from '../truncate'; +import { getCoords } from '../invariant'; +import { lineString } from '../helpers'; +import { featureEach } from '../meta'; +import { randomPolygon } from '../random'; +import matrixToGrid from './lib/matrix-to-grid'; +import isobands from './'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + json: load.sync(directories.in + filename) + }; +}); + +test('isobands', t => { + fixtures.forEach(({name, json, filename}) => { + const options = json.properties || json + const { breaks, matrix, origin, cellSize } = options; + + // allow GeoJSON featureCollection or matrix + let points = json.properties ? json : matrixToGrid(matrix, origin, cellSize, options); + + // Results + const results = truncate(isobands(points, breaks, options)); + + // Add red line around point data + results.features.push(lineString(getCoords(envelope(points))[0], { + stroke: '#F00', + 'stroke-width': 1 + })); + + if (process.env.REGEN) write.sync(directories.out + name + '.geojson', results); + t.deepEqual(results, load.sync(directories.out + name + '.geojson'), name); + }); + + t.end(); +}); + +test('isobands -- throws', t => { + const points = pointGrid([-70.823364, -33.553984, -70.473175, -33.302986], 5); + + t.throws(() => isobands(randomPolygon(), [1, 2, 3]), 'invalid points'); + t.throws(() => isobands(points, ''), 'invalid breaks'); + t.throws(() => isobands(points, [1, 2, 3], {zProperty: 'temp', breaksProperties: 'hello' }), 'invalid options'); + + t.end(); +}); \ No newline at end of file diff --git a/packages/turf-isobands/test/in/bigMatrix.json b/src/isobands/test/in/bigMatrix.json similarity index 100% rename from packages/turf-isobands/test/in/bigMatrix.json rename to src/isobands/test/in/bigMatrix.json diff --git a/packages/turf-isobands/test/in/matrix1.json b/src/isobands/test/in/matrix1.json similarity index 100% rename from packages/turf-isobands/test/in/matrix1.json rename to src/isobands/test/in/matrix1.json diff --git a/packages/turf-isobands/test/in/matrix2.json b/src/isobands/test/in/matrix2.json similarity index 100% rename from packages/turf-isobands/test/in/matrix2.json rename to src/isobands/test/in/matrix2.json diff --git a/packages/turf-isobands/test/in/pointGrid.geojson b/src/isobands/test/in/pointGrid.geojson similarity index 100% rename from packages/turf-isobands/test/in/pointGrid.geojson rename to src/isobands/test/in/pointGrid.geojson diff --git a/packages/turf-isobands/test/out/bigMatrix.geojson b/src/isobands/test/out/bigMatrix.geojson similarity index 100% rename from packages/turf-isobands/test/out/bigMatrix.geojson rename to src/isobands/test/out/bigMatrix.geojson diff --git a/packages/turf-isobands/test/out/matrix1.geojson b/src/isobands/test/out/matrix1.geojson similarity index 100% rename from packages/turf-isobands/test/out/matrix1.geojson rename to src/isobands/test/out/matrix1.geojson diff --git a/packages/turf-isobands/test/out/matrix2.geojson b/src/isobands/test/out/matrix2.geojson similarity index 100% rename from packages/turf-isobands/test/out/matrix2.geojson rename to src/isobands/test/out/matrix2.geojson diff --git a/packages/turf-isobands/test/out/pointGrid.geojson b/src/isobands/test/out/pointGrid.geojson similarity index 100% rename from packages/turf-isobands/test/out/pointGrid.geojson rename to src/isobands/test/out/pointGrid.geojson diff --git a/packages/turf-isolines/bench.js b/src/isolines/bench.js similarity index 100% rename from packages/turf-isolines/bench.js rename to src/isolines/bench.js diff --git a/src/isolines/index.d.ts b/src/isolines/index.d.ts new file mode 100644 index 0000000000..7bc740aa70 --- /dev/null +++ b/src/isolines/index.d.ts @@ -0,0 +1,14 @@ +import { Point, MultiLineString, FeatureCollection, Properties } from '../helpers' + +/** + * http://turfjs.org/docs/#isolines + */ +export default function isolines( + points: FeatureCollection, + breaks: number[], + options?: { + zProperty?: string, + commonProperties?: Properties, + breaksProperties?: Properties[] + } +): FeatureCollection; diff --git a/src/isolines/index.js b/src/isolines/index.js new file mode 100644 index 0000000000..25c6f11189 --- /dev/null +++ b/src/isolines/index.js @@ -0,0 +1,133 @@ +import bbox from '../bbox'; +import { coordEach } from '../meta'; +import { collectionOf } from '../invariant'; +import { multiLineString, featureCollection, isObject } from '../helpers'; +import isoContours from './lib/marchingsquares-isocontours'; +import gridToMatrix from './lib/grid-to-matrix'; + +/** + * Takes a grid {@link FeatureCollection} of {@link Point} features with z-values and an array of + * value breaks and generates [isolines](http://en.wikipedia.org/wiki/Isoline). + * + * @name isolines + * @param {FeatureCollection} pointGrid input points + * @param {Array} breaks values of `zProperty` where to draw isolines + * @param {Object} [options={}] Optional parameters + * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled + * @param {Object} [options.commonProperties={}] GeoJSON properties passed to ALL isolines + * @param {Array} [options.breaksProperties=[]] GeoJSON properties passed, in order, to the correspondent isoline; + * the breaks array will define the order in which the isolines are created + * @returns {FeatureCollection} a FeatureCollection of {@link MultiLineString} features representing isolines + * @example + * // create a grid of points with random z-values in their properties + * var extent = [0, 30, 20, 50]; + * var cellWidth = 100; + * var pointGrid = turf.pointGrid(extent, cellWidth, {units: 'miles'}); + * + * for (var i = 0; i < pointGrid.features.length; i++) { + * pointGrid.features[i].properties.temperature = Math.random() * 10; + * } + * var breaks = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + * + * var lines = turf.isolines(pointGrid, breaks, {zProperty: 'temperature'}); + * + * //addToMap + * var addToMap = [lines]; + */ +function isolines(pointGrid, breaks, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var zProperty = options.zProperty || 'elevation'; + var commonProperties = options.commonProperties || {}; + var breaksProperties = options.breaksProperties || []; + + // Input validation + collectionOf(pointGrid, 'Point', 'Input must contain Points'); + if (!breaks) throw new Error('breaks is required'); + if (!Array.isArray(breaks)) throw new Error('breaks must be an Array'); + if (!isObject(commonProperties)) throw new Error('commonProperties must be an Object'); + if (!Array.isArray(breaksProperties)) throw new Error('breaksProperties must be an Array'); + + // Isoline methods + var matrix = gridToMatrix(pointGrid, {zProperty: zProperty, flip: true}); + var createdIsoLines = createIsoLines(matrix, breaks, zProperty, commonProperties, breaksProperties); + var scaledIsolines = rescaleIsolines(createdIsoLines, matrix, pointGrid); + + return featureCollection(scaledIsolines); +} + +/** + * Creates the isolines lines (featuresCollection of MultiLineString features) from the 2D data grid + * + * Marchingsquares process the grid data as a 3D representation of a function on a 2D plane, therefore it + * assumes the points (x-y coordinates) are one 'unit' distance. The result of the isolines function needs to be + * rescaled, with turfjs, to the original area and proportions on the map + * + * @private + * @param {Array>} matrix Grid Data + * @param {Array} breaks Breaks + * @param {string} zProperty name of the z-values property + * @param {Object} [commonProperties={}] GeoJSON properties passed to ALL isolines + * @param {Object} [breaksProperties=[]] GeoJSON properties passed to the correspondent isoline + * @returns {Array} isolines + */ +function createIsoLines(matrix, breaks, zProperty, commonProperties, breaksProperties) { + var results = []; + for (var i = 1; i < breaks.length; i++) { + var threshold = +breaks[i]; // make sure it's a number + + var properties = Object.assign( + {}, + commonProperties, + breaksProperties[i] + ); + properties[zProperty] = threshold; + var isoline = multiLineString(isoContours(matrix, threshold), properties); + + results.push(isoline); + } + return results; +} + +/** + * Translates and scales isolines + * + * @private + * @param {Array} createdIsoLines to be rescaled + * @param {Array>} matrix Grid Data + * @param {Object} points Points by Latitude + * @returns {Array} isolines + */ +function rescaleIsolines(createdIsoLines, matrix, points) { + + // get dimensions (on the map) of the original grid + var gridBbox = bbox(points); // [ minX, minY, maxX, maxY ] + var originalWidth = gridBbox[2] - gridBbox[0]; + var originalHeigth = gridBbox[3] - gridBbox[1]; + + // get origin, which is the first point of the last row on the rectangular data on the map + var x0 = gridBbox[0]; + var y0 = gridBbox[1]; + + // get number of cells per side + var matrixWidth = matrix[0].length - 1; + var matrixHeight = matrix.length - 1; + + // calculate the scaling factor between matrix and rectangular grid on the map + var scaleX = originalWidth / matrixWidth; + var scaleY = originalHeigth / matrixHeight; + + var resize = function (point) { + point[0] = point[0] * scaleX + x0; + point[1] = point[1] * scaleY + y0; + }; + + // resize and shift each point/line of the createdIsoLines + createdIsoLines.forEach(function (isoline) { + coordEach(isoline, resize); + }); + return createdIsoLines; +} + +export default isolines; diff --git a/src/isolines/lib/grid-to-matrix.js b/src/isolines/lib/grid-to-matrix.js new file mode 100644 index 0000000000..b69ae72c7e --- /dev/null +++ b/src/isolines/lib/grid-to-matrix.js @@ -0,0 +1,104 @@ +import { getCoords, collectionOf } from '../../invariant'; +import { featureEach } from '../../meta'; +import { isObject } from '../../helpers'; + +/** + * Takes a {@link Point} grid and returns a correspondent matrix {Array>} + * of the 'property' values + * + * @name gridToMatrix + * @param {FeatureCollection} grid of points + * @param {Object} [options={}] Optional parameters + * @param {string} [options.zProperty='elevation'] the property name in `points` from which z-values will be pulled + * @param {boolean} [options.flip=false] returns the matrix upside-down + * @param {boolean} [options.flags=false] flags, adding a `matrixPosition` array field ([row, column]) to its properties, + * the grid points with coordinates on the matrix + * @returns {Array>} matrix of property values + * @example + * var extent = [-70.823364, -33.553984, -70.473175, -33.302986]; + * var cellSize = 3; + * var grid = turf.pointGrid(extent, cellSize); + * // add a random property to each point between 0 and 60 + * for (var i = 0; i < grid.features.length; i++) { + * grid.features[i].properties.elevation = (Math.random() * 60); + * } + * gridToMatrix(grid); + * //= [ + * [ 1, 13, 10, 9, 10, 13, 18], + * [34, 8, 5, 4, 5, 8, 13], + * [10, 5, 2, 1, 2, 5, 4], + * [ 0, 4, 56, 19, 1, 4, 9], + * [10, 5, 2, 1, 2, 5, 10], + * [57, 8, 5, 4, 5, 0, 57], + * [ 3, 13, 10, 9, 5, 13, 18], + * [18, 13, 10, 9, 78, 13, 18] + * ] + */ +export default function gridToMatrix(grid, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var zProperty = options.zProperty || 'elevation'; + var flip = options.flip; + var flags = options.flags; + + // validation + collectionOf(grid, 'Point', 'input must contain Points'); + + var pointsMatrix = sortPointsByLatLng(grid, flip); + + var matrix = []; + // create property matrix from sorted points + // looping order matters here + for (var r = 0; r < pointsMatrix.length; r++) { + var pointRow = pointsMatrix[r]; + var row = []; + for (var c = 0; c < pointRow.length; c++) { + var point = pointRow[c]; + // Check if zProperty exist + if (point.properties[zProperty]) row.push(point.properties[zProperty]); + else row.push(0); + // add flags + if (flags === true) point.properties.matrixPosition = [r, c]; + } + matrix.push(row); + } + + return matrix; +} + +/** + * Sorts points by latitude and longitude, creating a 2-dimensional array of points + * + * @private + * @param {FeatureCollection} points GeoJSON Point features + * @param {boolean} [flip=false] returns the matrix upside-down + * @returns {Array>} points ordered by latitude and longitude + */ +function sortPointsByLatLng(points, flip) { + var pointsByLatitude = {}; + + // divide points by rows with the same latitude + featureEach(points, function (point) { + var lat = getCoords(point)[1]; + if (!pointsByLatitude[lat]) pointsByLatitude[lat] = []; + pointsByLatitude[lat].push(point); + }); + + // sort points (with the same latitude) by longitude + var orderedRowsByLatitude = Object.keys(pointsByLatitude).map(function (lat) { + var row = pointsByLatitude[lat]; + var rowOrderedByLongitude = row.sort(function (a, b) { + return getCoords(a)[0] - getCoords(b)[0]; + }); + return rowOrderedByLongitude; + }); + + // sort rows (of points with the same latitude) by latitude + var pointMatrix = orderedRowsByLatitude.sort(function (a, b) { + if (flip) return getCoords(a[0])[1] - getCoords(b[0])[1]; + else return getCoords(b[0])[1] - getCoords(a[0])[1]; + }); + + return pointMatrix; +} diff --git a/packages/turf-isolines/lib/marchingsquares-isocontours.js b/src/isolines/lib/marchingsquares-isocontours.js similarity index 100% rename from packages/turf-isolines/lib/marchingsquares-isocontours.js rename to src/isolines/lib/marchingsquares-isocontours.js diff --git a/src/isolines/lib/matrix-to-grid.js b/src/isolines/lib/matrix-to-grid.js new file mode 100644 index 0000000000..4d7473bdb9 --- /dev/null +++ b/src/isolines/lib/matrix-to-grid.js @@ -0,0 +1,78 @@ +import { isObject, featureCollection, point } from '../../helpers'; +import rhumbDestination from '../../rhumb-destination'; + +/** + * Takes a {@link Point} grid and returns a correspondent matrix {Array>} + * of the 'property' values + * + * @name matrixToGrid + * @param {Array>} matrix of numbers + * @param {Point|Array} origin position of the first bottom-left (South-West) point of the grid + * @param {number} cellSize the distance across each cell + * @param {Object} [options={}] optional parameters + * @param {string} [options.zProperty='elevation'] the grid points property name associated with the matrix value + * @param {Object} [options.properties={}] GeoJSON properties passed to all the points + * @param {string} [options.units='kilometers'] used in calculating cellSize, can be miles, or kilometers + * @returns {FeatureCollection} grid of points + * + * @example + * var matrixToGrid = require('matrix-to-grid'); + * var matrix = [ + * [ 1, 13, 20, 9, 10, 13, 18], + * [34, 8, 0, 4, 5, 8, 13], + * [10, 5, 2, 1, 2, 5, 24], + * [ 0, 4, 56, 19, 0, 4, 9], + * [10, 5, 2, 12, 2, 5, 10], + * [57, 8, 5, 4, 5, 0, 57], + * [ 3, 13, 0, 9, 5, 13, 35], + * [18, 13, 10, 9, 78, 13, 18] + * ]; + * var origin = [-70.823364, -33.553984] + * matrixToGrid(matrix, origin, 10); + * //= pointGrid + */ +export default function matrixToGrid(matrix, origin, cellSize, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var zProperty = options.zProperty || 'elevation'; + var properties = options.properties; + var units = options.units; + + // validation + if (!matrix || !Array.isArray(matrix)) throw new Error('matrix is required'); + if (!origin) throw new Error('origin is required'); + if (Array.isArray(origin)) { + origin = point(origin); // Convert coordinates array to point + } + // all matrix array have to be of the same size + var matrixCols = matrix[0].length; + var matrixRows = matrix.length; + for (var row = 1; row < matrixRows; row++) { + if (matrix[row].length !== matrixCols) throw new Error('matrix requires all rows of equal size'); + } + + var points = []; + for (var r = 0; r < matrixRows; r++) { + // create first point in the row + var first = rhumbDestination(origin, cellSize * r, 0, { units: units }); + first.properties[zProperty] = matrix[matrixRows - 1 - r][0]; + for (var prop in properties) { + first.properties[prop] = properties[prop]; + } + points.push(first); + for (var c = 1; c < matrixCols; c++) { + // create the other points in the same row + var pt = rhumbDestination(first, cellSize * c, 90, { units: units }); + for (var prop2 in properties) { + pt.properties[prop2] = properties[prop2]; + } + // add matrix property + var val = matrix[matrixRows - 1 - r][c]; + pt.properties[zProperty] = val; + points.push(pt); + } + } + var grid = featureCollection(points); + return grid; +} diff --git a/src/isolines/test.js b/src/isolines/test.js new file mode 100644 index 0000000000..a236be3669 --- /dev/null +++ b/src/isolines/test.js @@ -0,0 +1,79 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import envelope from '../envelope'; +import truncate from '../truncate'; +import pointGrid from '../point-grid'; +import { getCoords } from '../invariant'; +import { randomPolygon } from '../random'; +import { lineString, polygon } from '../helpers'; +import matrixToGrid from './lib/matrix-to-grid'; +import isolines from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + json: load.sync(directories.in + filename) + }; +}); + +test('isolines', t => { + fixtures.forEach(({name, json, filename}) => { + const options = json.properties || json; + const { breaks, matrix, cellSize, origin} = options; + + // allow GeoJSON featureCollection or matrix + let points = json.properties ? json : matrixToGrid(matrix, origin, cellSize, options); + + // Results + const results = truncate(isolines(points, breaks, options)); + + // Add red line around point data + results.features.push(lineString(getCoords(envelope(points))[0], { + stroke: '#F00', + 'stroke-width': 1 + })); + + if (process.env.REGEN) write.sync(directories.out + name + '.geojson', results); + t.deepEqual(results, load.sync(directories.out + name + '.geojson'), name); + }); + + t.end(); +}); + +test('isolines -- throws', t => { + const points = pointGrid([-70.823364, -33.553984, -70.473175, -33.302986], 5); + + t.throws(() => isolines(randomPolygon()), 'invalid points'); + t.throws(() => isolines(points), /breaks is required/); + t.throws(() => isolines(points, 'string'), /breaks must be an Array/); + t.throws(() => isolines(points, [1, 2, 3], {commonProperties: 'foo'}), /commonProperties must be an Object/); + t.throws(() => isolines(points, [1, 2, 3], {breaksProperties: 'foo'}), /breaksProperties must be an Array/); + + // Updated tests since Turf 5.0 + t.assert(isolines(points, [1, 2, 3], {zProperty: 5}), 'zProperty can be a string'); + t.end(); +}); + +test('isolines -- handling properties', t => { + const points = pointGrid([-70.823364, -33.553984, -70.473175, -33.302986], 5); + const commonProperties = {name: 'unknown', source: 'foobar'}; + const breaksProperties = [{name: 'break1'}, {name: 'break2'}, {name: 'break3'}]; + + const lines = isolines(points, [1, 2, 3], { + zProperty: 'z', + commonProperties: commonProperties, + breaksProperties: breaksProperties + }); + t.equal(lines.features[0].properties.name, 'break2'); + t.equal(lines.features[0].properties.source, 'foobar'); + t.end(); +}); diff --git a/packages/turf-isolines/test/in/bigMatrix.json b/src/isolines/test/in/bigMatrix.json similarity index 100% rename from packages/turf-isolines/test/in/bigMatrix.json rename to src/isolines/test/in/bigMatrix.json diff --git a/packages/turf-isolines/test/in/matrix1.json b/src/isolines/test/in/matrix1.json similarity index 100% rename from packages/turf-isolines/test/in/matrix1.json rename to src/isolines/test/in/matrix1.json diff --git a/packages/turf-isolines/test/in/matrix2.json b/src/isolines/test/in/matrix2.json similarity index 100% rename from packages/turf-isolines/test/in/matrix2.json rename to src/isolines/test/in/matrix2.json diff --git a/packages/turf-isolines/test/in/pointGrid.geojson b/src/isolines/test/in/pointGrid.geojson similarity index 100% rename from packages/turf-isolines/test/in/pointGrid.geojson rename to src/isolines/test/in/pointGrid.geojson diff --git a/packages/turf-isolines/test/out/bigMatrix.geojson b/src/isolines/test/out/bigMatrix.geojson similarity index 100% rename from packages/turf-isolines/test/out/bigMatrix.geojson rename to src/isolines/test/out/bigMatrix.geojson diff --git a/packages/turf-isolines/test/out/matrix1.geojson b/src/isolines/test/out/matrix1.geojson similarity index 100% rename from packages/turf-isolines/test/out/matrix1.geojson rename to src/isolines/test/out/matrix1.geojson diff --git a/packages/turf-isolines/test/out/matrix2.geojson b/src/isolines/test/out/matrix2.geojson similarity index 100% rename from packages/turf-isolines/test/out/matrix2.geojson rename to src/isolines/test/out/matrix2.geojson diff --git a/packages/turf-isolines/test/out/pointGrid.geojson b/src/isolines/test/out/pointGrid.geojson similarity index 100% rename from packages/turf-isolines/test/out/pointGrid.geojson rename to src/isolines/test/out/pointGrid.geojson diff --git a/packages/turf-kinks/bench.js b/src/kinks/bench.js similarity index 100% rename from packages/turf-kinks/bench.js rename to src/kinks/bench.js diff --git a/src/kinks/index.d.ts b/src/kinks/index.d.ts new file mode 100644 index 0000000000..0b5a3f5417 --- /dev/null +++ b/src/kinks/index.d.ts @@ -0,0 +1,24 @@ +import { Feature, FeatureCollection, LineString, MultiLineString, MultiPolygon, Point, Polygon } from "../helpers"; +/** + * Takes a {@link LineString|linestring}, {@link MultiLineString|multi-linestring}, + * {@link MultiPolygon|multi-polygon} or {@link Polygon|polygon} and + * returns {@link Point|points} at all self-intersections. + * + * @name kinks + * @param {Feature} featureIn input feature + * @returns {FeatureCollection} self-intersections + * @example + * var poly = turf.polygon([[ + * [-12.034835, 8.901183], + * [-12.060413, 8.899826], + * [-12.03638, 8.873199], + * [-12.059383, 8.871418], + * [-12.034835, 8.901183] + * ]]); + * + * var kinks = turf.kinks(poly); + * + * //addToMap + * var addToMap = [poly, kinks] + */ +export default function kinks(featureIn: Feature | T): FeatureCollection; diff --git a/src/kinks/index.js b/src/kinks/index.js new file mode 100644 index 0000000000..4d0de7bd06 --- /dev/null +++ b/src/kinks/index.js @@ -0,0 +1,142 @@ +import { point } from '../helpers'; + +/** + * Takes a {@link LineString|linestring}, {@link MultiLineString|multi-linestring}, + * {@link MultiPolygon|multi-polygon} or {@link Polygon|polygon} and + * returns {@link Point|points} at all self-intersections. + * + * @name kinks + * @param {Feature} featureIn input feature + * @returns {FeatureCollection} self-intersections + * @example + * var poly = turf.polygon([[ + * [-12.034835, 8.901183], + * [-12.060413, 8.899826], + * [-12.03638, 8.873199], + * [-12.059383, 8.871418], + * [-12.034835, 8.901183] + * ]]); + * + * var kinks = turf.kinks(poly); + * + * //addToMap + * var addToMap = [poly, kinks] + */ +export default function kinks(featureIn) { + let coordinates = null; + let feature = null; + const results = { + type: 'FeatureCollection', + features: [], + }; + if (featureIn.type === 'Feature') { + feature = featureIn.geometry; + } else { + feature = featureIn; + } + if (feature.type === 'LineString') { + coordinates = [feature.coordinates]; + } else if (feature.type === 'MultiLineString') { + coordinates = feature.coordinates; + } else if (feature.type === 'MultiPolygon') { + coordinates = [].concat.apply([], feature.coordinates); + } else if (feature.type === 'Polygon') { + coordinates = feature.coordinates; + } else { + throw new Error('Input must be a LineString, MultiLineString, ' + + 'Polygon, or MultiPolygon Feature or Geometry'); + } + coordinates.forEach(function (line1) { + coordinates.forEach(function (line2) { + for (let i = 0; i < line1.length - 1; i++) { + // start iteration at i, intersections for k < i have already + // been checked in previous outer loop iterations + for (let k = i; k < line2.length - 1; k++) { + if (line1 === line2) { + // segments are adjacent and always share a vertex, not a kink + if (Math.abs(i - k) === 1) { + continue; + } + // first and last segment in a closed lineString or ring always share a vertex, not a kink + if ( + // segments are first and last segment of lineString + i === 0 && + k === line1.length - 2 && + // lineString is closed + line1[i][0] === line1[line1.length - 1][0] && + line1[i][1] === line1[line1.length - 1][1] + ) { + continue; + } + } + + const intersection = lineIntersects(line1[i][0], line1[i][1], line1[i + 1][0], line1[i + 1][1], + line2[k][0], line2[k][1], line2[k + 1][0], line2[k + 1][1]); + if (intersection) { + results.features.push(point([intersection[0], intersection[1]])); + } + } + } + }); + }); + return results; +} + +// modified from http://jsfiddle.net/justin_c_rounds/Gd2S2/light/ +function lineIntersects( + line1StartX, + line1StartY, + line1EndX, + line1EndY, + line2StartX, + line2StartY, + line2EndX, + line2EndY) { + // if the lines intersect, the result contains the x and y of the + // intersection (treating the lines as infinite) and booleans for whether + // line segment 1 or line segment 2 contain the point + let denominator; + let a; + let b; + let numerator1; + let numerator2; + const result = { + x: null, + y: null, + onLine1: false, + onLine2: false, + }; + denominator = ((line2EndY - line2StartY) * (line1EndX - line1StartX)) - ((line2EndX - line2StartX) * (line1EndY - line1StartY)); + if (denominator === 0) { + if (result.x !== null && result.y !== null) { + return result; + } else { + return false; + } + } + a = line1StartY - line2StartY; + b = line1StartX - line2StartX; + numerator1 = ((line2EndX - line2StartX) * a) - ((line2EndY - line2StartY) * b); + numerator2 = ((line1EndX - line1StartX) * a) - ((line1EndY - line1StartY) * b); + a = numerator1 / denominator; + b = numerator2 / denominator; + + // if we cast these lines infinitely in both directions, they intersect here: + result.x = line1StartX + (a * (line1EndX - line1StartX)); + result.y = line1StartY + (a * (line1EndY - line1StartY)); + + // if line1 is a segment and line2 is infinite, they intersect if: + if (a >= 0 && a <= 1) { + result.onLine1 = true; + } + // if line2 is a segment and line1 is infinite, they intersect if: + if (b >= 0 && b <= 1) { + result.onLine2 = true; + } + // if line1 and line2 are segments, they intersect if both of the above are true + if (result.onLine1 && result.onLine2) { + return [result.x, result.y]; + } else { + return false; + } +} diff --git a/src/kinks/test.js b/src/kinks/test.js new file mode 100644 index 0000000000..ea90cdf083 --- /dev/null +++ b/src/kinks/test.js @@ -0,0 +1,31 @@ +const test = require('tape'); +const fs = require('fs'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { featureEach } = require('../meta'); +const kinks = require('.').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-kinks', t => { + for (const {name, filename, geojson} of fixtures) { + const results = kinks(geojson); + featureEach(geojson, feature => results.features.push(feature)); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(results, load.sync(directories.out + filename), name); + } + t.end(); +}); diff --git a/packages/turf-kinks/test/in/hourglass.geojson b/src/kinks/test/in/hourglass.geojson similarity index 100% rename from packages/turf-kinks/test/in/hourglass.geojson rename to src/kinks/test/in/hourglass.geojson diff --git a/packages/turf-kinks/test/in/multi-linestring.geojson b/src/kinks/test/in/multi-linestring.geojson similarity index 100% rename from packages/turf-kinks/test/in/multi-linestring.geojson rename to src/kinks/test/in/multi-linestring.geojson diff --git a/packages/turf-kinks/test/in/multi-polygon.geojson b/src/kinks/test/in/multi-polygon.geojson similarity index 100% rename from packages/turf-kinks/test/in/multi-polygon.geojson rename to src/kinks/test/in/multi-polygon.geojson diff --git a/packages/turf-kinks/test/in/open-hourglass.geojson b/src/kinks/test/in/open-hourglass.geojson similarity index 100% rename from packages/turf-kinks/test/in/open-hourglass.geojson rename to src/kinks/test/in/open-hourglass.geojson diff --git a/packages/turf-kinks/test/in/triple.geojson b/src/kinks/test/in/triple.geojson similarity index 100% rename from packages/turf-kinks/test/in/triple.geojson rename to src/kinks/test/in/triple.geojson diff --git a/packages/turf-kinks/test/out/hourglass.geojson b/src/kinks/test/out/hourglass.geojson similarity index 100% rename from packages/turf-kinks/test/out/hourglass.geojson rename to src/kinks/test/out/hourglass.geojson diff --git a/packages/turf-kinks/test/out/multi-linestring.geojson b/src/kinks/test/out/multi-linestring.geojson similarity index 100% rename from packages/turf-kinks/test/out/multi-linestring.geojson rename to src/kinks/test/out/multi-linestring.geojson diff --git a/packages/turf-kinks/test/out/multi-polygon.geojson b/src/kinks/test/out/multi-polygon.geojson similarity index 100% rename from packages/turf-kinks/test/out/multi-polygon.geojson rename to src/kinks/test/out/multi-polygon.geojson diff --git a/packages/turf-kinks/test/out/open-hourglass.geojson b/src/kinks/test/out/open-hourglass.geojson similarity index 100% rename from packages/turf-kinks/test/out/open-hourglass.geojson rename to src/kinks/test/out/open-hourglass.geojson diff --git a/packages/turf-kinks/test/out/triple.geojson b/src/kinks/test/out/triple.geojson similarity index 100% rename from packages/turf-kinks/test/out/triple.geojson rename to src/kinks/test/out/triple.geojson diff --git a/packages/turf-length/bench.js b/src/length/bench.js similarity index 100% rename from packages/turf-length/bench.js rename to src/length/bench.js diff --git a/src/length/index.d.ts b/src/length/index.d.ts new file mode 100644 index 0000000000..bda7f11118 --- /dev/null +++ b/src/length/index.d.ts @@ -0,0 +1,20 @@ +import { Feature, FeatureCollection, GeometryCollection, Units } from "../helpers"; +/** + * Takes a {@link GeoJSON} and measures its length in the specified units, {@link (Multi)Point}'s distance are ignored. + * + * @name length + * @param {Feature} geojson GeoJSON to measure + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units=kilometers] can be degrees, radians, miles, or kilometers + * @returns {number} length of GeoJSON + * @example + * var line = turf.lineString([[115, -32], [131, -22], [143, -25], [150, -34]]); + * var length = turf.length(line, {units: 'miles'}); + * + * //addToMap + * var addToMap = [line]; + * line.properties.distance = length; + */ +export default function length(geojson: Feature | FeatureCollection | GeometryCollection, options?: { + units?: Units; +}): number; diff --git a/src/length/index.js b/src/length/index.js new file mode 100644 index 0000000000..b888be02d8 --- /dev/null +++ b/src/length/index.js @@ -0,0 +1,26 @@ +import distance from "../distance"; +import { segmentReduce } from "../meta"; + +/** + * Takes a {@link GeoJSON} and measures its length in the specified units, {@link (Multi)Point}'s distance are ignored. + * + * @name length + * @param {Feature} geojson GeoJSON to measure + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units=kilometers] can be degrees, radians, miles, or kilometers + * @returns {number} length of GeoJSON + * @example + * var line = turf.lineString([[115, -32], [131, -22], [143, -25], [150, -34]]); + * var length = turf.length(line, {units: 'miles'}); + * + * //addToMap + * var addToMap = [line]; + * line.properties.distance = length; + */ +export default function length(geojson, options) { + // Calculate distance from 2-vertex line segments + return segmentReduce(geojson, function (previousValue, segment) { + const coords = segment.geometry.coordinates; + return previousValue + distance(coords[0], coords[1], options); + }, 0); +} diff --git a/packages/turf-length/test.js b/src/length/test.js similarity index 100% rename from packages/turf-length/test.js rename to src/length/test.js diff --git a/packages/turf-length/test/in/feature-collection.geojson b/src/length/test/in/feature-collection.geojson similarity index 100% rename from packages/turf-length/test/in/feature-collection.geojson rename to src/length/test/in/feature-collection.geojson diff --git a/packages/turf-length/test/in/multi-linestring.geojson b/src/length/test/in/multi-linestring.geojson similarity index 100% rename from packages/turf-length/test/in/multi-linestring.geojson rename to src/length/test/in/multi-linestring.geojson diff --git a/packages/turf-length/test/in/multi-polygon.geojson b/src/length/test/in/multi-polygon.geojson similarity index 100% rename from packages/turf-length/test/in/multi-polygon.geojson rename to src/length/test/in/multi-polygon.geojson diff --git a/packages/turf-length/test/in/polygon.geojson b/src/length/test/in/polygon.geojson similarity index 100% rename from packages/turf-length/test/in/polygon.geojson rename to src/length/test/in/polygon.geojson diff --git a/packages/turf-length/test/in/route1.geojson b/src/length/test/in/route1.geojson similarity index 100% rename from packages/turf-length/test/in/route1.geojson rename to src/length/test/in/route1.geojson diff --git a/packages/turf-length/test/in/route2.geojson b/src/length/test/in/route2.geojson similarity index 100% rename from packages/turf-length/test/in/route2.geojson rename to src/length/test/in/route2.geojson diff --git a/packages/turf-length/test/out/feature-collection.json b/src/length/test/out/feature-collection.json similarity index 100% rename from packages/turf-length/test/out/feature-collection.json rename to src/length/test/out/feature-collection.json diff --git a/packages/turf-length/test/out/multi-linestring.json b/src/length/test/out/multi-linestring.json similarity index 100% rename from packages/turf-length/test/out/multi-linestring.json rename to src/length/test/out/multi-linestring.json diff --git a/packages/turf-length/test/out/multi-polygon.json b/src/length/test/out/multi-polygon.json similarity index 100% rename from packages/turf-length/test/out/multi-polygon.json rename to src/length/test/out/multi-polygon.json diff --git a/packages/turf-length/test/out/polygon.json b/src/length/test/out/polygon.json similarity index 100% rename from packages/turf-length/test/out/polygon.json rename to src/length/test/out/polygon.json diff --git a/packages/turf-length/test/out/route1.json b/src/length/test/out/route1.json similarity index 100% rename from packages/turf-length/test/out/route1.json rename to src/length/test/out/route1.json diff --git a/packages/turf-length/test/out/route2.json b/src/length/test/out/route2.json similarity index 100% rename from packages/turf-length/test/out/route2.json rename to src/length/test/out/route2.json diff --git a/packages/turf-line-arc/bench.js b/src/line-arc/bench.js similarity index 100% rename from packages/turf-line-arc/bench.js rename to src/line-arc/bench.js diff --git a/src/line-arc/index.d.ts b/src/line-arc/index.d.ts new file mode 100644 index 0000000000..fd89d5461e --- /dev/null +++ b/src/line-arc/index.d.ts @@ -0,0 +1,29 @@ +import { Coord, Feature, LineString, Units } from "../helpers"; +/** + * Creates a circular arc, of a circle of the given radius and center point, between bearing1 and bearing2; + * 0 bearing is North of center point, positive clockwise. + * + * @name lineArc + * @param {Coord} center center point + * @param {number} radius radius of the circle + * @param {number} bearing1 angle, in decimal degrees, of the first radius of the arc + * @param {number} bearing2 angle, in decimal degrees, of the second radius of the arc + * @param {Object} [options={}] Optional parameters + * @param {number} [options.steps=64] number of steps + * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians + * @returns {Feature} line arc + * @example + * var center = turf.point([-75, 40]); + * var radius = 5; + * var bearing1 = 25; + * var bearing2 = 47; + * + * var arc = turf.lineArc(center, radius, bearing1, bearing2); + * + * //addToMap + * var addToMap = [center, arc] + */ +export default function lineArc(center: Coord, radius: number, bearing1: number, bearing2: number, options?: { + steps?: number; + units?: Units; +}): Feature; diff --git a/src/line-arc/index.js b/src/line-arc/index.js new file mode 100644 index 0000000000..5cc5b68650 --- /dev/null +++ b/src/line-arc/index.js @@ -0,0 +1,74 @@ +import circle from "../circle"; +import destination from "../destination"; +import { isObject, lineString, checkIfOptionsExist } from "../helpers"; + +/** + * Creates a circular arc, of a circle of the given radius and center point, between bearing1 and bearing2; + * 0 bearing is North of center point, positive clockwise. + * + * @name lineArc + * @param {Coord} center center point + * @param {number} radius radius of the circle + * @param {number} bearing1 angle, in decimal degrees, of the first radius of the arc + * @param {number} bearing2 angle, in decimal degrees, of the second radius of the arc + * @param {Object} [options={}] Optional parameters + * @param {number} [options.steps=64] number of steps + * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians + * @returns {Feature} line arc + * @example + * var center = turf.point([-75, 40]); + * var radius = 5; + * var bearing1 = 25; + * var bearing2 = 47; + * + * var arc = turf.lineArc(center, radius, bearing1, bearing2); + * + * //addToMap + * var addToMap = [center, arc] + */ +export default function lineArc(center, radius, bearing1, bearing2, options) { + options = checkIfOptionsExist(options); + // default params + const steps = options.steps || 64; + + const angle1 = convertAngleTo360(bearing1); + const angle2 = convertAngleTo360(bearing2); + const properties = (!Array.isArray(center) && center.type === "Feature") ? center.properties : {}; + + // handle angle parameters + if (angle1 === angle2) { + return lineString(circle(center, radius, options).geometry.coordinates[0], properties); + } + const arcStartDegree = angle1; + const arcEndDegree = (angle1 < angle2) ? angle2 : angle2 + 360; + + let alfa = arcStartDegree; + const coordinates = []; + let i = 0; + + while (alfa < arcEndDegree) { + coordinates.push(destination(center, radius, alfa, options).geometry.coordinates); + i++; + alfa = arcStartDegree + i * 360 / steps; + } + if (alfa > arcEndDegree) { + coordinates.push(destination(center, radius, arcEndDegree, options).geometry.coordinates); + } + return lineString(coordinates, properties); +} + +/** + * Takes any angle in degrees + * and returns a valid angle between 0-360 degrees + * + * @private + * @param {number} alfa angle between -180-180 degrees + * @returns {number} angle between 0-360 degrees + */ +function convertAngleTo360(alfa) { + let beta = alfa % 360; + if (beta < 0) { + beta += 360; + } + return beta; +} diff --git a/src/line-arc/test.js b/src/line-arc/test.js new file mode 100644 index 0000000000..3dbc942cda --- /dev/null +++ b/src/line-arc/test.js @@ -0,0 +1,33 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const truncate = require('../truncate').default; +const { featureCollection } = require('../helpers'); +const lineArc = require('./index').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-line-arc', t => { + for (const {filename, name, geojson} of fixtures) { + const {radius, bearing1, bearing2, steps, units} = geojson.properties; + const arc = truncate(lineArc(geojson, radius, bearing1, bearing2, steps, units)); + const results = featureCollection([geojson, arc]); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEquals(results, load.sync(directories.out + filename), name); + } + t.end(); +}); diff --git a/packages/turf-line-arc/test/in/line-arc-full-360.geojson b/src/line-arc/test/in/line-arc-full-360.geojson similarity index 100% rename from packages/turf-line-arc/test/in/line-arc-full-360.geojson rename to src/line-arc/test/in/line-arc-full-360.geojson diff --git a/packages/turf-line-arc/test/in/line-arc-greater-360.geojson b/src/line-arc/test/in/line-arc-greater-360.geojson similarity index 100% rename from packages/turf-line-arc/test/in/line-arc-greater-360.geojson rename to src/line-arc/test/in/line-arc-greater-360.geojson diff --git a/packages/turf-line-arc/test/in/line-arc1.geojson b/src/line-arc/test/in/line-arc1.geojson similarity index 100% rename from packages/turf-line-arc/test/in/line-arc1.geojson rename to src/line-arc/test/in/line-arc1.geojson diff --git a/packages/turf-line-arc/test/in/line-arc2.geojson b/src/line-arc/test/in/line-arc2.geojson similarity index 100% rename from packages/turf-line-arc/test/in/line-arc2.geojson rename to src/line-arc/test/in/line-arc2.geojson diff --git a/packages/turf-line-arc/test/in/line-arc3.geojson b/src/line-arc/test/in/line-arc3.geojson similarity index 100% rename from packages/turf-line-arc/test/in/line-arc3.geojson rename to src/line-arc/test/in/line-arc3.geojson diff --git a/packages/turf-line-arc/test/in/line-arc4.geojson b/src/line-arc/test/in/line-arc4.geojson similarity index 100% rename from packages/turf-line-arc/test/in/line-arc4.geojson rename to src/line-arc/test/in/line-arc4.geojson diff --git a/packages/turf-line-arc/test/in/line-arc5.geojson b/src/line-arc/test/in/line-arc5.geojson similarity index 100% rename from packages/turf-line-arc/test/in/line-arc5.geojson rename to src/line-arc/test/in/line-arc5.geojson diff --git a/packages/turf-line-arc/test/in/line-arc6.geojson b/src/line-arc/test/in/line-arc6.geojson similarity index 100% rename from packages/turf-line-arc/test/in/line-arc6.geojson rename to src/line-arc/test/in/line-arc6.geojson diff --git a/packages/turf-line-arc/test/out/line-arc-full-360.geojson b/src/line-arc/test/out/line-arc-full-360.geojson similarity index 100% rename from packages/turf-line-arc/test/out/line-arc-full-360.geojson rename to src/line-arc/test/out/line-arc-full-360.geojson diff --git a/packages/turf-line-arc/test/out/line-arc-greater-360.geojson b/src/line-arc/test/out/line-arc-greater-360.geojson similarity index 100% rename from packages/turf-line-arc/test/out/line-arc-greater-360.geojson rename to src/line-arc/test/out/line-arc-greater-360.geojson diff --git a/packages/turf-line-arc/test/out/line-arc1.geojson b/src/line-arc/test/out/line-arc1.geojson similarity index 100% rename from packages/turf-line-arc/test/out/line-arc1.geojson rename to src/line-arc/test/out/line-arc1.geojson diff --git a/packages/turf-line-arc/test/out/line-arc2.geojson b/src/line-arc/test/out/line-arc2.geojson similarity index 100% rename from packages/turf-line-arc/test/out/line-arc2.geojson rename to src/line-arc/test/out/line-arc2.geojson diff --git a/packages/turf-line-arc/test/out/line-arc3.geojson b/src/line-arc/test/out/line-arc3.geojson similarity index 100% rename from packages/turf-line-arc/test/out/line-arc3.geojson rename to src/line-arc/test/out/line-arc3.geojson diff --git a/packages/turf-line-arc/test/out/line-arc4.geojson b/src/line-arc/test/out/line-arc4.geojson similarity index 100% rename from packages/turf-line-arc/test/out/line-arc4.geojson rename to src/line-arc/test/out/line-arc4.geojson diff --git a/packages/turf-line-arc/test/out/line-arc5.geojson b/src/line-arc/test/out/line-arc5.geojson similarity index 100% rename from packages/turf-line-arc/test/out/line-arc5.geojson rename to src/line-arc/test/out/line-arc5.geojson diff --git a/packages/turf-line-arc/test/out/line-arc6.geojson b/src/line-arc/test/out/line-arc6.geojson similarity index 100% rename from packages/turf-line-arc/test/out/line-arc6.geojson rename to src/line-arc/test/out/line-arc6.geojson diff --git a/packages/turf-line-chunk/bench.js b/src/line-chunk/bench.js similarity index 100% rename from packages/turf-line-chunk/bench.js rename to src/line-chunk/bench.js diff --git a/src/line-chunk/index.d.ts b/src/line-chunk/index.d.ts new file mode 100644 index 0000000000..4277701902 --- /dev/null +++ b/src/line-chunk/index.d.ts @@ -0,0 +1,20 @@ +import { + LineString, + MultiLineString, + GeometryCollection, + Units, + Feature, + FeatureCollection, +} from '../helpers' + +/** + * http://turfjs.org/docs/#linechunk + */ +export default function lineChunk( + geojson: Feature | FeatureCollection | T | GeometryCollection| Feature, + segmentLength: number, + options?: { + units?: Units, + reverse?: boolean + } +): FeatureCollection; diff --git a/src/line-chunk/index.js b/src/line-chunk/index.js new file mode 100644 index 0000000000..93ddcb4893 --- /dev/null +++ b/src/line-chunk/index.js @@ -0,0 +1,80 @@ +import length from '../length'; +import lineSliceAlong from '../line-slice-along'; +import { flattenEach } from '../meta'; +import { featureCollection, isObject } from '../helpers'; + +/** + * Divides a {@link LineString} into chunks of a specified length. + * If the line is shorter than the segment length then the original line is returned. + * + * @name lineChunk + * @param {FeatureCollection|Geometry|Feature} geojson the lines to split + * @param {number} segmentLength how long to make each segment + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] units can be degrees, radians, miles, or kilometers + * @param {boolean} [options.reverse=false] reverses coordinates to start the first chunked segment at the end + * @returns {FeatureCollection} collection of line segments + * @example + * var line = turf.lineString([[-95, 40], [-93, 45], [-85, 50]]); + * + * var chunk = turf.lineChunk(line, 15, {units: 'miles'}); + * + * //addToMap + * var addToMap = [chunk]; + */ +function lineChunk(geojson, segmentLength, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var units = options.units; + var reverse = options.reverse; + + // Validation + if (!geojson) throw new Error('geojson is required'); + if (segmentLength <= 0) throw new Error('segmentLength must be greater than 0'); + + // Container + var results = []; + + // Flatten each feature to simple LineString + flattenEach(geojson, function (feature) { + // reverses coordinates to start the first chunked segment at the end + if (reverse) feature.geometry.coordinates = feature.geometry.coordinates.reverse(); + + sliceLineSegments(feature, segmentLength, units, function (segment) { + results.push(segment); + }); + }); + return featureCollection(results); +} + +/** + * Slice Line Segments + * + * @private + * @param {Feature} line GeoJSON LineString + * @param {number} segmentLength how long to make each segment + * @param {string}[units='kilometers'] units can be degrees, radians, miles, or kilometers + * @param {Function} callback iterate over sliced line segments + * @returns {void} + */ +function sliceLineSegments(line, segmentLength, units, callback) { + var lineLength = length(line, {units: units}); + + // If the line is shorter than the segment length then the orginal line is returned. + if (lineLength <= segmentLength) return callback(line); + + var numberOfSegments = lineLength / segmentLength; + + // If numberOfSegments is integer, no need to plus 1 + if (!Number.isInteger(numberOfSegments)) { + numberOfSegments = Math.floor(numberOfSegments) + 1; + } + + for (var i = 0; i < numberOfSegments; i++) { + var outline = lineSliceAlong(line, segmentLength * i, segmentLength * (i + 1), {units: units}); + callback(outline, i); + } +} + +export default lineChunk; diff --git a/src/line-chunk/test.js b/src/line-chunk/test.js new file mode 100644 index 0000000000..73f808f235 --- /dev/null +++ b/src/line-chunk/test.js @@ -0,0 +1,89 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import truncate from '../truncate'; +import { featureEach } from '../meta'; +import { lineString, featureCollection } from '../helpers'; +import lineChunk from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return {filename, geojson: load.sync(directories.in + filename)}; +}); + +test('turf-line-chunk: shorter', t => { + for (let {filename, geojson} of fixtures) { + const chunked = colorize(truncate(lineChunk(geojson, 5, {units: 'miles'}))); + filename = filename.replace('.geojson', '.shorter.geojson'); + if (process.env.REGEN) { write.sync(directories.out + filename, chunked); } + + const expected = load.sync(directories.out + filename); + t.deepEquals(chunked, expected, path.parse(filename).name); + } + t.end(); +}); + +test('turf-line-chunk: longer', t => { + for (let {filename, geojson} of fixtures) { + const chunked = colorize(truncate(lineChunk(geojson, 50, {units: 'miles'}))); + filename = filename.replace('.geojson', '.longer.geojson'); + if (process.env.REGEN) { write.sync(directories.out + filename, chunked); } + + const expected = load.sync(directories.out + filename); + t.deepEquals(chunked, expected, path.parse(filename).name); + } + t.end(); +}); + +test('turf-line-chunk: reverse', t => { + for (let {filename, geojson} of fixtures) { + const chunked = colorize(truncate(lineChunk(geojson, 5, {units: 'miles', reverse: true}))); + filename = filename.replace('.geojson', '.reverse.geojson'); + if (process.env.REGEN) write.sync(directories.out + filename, chunked); + + const expected = load.sync(directories.out + filename); + t.deepEquals(chunked, expected, path.parse(filename).name); + } + t.end(); +}); + +test('turf-line-chunk: Support Geometry Objects', t => { + const line = lineString([[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]); + t.assert(lineChunk(line.geometry, 10), 'support geometry objects'); + t.end(); +}); + +test('turf-line-chunk: Prevent input mutation', t => { + const line = lineString([[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]); + const before = JSON.parse(JSON.stringify(line)); + lineChunk(line, 10); + t.deepEqual(line, before, 'input should not mutate'); + t.end(); +}); + +/** + * Colorize FeatureCollection + * + * @param {FeatureCollection|Feature} geojson Feature or FeatureCollection + * @returns {FeatureCollection} colorized FeatureCollection + */ +function colorize(geojson) { + const results = []; + featureEach(geojson, (feature, index) => { + const r = (index % 2 === 0) ? 'F' : '0'; + const g = (index % 2 === 0) ? '0' : '0'; + const b = (index % 2 === 0) ? '0' : 'F'; + feature.properties = Object.assign({ + stroke: '#' + r + g + b, + 'stroke-width': 10 + }, feature.properties); + results.push(feature); + }); + return featureCollection(results); +} diff --git a/packages/turf-line-chunk/test/in/FeatureCollection.geojson b/src/line-chunk/test/in/FeatureCollection.geojson similarity index 100% rename from packages/turf-line-chunk/test/in/FeatureCollection.geojson rename to src/line-chunk/test/in/FeatureCollection.geojson diff --git a/packages/turf-line-chunk/test/in/GeometryCollection.geojson b/src/line-chunk/test/in/GeometryCollection.geojson similarity index 100% rename from packages/turf-line-chunk/test/in/GeometryCollection.geojson rename to src/line-chunk/test/in/GeometryCollection.geojson diff --git a/packages/turf-line-chunk/test/in/LineString.geojson b/src/line-chunk/test/in/LineString.geojson similarity index 100% rename from packages/turf-line-chunk/test/in/LineString.geojson rename to src/line-chunk/test/in/LineString.geojson diff --git a/packages/turf-line-chunk/test/in/MultiLineString.geojson b/src/line-chunk/test/in/MultiLineString.geojson similarity index 100% rename from packages/turf-line-chunk/test/in/MultiLineString.geojson rename to src/line-chunk/test/in/MultiLineString.geojson diff --git a/packages/turf-line-chunk/test/out/FeatureCollection.longer.geojson b/src/line-chunk/test/out/FeatureCollection.longer.geojson similarity index 100% rename from packages/turf-line-chunk/test/out/FeatureCollection.longer.geojson rename to src/line-chunk/test/out/FeatureCollection.longer.geojson diff --git a/packages/turf-line-chunk/test/out/FeatureCollection.reverse.geojson b/src/line-chunk/test/out/FeatureCollection.reverse.geojson similarity index 80% rename from packages/turf-line-chunk/test/out/FeatureCollection.reverse.geojson rename to src/line-chunk/test/out/FeatureCollection.reverse.geojson index 15ea217610..50fb38c75e 100644 --- a/packages/turf-line-chunk/test/out/FeatureCollection.reverse.geojson +++ b/src/line-chunk/test/out/FeatureCollection.reverse.geojson @@ -15,8 +15,8 @@ 40.155786 ], [ - -85.865993, - 40.125739 + -85.86597, + 40.125699 ] ] } @@ -31,12 +31,12 @@ "type": "LineString", "coordinates": [ [ - -85.865993, - 40.125739 + -85.86597, + 40.125699 ], [ - -85.952033, - 40.095627 + -85.952024, + 40.095613 ] ] } @@ -51,15 +51,15 @@ "type": "LineString", "coordinates": [ [ - -85.952033, - 40.095627 + -85.952024, + 40.095613 ], [ -85.972137, 40.088579 ], [ - -85.98051, + -85.980512, 40.143655 ] ] @@ -75,7 +75,7 @@ "type": "LineString", "coordinates": [ [ - -85.98051, + -85.980512, 40.143655 ], [ @@ -83,8 +83,8 @@ 40.178873 ], [ - -86.031972, - 40.189915 + -86.031992, + 40.189864 ] ] } @@ -99,12 +99,12 @@ "type": "LineString", "coordinates": [ [ - -86.031972, - 40.189915 + -86.031992, + 40.189864 ], [ - -86.122401, - 40.211509 + -86.12244, + 40.211413 ] ] } @@ -119,12 +119,12 @@ "type": "LineString", "coordinates": [ [ - -86.122401, - 40.211509 + -86.12244, + 40.211413 ], [ - -86.212888, - 40.233033 + -86.212916, + 40.232962 ] ] } @@ -139,8 +139,8 @@ "type": "LineString", "coordinates": [ [ - -86.212888, - 40.233033 + -86.212916, + 40.232962 ], [ -86.285248, @@ -163,8 +163,8 @@ 39.95607 ], [ - -86.027363, - 39.936651 + -86.027333, + 39.93657 ] ] } @@ -179,12 +179,12 @@ "type": "LineString", "coordinates": [ [ - -86.027363, - 39.936651 + -86.027333, + 39.93657 ], [ - -86.118242, - 39.917161 + -86.118208, + 39.91707 ] ] } @@ -199,12 +199,12 @@ "type": "LineString", "coordinates": [ [ - -86.118242, - 39.917161 + -86.118208, + 39.91707 ], [ - -86.209069, - 39.897601 + -86.209057, + 39.897569 ] ] } @@ -219,16 +219,16 @@ "type": "LineString", "coordinates": [ [ - -86.209069, - 39.897601 + -86.209057, + 39.897569 ], [ -86.235809, 39.891826 ], [ - -86.246098, - 39.942266 + -86.246115, + 39.942263 ] ] } @@ -243,12 +243,12 @@ "type": "LineString", "coordinates": [ [ - -86.246098, - 39.942266 + -86.246115, + 39.942263 ], [ - -86.260707, - 40.01376 + -86.260736, + 40.013757 ] ] } @@ -263,12 +263,12 @@ "type": "LineString", "coordinates": [ [ - -86.260707, - 40.01376 + -86.260736, + 40.013757 ], [ - -86.275347, - 40.085253 + -86.275373, + 40.08525 ] ] } @@ -283,12 +283,12 @@ "type": "LineString", "coordinates": [ [ - -86.275347, - 40.085253 + -86.275373, + 40.08525 ], [ - -86.290018, - 40.156744 + -86.290025, + 40.156743 ] ] } @@ -303,8 +303,8 @@ "type": "LineString", "coordinates": [ [ - -86.290018, - 40.156744 + -86.290025, + 40.156743 ], [ -86.293488, diff --git a/packages/turf-line-chunk/test/out/FeatureCollection.shorter.geojson b/src/line-chunk/test/out/FeatureCollection.shorter.geojson similarity index 80% rename from packages/turf-line-chunk/test/out/FeatureCollection.shorter.geojson rename to src/line-chunk/test/out/FeatureCollection.shorter.geojson index 82175f6377..ad4b979660 100644 --- a/packages/turf-line-chunk/test/out/FeatureCollection.shorter.geojson +++ b/src/line-chunk/test/out/FeatureCollection.shorter.geojson @@ -15,8 +15,8 @@ 40.250184 ], [ - -86.194715, - 40.228717 + -86.194748, + 40.228635 ] ] } @@ -31,12 +31,12 @@ "type": "LineString", "coordinates": [ [ - -86.194715, - 40.228717 + -86.194748, + 40.228635 ], [ - -86.10424, - 40.207179 + -86.104278, + 40.207087 ] ] } @@ -51,12 +51,12 @@ "type": "LineString", "coordinates": [ [ - -86.10424, - 40.207179 + -86.104278, + 40.207087 ], [ - -86.013822, - 40.18557 + -86.013836, + 40.185538 ] ] } @@ -71,15 +71,15 @@ "type": "LineString", "coordinates": [ [ - -86.013822, - 40.18557 + -86.013836, + 40.185538 ], [ -85.98587, 40.178873 ], [ - -85.978314, + -85.978317, 40.129223 ] ] @@ -95,7 +95,7 @@ "type": "LineString", "coordinates": [ [ - -85.978314, + -85.978317, 40.129223 ], [ @@ -103,8 +103,8 @@ 40.088579 ], [ - -85.934764, - 40.101678 + -85.934749, + 40.101653 ] ] } @@ -119,12 +119,12 @@ "type": "LineString", "coordinates": [ [ - -85.934764, - 40.101678 + -85.934749, + 40.101653 ], [ - -85.848709, - 40.131777 + -85.848687, + 40.13174 ] ] } @@ -139,8 +139,8 @@ "type": "LineString", "coordinates": [ [ - -85.848709, - 40.131777 + -85.848687, + 40.13174 ], [ -85.779877, @@ -163,8 +163,8 @@ 40.173627 ], [ - -86.278809, - 40.102136 + -86.278832, + 40.102134 ] ] } @@ -179,12 +179,12 @@ "type": "LineString", "coordinates": [ [ - -86.278809, - 40.102136 + -86.278832, + 40.102134 ], [ - -86.264162, - 40.030644 + -86.264192, + 40.030641 ] ] } @@ -199,12 +199,12 @@ "type": "LineString", "coordinates": [ [ - -86.264162, - 40.030644 + -86.264192, + 40.030641 ], [ - -86.249545, - 39.95915 + -86.249567, + 39.959147 ] ] } @@ -219,16 +219,16 @@ "type": "LineString", "coordinates": [ [ - -86.249545, - 39.95915 + -86.249567, + 39.959147 ], [ -86.235809, 39.891826 ], [ - -86.230511, - 39.892971 + -86.230509, + 39.892964 ] ] } @@ -243,12 +243,12 @@ "type": "LineString", "coordinates": [ [ - -86.230511, - 39.892971 + -86.230509, + 39.892964 ], [ - -86.139696, - 39.912548 + -86.139666, + 39.912464 ] ] } @@ -263,12 +263,12 @@ "type": "LineString", "coordinates": [ [ - -86.139696, - 39.912548 + -86.139666, + 39.912464 ], [ - -86.048829, - 39.932055 + -86.048797, + 39.931964 ] ] } @@ -283,12 +283,12 @@ "type": "LineString", "coordinates": [ [ - -86.048829, - 39.932055 + -86.048797, + 39.931964 ], [ - -85.957911, - 39.95149 + -85.957902, + 39.951465 ] ] } @@ -303,8 +303,8 @@ "type": "LineString", "coordinates": [ [ - -85.957911, - 39.95149 + -85.957902, + 39.951465 ], [ -85.936432, diff --git a/packages/turf-line-chunk/test/out/GeometryCollection.longer.geojson b/src/line-chunk/test/out/GeometryCollection.longer.geojson similarity index 100% rename from packages/turf-line-chunk/test/out/GeometryCollection.longer.geojson rename to src/line-chunk/test/out/GeometryCollection.longer.geojson diff --git a/packages/turf-line-chunk/test/out/GeometryCollection.reverse.geojson b/src/line-chunk/test/out/GeometryCollection.reverse.geojson similarity index 80% rename from packages/turf-line-chunk/test/out/GeometryCollection.reverse.geojson rename to src/line-chunk/test/out/GeometryCollection.reverse.geojson index 15ea217610..50fb38c75e 100644 --- a/packages/turf-line-chunk/test/out/GeometryCollection.reverse.geojson +++ b/src/line-chunk/test/out/GeometryCollection.reverse.geojson @@ -15,8 +15,8 @@ 40.155786 ], [ - -85.865993, - 40.125739 + -85.86597, + 40.125699 ] ] } @@ -31,12 +31,12 @@ "type": "LineString", "coordinates": [ [ - -85.865993, - 40.125739 + -85.86597, + 40.125699 ], [ - -85.952033, - 40.095627 + -85.952024, + 40.095613 ] ] } @@ -51,15 +51,15 @@ "type": "LineString", "coordinates": [ [ - -85.952033, - 40.095627 + -85.952024, + 40.095613 ], [ -85.972137, 40.088579 ], [ - -85.98051, + -85.980512, 40.143655 ] ] @@ -75,7 +75,7 @@ "type": "LineString", "coordinates": [ [ - -85.98051, + -85.980512, 40.143655 ], [ @@ -83,8 +83,8 @@ 40.178873 ], [ - -86.031972, - 40.189915 + -86.031992, + 40.189864 ] ] } @@ -99,12 +99,12 @@ "type": "LineString", "coordinates": [ [ - -86.031972, - 40.189915 + -86.031992, + 40.189864 ], [ - -86.122401, - 40.211509 + -86.12244, + 40.211413 ] ] } @@ -119,12 +119,12 @@ "type": "LineString", "coordinates": [ [ - -86.122401, - 40.211509 + -86.12244, + 40.211413 ], [ - -86.212888, - 40.233033 + -86.212916, + 40.232962 ] ] } @@ -139,8 +139,8 @@ "type": "LineString", "coordinates": [ [ - -86.212888, - 40.233033 + -86.212916, + 40.232962 ], [ -86.285248, @@ -163,8 +163,8 @@ 39.95607 ], [ - -86.027363, - 39.936651 + -86.027333, + 39.93657 ] ] } @@ -179,12 +179,12 @@ "type": "LineString", "coordinates": [ [ - -86.027363, - 39.936651 + -86.027333, + 39.93657 ], [ - -86.118242, - 39.917161 + -86.118208, + 39.91707 ] ] } @@ -199,12 +199,12 @@ "type": "LineString", "coordinates": [ [ - -86.118242, - 39.917161 + -86.118208, + 39.91707 ], [ - -86.209069, - 39.897601 + -86.209057, + 39.897569 ] ] } @@ -219,16 +219,16 @@ "type": "LineString", "coordinates": [ [ - -86.209069, - 39.897601 + -86.209057, + 39.897569 ], [ -86.235809, 39.891826 ], [ - -86.246098, - 39.942266 + -86.246115, + 39.942263 ] ] } @@ -243,12 +243,12 @@ "type": "LineString", "coordinates": [ [ - -86.246098, - 39.942266 + -86.246115, + 39.942263 ], [ - -86.260707, - 40.01376 + -86.260736, + 40.013757 ] ] } @@ -263,12 +263,12 @@ "type": "LineString", "coordinates": [ [ - -86.260707, - 40.01376 + -86.260736, + 40.013757 ], [ - -86.275347, - 40.085253 + -86.275373, + 40.08525 ] ] } @@ -283,12 +283,12 @@ "type": "LineString", "coordinates": [ [ - -86.275347, - 40.085253 + -86.275373, + 40.08525 ], [ - -86.290018, - 40.156744 + -86.290025, + 40.156743 ] ] } @@ -303,8 +303,8 @@ "type": "LineString", "coordinates": [ [ - -86.290018, - 40.156744 + -86.290025, + 40.156743 ], [ -86.293488, diff --git a/packages/turf-line-chunk/test/out/GeometryCollection.shorter.geojson b/src/line-chunk/test/out/GeometryCollection.shorter.geojson similarity index 80% rename from packages/turf-line-chunk/test/out/GeometryCollection.shorter.geojson rename to src/line-chunk/test/out/GeometryCollection.shorter.geojson index 82175f6377..ad4b979660 100644 --- a/packages/turf-line-chunk/test/out/GeometryCollection.shorter.geojson +++ b/src/line-chunk/test/out/GeometryCollection.shorter.geojson @@ -15,8 +15,8 @@ 40.250184 ], [ - -86.194715, - 40.228717 + -86.194748, + 40.228635 ] ] } @@ -31,12 +31,12 @@ "type": "LineString", "coordinates": [ [ - -86.194715, - 40.228717 + -86.194748, + 40.228635 ], [ - -86.10424, - 40.207179 + -86.104278, + 40.207087 ] ] } @@ -51,12 +51,12 @@ "type": "LineString", "coordinates": [ [ - -86.10424, - 40.207179 + -86.104278, + 40.207087 ], [ - -86.013822, - 40.18557 + -86.013836, + 40.185538 ] ] } @@ -71,15 +71,15 @@ "type": "LineString", "coordinates": [ [ - -86.013822, - 40.18557 + -86.013836, + 40.185538 ], [ -85.98587, 40.178873 ], [ - -85.978314, + -85.978317, 40.129223 ] ] @@ -95,7 +95,7 @@ "type": "LineString", "coordinates": [ [ - -85.978314, + -85.978317, 40.129223 ], [ @@ -103,8 +103,8 @@ 40.088579 ], [ - -85.934764, - 40.101678 + -85.934749, + 40.101653 ] ] } @@ -119,12 +119,12 @@ "type": "LineString", "coordinates": [ [ - -85.934764, - 40.101678 + -85.934749, + 40.101653 ], [ - -85.848709, - 40.131777 + -85.848687, + 40.13174 ] ] } @@ -139,8 +139,8 @@ "type": "LineString", "coordinates": [ [ - -85.848709, - 40.131777 + -85.848687, + 40.13174 ], [ -85.779877, @@ -163,8 +163,8 @@ 40.173627 ], [ - -86.278809, - 40.102136 + -86.278832, + 40.102134 ] ] } @@ -179,12 +179,12 @@ "type": "LineString", "coordinates": [ [ - -86.278809, - 40.102136 + -86.278832, + 40.102134 ], [ - -86.264162, - 40.030644 + -86.264192, + 40.030641 ] ] } @@ -199,12 +199,12 @@ "type": "LineString", "coordinates": [ [ - -86.264162, - 40.030644 + -86.264192, + 40.030641 ], [ - -86.249545, - 39.95915 + -86.249567, + 39.959147 ] ] } @@ -219,16 +219,16 @@ "type": "LineString", "coordinates": [ [ - -86.249545, - 39.95915 + -86.249567, + 39.959147 ], [ -86.235809, 39.891826 ], [ - -86.230511, - 39.892971 + -86.230509, + 39.892964 ] ] } @@ -243,12 +243,12 @@ "type": "LineString", "coordinates": [ [ - -86.230511, - 39.892971 + -86.230509, + 39.892964 ], [ - -86.139696, - 39.912548 + -86.139666, + 39.912464 ] ] } @@ -263,12 +263,12 @@ "type": "LineString", "coordinates": [ [ - -86.139696, - 39.912548 + -86.139666, + 39.912464 ], [ - -86.048829, - 39.932055 + -86.048797, + 39.931964 ] ] } @@ -283,12 +283,12 @@ "type": "LineString", "coordinates": [ [ - -86.048829, - 39.932055 + -86.048797, + 39.931964 ], [ - -85.957911, - 39.95149 + -85.957902, + 39.951465 ] ] } @@ -303,8 +303,8 @@ "type": "LineString", "coordinates": [ [ - -85.957911, - 39.95149 + -85.957902, + 39.951465 ], [ -85.936432, diff --git a/packages/turf-line-chunk/test/out/LineString.longer.geojson b/src/line-chunk/test/out/LineString.longer.geojson similarity index 100% rename from packages/turf-line-chunk/test/out/LineString.longer.geojson rename to src/line-chunk/test/out/LineString.longer.geojson diff --git a/packages/turf-line-chunk/test/out/LineString.reverse.geojson b/src/line-chunk/test/out/LineString.reverse.geojson similarity index 81% rename from packages/turf-line-chunk/test/out/LineString.reverse.geojson rename to src/line-chunk/test/out/LineString.reverse.geojson index 075bd73445..ccbaca82bd 100644 --- a/packages/turf-line-chunk/test/out/LineString.reverse.geojson +++ b/src/line-chunk/test/out/LineString.reverse.geojson @@ -15,8 +15,8 @@ 40.155786 ], [ - -85.865993, - 40.125739 + -85.86597, + 40.125699 ] ] } @@ -31,12 +31,12 @@ "type": "LineString", "coordinates": [ [ - -85.865993, - 40.125739 + -85.86597, + 40.125699 ], [ - -85.952033, - 40.095627 + -85.952024, + 40.095613 ] ] } @@ -51,15 +51,15 @@ "type": "LineString", "coordinates": [ [ - -85.952033, - 40.095627 + -85.952024, + 40.095613 ], [ -85.972137, 40.088579 ], [ - -85.98051, + -85.980512, 40.143655 ] ] @@ -75,7 +75,7 @@ "type": "LineString", "coordinates": [ [ - -85.98051, + -85.980512, 40.143655 ], [ @@ -83,8 +83,8 @@ 40.178873 ], [ - -86.031972, - 40.189915 + -86.031992, + 40.189864 ] ] } @@ -99,12 +99,12 @@ "type": "LineString", "coordinates": [ [ - -86.031972, - 40.189915 + -86.031992, + 40.189864 ], [ - -86.122401, - 40.211509 + -86.12244, + 40.211413 ] ] } @@ -119,12 +119,12 @@ "type": "LineString", "coordinates": [ [ - -86.122401, - 40.211509 + -86.12244, + 40.211413 ], [ - -86.212888, - 40.233033 + -86.212916, + 40.232962 ] ] } @@ -139,8 +139,8 @@ "type": "LineString", "coordinates": [ [ - -86.212888, - 40.233033 + -86.212916, + 40.232962 ], [ -86.285248, diff --git a/packages/turf-line-chunk/test/out/LineString.shorter.geojson b/src/line-chunk/test/out/LineString.shorter.geojson similarity index 81% rename from packages/turf-line-chunk/test/out/LineString.shorter.geojson rename to src/line-chunk/test/out/LineString.shorter.geojson index 8a02365bfd..a5d62df80c 100644 --- a/packages/turf-line-chunk/test/out/LineString.shorter.geojson +++ b/src/line-chunk/test/out/LineString.shorter.geojson @@ -15,8 +15,8 @@ 40.250184 ], [ - -86.194715, - 40.228717 + -86.194748, + 40.228635 ] ] } @@ -31,12 +31,12 @@ "type": "LineString", "coordinates": [ [ - -86.194715, - 40.228717 + -86.194748, + 40.228635 ], [ - -86.10424, - 40.207179 + -86.104278, + 40.207087 ] ] } @@ -51,12 +51,12 @@ "type": "LineString", "coordinates": [ [ - -86.10424, - 40.207179 + -86.104278, + 40.207087 ], [ - -86.013822, - 40.18557 + -86.013836, + 40.185538 ] ] } @@ -71,15 +71,15 @@ "type": "LineString", "coordinates": [ [ - -86.013822, - 40.18557 + -86.013836, + 40.185538 ], [ -85.98587, 40.178873 ], [ - -85.978314, + -85.978317, 40.129223 ] ] @@ -95,7 +95,7 @@ "type": "LineString", "coordinates": [ [ - -85.978314, + -85.978317, 40.129223 ], [ @@ -103,8 +103,8 @@ 40.088579 ], [ - -85.934764, - 40.101678 + -85.934749, + 40.101653 ] ] } @@ -119,12 +119,12 @@ "type": "LineString", "coordinates": [ [ - -85.934764, - 40.101678 + -85.934749, + 40.101653 ], [ - -85.848709, - 40.131777 + -85.848687, + 40.13174 ] ] } @@ -139,8 +139,8 @@ "type": "LineString", "coordinates": [ [ - -85.848709, - 40.131777 + -85.848687, + 40.13174 ], [ -85.779877, diff --git a/packages/turf-line-chunk/test/out/MultiLineString.longer.geojson b/src/line-chunk/test/out/MultiLineString.longer.geojson similarity index 100% rename from packages/turf-line-chunk/test/out/MultiLineString.longer.geojson rename to src/line-chunk/test/out/MultiLineString.longer.geojson diff --git a/packages/turf-line-chunk/test/out/MultiLineString.reverse.geojson b/src/line-chunk/test/out/MultiLineString.reverse.geojson similarity index 82% rename from packages/turf-line-chunk/test/out/MultiLineString.reverse.geojson rename to src/line-chunk/test/out/MultiLineString.reverse.geojson index 33ec0af90d..aa2f5ee716 100644 --- a/packages/turf-line-chunk/test/out/MultiLineString.reverse.geojson +++ b/src/line-chunk/test/out/MultiLineString.reverse.geojson @@ -15,8 +15,8 @@ 40.178873 ], [ - -86.07627, - 40.200503 + -86.076303, + 40.200422 ] ] } @@ -31,12 +31,12 @@ "type": "LineString", "coordinates": [ [ - -86.07627, - 40.200503 + -86.076303, + 40.200422 ], [ - -86.166728, - 40.222063 + -86.166765, + 40.221971 ] ] } @@ -51,12 +51,12 @@ "type": "LineString", "coordinates": [ [ - -86.166728, - 40.222063 + -86.166765, + 40.221971 ], [ - -86.257243, - 40.243552 + -86.257256, + 40.24352 ] ] } @@ -71,8 +71,8 @@ "type": "LineString", "coordinates": [ [ - -86.257243, - 40.243552 + -86.257256, + 40.24352 ], [ -86.285248, @@ -95,8 +95,8 @@ 40.155786 ], [ - -85.865993, - 40.125739 + -85.86597, + 40.125699 ] ] } @@ -111,12 +111,12 @@ "type": "LineString", "coordinates": [ [ - -85.865993, - 40.125739 + -85.86597, + 40.125699 ], [ - -85.952033, - 40.095627 + -85.952024, + 40.095613 ] ] } @@ -131,8 +131,8 @@ "type": "LineString", "coordinates": [ [ - -85.952033, - 40.095627 + -85.952024, + 40.095613 ], [ -85.972137, diff --git a/packages/turf-line-chunk/test/out/MultiLineString.shorter.geojson b/src/line-chunk/test/out/MultiLineString.shorter.geojson similarity index 82% rename from packages/turf-line-chunk/test/out/MultiLineString.shorter.geojson rename to src/line-chunk/test/out/MultiLineString.shorter.geojson index 161474bffd..8f706ca067 100644 --- a/packages/turf-line-chunk/test/out/MultiLineString.shorter.geojson +++ b/src/line-chunk/test/out/MultiLineString.shorter.geojson @@ -15,8 +15,8 @@ 40.250184 ], [ - -86.194715, - 40.228717 + -86.194748, + 40.228635 ] ] } @@ -31,12 +31,12 @@ "type": "LineString", "coordinates": [ [ - -86.194715, - 40.228717 + -86.194748, + 40.228635 ], [ - -86.10424, - 40.207179 + -86.104278, + 40.207087 ] ] } @@ -51,12 +51,12 @@ "type": "LineString", "coordinates": [ [ - -86.10424, - 40.207179 + -86.104278, + 40.207087 ], [ - -86.013822, - 40.18557 + -86.013836, + 40.185538 ] ] } @@ -71,8 +71,8 @@ "type": "LineString", "coordinates": [ [ - -86.013822, - 40.18557 + -86.013836, + 40.185538 ], [ -85.98587, @@ -95,8 +95,8 @@ 40.088579 ], [ - -85.886115, - 40.118705 + -85.886092, + 40.118665 ] ] } @@ -111,12 +111,12 @@ "type": "LineString", "coordinates": [ [ - -85.886115, - 40.118705 + -85.886092, + 40.118665 ], [ - -85.800016, - 40.148767 + -85.800008, + 40.148752 ] ] } @@ -131,8 +131,8 @@ "type": "LineString", "coordinates": [ [ - -85.800016, - 40.148767 + -85.800008, + 40.148752 ], [ -85.779877, diff --git a/packages/turf-line-intersect/bench.js b/src/line-intersect/bench.js similarity index 100% rename from packages/turf-line-intersect/bench.js rename to src/line-intersect/bench.js diff --git a/src/line-intersect/index.d.ts b/src/line-intersect/index.d.ts new file mode 100644 index 0000000000..5978d787c2 --- /dev/null +++ b/src/line-intersect/index.d.ts @@ -0,0 +1,18 @@ +import { Feature, FeatureCollection, LineString, MultiLineString, MultiPolygon, Point, Polygon } from "../helpers"; +/** + * Takes any LineString or Polygon GeoJSON and returns the intersecting point(s). + * + * @name lineIntersect + * @param {GeoJSON} line1 any LineString or Polygon + * @param {GeoJSON} line2 any LineString or Polygon + * @returns {FeatureCollection} point(s) that intersect both + * @example + * var line1 = turf.lineString([[126, -11], [129, -21]]); + * var line2 = turf.lineString([[123, -18], [131, -14]]); + * var intersects = turf.lineIntersect(line1, line2); + * + * //addToMap + * var addToMap = [line1, line2, intersects] + */ +declare function lineIntersect(line1: FeatureCollection | Feature | G1, line2: FeatureCollection | Feature | G2): FeatureCollection; +export default lineIntersect; diff --git a/src/line-intersect/index.js b/src/line-intersect/index.js new file mode 100644 index 0000000000..656ceb6642 --- /dev/null +++ b/src/line-intersect/index.js @@ -0,0 +1,110 @@ +import { feature, featureCollection, point } from '../helpers'; +import { getCoords } from '../invariant'; +import lineSegment from '../line-segment'; +import { featureEach } from '../meta'; +import rbush from '../spatial-index'; + +/** + * Takes any LineString or Polygon GeoJSON and returns the intersecting point(s). + * + * @name lineIntersect + * @param {GeoJSON} line1 any LineString or Polygon + * @param {GeoJSON} line2 any LineString or Polygon + * @returns {FeatureCollection} point(s) that intersect both + * @example + * var line1 = turf.lineString([[126, -11], [129, -21]]); + * var line2 = turf.lineString([[123, -18], [131, -14]]); + * var intersects = turf.lineIntersect(line1, line2); + * + * //addToMap + * var addToMap = [line1, line2, intersects] + */ +function lineIntersect(line1, line2) { + const unique = {}; + const results = []; + + // First, normalize geometries to features + // Then, handle simple 2-vertex segments + if (line1.type === 'LineString') { line1 = feature(line1); } + if (line2.type === 'LineString') { line2 = feature(line2); } + if (line1.type === 'Feature' && + line2.type === 'Feature' && + line1.geometry !== null && + line2.geometry !== null && + line1.geometry.type === 'LineString' && + line2.geometry.type === 'LineString' && + line1.geometry.coordinates.length === 2 && + line2.geometry.coordinates.length === 2) { + const intersect = intersects(line1, line2); + if (intersect) { results.push(intersect); } + return featureCollection(results); + } + + // Handles complex GeoJSON Geometries + const tree = rbush(); + tree.load(lineSegment(line2)); + featureEach(lineSegment(line1), function (segment) { + featureEach(tree.search(segment), function (match) { + const intersect = intersects(segment, match); + if (intersect) { + // prevent duplicate points https://github.com/Turfjs/turf/issues/688 + const key = getCoords(intersect).join(','); + if (!unique[key]) { + unique[key] = true; + results.push(intersect); + } + } + }); + }); + return featureCollection(results); +} + +/** + * Find a point that intersects LineStrings with two coordinates each + * + * @private + * @param {Feature} line1 GeoJSON LineString (Must only contain 2 coordinates) + * @param {Feature} line2 GeoJSON LineString (Must only contain 2 coordinates) + * @returns {Feature} intersecting GeoJSON Point + */ +function intersects(line1, line2) { + const coords1 = getCoords(line1); + const coords2 = getCoords(line2); + if (coords1.length !== 2) { + throw new Error(' line1 must only contain 2 coordinates'); + } + if (coords2.length !== 2) { + throw new Error(' line2 must only contain 2 coordinates'); + } + const x1 = coords1[0][0]; + const y1 = coords1[0][1]; + const x2 = coords1[1][0]; + const y2 = coords1[1][1]; + const x3 = coords2[0][0]; + const y3 = coords2[0][1]; + const x4 = coords2[1][0]; + const y4 = coords2[1][1]; + const denom = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1)); + const numeA = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3)); + const numeB = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3)); + + if (denom === 0) { + if (numeA === 0 && numeB === 0) { + return null; + } + return null; + } + + const uA = numeA / denom; + const uB = numeB / denom; + + if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) { + const x = x1 + (uA * (x2 - x1)); + const y = y1 + (uA * (y2 - y1)); + return point([x, y]); + } + return null; +} + + +export default lineIntersect; diff --git a/src/line-intersect/test.js b/src/line-intersect/test.js new file mode 100644 index 0000000000..3a8b42196f --- /dev/null +++ b/src/line-intersect/test.js @@ -0,0 +1,73 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const truncate = require('../truncate').default; +const { featureCollection, geometryCollection, lineString, polygon } = require('../helpers'); +const lineIntersect = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-line-intersect', t => { + for (const {filename, name, geojson} of fixtures) { + const [line1, line2] = geojson.features; + const results = truncate(lineIntersect(line1, line2)); + results.features.push(line1); + results.features.push(line2); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEquals(results, load.sync(directories.out + filename), name); + } + t.end(); +}); + +test('turf-line-intersect - prevent input mutation', t => { + const line1 = lineString([[7, 50], [8, 50], [9, 50]]); + const line2 = lineString([[8, 49], [8, 50], [8, 51]]); + const before1 = JSON.parse(JSON.stringify(line1)); + const before2 = JSON.parse(JSON.stringify(line2)); + + lineIntersect(line1, line2); + t.deepEqual(line1, before1, 'line1 input should not be mutated'); + t.deepEqual(line2, before2, 'line2 input should not be mutated'); + t.end(); +}); + +test('turf-line-intersect - Geometry Objects', t => { + const line1 = lineString([[7, 50], [8, 50], [9, 50]]); + const line2 = lineString([[8, 49], [8, 50], [8, 51]]); + t.ok(lineIntersect(line1.geometry, line2.geometry).features.length, 'support Geometry Objects'); + t.ok(lineIntersect(featureCollection([line1]), featureCollection([line2])).features.length, 'support Feature Collection'); + t.ok(lineIntersect(geometryCollection([line1.geometry]), geometryCollection([line2.geometry])).features.length, 'support Geometry Collection'); + t.end(); +}); + +test('turf-line-intersect - same point #688', t => { + const line1 = lineString([[7, 50], [8, 50], [9, 50]]); + const line2 = lineString([[8, 49], [8, 50], [8, 51]]); + + const results = lineIntersect(line1, line2); + t.equal(results.features.length, 1, 'should return single point'); + t.end(); +}); + +test('turf-line-intersect - polygon support #586', t => { + const poly1 = polygon([[[7, 50], [8, 50], [9, 50], [7, 50]]]); + const poly2 = polygon([[[8, 49], [8, 50], [8, 51], [8, 49]]]); + + const results = lineIntersect(poly1, poly2); + t.equal(results.features.length, 1, 'should return single point'); + t.end(); +}); diff --git a/packages/turf-line-intersect/test/in/2-vertex-segment.geojson b/src/line-intersect/test/in/2-vertex-segment.geojson similarity index 100% rename from packages/turf-line-intersect/test/in/2-vertex-segment.geojson rename to src/line-intersect/test/in/2-vertex-segment.geojson diff --git a/packages/turf-line-intersect/test/in/double-intersect.geojson b/src/line-intersect/test/in/double-intersect.geojson similarity index 100% rename from packages/turf-line-intersect/test/in/double-intersect.geojson rename to src/line-intersect/test/in/double-intersect.geojson diff --git a/packages/turf-line-intersect/test/in/multi-linestring.geojson b/src/line-intersect/test/in/multi-linestring.geojson similarity index 100% rename from packages/turf-line-intersect/test/in/multi-linestring.geojson rename to src/line-intersect/test/in/multi-linestring.geojson diff --git a/packages/turf-line-intersect/test/in/polygons-with-holes.geojson b/src/line-intersect/test/in/polygons-with-holes.geojson similarity index 100% rename from packages/turf-line-intersect/test/in/polygons-with-holes.geojson rename to src/line-intersect/test/in/polygons-with-holes.geojson diff --git a/packages/turf-line-intersect/test/in/same-coordinates.geojson b/src/line-intersect/test/in/same-coordinates.geojson similarity index 100% rename from packages/turf-line-intersect/test/in/same-coordinates.geojson rename to src/line-intersect/test/in/same-coordinates.geojson diff --git a/packages/turf-line-intersect/test/out/2-vertex-segment.geojson b/src/line-intersect/test/out/2-vertex-segment.geojson similarity index 100% rename from packages/turf-line-intersect/test/out/2-vertex-segment.geojson rename to src/line-intersect/test/out/2-vertex-segment.geojson diff --git a/packages/turf-line-intersect/test/out/double-intersect.geojson b/src/line-intersect/test/out/double-intersect.geojson similarity index 100% rename from packages/turf-line-intersect/test/out/double-intersect.geojson rename to src/line-intersect/test/out/double-intersect.geojson diff --git a/packages/turf-line-intersect/test/out/multi-linestring.geojson b/src/line-intersect/test/out/multi-linestring.geojson similarity index 100% rename from packages/turf-line-intersect/test/out/multi-linestring.geojson rename to src/line-intersect/test/out/multi-linestring.geojson diff --git a/packages/turf-line-intersect/test/out/polygons-with-holes.geojson b/src/line-intersect/test/out/polygons-with-holes.geojson similarity index 100% rename from packages/turf-line-intersect/test/out/polygons-with-holes.geojson rename to src/line-intersect/test/out/polygons-with-holes.geojson diff --git a/packages/turf-line-intersect/test/out/same-coordinates.geojson b/src/line-intersect/test/out/same-coordinates.geojson similarity index 100% rename from packages/turf-line-intersect/test/out/same-coordinates.geojson rename to src/line-intersect/test/out/same-coordinates.geojson diff --git a/packages/turf-line-offset/bench.js b/src/line-offset/bench.js similarity index 100% rename from packages/turf-line-offset/bench.js rename to src/line-offset/bench.js diff --git a/packages/turf-line-offset/index.d.ts b/src/line-offset/index.d.ts similarity index 100% rename from packages/turf-line-offset/index.d.ts rename to src/line-offset/index.d.ts diff --git a/src/line-offset/index.js b/src/line-offset/index.js new file mode 100644 index 0000000000..e0adade8ee --- /dev/null +++ b/src/line-offset/index.js @@ -0,0 +1,307 @@ +import { flattenEach, coordEach } from '../meta'; +import { getCoords, getType } from '../invariant'; +import { isObject, lineString, multiLineString, convertLength, degreesToRadians, radiansToDegrees } from '../helpers'; +import intersection from './lib/intersection'; +import centerOfMass from '../center-of-mass'; + +/** + * Takes a {@link LineString|line} and returns a {@link LineString|line} at offset by the specified distance. + * + * @name lineOffset + * @param {Geometry|Feature} geojson input GeoJSON + * @param {number} distance distance to offset the line (can be of negative value) + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] can be degrees, radians, miles, kilometers, inches, yards, meters + * @returns {Feature} Line offset from the input line + * @example + * var line = turf.lineString([[-83, 30], [-84, 36], [-78, 41]], { "stroke": "#F00" }); + * + * var offsetLine = turf.lineOffset(line, 2, {units: 'miles'}); + * + * //addToMap + * var addToMap = [offsetLine, line] + * offsetLine.properties.stroke = "#00F" + */ +function lineOffset(geojson, distance, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var units = options.units ? options.units : 'kilometers'; + + // Valdiation + if (!geojson) throw new Error('geojson is required'); + if (distance === undefined || distance === null || isNaN(distance)) throw new Error('distance is required'); + const distanceMeters = convertLength(distance, units, 'meters'); + + var type = getType(geojson); + var properties = geojson.properties; + + geojson = JSON.parse(JSON.stringify(geojson)); + + switch (type) { + case 'LineString': + return lineOffsetFeature(geojson, distanceMeters); + case 'MultiLineString': + var coords = []; + flattenEach(geojson, function (feature) { + coords.push(lineOffsetFeature(feature, distanceMeters).geometry.coordinates); + }); + return multiLineString(coords, properties); + default: + throw new Error('geometry ' + type + ' is not supported'); + } +} + +/** + * Line Offset + * + * @private + * @param {Geometry|Feature} line input line + * @param {number} distance distance to offset the line (can be of negative value) + * @param {string} [units=kilometers] units + * @returns {Feature} Line offset from the input line + */ +function lineOffsetFeature(line, distance) { + + var centroid = centerOfMass(line); + var utmZone = checkUtmZone(centroid.geometry); + reprojectFeature(line, utmZone, true); + + var segments = []; + var coords = getCoords(line); + var finalCoords = []; + coords.forEach(function (currentCoords, index) { + if (index !== coords.length - 1) { + var segment = processSegment(currentCoords, coords[index + 1], distance); + segments.push(segment); + if (index > 0) { + var seg2Coords = segments[index - 1]; + var intersects = intersection(segment, seg2Coords); + + // Handling for line segments that aren't straight + if (intersects !== false) { + seg2Coords[1] = intersects; + segment[0] = intersects; + } + + finalCoords.push(seg2Coords[0]); + if (index === coords.length - 2) { + finalCoords.push(segment[0]); + finalCoords.push(segment[1]); + } + } + // Handling for lines that only have 1 segment + if (coords.length === 2) { + finalCoords.push(segment[0]); + finalCoords.push(segment[1]); + } + } + }); + var out = lineString(finalCoords, line.properties); + reprojectFeature(out, utmZone, false); + return out; +} + +/** + * Process Segment + * Inspiration taken from http://stackoverflow.com/questions/2825412/draw-a-parallel-line + * + * @private + * @param {Array} point1 Point coordinates + * @param {Array} point2 Point coordinates + * @param {number} offset Offset + * @returns {Array>} offset points + */ +function processSegment(point1, point2, offset) { + var L = Math.sqrt((point1[0] - point2[0]) * (point1[0] - point2[0]) + (point1[1] - point2[1]) * (point1[1] - point2[1])); + + var out1x = point1[0] + offset * (point2[1] - point1[1]) / L; + var out2x = point2[0] + offset * (point2[1] - point1[1]) / L; + var out1y = point1[1] + offset * (point1[0] - point2[0]) / L; + var out2y = point2[1] + offset * (point1[0] - point2[0]) / L; + return [[out1x, out1y], [out2x, out2y]]; +} + +function reprojectFeature(feature, utmZone, toUtm) { + coordEach(feature, function (coord, coordIndex) { //eslint-disable-line + var blah = toUtm ? convertCoordToUtm(coord[0], coord[1], utmZone) : convertUtmToLatLon(coord[0], coord[1], utmZone); + coord.length = 0; + coord.push(blah[0], blah[1]); + }, false); +} + +function checkUtmZone(centerPoint) { + + const lat = centerPoint.coordinates[1]; + const lon = centerPoint.coordinates[0]; + let zoneNumber = Math.floor((lon + 180) / 6) + 1; + let hemisphere = 'N'; + + if (lon === 180) zoneNumber = 60; + if (lat < 0.0) hemisphere = 'S'; + + if (lat >= 56.0 && lat < 64.0 && lon >= 3.0 && lon < 12.0) zoneNumber = 32; + + return {zoneNumber, hemisphere}; +} + +function convertCoordToUtm(lon, lat, zone) { + + let falseEasting = 500e3; + let falseNorthing = 10000e3; + let λ0 = degreesToRadians(((zone.zoneNumber - 1) * 6 - 180 + 3)); + + let mgrsLatBands = 'CDEFGHJKLMNPQRSTUVWXX'; // X is repeated for 80-84°N + let latBand = mgrsLatBands.charAt(Math.floor(lat / 8 + 10)); + + // adjust zone & central meridian for Norway + if (zone === 31 && latBand === 'V' && lon >= 3) { zone++; degreesToRadians(λ0 += 6); } + // adjust zone & central meridian for Svalbard + if (zone === 32 && latBand === 'X' && lon < 9) { zone--; degreesToRadians(λ0 -= 6); } + if (zone === 32 && latBand === 'X' && lon >= 9) { zone++; degreesToRadians(λ0 += 6); } + if (zone === 34 && latBand === 'X' && lon < 21) { zone--; degreesToRadians(λ0 -= 6); } + if (zone === 34 && latBand === 'X' && lon >= 21) { zone++; degreesToRadians(λ0 += 6); } + if (zone === 36 && latBand === 'X' && lon < 33) { zone--; degreesToRadians(λ0 -= 6); } + if (zone === 36 && latBand === 'X' && lon >= 33) { zone++; degreesToRadians(λ0 += 6); } + + var φ = degreesToRadians(lat); // latitude ± from equator + var λ = degreesToRadians(lon) - λ0; // longitude ± from central meridian + + let a = 6378137; + let f = 1 / 298.257223563; + // WGS 84: a = 6378137, b = 6356752.314245, f = 1/298.257223563; + + let k0 = 0.9996; // UTM scale on the central meridian + + // ---- easting, northing: Karney 2011 Eq 7-14, 29, 35: + + let e = Math.sqrt(f * (2 - f)); // eccentricity + let n = f / (2 - f); // 3rd flattening + let n2 = n * n, n3 = n * n2, n4 = n * n3, n5 = n * n4, n6 = n * n5; // TODO: compare Horner-form accuracy? + + let cosλ = Math.cos(λ), sinλ = Math.sin(λ); + + let τ = Math.tan(φ); // τ ≡ tanφ, τʹ ≡ tanφʹ; prime (ʹ) indicates angles on the conformal sphere + let σ = Math.sinh(e * Math.atanh(e * τ / Math.sqrt(1 + τ * τ))); + + let τʹ = τ * Math.sqrt(1 + σ * σ) - σ * Math.sqrt(1 + τ * τ); + + let ξʹ = Math.atan2(τʹ, cosλ); + let ηʹ = Math.asinh(sinλ / Math.sqrt(τʹ * τʹ + cosλ * cosλ)); + + let A = a / (1 + n) * (1 + 1 / 4 * n2 + 1 / 64 * n4 + 1 / 256 * n6); // 2πA is the circumference of a meridian + + let α = [null, // note α is one-based array (6th order Krüger expressions) + 1 / 2 * n - 2 / 3 * n2 + 5 / 16 * n3 + 41 / 180 * n4 - 127 / 288 * n5 + 7891 / 37800 * n6, + 13 / 48 * n2 - 3 / 5 * n3 + 557 / 1440 * n4 + 281 / 630 * n5 - 1983433 / 1935360 * n6, + 61 / 240 * n3 - 103 / 140 * n4 + 15061 / 26880 * n5 + 167603 / 181440 * n6, + 49561 / 161280 * n4 - 179 / 168 * n5 + 6601661 / 7257600 * n6, + 34729 / 80640 * n5 - 3418889 / 1995840 * n6, + 212378941 / 319334400 * n6]; + + let ξ = ξʹ; + for (let j = 1; j <= 6; j++) ξ += α[j] * Math.sin(2 * j * ξʹ) * Math.cosh(2 * j * ηʹ); + + let η = ηʹ; + for (let j = 1; j <= 6; j++) η += α[j] * Math.cos(2 * j * ξʹ) * Math.sinh(2 * j * ηʹ); + + let x = k0 * A * η; + let y = k0 * A * ξ; + + x = x + falseEasting; + if (y < 0) y = y + falseNorthing; + + return [y, x]; +} + +function convertUtmToLatLon(y, x, zone) { + var z = zone.zoneNumber; + var h = zone.hemisphere; + + var falseEasting = 500e3, falseNorthing = 10000e3; + + var a = 6378137, f = 1 / 298.257223563; + + var k0 = 0.9996; // UTM scale on the central meridian + + x = x - falseEasting; // make x ± relative to central meridian + y = h === 'S' ? y - falseNorthing : y; // make y ± relative to equator + + // ---- from Karney 2011 Eq 15-22, 36: + + var e = Math.sqrt(f * (2 - f)); // eccentricity + var n = f / (2 - f); // 3rd flattening + var n2 = n * n, n3 = n * n2, n4 = n * n3, n5 = n * n4, n6 = n * n5; + + var A = a / (1 + n) * (1 + 1 / 4 * n2 + 1 / 64 * n4 + 1 / 256 * n6); // 2πA is the circumference of a meridian + + var η = x / (k0 * A); + var ξ = y / (k0 * A); + + var β = [null, // note β is one-based array (6th order Krüger expressions) + 1 / 2 * n - 2 / 3 * n2 + 37 / 96 * n3 - 1 / 360 * n4 - 81 / 512 * n5 + 96199 / 604800 * n6, + 1 / 48 * n2 + 1 / 15 * n3 - 437 / 1440 * n4 + 46 / 105 * n5 - 1118711 / 3870720 * n6, + 17 / 480 * n3 - 37 / 840 * n4 - 209 / 4480 * n5 + 5569 / 90720 * n6, + 4397 / 161280 * n4 - 11 / 504 * n5 - 830251 / 7257600 * n6, + 4583 / 161280 * n5 - 108847 / 3991680 * n6, + 20648693 / 638668800 * n6 ]; + + var ξʹ = ξ; + for (var j = 1; j <= 6; j++) ξʹ -= β[j] * Math.sin(2 * j * ξ) * Math.cosh(2 * j * η); + + var ηʹ = η; + for (var j = 1; j <= 6; j++) ηʹ -= β[j] * Math.cos(2 * j * ξ) * Math.sinh(2 * j * η); + + var sinhηʹ = Math.sinh(ηʹ); + var sinξʹ = Math.sin(ξʹ), cosξʹ = Math.cos(ξʹ); + + var τʹ = sinξʹ / Math.sqrt(sinhηʹ * sinhηʹ + cosξʹ * cosξʹ); + + var τi = τʹ; + do { + var σi = Math.sinh(e * Math.atanh(e * τi / Math.sqrt(1 + τi * τi))); + var τiʹ = τi * Math.sqrt(1 + σi * σi) - σi * Math.sqrt(1 + τi * τi); + var δτi = (τʹ - τiʹ) / Math.sqrt(1 + τiʹ * τiʹ) + * (1 + (1 - e * e) * τi * τi) / ((1 - e * e) * Math.sqrt(1 + τi * τi)); + τi += δτi; + } while (Math.abs(δτi) > 1e-12); // using IEEE 754 δτi -> 0 after 2-3 iterations + // note relatively large convergence test as δτi toggles on ±1.12e-16 for eg 31 N 400000 5000000 + var τ = τi; + + var φ = Math.atan(τ); + + var λ = Math.atan2(sinhηʹ, cosξʹ); + + // ---- convergence: Karney 2011 Eq 26, 27 + + var p = 1; + for (var j = 1; j <= 6; j++) p -= 2 * j * β[j] * Math.cos(2 * j * ξ) * Math.cosh(2 * j * η); + var q = 0; + for (var j = 1; j <= 6; j++) q += 2 * j * β[j] * Math.sin(2 * j * ξ) * Math.sinh(2 * j * η); + + var γʹ = Math.atan(Math.tan(ξʹ) * Math.tanh(ηʹ)); + var γʺ = Math.atan2(q, p); + + var γ = γʹ + γʺ; + + // ---- scale: Karney 2011 Eq 28 + + var sinφ = Math.sin(φ); + var kʹ = Math.sqrt(1 - e * e * sinφ * sinφ) * Math.sqrt(1 + τ * τ) * Math.sqrt(sinhηʹ * sinhηʹ + cosξʹ * cosξʹ); + var kʺ = A / a / Math.sqrt(p * p + q * q); + + var k = k0 * kʹ * kʺ; + + // ------------ + + var λ0 = degreesToRadians((z - 1) * 6 - 180 + 3); // longitude of central meridian + λ += λ0; // move λ from zonal to global coordinates + + // round to reasonable precision + var lat = radiansToDegrees(φ); // nm precision (1nm = 10^-11°) + var lon = radiansToDegrees(λ); // (strictly lat rounding should be φ⋅cosφ!) + + return [lon, lat]; +} + +export default lineOffset; diff --git a/packages/turf-line-offset/lib/intersection.js b/src/line-offset/lib/intersection.js similarity index 95% rename from packages/turf-line-offset/lib/intersection.js rename to src/line-offset/lib/intersection.js index 4e0c50b112..68acc2dd7f 100644 --- a/packages/turf-line-offset/lib/intersection.js +++ b/src/line-offset/lib/intersection.js @@ -98,7 +98,9 @@ function intersectSegments(a, b) { function isParallel(a, b) { var r = ab(a); var s = ab(b); - return (crossProduct(r, s) === 0); + var cp = Math.abs(crossProduct(r, s)); + // return (crossProduct(r, s) === 0); + return (cp < 0.0000001); } /** diff --git a/src/line-offset/test.js b/src/line-offset/test.js new file mode 100644 index 0000000000..20dea18fa9 --- /dev/null +++ b/src/line-offset/test.js @@ -0,0 +1,62 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import truncate from '../truncate'; +import { featureCollection, lineString } from '../helpers'; +import lineOffset from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); +// fixtures = fixtures.filter(fixture => fixture.name === 'polygon'); + +test('turf-line-offset', t => { + fixtures.forEach(fixture => { + const name = fixture.name; + const geojson = fixture.geojson; + const properties = geojson.properties || {}; + const distance = properties.distance || 50; + const units = properties.units; + + const output = lineOffset(geojson, distance, {units: units}); + output.properties.stroke = '#00F'; + const results = featureCollection([output, geojson]); + + if (process.env.REGEN) write.sync(directories.out + name + '.geojson', results); + t.deepEqual(results, load.sync(directories.out + name + '.geojson'), name); + }) + t.end(); +}); + +test('turf-line-offset - Throws Errors', t => { + const line = lineString([[10, 10], [0, 0]]); + t.throws(() => lineOffset(), /geojson is required/); + t.throws(() => lineOffset(line, /offset is required/)); + t.end(); +}); + +test('turf-line-offset - Support Geometry Objects', t => { + const line = lineString([[10, 10], [0, 0]]); + t.ok(lineOffset(line.geometry, 10), 'Geometry Object'); + t.end(); +}); + +test('turf-line-offset - Prevent Input Mutation', t => { + const line = lineString([[10, 10], [0, 0]]); + const before = JSON.parse(JSON.stringify(line)); + lineOffset(line.geometry, 10); + + t.deepEqual(line, before, 'input does not mutate'); + t.end(); +}); diff --git a/packages/turf-line-offset/test/in/linestring-straight.geojson b/src/line-offset/test/in/linestring-straight.geojson similarity index 100% rename from packages/turf-line-offset/test/in/linestring-straight.geojson rename to src/line-offset/test/in/linestring-straight.geojson diff --git a/src/line-offset/test/issue-933.geojson b/src/line-offset/test/issue-933.geojson new file mode 100644 index 0000000000..b3b44c0ddd --- /dev/null +++ b/src/line-offset/test/issue-933.geojson @@ -0,0 +1,304 @@ +{ + "type": "Feature", + "properties": { + "distance": 100, + "units": "meters" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -116.87261518236242, + 32.467535586725724 + ], + [ + -116.87327388263317, + 32.467003334978095 + ], + [ + -116.87362469971774, + 32.46701908197356 + ], + [ + -116.87355831912846, + 32.467016630222425 + ], + [ + -116.87354499046191, + 32.46728229478041 + ], + [ + -116.87363835206422, + 32.465622037913285 + ], + [ + -116.87368122736808, + 32.46536468614763 + ], + [ + -116.87370018521001, + 32.46502247052452 + ], + [ + -116.87365477385369, + 32.4644570847373 + ], + [ + -116.87357424830391, + 32.46339462232371 + ], + [ + -116.87335455010377, + 32.461884501090125 + ], + [ + -116.87386781770444, + 32.46178913342283 + ], + [ + -116.87446640603497, + 32.46167795369656 + ], + [ + -116.87803555785949, + 32.46144315959175 + ], + [ + -116.88027000359166, + 32.46125814880662 + ], + [ + -116.88093805894644, + 32.46122372340186 + ], + [ + -116.88205145130657, + 32.461182909607714 + ], + [ + -116.88246882560875, + 32.46114317290651 + ], + [ + -116.88310483879262, + 32.46099956319482 + ], + [ + -116.88434539030767, + 32.46066801845082 + ], + [ + -116.88565765445, + 32.46034020396103 + ], + [ + -116.88679465380157, + 32.460091997042525 + ], + [ + -116.888539846651, + 32.45963698502827 + ], + [ + -116.88998655472773, + 32.45927108492462 + ], + [ + -116.89048716962004, + 32.45916454787991 + ], + [ + -116.89143224144337, + 32.458904926592375 + ], + [ + -116.89200779760762, + 32.45866859219537 + ], + [ + -116.89266965759607, + 32.45837325117386 + ], + [ + -116.89337624126523, + 32.45788409345164 + ], + [ + -116.89356405688325, + 32.45781375830756 + ], + [ + -116.89383471220685, + 32.45766208233762 + ], + [ + -116.89407205647734, + 32.45757738424909 + ], + [ + -116.89439109886918, + 32.45757738424909 + ], + [ + -116.89464784704973, + 32.457622709311664 + ], + [ + -116.89535722159393, + 32.45793798688687 + ], + [ + -116.8959119697416, + 32.45815779827918 + ], + [ + -116.89664461336746, + 32.45841315267384 + ], + [ + -116.89716570752867, + 32.45871239691157 + ], + [ + -116.89942014242583, + 32.45978085843696 + ], + [ + -116.90063050979913, + 32.460386093406015 + ], + [ + -116.90106690346026, + 32.46070453986352 + ], + [ + -116.90215069869289, + 32.461683103688614 + ], + [ + -116.90258475682084, + 32.46190478153064 + ], + [ + -116.90280899846596, + 32.46197374186452 + ], + [ + -116.90295207128946, + 32.46199598820265 + ], + [ + -116.9030962291227, + 32.46201858502548 + ], + [ + -116.90366426965086, + 32.46200846845815 + ], + [ + -116.90691622639837, + 32.46192292213458 + ], + [ + -116.90722480847238, + 32.46190083653342 + ], + [ + -116.90838901984156, + 32.461923269356895 + ], + [ + -116.90864982212855, + 32.4619754055084 + ], + [ + -116.90925688600727, + 32.46215048451554 + ], + [ + -116.90964807961842, + 32.46235471778101 + ], + [ + -116.91095837983494, + 32.46302887669653 + ], + [ + -116.91173325169443, + 32.46348086020447 + ], + [ + -116.91300013248556, + 32.464157330516315 + ], + [ + -116.91347359295229, + 32.46443703423199 + ], + [ + -116.91465167041959, + 32.46507944929073 + ], + [ + -116.9159423746194, + 32.46583620114723 + ], + [ + -116.91619870631482, + 32.46609253284265 + ], + [ + -116.9166062814952, + 32.46642815670281 + ], + [ + -116.91688630422998, + 32.46696270243158 + ], + [ + -116.91709143073622, + 32.46750595573502 + ], + [ + -116.91715912426716, + 32.468047188640035 + ], + [ + -116.91718872339416, + 32.46818305933138 + ], + [ + -116.91772270140771, + 32.470588453752576 + ], + [ + -116.91782562108189, + 32.47098986925715 + ], + [ + -116.91799640565858, + 32.471511313134066 + ], + [ + -116.91870276114635, + 32.472738989117964 + ], + [ + -116.91778727129388, + 32.4732528669243 + ], + [ + -116.91604670117596, + 32.474430053956375 + ], + [ + -116.91581369398399, + 32.47416648844421 + ], + [ + -116.91557051708041, + 32.473894285913495 + ] + ] + } +} \ No newline at end of file diff --git a/packages/turf-line-offset/test/in/line-concave.geojson b/src/line-offset/test/line-concave.geojson similarity index 100% rename from packages/turf-line-offset/test/in/line-concave.geojson rename to src/line-offset/test/line-concave.geojson diff --git a/src/line-offset/test/line-folds-itself-#1439.geojson b/src/line-offset/test/line-folds-itself-#1439.geojson new file mode 100644 index 0000000000..068157d3ff --- /dev/null +++ b/src/line-offset/test/line-folds-itself-#1439.geojson @@ -0,0 +1,34 @@ +{ + "type": "Feature", + "properties": { + "stroke-width": 5, + "stroke": "red", + "distance": 5, + "units": "meters" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 30.59357475489378, + 50.4496289184317 + ], + [ + 30.593773238360882, + 50.44968524482101 + ], + [ + 30.593875162303448, + 50.44971743132919 + ], + [ + 30.593773238360882, + 50.44968524482101 + ], + [ + 30.59357475489378, + 50.4496289184317 + ] + ] + } +} \ No newline at end of file diff --git a/packages/turf-line-offset/test/in/line-horizontal.geojson b/src/line-offset/test/line-horizontal.geojson similarity index 100% rename from packages/turf-line-offset/test/in/line-horizontal.geojson rename to src/line-offset/test/line-horizontal.geojson diff --git a/packages/turf-line-offset/test/in/linestring-long.geojson b/src/line-offset/test/linestring-long.geojson similarity index 100% rename from packages/turf-line-offset/test/in/linestring-long.geojson rename to src/line-offset/test/linestring-long.geojson diff --git a/packages/turf-line-offset/test/in/linestring-same-start-end.geojson b/src/line-offset/test/linestring-same-start-end.geojson similarity index 100% rename from packages/turf-line-offset/test/in/linestring-same-start-end.geojson rename to src/line-offset/test/linestring-same-start-end.geojson diff --git a/packages/turf-line-offset/test/in/linestring-single-segment-only.geojson b/src/line-offset/test/linestring-single-segment-only.geojson similarity index 100% rename from packages/turf-line-offset/test/in/linestring-single-segment-only.geojson rename to src/line-offset/test/linestring-single-segment-only.geojson diff --git a/packages/turf-line-offset/test/in/multi-linestring.geojson b/src/line-offset/test/multi-linestring.geojson similarity index 100% rename from packages/turf-line-offset/test/in/multi-linestring.geojson rename to src/line-offset/test/multi-linestring.geojson diff --git a/src/line-offset/test/northern-line.geojson b/src/line-offset/test/northern-line.geojson new file mode 100644 index 0000000000..c5519651eb --- /dev/null +++ b/src/line-offset/test/northern-line.geojson @@ -0,0 +1,62 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6, + "distance": 10, + "units": "kilometers" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -93.66943359374999, + 75.2782047773442 + ], + [ + -94.15283203125, + 75.52189820596192 + ], + [ + -94.68017578125, + 75.60133818586581 + ], + [ + -95.64697265625, + 75.55208098028335 + ], + [ + -95.8447265625, + 75.37837872661018 + ], + [ + -96.339111328125, + 75.10975495781904 + ], + [ + -96.251220703125, + 74.89940428652537 + ], + [ + -95.20751953125, + 74.73829331009176 + ], + [ + -94.50439453125, + 74.63965846462719 + ], + [ + -93.878173828125, + 74.65129477919845 + ], + [ + -93.526611328125, + 74.73250841433554 + ], + [ + -93.50463867187499, + 75.09845822124332 + ] + ] + } +} \ No newline at end of file diff --git a/src/line-offset/test/out/issue-933.geojson b/src/line-offset/test/out/issue-933.geojson new file mode 100644 index 0000000000..65b8a71e2c --- /dev/null +++ b/src/line-offset/test/out/issue-933.geojson @@ -0,0 +1,614 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "distance": 100, + "units": "meters", + "stroke": "#00F" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -116.87188099138724, + 32.466882580969624 + ], + [ + -116.87287187907094, + 32.4660819121591 + ], + [ + -117.10084038481934, + 32.47610827878878 + ], + [ + -116.87457623138829, + 32.467957191144755 + ], + [ + -116.89216473862638, + 32.11589442092188 + ], + [ + -116.87257779758093, + 32.46553729272848 + ], + [ + -116.87262062325408, + 32.4652802570574 + ], + [ + -116.87263438006879, + 32.465031979930636 + ], + [ + -116.87259299488836, + 32.46451664572503 + ], + [ + -116.87251434933572, + 32.46347882780077 + ], + [ + -116.87217982645359, + 32.46117923977643 + ], + [ + -116.87364006376339, + 32.46090792651512 + ], + [ + -116.87431065503165, + 32.46078337302579 + ], + [ + -116.87794267337364, + 32.46054444440999 + ], + [ + -116.88018598025737, + 32.460358699592284 + ], + [ + -116.88088279596171, + 32.46032279215281 + ], + [ + -116.88196899848673, + 32.460282975228566 + ], + [ + -116.88227144682871, + 32.46025418025794 + ], + [ + -116.88280781582851, + 32.46013306980279 + ], + [ + -116.88403504228978, + 32.45980508630403 + ], + [ + -116.88537454013932, + 32.459470468757814 + ], + [ + -116.88650545923191, + 32.45922358946941 + ], + [ + -116.8882313743285, + 32.45877360368617 + ], + [ + -116.8897048074272, + 32.458400944420895 + ], + [ + -116.89019332554159, + 32.45829698188398 + ], + [ + -116.89103447275032, + 32.45806591011796 + ], + [ + -116.89152798286419, + 32.45786326564651 + ], + [ + -116.8920794958486, + 32.45761716546781 + ], + [ + -116.8928147240892, + 32.4571081787329 + ], + [ + -116.89305214123252, + 32.45701926871606 + ], + [ + -116.89333064119697, + 32.45686319680187 + ], + [ + -116.89385726011454, + 32.456675268845345 + ], + [ + -116.89450069620793, + 32.45667526910074 + ], + [ + -116.89501023107066, + 32.45676521976227 + ], + [ + -116.89582971902767, + 32.457129436549096 + ], + [ + -116.89633973688288, + 32.45733152379102 + ], + [ + -116.89715055665935, + 32.4576141246138 + ], + [ + -116.8977246769984, + 32.45794381907607 + ], + [ + -116.89995008209247, + 32.458998518772454 + ], + [ + -116.90125275631088, + 32.45964990855593 + ], + [ + -116.90180389203103, + 32.460052082860955 + ], + [ + -116.90282572907934, + 32.460974699126 + ], + [ + -116.90304503205158, + 32.461086698960635 + ], + [ + -116.90308832762528, + 32.46110001349487 + ], + [ + -116.90314477583458, + 32.46110879058133 + ], + [ + -116.90318267972366, + 32.461114732053055 + ], + [ + -116.90363660146582, + 32.46110664769777 + ], + [ + -116.90685492052393, + 32.46102198647376 + ], + [ + -116.90719205095358, + 32.46099785750811 + ], + [ + -116.9085246821572, + 32.461023535250966 + ], + [ + -116.90894394992692, + 32.46110734979781 + ], + [ + -116.9097129037768, + 32.461329117878215 + ], + [ + -116.91020308962725, + 32.46158503229192 + ], + [ + -116.91153645172555, + 32.46227105434867 + ], + [ + -116.91231861278844, + 32.46272728817963 + ], + [ + -116.9135881780922, + 32.46340518936071 + ], + [ + -116.91406580361495, + 32.46368735268372 + ], + [ + -116.91524229952351, + 32.46432890286431 + ], + [ + -116.9166632044525, + 32.46516198830289 + ], + [ + -116.91697708196462, + 32.465475863608376 + ], + [ + -116.9174952996076, + 32.46590259370686 + ], + [ + -116.91788221545787, + 32.46664117755467 + ], + [ + -116.91813813901211, + 32.46731894041787 + ], + [ + -116.91821301175318, + 32.467917518424976 + ], + [ + -116.91823484187928, + 32.468017721238134 + ], + [ + -116.91876575722641, + 32.47040919514794 + ], + [ + -116.91885909521328, + 32.47077322312973 + ], + [ + -116.91899567969328, + 32.47119023222996 + ], + [ + -116.9200683004425, + 32.47305444050507 + ], + [ + -116.91841413506486, + 32.47398296102149 + ], + [ + -116.91585292034962, + 32.475715156161016 + ], + [ + -116.914963678561, + 32.474709292515264 + ], + [ + -116.91472212117878, + 32.47443889998326 + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "distance": 100, + "units": "meters" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -116.87261518236242, + 32.467535586725724 + ], + [ + -116.87327388263317, + 32.467003334978095 + ], + [ + -116.87362469971774, + 32.46701908197356 + ], + [ + -116.87355831912846, + 32.467016630222425 + ], + [ + -116.87354499046191, + 32.46728229478041 + ], + [ + -116.87363835206422, + 32.465622037913285 + ], + [ + -116.87368122736808, + 32.46536468614763 + ], + [ + -116.87370018521001, + 32.46502247052452 + ], + [ + -116.87365477385369, + 32.4644570847373 + ], + [ + -116.87357424830391, + 32.46339462232371 + ], + [ + -116.87335455010377, + 32.461884501090125 + ], + [ + -116.87386781770444, + 32.46178913342283 + ], + [ + -116.87446640603497, + 32.46167795369656 + ], + [ + -116.87803555785949, + 32.46144315959175 + ], + [ + -116.88027000359166, + 32.46125814880662 + ], + [ + -116.88093805894644, + 32.46122372340186 + ], + [ + -116.88205145130657, + 32.461182909607714 + ], + [ + -116.88246882560875, + 32.46114317290651 + ], + [ + -116.88310483879262, + 32.46099956319482 + ], + [ + -116.88434539030767, + 32.46066801845082 + ], + [ + -116.88565765445, + 32.46034020396103 + ], + [ + -116.88679465380157, + 32.460091997042525 + ], + [ + -116.888539846651, + 32.45963698502827 + ], + [ + -116.88998655472773, + 32.45927108492462 + ], + [ + -116.89048716962004, + 32.45916454787991 + ], + [ + -116.89143224144337, + 32.458904926592375 + ], + [ + -116.89200779760762, + 32.45866859219537 + ], + [ + -116.89266965759607, + 32.45837325117386 + ], + [ + -116.89337624126523, + 32.45788409345164 + ], + [ + -116.89356405688325, + 32.45781375830756 + ], + [ + -116.89383471220685, + 32.45766208233762 + ], + [ + -116.89407205647734, + 32.45757738424909 + ], + [ + -116.89439109886918, + 32.45757738424909 + ], + [ + -116.89464784704973, + 32.457622709311664 + ], + [ + -116.89535722159393, + 32.45793798688687 + ], + [ + -116.8959119697416, + 32.45815779827918 + ], + [ + -116.89664461336746, + 32.45841315267384 + ], + [ + -116.89716570752867, + 32.45871239691157 + ], + [ + -116.89942014242583, + 32.45978085843696 + ], + [ + -116.90063050979913, + 32.460386093406015 + ], + [ + -116.90106690346026, + 32.46070453986352 + ], + [ + -116.90215069869289, + 32.461683103688614 + ], + [ + -116.90258475682084, + 32.46190478153064 + ], + [ + -116.90280899846596, + 32.46197374186452 + ], + [ + -116.90295207128946, + 32.46199598820265 + ], + [ + -116.9030962291227, + 32.46201858502548 + ], + [ + -116.90366426965086, + 32.46200846845815 + ], + [ + -116.90691622639837, + 32.46192292213458 + ], + [ + -116.90722480847238, + 32.46190083653342 + ], + [ + -116.90838901984156, + 32.461923269356895 + ], + [ + -116.90864982212855, + 32.4619754055084 + ], + [ + -116.90925688600727, + 32.46215048451554 + ], + [ + -116.90964807961842, + 32.46235471778101 + ], + [ + -116.91095837983494, + 32.46302887669653 + ], + [ + -116.91173325169443, + 32.46348086020447 + ], + [ + -116.91300013248556, + 32.464157330516315 + ], + [ + -116.91347359295229, + 32.46443703423199 + ], + [ + -116.91465167041959, + 32.46507944929073 + ], + [ + -116.9159423746194, + 32.46583620114723 + ], + [ + -116.91619870631482, + 32.46609253284265 + ], + [ + -116.9166062814952, + 32.46642815670281 + ], + [ + -116.91688630422998, + 32.46696270243158 + ], + [ + -116.91709143073622, + 32.46750595573502 + ], + [ + -116.91715912426716, + 32.468047188640035 + ], + [ + -116.91718872339416, + 32.46818305933138 + ], + [ + -116.91772270140771, + 32.470588453752576 + ], + [ + -116.91782562108189, + 32.47098986925715 + ], + [ + -116.91799640565858, + 32.471511313134066 + ], + [ + -116.91870276114635, + 32.472738989117964 + ], + [ + -116.91778727129388, + 32.4732528669243 + ], + [ + -116.91604670117596, + 32.474430053956375 + ], + [ + -116.91581369398399, + 32.47416648844421 + ], + [ + -116.91557051708041, + 32.473894285913495 + ] + ] + } + } + ] +} diff --git a/packages/turf-line-offset/test/out/line-concave.geojson b/src/line-offset/test/out/line-concave.geojson similarity index 75% rename from packages/turf-line-offset/test/out/line-concave.geojson rename to src/line-offset/test/out/line-concave.geojson index ae06d81893..4d7292c60c 100644 --- a/packages/turf-line-offset/test/out/line-concave.geojson +++ b/src/line-offset/test/out/line-concave.geojson @@ -13,28 +13,28 @@ "type": "LineString", "coordinates": [ [ - 2.2937, - 23.4165 + -0.5349019372758107, + 20.038217290434766 ], [ - 0.2235, - 25.0153 + -5.540628918281228, + 23.82929752443656 ], [ - 1.6811, - 27.5904 + -1.2030368492656218, + 31.810793129773742 ], [ - 6.0031, - 27.7113 + 8.705210699200887, + 32.08185745106474 ], [ - 7.9604, - 24.4718 + 14.770235759317455, + 21.59952916935602 ], [ - 2.6806, - 23.1494 + 3.8630783146157044, + 18.951842012034614 ] ] } diff --git a/src/line-offset/test/out/line-folds-itself-#1439.geojson b/src/line-offset/test/out/line-folds-itself-#1439.geojson new file mode 100644 index 0000000000..add0c3de49 --- /dev/null +++ b/src/line-offset/test/out/line-folds-itself-#1439.geojson @@ -0,0 +1,73 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke-width": 5, + "stroke": "#00F", + "distance": 5, + "units": "meters" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 30.59354616165469, + 50.44966999464135 + ], + [ + 30.59374332390531, + 50.4497259461045 + ], + [ + 30.593906372763723, + 50.44967713931092 + ], + [ + 30.593803152764142, + 50.44964454352883 + ], + [ + 30.593603348082336, + 50.449587842214065 + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke-width": 5, + "stroke": "red", + "distance": 5, + "units": "meters" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 30.59357475489378, + 50.4496289184317 + ], + [ + 30.593773238360882, + 50.44968524482101 + ], + [ + 30.593875162303448, + 50.44971743132919 + ], + [ + 30.593773238360882, + 50.44968524482101 + ], + [ + 30.59357475489378, + 50.4496289184317 + ] + ] + } + } + ] +} diff --git a/packages/turf-line-offset/test/out/line-horizontal.geojson b/src/line-offset/test/out/line-horizontal.geojson similarity index 82% rename from packages/turf-line-offset/test/out/line-horizontal.geojson rename to src/line-offset/test/out/line-horizontal.geojson index 0e6a990e53..0928b8d6c2 100644 --- a/packages/turf-line-offset/test/out/line-horizontal.geojson +++ b/src/line-offset/test/out/line-horizontal.geojson @@ -11,12 +11,12 @@ "type": "LineString", "coordinates": [ [ - 10, - -0.4497 + 9.999845985734764, + 0.45063254461019653 ], [ - 20, - -0.4497 + 20.000154014265235, + 0.45063254461019653 ] ] } diff --git a/src/line-offset/test/out/linestring-long.geojson b/src/line-offset/test/out/linestring-long.geojson new file mode 100644 index 0000000000..2f69818009 --- /dev/null +++ b/src/line-offset/test/out/linestring-long.geojson @@ -0,0 +1,349 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 6 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -24.480861603310338, + 41.632721626863585 + ], + [ + -6.647216388004048, + 45.747825663046015 + ], + [ + 1.085136499171514, + 50.64257705324601 + ], + [ + 3.5233799128822874, + 44.14247782765204 + ], + [ + -5.679734328878592, + 38.936584137792124 + ], + [ + -5.043733109531778, + 36.98931290837109 + ], + [ + -0.5141975722153155, + 37.710558124653176 + ], + [ + 1.1388790227146635, + 39.66459049079397 + ], + [ + 3.0387375430061674, + 40.97928867188008 + ], + [ + 6.446934827886844, + 41.7779730541699 + ], + [ + 8.088029865430949, + 39.43161295104496 + ], + [ + 5.051616370451809, + 36.7779902268397 + ], + [ + 4.272830010826645, + 35.289273183183006 + ], + [ + 5.288588708170665, + 32.2184859539137 + ], + [ + 8.360261349054175, + 32.95512358600787 + ], + [ + 10.163986596895741, + 34.21603188668348 + ], + [ + 9.996278070618768, + 35.9999222344376 + ], + [ + 9.80767804952729, + 38.19498851549277 + ], + [ + 9.467006674765376, + 39.10447839688722 + ], + [ + 8.9128592002677, + 40.490694883787654 + ], + [ + 8.69530232586784, + 42.01939031042956 + ], + [ + 11.124650576548863, + 44.551235241846875 + ], + [ + 13.858983615800586, + 44.386534465310504 + ], + [ + 15.340285190470215, + 42.991563832235194 + ], + [ + 16.382725062768316, + 37.731565166281285 + ], + [ + 16.182101048666183, + 36.073664143133115 + ], + [ + 15.433756036208433, + 34.41845431098476 + ], + [ + 13.860866062320799, + 31.81280242814211 + ], + [ + 12.638188959393966, + 25.15944326737593 + ], + [ + 15.36467327869606, + 29.424345605324277 + ], + [ + 16.37356908672761, + 31.621305488840974 + ], + [ + 16.70307667215135, + 33.484535730917514 + ], + [ + 16.870934655338665, + 35.10238952489005 + ], + [ + 19.08280362887542, + 41.7112871975585 + ], + [ + 22.16966569952744, + 41.49324825508871 + ], + [ + 21.30729578581151, + 38.79429316818159 + ], + [ + 21.629808704082564, + 36.20951083983069 + ], + [ + 21.792055541762917, + 34.029098252156736 + ], + [ + 21.775764006951, + 32.06179956884881 + ], + [ + 25.809619417551353, + 33.67455265117563 + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -24.2578125, + 41.244772343082076 + ], + [ + -6.328125, + 45.336701909968134 + ], + [ + 0.703125, + 49.83798245308484 + ], + [ + 2.8125, + 44.33956524809713 + ], + [ + -6.328125, + 39.095962936305476 + ], + [ + -5.44921875, + 36.4566360115962 + ], + [ + -0.17578125, + 37.3002752813443 + ], + [ + 1.58203125, + 39.36827914916014 + ], + [ + 3.33984375, + 40.58058466412761 + ], + [ + 6.15234375, + 41.244772343082076 + ], + [ + 7.3828125, + 39.50404070558415 + ], + [ + 4.5703125, + 37.020098201368114 + ], + [ + 3.69140625, + 35.31736632923788 + ], + [ + 4.921875, + 31.653381399664 + ], + [ + 8.61328125, + 32.54681317351514 + ], + [ + 10.72265625, + 34.016241889667015 + ], + [ + 10.546875, + 36.03133177633187 + ], + [ + 10.37109375, + 38.272688535980976 + ], + [ + 10.01953125, + 39.232253141714885 + ], + [ + 9.4921875, + 40.58058466412761 + ], + [ + 9.31640625, + 41.902277040963696 + ], + [ + 11.42578125, + 44.08758502824516 + ], + [ + 13.53515625, + 43.96119063892024 + ], + [ + 14.765625, + 42.8115217450979 + ], + [ + 15.8203125, + 37.71859032558816 + ], + [ + 15.644531250000002, + 36.1733569352216 + ], + [ + 14.94140625, + 34.59704151614417 + ], + [ + 13.359375, + 31.952162238024975 + ], + [ + 11.77734375, + 22.755920681486405 + ], + [ + 15.8203125, + 29.22889003019423 + ], + [ + 16.875, + 31.50362930577303 + ], + [ + 17.2265625, + 33.43144133557529 + ], + [ + 17.402343749999996, + 35.02999636902566 + ], + [ + 19.51171875, + 41.244772343082076 + ], + [ + 21.4453125, + 41.11246878918088 + ], + [ + 20.7421875, + 38.8225909761771 + ], + [ + 21.09375, + 36.1733569352216 + ], + [ + 21.26953125, + 34.016241889667015 + ], + [ + 21.26953125, + 31.353636941500987 + ], + [ + 26.015625, + 33.284619968887675 + ] + ] + } + } + ] +} diff --git a/src/line-offset/test/out/linestring-same-start-end.geojson b/src/line-offset/test/out/linestring-same-start-end.geojson new file mode 100644 index 0000000000..891aa5c90b --- /dev/null +++ b/src/line-offset/test/out/linestring-same-start-end.geojson @@ -0,0 +1,77 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 6 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 122.90562215600141, + -19.551267415438044 + ], + [ + 123.01648220209874, + -26.48539089417093 + ], + [ + 134.6116387131457, + -26.769557938765345 + ], + [ + 138.69967342827408, + -22.943078015924282 + ], + [ + 133.75830913881214, + -15.027897544623638 + ], + [ + 122.61668719823943, + -19.97350780708439 + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 122.431640625, + -19.559790136497398 + ], + [ + 122.51953124999999, + -26.902476886279807 + ], + [ + 134.82421875, + -27.215556209029675 + ], + [ + 139.306640625, + -22.998851594142913 + ], + [ + 133.9453125, + -14.434680215297268 + ], + [ + 122.431640625, + -19.559790136497398 + ] + ] + } + } + ] +} diff --git a/packages/turf-line-offset/test/out/linestring-single-segment-only.geojson b/src/line-offset/test/out/linestring-single-segment-only.geojson similarity index 83% rename from packages/turf-line-offset/test/out/linestring-single-segment-only.geojson rename to src/line-offset/test/out/linestring-single-segment-only.geojson index d9535bb138..ba62964166 100644 --- a/packages/turf-line-offset/test/out/linestring-single-segment-only.geojson +++ b/src/line-offset/test/out/linestring-single-segment-only.geojson @@ -11,12 +11,12 @@ "type": "LineString", "coordinates": [ [ - 1.4497, - 1 + 0.5509381629746163, + 1.0012047804331288 ], [ - 1.4497, - 10 + 0.54411844646508, + 9.998458368725608 ] ] } diff --git a/packages/turf-line-offset/test/out/linestring-straight.geojson b/src/line-offset/test/out/linestring-straight.geojson similarity index 78% rename from packages/turf-line-offset/test/out/linestring-straight.geojson rename to src/line-offset/test/out/linestring-straight.geojson index fae0288359..2dfd97881c 100644 --- a/packages/turf-line-offset/test/out/linestring-straight.geojson +++ b/src/line-offset/test/out/linestring-straight.geojson @@ -11,16 +11,16 @@ "type": "LineString", "coordinates": [ [ - 1.4497, - -10 + -5.758360846275527, + 79.99600171863123 ], [ - 1.4497, - 1 + 0.47145584789608225, + -55.48317377575269 ], [ - 1.4497, - 10 + 0.54411844646508, + 9.998458368725608 ] ] } diff --git a/src/line-offset/test/out/multi-linestring.geojson b/src/line-offset/test/out/multi-linestring.geojson new file mode 100644 index 0000000000..36fa88172a --- /dev/null +++ b/src/line-offset/test/out/multi-linestring.geojson @@ -0,0 +1,85 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [ + 10.315309252922981, + 9.678087054280017 + ], + [ + 2.318518151526016, + 1.6808239960652362 + ], + [ + 0.31609742269222885, + -0.3207177518844196 + ] + ], + [ + [ + 24.68057769149906, + 4.682157881595944 + ], + [ + 20.000418429360757, + 9.363029976599721 + ], + [ + 15.3179746365098, + 4.682586257091832 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [ + 10, + 10 + ], + [ + 2, + 2 + ], + [ + 0, + 0 + ] + ], + [ + [ + 25, + 5 + ], + [ + 20, + 10 + ], + [ + 15, + 5 + ] + ] + ] + } + } + ] +} diff --git a/src/line-offset/test/out/northern-line.geojson b/src/line-offset/test/out/northern-line.geojson new file mode 100644 index 0000000000..eb486eb92b --- /dev/null +++ b/src/line-offset/test/out/northern-line.geojson @@ -0,0 +1,129 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 6, + "distance": 10, + "units": "kilometers" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -93.9845179830474, + 75.23822362687608 + ], + [ + -94.42542339907301, + 75.4585284934873 + ], + [ + -94.74604124504552, + 75.5067731689352 + ], + [ + -95.36295027577906, + 75.47545913577947 + ], + [ + -95.51213930182497, + 75.34648740813651 + ], + [ + -95.98242051938257, + 75.09438887664523 + ], + [ + -95.92684407948414, + 74.95401766243418 + ], + [ + -95.03996290528403, + 74.81640950621617 + ], + [ + -94.43072480956693, + 74.73099281146548 + ], + [ + -94.01592403338023, + 74.73871686384213 + ], + [ + -93.86532855857679, + 74.77364448708785 + ], + [ + -93.85299072067089, + 75.09961182120254 + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6, + "distance": 10, + "units": "kilometers" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -93.66943359374999, + 75.2782047773442 + ], + [ + -94.15283203125, + 75.52189820596192 + ], + [ + -94.68017578125, + 75.60133818586581 + ], + [ + -95.64697265625, + 75.55208098028335 + ], + [ + -95.8447265625, + 75.37837872661018 + ], + [ + -96.339111328125, + 75.10975495781904 + ], + [ + -96.251220703125, + 74.89940428652537 + ], + [ + -95.20751953125, + 74.73829331009176 + ], + [ + -94.50439453125, + 74.63965846462719 + ], + [ + -93.878173828125, + 74.65129477919845 + ], + [ + -93.526611328125, + 74.73250841433554 + ], + [ + -93.50463867187499, + 75.09845822124332 + ] + ] + } + } + ] +} diff --git a/packages/turf-line-overlap/bench.js b/src/line-overlap/bench.js similarity index 100% rename from packages/turf-line-overlap/bench.js rename to src/line-overlap/bench.js diff --git a/src/line-overlap/index.js b/src/line-overlap/index.js new file mode 100644 index 0000000000..acc1ba46b2 --- /dev/null +++ b/src/line-overlap/index.js @@ -0,0 +1,120 @@ +import rbush from '../spatial-index'; +import lineSegment from '../line-segment'; +import nearestPointOnLine from '../nearest-point-on-line'; +import booleanPointOnLine from '../boolean-point-on-line'; +import { getCoords } from '../invariant'; +import { featureEach, segmentEach } from '../meta'; +import {featureCollection, isObject} from '../helpers'; +import * as deepEqual from 'deep-equal'; +const equal = deepEqual.default; + +/** + * Takes any LineString or Polygon and returns the overlapping lines between both features. + * + * @name lineOverlap + * @param {Geometry|Feature} line1 any LineString or Polygon + * @param {Geometry|Feature} line2 any LineString or Polygon + * @param {Object} [options={}] Optional parameters + * @param {number} [options.tolerance=0] Tolerance distance to match overlapping line segments (in kilometers) + * @returns {FeatureCollection} lines(s) that are overlapping between both features + * @example + * var line1 = turf.lineString([[115, -35], [125, -30], [135, -30], [145, -35]]); + * var line2 = turf.lineString([[115, -25], [125, -30], [135, -30], [145, -25]]); + * + * var overlapping = turf.lineOverlap(line1, line2); + * + * //addToMap + * var addToMap = [line1, line2, overlapping] + */ +function lineOverlap(line1, line2, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var tolerance = options.tolerance || 0; + + // Containers + var features = []; + + // Create Spatial Index + var tree = rbush(); + + const line = lineSegment(line1); + tree.load(line); + var overlapSegment; + + // Line Intersection + + // Iterate over line segments + segmentEach(line2, function (segment) { + var doesOverlaps = false; + + // Iterate over each segments which falls within the same bounds + featureEach(tree.search(segment), function (match) { + if (doesOverlaps === false) { + var coordsSegment = getCoords(segment).sort(); + var coordsMatch = getCoords(match).sort(); + + // Segment overlaps feature + if (equal(coordsSegment, coordsMatch)) { + doesOverlaps = true; + // Overlaps already exists - only append last coordinate of segment + if (overlapSegment) overlapSegment = concatSegment(overlapSegment, segment); + else overlapSegment = segment; + // Match segments which don't share nodes (Issue #901) + } else if ( + (tolerance === 0) ? + booleanPointOnLine(coordsSegment[0], match) && booleanPointOnLine(coordsSegment[1], match) : + nearestPointOnLine(match, coordsSegment[0]).properties.dist <= tolerance && + nearestPointOnLine(match, coordsSegment[1]).properties.dist <= tolerance) { + doesOverlaps = true; + if (overlapSegment) overlapSegment = concatSegment(overlapSegment, segment); + else overlapSegment = segment; + } else if ( + (tolerance === 0) ? + booleanPointOnLine(coordsMatch[0], segment) && booleanPointOnLine(coordsMatch[1], segment) : + nearestPointOnLine(segment, coordsMatch[0]).properties.dist <= tolerance && + nearestPointOnLine(segment, coordsMatch[1]).properties.dist <= tolerance) { + // Do not define (doesOverlap = true) since more matches can occur within the same segment + // doesOverlaps = true; + if (overlapSegment) overlapSegment = concatSegment(overlapSegment, match); + else overlapSegment = match; + } + } + }); + + // Segment doesn't overlap - add overlaps to results & reset + if (doesOverlaps === false && overlapSegment) { + features.push(overlapSegment); + overlapSegment = undefined; + } + }); + // Add last segment if exists + if (overlapSegment) features.push(overlapSegment); + + return featureCollection(features); +} + + +/** + * Concat Segment + * + * @private + * @param {Feature} line LineString + * @param {Feature} segment 2-vertex LineString + * @returns {Feature} concat linestring + */ +function concatSegment(line, segment) { + var coords = getCoords(segment); + var lineCoords = getCoords(line); + var start = lineCoords[0]; + var end = lineCoords[lineCoords.length - 1]; + var geom = line.geometry.coordinates; + + if (equal(coords[0], start)) geom.unshift(coords[1]); + else if (equal(coords[0], end)) geom.push(coords[1]); + else if (equal(coords[1], start)) geom.unshift(coords[0]); + else if (equal(coords[1], end)) geom.push(coords[0]); + return line; +} + +export default lineOverlap; diff --git a/src/line-overlap/test.js b/src/line-overlap/test.js new file mode 100644 index 0000000000..96e1e716bd --- /dev/null +++ b/src/line-overlap/test.js @@ -0,0 +1,56 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { featureEach } = require('../meta'); +const { featureCollection, lineString } = require('../helpers'); +const lineOverlap = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); +// fixtures = fixtures.filter(({name}) => name.includes('#901')); + +test('turf-line-overlap', t => { + for (const {filename, name, geojson} of fixtures) { + const [source, target] = geojson.features; + const shared = colorize(lineOverlap(source, target, geojson.properties), '#0F0'); + const results = featureCollection(shared.features.concat([source, target])); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEquals(results, load.sync(directories.out + filename), name); + } + t.end(); +}); + +test('turf-line-overlap - Geometry Object', t => { + const line1 = lineString([[115, -35], [125, -30], [135, -30], [145, -35]]); + const line2 = lineString([[135, -30], [145, -35]]); + + t.true(lineOverlap(line1.geometry, line2.geometry).features.length > 0, 'support geometry object'); + t.end(); +}); + +function colorize(features, color = '#F00', width = 25) { + const results = []; + featureEach(features, feature => { + feature.properties = { + stroke: color, + fill: color, + 'stroke-width': width + }; + results.push(feature); + }); + if (features.type === 'Feature') return results[0]; + return featureCollection(results); +} diff --git a/packages/turf-line-overlap/test/in/boolean-line-overlap.geojson b/src/line-overlap/test/in/boolean-line-overlap.geojson similarity index 100% rename from packages/turf-line-overlap/test/in/boolean-line-overlap.geojson rename to src/line-overlap/test/in/boolean-line-overlap.geojson diff --git a/packages/turf-line-overlap/test/in/issue-#901-simplified.geojson b/src/line-overlap/test/in/issue-#901-simplified.geojson similarity index 100% rename from packages/turf-line-overlap/test/in/issue-#901-simplified.geojson rename to src/line-overlap/test/in/issue-#901-simplified.geojson diff --git a/packages/turf-line-overlap/test/in/issue-#901.geojson b/src/line-overlap/test/in/issue-#901.geojson similarity index 100% rename from packages/turf-line-overlap/test/in/issue-#901.geojson rename to src/line-overlap/test/in/issue-#901.geojson diff --git a/packages/turf-line-overlap/test/in/polygons.geojson b/src/line-overlap/test/in/polygons.geojson similarity index 100% rename from packages/turf-line-overlap/test/in/polygons.geojson rename to src/line-overlap/test/in/polygons.geojson diff --git a/packages/turf-line-overlap/test/in/simple1.geojson b/src/line-overlap/test/in/simple1.geojson similarity index 100% rename from packages/turf-line-overlap/test/in/simple1.geojson rename to src/line-overlap/test/in/simple1.geojson diff --git a/packages/turf-line-overlap/test/in/simple2.geojson b/src/line-overlap/test/in/simple2.geojson similarity index 100% rename from packages/turf-line-overlap/test/in/simple2.geojson rename to src/line-overlap/test/in/simple2.geojson diff --git a/packages/turf-line-overlap/test/in/simple3.geojson b/src/line-overlap/test/in/simple3.geojson similarity index 100% rename from packages/turf-line-overlap/test/in/simple3.geojson rename to src/line-overlap/test/in/simple3.geojson diff --git a/packages/turf-line-overlap/test/out/boolean-line-overlap.geojson b/src/line-overlap/test/out/boolean-line-overlap.geojson similarity index 100% rename from packages/turf-line-overlap/test/out/boolean-line-overlap.geojson rename to src/line-overlap/test/out/boolean-line-overlap.geojson diff --git a/packages/turf-line-overlap/test/out/issue-#901-simplified.geojson b/src/line-overlap/test/out/issue-#901-simplified.geojson similarity index 100% rename from packages/turf-line-overlap/test/out/issue-#901-simplified.geojson rename to src/line-overlap/test/out/issue-#901-simplified.geojson diff --git a/packages/turf-line-overlap/test/out/issue-#901.geojson b/src/line-overlap/test/out/issue-#901.geojson similarity index 100% rename from packages/turf-line-overlap/test/out/issue-#901.geojson rename to src/line-overlap/test/out/issue-#901.geojson diff --git a/packages/turf-line-overlap/test/out/polygons.geojson b/src/line-overlap/test/out/polygons.geojson similarity index 100% rename from packages/turf-line-overlap/test/out/polygons.geojson rename to src/line-overlap/test/out/polygons.geojson diff --git a/packages/turf-line-overlap/test/out/simple1.geojson b/src/line-overlap/test/out/simple1.geojson similarity index 100% rename from packages/turf-line-overlap/test/out/simple1.geojson rename to src/line-overlap/test/out/simple1.geojson diff --git a/packages/turf-line-overlap/test/out/simple2.geojson b/src/line-overlap/test/out/simple2.geojson similarity index 100% rename from packages/turf-line-overlap/test/out/simple2.geojson rename to src/line-overlap/test/out/simple2.geojson diff --git a/packages/turf-line-overlap/test/out/simple3.geojson b/src/line-overlap/test/out/simple3.geojson similarity index 100% rename from packages/turf-line-overlap/test/out/simple3.geojson rename to src/line-overlap/test/out/simple3.geojson diff --git a/packages/turf-line-segment/bench.js b/src/line-segment/bench.js similarity index 100% rename from packages/turf-line-segment/bench.js rename to src/line-segment/bench.js diff --git a/src/line-segment/index.d.ts b/src/line-segment/index.d.ts new file mode 100644 index 0000000000..7e7b4d5621 --- /dev/null +++ b/src/line-segment/index.d.ts @@ -0,0 +1,17 @@ +import { Feature, FeatureCollection, LineString, MultiLineString, MultiPolygon, Polygon } from "../helpers"; +/** + * Creates a {@link FeatureCollection} of 2-vertex {@link LineString} segments from a + * {@link LineString|(Multi)LineString} or {@link Polygon|(Multi)Polygon}. + * + * @name lineSegment + * @param {GeoJSON} geojson GeoJSON Polygon or LineString + * @returns {FeatureCollection} 2-vertex line segments + * @example + * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]); + * var segments = turf.lineSegment(polygon); + * + * //addToMap + * var addToMap = [polygon, segments] + */ +declare function lineSegment(geojson: Feature | FeatureCollection | G): FeatureCollection; +export default lineSegment; diff --git a/src/line-segment/index.js b/src/line-segment/index.js new file mode 100644 index 0000000000..36a429c546 --- /dev/null +++ b/src/line-segment/index.js @@ -0,0 +1,97 @@ +import { featureCollection, lineString } from '../helpers'; +import { getCoords } from '../invariant'; +import { flattenEach } from '../meta'; + +/** + * Creates a {@link FeatureCollection} of 2-vertex {@link LineString} segments from a + * {@link LineString|(Multi)LineString} or {@link Polygon|(Multi)Polygon}. + * + * @name lineSegment + * @param {GeoJSON} geojson GeoJSON Polygon or LineString + * @returns {FeatureCollection} 2-vertex line segments + * @example + * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]); + * var segments = turf.lineSegment(polygon); + * + * //addToMap + * var addToMap = [polygon, segments] + */ +function lineSegment(geojson) { + if (!geojson) { throw new Error('geojson is required'); } + + const results = []; + flattenEach(geojson, function (feature) { + lineSegmentFeature(feature, results); + }); + return featureCollection(results); +} + +/** + * Line Segment + * + * @private + * @param {Feature} geojson Line or polygon feature + * @param {Array} results push to results + * @returns {void} + */ +function lineSegmentFeature(geojson, results) { + let coords = []; + const geometry = geojson.geometry; + if (geometry !== null) { + switch (geometry.type) { + case 'Polygon': + coords = getCoords(geometry); + break; + case 'LineString': + coords = [getCoords(geometry)]; + } + coords.forEach(function (coord) { + const segments = createSegments(coord, geojson.properties); + segments.forEach(function (segment) { + segment.id = results.length; + results.push(segment); + }); + }); + } +} + +/** + * Create Segments from LineString coordinates + * + * @private + * @param {Array>} coords LineString coordinates + * @param {*} properties GeoJSON properties + * @returns {Array>} line segments + */ +function createSegments(coords, properties) { + const segments = []; + coords.reduce(function (previousCoords, currentCoords) { + const segment = lineString([previousCoords, currentCoords], properties); + segment.bbox = bbox(previousCoords, currentCoords); + segments.push(segment); + return currentCoords; + }); + return segments; +} + +/** + * Create BBox between two coordinates (faster than ../bbox) + * + * @private + * @param {Array} coords1 Point coordinate + * @param {Array} coords2 Point coordinate + * @returns {BBox} [west, south, east, north] + */ +function bbox(coords1, coords2) { + const x1 = coords1[0]; + const y1 = coords1[1]; + const x2 = coords2[0]; + const y2 = coords2[1]; + const west = (x1 < x2) ? x1 : x2; + const south = (y1 < y2) ? y1 : y2; + const east = (x1 > x2) ? x1 : x2; + const north = (y1 > y2) ? y1 : y2; + return [west, south, east, north]; +} + +export default lineSegment; diff --git a/src/line-segment/test.js b/src/line-segment/test.js new file mode 100644 index 0000000000..af5e7e146e --- /dev/null +++ b/src/line-segment/test.js @@ -0,0 +1,61 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { featureEach } = require('../meta'); +const { featureCollection, lineString } = require('../helpers'); +const lineSegment = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-line-segment', t => { + for (const {name, filename, geojson} of fixtures) { + const results = colorSegments(lineSegment(geojson)); + featureEach(geojson, feature => { + feature.properties = { + stroke: '#000', + 'stroke-width': 3 + }; + results.features.push(feature); + }); + + // Save output + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(results, load.sync(directories.out + filename), name); + } + t.end(); +}); + +test('turf-line-segment - Geometry Object', t => { + const line = lineString([[115, -35], [125, -30], [135, -30], [145, -35]]); + t.true(lineSegment(line.geometry).features.length > 0, 'geometry object'); + t.end(); +}); + +// Preview 2-vertex LineStrings with colors +function colorSegments(segments) { + const results = featureCollection([]); + featureEach(segments, (feature, index) => { + const r = (index % 2 === 0) ? 'F' : '0'; + const g = (index % 2 === 0) ? '0' : '0'; + const b = (index % 2 === 0) ? '0' : 'F'; + feature.properties = Object.assign({ + stroke: '#' + r + g + b, + 'stroke-width': 10 + }, feature.properties); + results.features.push(feature); + }); + return results; +} diff --git a/packages/turf-line-segment/test/in/2-vertex-segment.geojson b/src/line-segment/test/in/2-vertex-segment.geojson similarity index 100% rename from packages/turf-line-segment/test/in/2-vertex-segment.geojson rename to src/line-segment/test/in/2-vertex-segment.geojson diff --git a/packages/turf-line-segment/test/in/feature-collection.geojson b/src/line-segment/test/in/feature-collection.geojson similarity index 100% rename from packages/turf-line-segment/test/in/feature-collection.geojson rename to src/line-segment/test/in/feature-collection.geojson diff --git a/packages/turf-line-segment/test/in/geometry-collection.geojson b/src/line-segment/test/in/geometry-collection.geojson similarity index 100% rename from packages/turf-line-segment/test/in/geometry-collection.geojson rename to src/line-segment/test/in/geometry-collection.geojson diff --git a/packages/turf-line-segment/test/in/linestring.geojson b/src/line-segment/test/in/linestring.geojson similarity index 100% rename from packages/turf-line-segment/test/in/linestring.geojson rename to src/line-segment/test/in/linestring.geojson diff --git a/packages/turf-line-segment/test/in/multi-linestring.geojson b/src/line-segment/test/in/multi-linestring.geojson similarity index 100% rename from packages/turf-line-segment/test/in/multi-linestring.geojson rename to src/line-segment/test/in/multi-linestring.geojson diff --git a/packages/turf-line-segment/test/in/multi-polygon.geojson b/src/line-segment/test/in/multi-polygon.geojson similarity index 100% rename from packages/turf-line-segment/test/in/multi-polygon.geojson rename to src/line-segment/test/in/multi-polygon.geojson diff --git a/packages/turf-line-segment/test/in/polygon-with-holes.geojson b/src/line-segment/test/in/polygon-with-holes.geojson similarity index 100% rename from packages/turf-line-segment/test/in/polygon-with-holes.geojson rename to src/line-segment/test/in/polygon-with-holes.geojson diff --git a/packages/turf-line-segment/test/in/polygon.geojson b/src/line-segment/test/in/polygon.geojson similarity index 100% rename from packages/turf-line-segment/test/in/polygon.geojson rename to src/line-segment/test/in/polygon.geojson diff --git a/packages/turf-line-segment/test/out/2-vertex-segment.geojson b/src/line-segment/test/out/2-vertex-segment.geojson similarity index 100% rename from packages/turf-line-segment/test/out/2-vertex-segment.geojson rename to src/line-segment/test/out/2-vertex-segment.geojson diff --git a/packages/turf-line-segment/test/out/feature-collection.geojson b/src/line-segment/test/out/feature-collection.geojson similarity index 100% rename from packages/turf-line-segment/test/out/feature-collection.geojson rename to src/line-segment/test/out/feature-collection.geojson diff --git a/packages/turf-line-segment/test/out/geometry-collection.geojson b/src/line-segment/test/out/geometry-collection.geojson similarity index 100% rename from packages/turf-line-segment/test/out/geometry-collection.geojson rename to src/line-segment/test/out/geometry-collection.geojson diff --git a/packages/turf-line-segment/test/out/linestring.geojson b/src/line-segment/test/out/linestring.geojson similarity index 100% rename from packages/turf-line-segment/test/out/linestring.geojson rename to src/line-segment/test/out/linestring.geojson diff --git a/packages/turf-line-segment/test/out/multi-linestring.geojson b/src/line-segment/test/out/multi-linestring.geojson similarity index 100% rename from packages/turf-line-segment/test/out/multi-linestring.geojson rename to src/line-segment/test/out/multi-linestring.geojson diff --git a/packages/turf-line-segment/test/out/multi-polygon.geojson b/src/line-segment/test/out/multi-polygon.geojson similarity index 100% rename from packages/turf-line-segment/test/out/multi-polygon.geojson rename to src/line-segment/test/out/multi-polygon.geojson diff --git a/packages/turf-line-segment/test/out/polygon-with-holes.geojson b/src/line-segment/test/out/polygon-with-holes.geojson similarity index 100% rename from packages/turf-line-segment/test/out/polygon-with-holes.geojson rename to src/line-segment/test/out/polygon-with-holes.geojson diff --git a/packages/turf-line-segment/test/out/polygon.geojson b/src/line-segment/test/out/polygon.geojson similarity index 100% rename from packages/turf-line-segment/test/out/polygon.geojson rename to src/line-segment/test/out/polygon.geojson diff --git a/packages/turf-line-slice-along/bench.js b/src/line-slice-along/bench.js similarity index 100% rename from packages/turf-line-slice-along/bench.js rename to src/line-slice-along/bench.js diff --git a/src/line-slice-along/index.d.ts b/src/line-slice-along/index.d.ts new file mode 100644 index 0000000000..f280a64e24 --- /dev/null +++ b/src/line-slice-along/index.d.ts @@ -0,0 +1,13 @@ +import { Units, LineString, Feature} from '../helpers' + +/** + * http://turfjs.org/docs/ + */ +export default function lineSliceAlong( + line: Feature | LineString, + startDist: number, + stopDist: number, + options?: { + units?: Units + } +): Feature; diff --git a/src/line-slice-along/index.js b/src/line-slice-along/index.js new file mode 100644 index 0000000000..79f1bee682 --- /dev/null +++ b/src/line-slice-along/index.js @@ -0,0 +1,82 @@ +import bearing from '../rhumb-bearing'; +import distance from '../rhumb-distance'; +import destination from '../rhumb-destination'; +import { lineString, isObject } from '../helpers'; + +/** + * Takes a {@link LineString|line}, a specified distance along the line to a start {@link Point}, + * and a specified distance along the line to a stop point + * and returns a subsection of the line in-between those points. + * + * This can be useful for extracting only the part of a route between two distances. + * + * @name lineSliceAlong + * @param {Feature|LineString} line input line + * @param {number} startDist distance along the line to starting point + * @param {number} stopDist distance along the line to ending point + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers + * @returns {Feature} sliced line + * @example + * var line = turf.lineString([[7, 45], [9, 45], [14, 40], [14, 41]]); + * var start = 12.5; + * var stop = 25; + * var sliced = turf.lineSliceAlong(line, start, stop, {units: 'miles'}); + * + * //addToMap + * var addToMap = [line, start, stop, sliced] + */ +function lineSliceAlong(line, startDist, stopDist, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + + var coords; + var slice = []; + + // Validation + if (line.type === 'Feature') coords = line.geometry.coordinates; + else if (line.type === 'LineString') coords = line.coordinates; + else throw new Error('input must be a LineString Feature or Geometry'); + + var travelled = 0; + var overshot, direction, interpolated; + for (var i = 0; i < coords.length; i++) { + if (startDist >= travelled && i === coords.length - 1) throw new Error('Start distance is beyond length of line'); + else if (travelled > startDist && slice.length === 0) { + overshot = startDist - travelled; + if (!overshot) { + slice.push(coords[i]); + return lineString(slice); + } + direction = bearing(coords[i], coords[i - 1]) - 180; + interpolated = destination(coords[i], overshot, direction, options); + slice.push(interpolated.geometry.coordinates); + } + + if (travelled >= stopDist) { + overshot = stopDist - travelled; + if (!overshot) { + slice.push(coords[i]); + return lineString(slice); + } + direction = bearing(coords[i], coords[i - 1]) - 180; + interpolated = destination(coords[i], overshot, direction, options); + slice.push(interpolated.geometry.coordinates); + return lineString(slice); + } + + if (travelled >= startDist) { + slice.push(coords[i]); + } + + if (i === coords.length - 1) { + return lineString(slice); + } + + travelled += distance(coords[i], coords[i + 1], options); + } + return lineString(coords[coords.length - 1]); +} + +export default lineSliceAlong; diff --git a/src/line-slice-along/test.js b/src/line-slice-along/test.js new file mode 100644 index 0000000000..f656d631dd --- /dev/null +++ b/src/line-slice-along/test.js @@ -0,0 +1,78 @@ +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import along from '../along'; +import lineSliceAlong from '.'; + +var line1 = load.sync(path.join(__dirname, 'test', 'fixtures', 'line1.geojson')); +var route1 = load.sync(path.join(__dirname, 'test', 'fixtures', 'route1.geojson')); +var route2 = load.sync(path.join(__dirname, 'test', 'fixtures', 'route2.geojson')); + +test('turf-line-slice -- line1', function (t) { + var start = 500; + var stop = 750; + var options = {units: 'miles'}; + + var start_point = along(line1, start, options); + var end_point = along(line1, stop, options); + var sliced = lineSliceAlong(line1, start, stop, options); + t.equal(sliced.type, 'Feature'); + t.equal(sliced.geometry.type, 'LineString'); + t.deepEqual(sliced.geometry.coordinates[0], start_point.geometry.coordinates); + t.deepEqual(sliced.geometry.coordinates[sliced.geometry.coordinates.length - 1], end_point.geometry.coordinates); + t.end(); +}); + +test('turf-line-slice -- line1 overshoot', function (t) { + var start = 500; + var stop = 1500; + var options = {units: 'miles'}; + + var start_point = along(line1, start, options); + var end_point = along(line1, stop, options); + var sliced = lineSliceAlong(line1, start, stop, options); + t.equal(sliced.type, 'Feature'); + t.equal(sliced.geometry.type, 'LineString'); + t.deepEqual(sliced.geometry.coordinates[0], start_point.geometry.coordinates); + t.deepEqual(sliced.geometry.coordinates[sliced.geometry.coordinates.length - 1], end_point.geometry.coordinates); + t.end(); +}); + +test('turf-line-slice-along -- route1', function (t) { + var start = 500; + var stop = 750; + var options = {units: 'miles'}; + + var start_point = along(route1, start, options); + var end_point = along(route1, stop, options); + var sliced = lineSliceAlong(route1, start, stop, options); + t.equal(sliced.type, 'Feature'); + t.equal(sliced.geometry.type, 'LineString'); + t.deepEqual(sliced.geometry.coordinates[0], start_point.geometry.coordinates); + t.deepEqual(sliced.geometry.coordinates[sliced.geometry.coordinates.length - 1], end_point.geometry.coordinates); + t.end(); +}); + +test('turf-line-slice-along -- route2', function (t) { + var start = 25; + var stop = 50; + var options = {units: 'miles'}; + + var start_point = along(route2, start, options); + var end_point = along(route2, stop, options); + var sliced = lineSliceAlong(route2, start, stop, options); + t.equal(sliced.type, 'Feature'); + t.equal(sliced.geometry.type, 'LineString'); + t.deepEqual(sliced.geometry.coordinates[0], start_point.geometry.coordinates); + t.deepEqual(sliced.geometry.coordinates[sliced.geometry.coordinates.length - 1], end_point.geometry.coordinates); + t.end(); +}); + +test('turf-line-slice -- start longer than line length', function (t) { + var start = 500000; + var stop = 800000; + var options = {units: 'miles'}; + + t.throws(() => lineSliceAlong(line1, start, stop, options), 'Start position is beyond line'); + t.end(); +}); diff --git a/packages/turf-line-slice-along/test/fixtures/line1.geojson b/src/line-slice-along/test/fixtures/line1.geojson similarity index 100% rename from packages/turf-line-slice-along/test/fixtures/line1.geojson rename to src/line-slice-along/test/fixtures/line1.geojson diff --git a/packages/turf-line-slice-along/test/fixtures/route1.geojson b/src/line-slice-along/test/fixtures/route1.geojson similarity index 100% rename from packages/turf-line-slice-along/test/fixtures/route1.geojson rename to src/line-slice-along/test/fixtures/route1.geojson diff --git a/packages/turf-line-slice-along/test/fixtures/route2.geojson b/src/line-slice-along/test/fixtures/route2.geojson similarity index 100% rename from packages/turf-line-slice-along/test/fixtures/route2.geojson rename to src/line-slice-along/test/fixtures/route2.geojson diff --git a/src/line-slice/bench.js b/src/line-slice/bench.js new file mode 100644 index 0000000000..dbd13b9f91 --- /dev/null +++ b/src/line-slice/bench.js @@ -0,0 +1,34 @@ +import fs from 'fs'; +import Benchmark from 'benchmark'; +import { point } from '../helpers'; +import lineSlice from './'; + +var route1 = JSON.parse(fs.readFileSync(__dirname + '/test/in/route1.geojson')); +var route2 = JSON.parse(fs.readFileSync(__dirname + '/test/in/route2.geojson')); +var line1 = JSON.parse(fs.readFileSync(__dirname + '/test/in/line1.geojson')); + +var start1 = point([-97.79617309570312,22.254624939561698]); +var stop1 = point([-97.72750854492188,22.057641623615734]); +var start2 = point([-79.0850830078125,37.60117623656667]); +var stop2 = point([-77.7667236328125,38.65119833229951]); +var start3 = point([-112.60660171508789,45.96021963947196]); +var stop3 = point([-111.97265625,48.84302835299516]); + +var suite = new Benchmark.Suite('turf-line-slice'); +suite + .add('turf-line-slice#simple',function () { + lineSlice(start1, stop1, line1); + }) + .add('turf-line-slice#route1',function () { + lineSlice(start2, stop2, route1); + }) + .add('turf-line-slice#route2',function () { + lineSlice(start3, stop3, route2); + }) + .on('cycle', function (event) { + console.log(String(event.target)); + }) + .on('complete', function () { + + }) + .run(); diff --git a/src/line-slice/index.d.ts b/src/line-slice/index.d.ts new file mode 100644 index 0000000000..989efc0c7e --- /dev/null +++ b/src/line-slice/index.d.ts @@ -0,0 +1,10 @@ +import { Feature, LineString, Coord } from '../helpers' + +/** + * http://turfjs.org/docs/#lineslice + */ +export default function lineSlice( + startPt: Coord, + stopPt: Coord, + line: Feature | LineString +): Feature; diff --git a/src/line-slice/index.js b/src/line-slice/index.js new file mode 100644 index 0000000000..e3844bfd28 --- /dev/null +++ b/src/line-slice/index.js @@ -0,0 +1,55 @@ +import { getCoords, getType } from '../invariant'; +import { lineString as linestring } from '../helpers'; +import nearestPointOnLine from '../nearest-point-on-line'; + +/** + * Takes a {@link LineString|line}, a start {@link Point}, and a stop point + * and returns a subsection of the line in-between those points. + * The start & stop points don't need to fall exactly on the line. + * + * This can be useful for extracting only the part of a route between waypoints. + * + * @name lineSlice + * @param {Coord} startPt starting point + * @param {Coord} stopPt stopping point + * @param {Feature|LineString} line line to slice + * @returns {Feature} sliced line + * @example + * var line = turf.lineString([ + * [-77.031669, 38.878605], + * [-77.029609, 38.881946], + * [-77.020339, 38.884084], + * [-77.025661, 38.885821], + * [-77.021884, 38.889563], + * [-77.019824, 38.892368] + * ]); + * var start = turf.point([-77.029609, 38.881946]); + * var stop = turf.point([-77.021884, 38.889563]); + * + * var sliced = turf.lineSlice(start, stop, line); + * + * //addToMap + * var addToMap = [start, stop, line] + */ +function lineSlice(startPt, stopPt, line) { + // Validation + var coords = getCoords(line); + if (getType(line) !== 'LineString') throw new Error('line must be a LineString'); + + var startVertex = nearestPointOnLine(line, startPt); + var stopVertex = nearestPointOnLine(line, stopPt); + var ends; + if (startVertex.properties.index <= stopVertex.properties.index) { + ends = [startVertex, stopVertex]; + } else { + ends = [stopVertex, startVertex]; + } + var clipCoords = [ends[0].geometry.coordinates]; + for (var i = ends[0].properties.index + 1; i < ends[1].properties.index + 1; i++) { + clipCoords.push(coords[i]); + } + clipCoords.push(ends[1].geometry.coordinates); + return linestring(clipCoords, line.properties); +} + +export default lineSlice; diff --git a/src/line-slice/test.js b/src/line-slice/test.js new file mode 100644 index 0000000000..6d226bef67 --- /dev/null +++ b/src/line-slice/test.js @@ -0,0 +1,36 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import truncate from '../truncate'; +import { featureCollection } from '../helpers'; +import lineSlice from './'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-line-slice', t => { + for (const {filename, geojson, name} of fixtures) { + const [linestring, start, stop] = geojson.features; + const sliced = truncate(lineSlice(start, stop, linestring)); + sliced.properties['stroke'] = '#f0f'; + sliced.properties['stroke-width'] = 6; + const results = featureCollection(geojson.features); + results.features.push(sliced); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEquals(results, load.sync(directories.out + filename), name); + } + t.end(); +}); diff --git a/packages/turf-line-slice/test/in/line1.geojson b/src/line-slice/test/in/line1.geojson similarity index 100% rename from packages/turf-line-slice/test/in/line1.geojson rename to src/line-slice/test/in/line1.geojson diff --git a/packages/turf-line-slice/test/in/line2.geojson b/src/line-slice/test/in/line2.geojson similarity index 100% rename from packages/turf-line-slice/test/in/line2.geojson rename to src/line-slice/test/in/line2.geojson diff --git a/packages/turf-line-slice/test/in/route1.geojson b/src/line-slice/test/in/route1.geojson similarity index 100% rename from packages/turf-line-slice/test/in/route1.geojson rename to src/line-slice/test/in/route1.geojson diff --git a/packages/turf-line-slice/test/in/route2.geojson b/src/line-slice/test/in/route2.geojson similarity index 100% rename from packages/turf-line-slice/test/in/route2.geojson rename to src/line-slice/test/in/route2.geojson diff --git a/packages/turf-line-slice/test/in/vertical.geojson b/src/line-slice/test/in/vertical.geojson similarity index 100% rename from packages/turf-line-slice/test/in/vertical.geojson rename to src/line-slice/test/in/vertical.geojson diff --git a/packages/turf-line-slice/test/out/line1.geojson b/src/line-slice/test/out/line1.geojson similarity index 100% rename from packages/turf-line-slice/test/out/line1.geojson rename to src/line-slice/test/out/line1.geojson diff --git a/packages/turf-line-slice/test/out/line2.geojson b/src/line-slice/test/out/line2.geojson similarity index 100% rename from packages/turf-line-slice/test/out/line2.geojson rename to src/line-slice/test/out/line2.geojson diff --git a/packages/turf-line-slice/test/out/route1.geojson b/src/line-slice/test/out/route1.geojson similarity index 100% rename from packages/turf-line-slice/test/out/route1.geojson rename to src/line-slice/test/out/route1.geojson diff --git a/packages/turf-line-slice/test/out/route2.geojson b/src/line-slice/test/out/route2.geojson similarity index 100% rename from packages/turf-line-slice/test/out/route2.geojson rename to src/line-slice/test/out/route2.geojson diff --git a/packages/turf-line-slice/test/out/vertical.geojson b/src/line-slice/test/out/vertical.geojson similarity index 100% rename from packages/turf-line-slice/test/out/vertical.geojson rename to src/line-slice/test/out/vertical.geojson diff --git a/packages/turf-line-split/bench.js b/src/line-split/bench.js similarity index 100% rename from packages/turf-line-split/bench.js rename to src/line-split/bench.js diff --git a/src/line-split/index.d.ts b/src/line-split/index.d.ts new file mode 100644 index 0000000000..d922bb90b2 --- /dev/null +++ b/src/line-split/index.d.ts @@ -0,0 +1,20 @@ +import { + Feature, + FeatureCollection, + Point, + MultiPoint, + LineString, + MultiLineString, + Polygon, + MultiPolygon, +} from '../helpers'; + +export type Splitter = Feature + +/** + * http://turfjs.org/docs/#linesplit + */ +export default function lineSplit( + line: Feature | T, + splitter: Splitter +): FeatureCollection; diff --git a/src/line-split/index.js b/src/line-split/index.js new file mode 100644 index 0000000000..9fd94edcd7 --- /dev/null +++ b/src/line-split/index.js @@ -0,0 +1,204 @@ +import rbush from '../spatial-index'; +import square from '../square'; +import bbox from '../bbox'; +import truncate from '../truncate'; +import lineSegment from '../line-segment'; +import lineIntersect from '../line-intersect'; +import nearestPointOnLine from '../nearest-point-on-line'; +import { getCoords, getCoord, getType } from '../invariant'; +import { featureEach, featureReduce, flattenEach } from '../meta'; +import { lineString, featureCollection } from '../helpers'; + +/** + * Split a LineString by another GeoJSON Feature. + * + * @name lineSplit + * @param {Feature} line LineString Feature to split + * @param {Feature} splitter Feature used to split line + * @returns {FeatureCollection} Split LineStrings + * @example + * var line = turf.lineString([[120, -25], [145, -25]]); + * var splitter = turf.lineString([[130, -15], [130, -35]]); + * + * var split = turf.lineSplit(line, splitter); + * + * //addToMap + * var addToMap = [line, splitter] + */ +function lineSplit(line, splitter) { + if (!line) throw new Error('line is required'); + if (!splitter) throw new Error('splitter is required'); + + var lineType = getType(line); + var splitterType = getType(splitter); + + if (lineType !== 'LineString') throw new Error('line must be LineString'); + if (splitterType === 'FeatureCollection') throw new Error('splitter cannot be a FeatureCollection'); + if (splitterType === 'GeometryCollection') throw new Error('splitter cannot be a GeometryCollection'); + + // remove excessive decimals from splitter + // to avoid possible approximation issues in rbush + var truncatedSplitter = truncate(splitter, {precision: 7}); + + switch (splitterType) { + case 'Point': + return splitLineWithPoint(line, truncatedSplitter); + case 'MultiPoint': + return splitLineWithPoints(line, truncatedSplitter); + case 'LineString': + case 'MultiLineString': + case 'Polygon': + case 'MultiPolygon': + return splitLineWithPoints(line, lineIntersect(line, truncatedSplitter)); + } +} + +/** + * Split LineString with MultiPoint + * + * @private + * @param {Feature} line LineString + * @param {FeatureCollection} splitter Point + * @returns {FeatureCollection} split LineStrings + */ +function splitLineWithPoints(line, splitter) { + var results = []; + var tree = rbush(); + + flattenEach(splitter, function (point) { + // Add index/id to features (needed for filter) + results.forEach(function (feature, index) { + feature.id = index; + }); + // First Point - doesn't need to handle any previous line results + if (!results.length) { + results = splitLineWithPoint(line, point).features; + + // Add Square BBox to each feature for GeoJSON-RBush + results.forEach(function (feature) { + if (!feature.bbox) feature.bbox = square(bbox(feature)); + }); + tree.load(featureCollection(results)); + // Split with remaining points - lines might needed to be split multiple times + } else { + // Find all lines that are within the splitter's bbox + var search = tree.search(point); + + if (search.features.length) { + // RBush might return multiple lines - only process the closest line to splitter + var closestLine = findClosestFeature(point, search); + + // Remove closest line from results since this will be split into two lines + // This removes any duplicates inside the results & index + results = results.filter(function (feature) { return feature.id !== closestLine.id; }); + tree.remove(closestLine); + + // Append the two newly split lines into the results + featureEach(splitLineWithPoint(closestLine, point), function (line) { + results.push(line); + tree.insert(line); + }); + } + } + }); + return featureCollection(results); +} + +/** + * Split LineString with Point + * + * @private + * @param {Feature} line LineString + * @param {Feature} splitter Point + * @returns {FeatureCollection} split LineStrings + */ +function splitLineWithPoint(line, splitter) { + var results = []; + + // handle endpoints + var startPoint = getCoords(line)[0]; + var endPoint = getCoords(line)[line.geometry.coordinates.length - 1]; + if (pointsEquals(startPoint, getCoord(splitter)) || + pointsEquals(endPoint, getCoord(splitter))) return featureCollection([line]); + + // Create spatial index + var tree = rbush(); + var segments = lineSegment(line); + tree.load(segments); + + // Find all segments that are within bbox of splitter + var search = tree.search(splitter); + + // Return itself if point is not within spatial index + if (!search.features.length) return featureCollection([line]); + + // RBush might return multiple lines - only process the closest line to splitter + var closestSegment = findClosestFeature(splitter, search); + + // Initial value is the first point of the first segments (beginning of line) + var initialValue = [startPoint]; + var lastCoords = featureReduce(segments, function (previous, current, index) { + var currentCoords = getCoords(current)[1]; + var splitterCoords = getCoord(splitter); + + // Location where segment intersects with line + if (index === closestSegment.id) { + previous.push(splitterCoords); + results.push(lineString(previous)); + // Don't duplicate splitter coordinate (Issue #688) + if (pointsEquals(splitterCoords, currentCoords)) return [splitterCoords]; + return [splitterCoords, currentCoords]; + + // Keep iterating over coords until finished or intersection is found + } else { + previous.push(currentCoords); + return previous; + } + }, initialValue); + // Append last line to final split results + if (lastCoords.length > 1) { + results.push(lineString(lastCoords)); + } + return featureCollection(results); +} + + +/** + * Find Closest Feature + * + * @private + * @param {Feature} point Feature must be closest to this point + * @param {FeatureCollection} lines Collection of Features + * @returns {Feature} closest LineString + */ +function findClosestFeature(point, lines) { + if (!lines.features.length) throw new Error('lines must contain features'); + // Filter to one segment that is the closest to the line + if (lines.features.length === 1) return lines.features[0]; + + var closestFeature; + var closestDistance = Infinity; + featureEach(lines, function (segment) { + var pt = nearestPointOnLine(segment, point); + var dist = pt.properties.dist; + if (dist < closestDistance) { + closestFeature = segment; + closestDistance = dist; + } + }); + return closestFeature; +} + +/** + * Compares two points and returns if they are equals + * + * @private + * @param {Array} pt1 point + * @param {Array} pt2 point + * @returns {boolean} true if they are equals + */ +function pointsEquals(pt1, pt2) { + return pt1[0] === pt2[0] && pt1[1] === pt2[1]; +} + +export default lineSplit; diff --git a/src/line-split/test.js b/src/line-split/test.js new file mode 100644 index 0000000000..8175bf0f1c --- /dev/null +++ b/src/line-split/test.js @@ -0,0 +1,138 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import { featureEach } from '../meta'; +import { point, lineString, multiPoint, featureCollection, round } from '../helpers'; +import { getCoords } from '../invariant'; +import lineSplit from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-line-split', t => { + for (const {filename, name, geojson} of fixtures) { + const line = geojson.features[0]; + const splitter = geojson.features[1]; + const results = colorize(lineSplit(line, splitter)); + featureEach(geojson, feature => results.features.push(feature)); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEquals(results, load.sync(directories.out + filename), name); + } + t.end(); +}); + +test('turf-line-split -- lines should split the same feature 1 with 2 as 2 with 1', t => { + const featureOne = lineString([[114.58215786065353825, -14.82470576519326144], [137.21678649707752129, -16.71692980416107588]]); + const featureTwo = lineString([[119.1412061636556956, -19.83670052919270788], [133.06640625, -12.64033830684678961]]); + + const resultsOne = lineSplit(featureOne, featureTwo); + const resultsTwo = lineSplit(featureTwo, featureOne); + + const midCoordOne = getCoords(resultsOne.features[0])[1]; + const midCoordTwo = getCoords(resultsTwo.features[1])[0]; + + // Round precision to 6 decimals + midCoordOne[0] = round(midCoordOne[0], 6); + midCoordOne[1] = round(midCoordOne[1], 6); + midCoordTwo[0] = round(midCoordTwo[0], 6); + midCoordTwo[1] = round(midCoordTwo[1], 6); + t.deepEquals(midCoordOne, midCoordTwo, 'Splits were made in different locations'); + t.end(); +}); + +test('turf-line-split -- throws', t => { + const pt = point([9, 50]); + const line = lineString([[7, 50], [8, 50], [9, 50]]); + + t.throws(() => lineSplit(null, pt), ' is required'); + t.throws(() => lineSplit(line, null), ' is required'); + t.throws(() => lineSplit(pt, pt), ' must be LineString'); + t.throws(() => lineSplit(line, featureCollection([pt, line])), ' cannot be a FeatureCollection'); + t.end(); +}); + +test('turf-line-split -- splitter exactly on end of line', t => { + const pt = point([9, 50]); + const line = lineString([[7, 50], [8, 50], [9, 50]]); + const features = lineSplit(line, pt).features; + + t.deepEqual(features, [line], 'should only contain 1 line of 3 vertices'); + t.end(); +}); + + +test('turf-line-split -- lines should only contain 2 vertices #688', t => { + const middlePoint = point([8, 50]); + const line = lineString([[7, 50], [8, 50], [9, 50]]); + const [line1, line2] = lineSplit(line, middlePoint).features; + + t.deepEqual(line1, lineString([[7, 50], [8, 50]]), 'line1 should have 2 vertices'); + t.deepEqual(line2, lineString([[8, 50], [9, 50]]), 'line2 should have 2 vertices'); + t.end(); +}); + +test('turf-line-split -- precision issue #852', t => { + const line = lineString([[9.2202022, 49.1438226], [9.2199531, 49.1439048], [9.2196177, 49.1440264]]); + const startPoint = point([9.2202022, 49.1438226]); + const middlePoint = point([9.2199531, 49.1439048]); + const endPoint = point([9.2196177, 49.1440264]); + const [line1, line2] = lineSplit(line, middlePoint).features; + + t.deepEqual(line1, lineString([[9.2202022, 49.1438226], [9.2199531, 49.1439048]]), 'middlePoint: line1 should have 2 vertices'); + t.deepEqual(line2, lineString([[9.2199531, 49.1439048], [9.2196177, 49.1440264]]), 'middlePoint: line2 should have 2 vertices'); + t.deepEqual(lineSplit(line, startPoint).features, [line], 'startPoint: should only contain 1 line of 3 vertices'); + t.deepEqual(lineSplit(line, endPoint).features, [line], 'endPoint: should only contain 1 line of 3 vertices'); + t.end(); +}); + +test('turf-line-split -- prevent input mutation', t => { + const line = lineString([[9.2202022, 49.1438226], [9.2199531, 49.1439048], [9.2196177, 49.1440264]]); + const lineBefore = JSON.parse(JSON.stringify(line)); + lineSplit(line, point([9.2196177, 49.1440264])); + + t.deepEqual(line, lineBefore, 'line should be the same'); + t.end(); +}); + +test('turf-line-split -- issue #1075', t => { + const line = lineString([[-87.168433, 37.946093], [-87.168510, 37.960085]]); + const splitter = multiPoint([[-87.168446, 37.947929], [-87.168445, 37.948301]]); + const split = lineSplit(line, splitter); + t.assert(split); + t.end(); +}) + +/** + * Colorize FeatureCollection + * + * @param {FeatureCollection|Feature} geojson Feature or FeatureCollection + * @returns {FeatureCollection} colorized FeatureCollection + */ +function colorize(geojson) { + const results = []; + featureEach(geojson, (feature, index) => { + const r = (index % 2 === 0) ? 'F' : '0'; + const g = '0'; + const b = (index % 2 === 0) ? '0' : 'F'; + feature.properties = Object.assign({ + stroke: '#' + r + g + b, + 'stroke-width': 10 + }, feature.properties); + results.push(feature); + }); + return featureCollection(results); +} + diff --git a/packages/turf-line-split/test/in/issue-#1075-1.geojson b/src/line-split/test/in/issue-#1075-1.geojson similarity index 100% rename from packages/turf-line-split/test/in/issue-#1075-1.geojson rename to src/line-split/test/in/issue-#1075-1.geojson diff --git a/packages/turf-line-split/test/in/issue-#1075-2.geojson b/src/line-split/test/in/issue-#1075-2.geojson similarity index 100% rename from packages/turf-line-split/test/in/issue-#1075-2.geojson rename to src/line-split/test/in/issue-#1075-2.geojson diff --git a/packages/turf-line-split/test/in/issue-#1075-3.geojson b/src/line-split/test/in/issue-#1075-3.geojson similarity index 100% rename from packages/turf-line-split/test/in/issue-#1075-3.geojson rename to src/line-split/test/in/issue-#1075-3.geojson diff --git a/packages/turf-line-split/test/in/issue-#852.geojson b/src/line-split/test/in/issue-#852.geojson similarity index 100% rename from packages/turf-line-split/test/in/issue-#852.geojson rename to src/line-split/test/in/issue-#852.geojson diff --git a/packages/turf-line-split/test/in/linestrings.geojson b/src/line-split/test/in/linestrings.geojson similarity index 100% rename from packages/turf-line-split/test/in/linestrings.geojson rename to src/line-split/test/in/linestrings.geojson diff --git a/packages/turf-line-split/test/in/multi-linestring.geojson b/src/line-split/test/in/multi-linestring.geojson similarity index 100% rename from packages/turf-line-split/test/in/multi-linestring.geojson rename to src/line-split/test/in/multi-linestring.geojson diff --git a/packages/turf-line-split/test/in/multi-polygon.geojson b/src/line-split/test/in/multi-polygon.geojson similarity index 100% rename from packages/turf-line-split/test/in/multi-polygon.geojson rename to src/line-split/test/in/multi-polygon.geojson diff --git a/packages/turf-line-split/test/in/multiPoint-on-line-1.geojson b/src/line-split/test/in/multiPoint-on-line-1.geojson similarity index 100% rename from packages/turf-line-split/test/in/multiPoint-on-line-1.geojson rename to src/line-split/test/in/multiPoint-on-line-1.geojson diff --git a/packages/turf-line-split/test/in/multiPoint-on-line-2.geojson b/src/line-split/test/in/multiPoint-on-line-2.geojson similarity index 100% rename from packages/turf-line-split/test/in/multiPoint-on-line-2.geojson rename to src/line-split/test/in/multiPoint-on-line-2.geojson diff --git a/packages/turf-line-split/test/in/point-on-line-1.geojson b/src/line-split/test/in/point-on-line-1.geojson similarity index 100% rename from packages/turf-line-split/test/in/point-on-line-1.geojson rename to src/line-split/test/in/point-on-line-1.geojson diff --git a/packages/turf-line-split/test/in/point-on-line-2.geojson b/src/line-split/test/in/point-on-line-2.geojson similarity index 100% rename from packages/turf-line-split/test/in/point-on-line-2.geojson rename to src/line-split/test/in/point-on-line-2.geojson diff --git a/packages/turf-line-split/test/in/point-on-line-3.geojson b/src/line-split/test/in/point-on-line-3.geojson similarity index 100% rename from packages/turf-line-split/test/in/point-on-line-3.geojson rename to src/line-split/test/in/point-on-line-3.geojson diff --git a/packages/turf-line-split/test/in/polygon-with-holes.geojson b/src/line-split/test/in/polygon-with-holes.geojson similarity index 100% rename from packages/turf-line-split/test/in/polygon-with-holes.geojson rename to src/line-split/test/in/polygon-with-holes.geojson diff --git a/packages/turf-line-split/test/in/polygon.geojson b/src/line-split/test/in/polygon.geojson similarity index 100% rename from packages/turf-line-split/test/in/polygon.geojson rename to src/line-split/test/in/polygon.geojson diff --git a/packages/turf-line-split/test/out/issue-#1075-1.geojson b/src/line-split/test/out/issue-#1075-1.geojson similarity index 100% rename from packages/turf-line-split/test/out/issue-#1075-1.geojson rename to src/line-split/test/out/issue-#1075-1.geojson diff --git a/packages/turf-line-split/test/out/issue-#1075-2.geojson b/src/line-split/test/out/issue-#1075-2.geojson similarity index 100% rename from packages/turf-line-split/test/out/issue-#1075-2.geojson rename to src/line-split/test/out/issue-#1075-2.geojson diff --git a/packages/turf-line-split/test/out/issue-#1075-3.geojson b/src/line-split/test/out/issue-#1075-3.geojson similarity index 100% rename from packages/turf-line-split/test/out/issue-#1075-3.geojson rename to src/line-split/test/out/issue-#1075-3.geojson diff --git a/packages/turf-line-split/test/out/issue-#852.geojson b/src/line-split/test/out/issue-#852.geojson similarity index 100% rename from packages/turf-line-split/test/out/issue-#852.geojson rename to src/line-split/test/out/issue-#852.geojson diff --git a/packages/turf-line-split/test/out/linestrings.geojson b/src/line-split/test/out/linestrings.geojson similarity index 100% rename from packages/turf-line-split/test/out/linestrings.geojson rename to src/line-split/test/out/linestrings.geojson diff --git a/packages/turf-line-split/test/out/multi-linestring.geojson b/src/line-split/test/out/multi-linestring.geojson similarity index 100% rename from packages/turf-line-split/test/out/multi-linestring.geojson rename to src/line-split/test/out/multi-linestring.geojson diff --git a/packages/turf-line-split/test/out/multi-polygon.geojson b/src/line-split/test/out/multi-polygon.geojson similarity index 100% rename from packages/turf-line-split/test/out/multi-polygon.geojson rename to src/line-split/test/out/multi-polygon.geojson diff --git a/packages/turf-line-split/test/out/multiPoint-on-line-1.geojson b/src/line-split/test/out/multiPoint-on-line-1.geojson similarity index 100% rename from packages/turf-line-split/test/out/multiPoint-on-line-1.geojson rename to src/line-split/test/out/multiPoint-on-line-1.geojson diff --git a/packages/turf-line-split/test/out/multiPoint-on-line-2.geojson b/src/line-split/test/out/multiPoint-on-line-2.geojson similarity index 100% rename from packages/turf-line-split/test/out/multiPoint-on-line-2.geojson rename to src/line-split/test/out/multiPoint-on-line-2.geojson diff --git a/packages/turf-line-split/test/out/point-on-line-1.geojson b/src/line-split/test/out/point-on-line-1.geojson similarity index 100% rename from packages/turf-line-split/test/out/point-on-line-1.geojson rename to src/line-split/test/out/point-on-line-1.geojson diff --git a/packages/turf-line-split/test/out/point-on-line-2.geojson b/src/line-split/test/out/point-on-line-2.geojson similarity index 100% rename from packages/turf-line-split/test/out/point-on-line-2.geojson rename to src/line-split/test/out/point-on-line-2.geojson diff --git a/packages/turf-line-split/test/out/point-on-line-3.geojson b/src/line-split/test/out/point-on-line-3.geojson similarity index 100% rename from packages/turf-line-split/test/out/point-on-line-3.geojson rename to src/line-split/test/out/point-on-line-3.geojson diff --git a/packages/turf-line-split/test/out/polygon-with-holes.geojson b/src/line-split/test/out/polygon-with-holes.geojson similarity index 100% rename from packages/turf-line-split/test/out/polygon-with-holes.geojson rename to src/line-split/test/out/polygon-with-holes.geojson diff --git a/packages/turf-line-split/test/out/polygon.geojson b/src/line-split/test/out/polygon.geojson similarity index 100% rename from packages/turf-line-split/test/out/polygon.geojson rename to src/line-split/test/out/polygon.geojson diff --git a/packages/turf-line-to-polygon/bench.js b/src/line-to-polygon/bench.js similarity index 100% rename from packages/turf-line-to-polygon/bench.js rename to src/line-to-polygon/bench.js diff --git a/src/line-to-polygon/index.js b/src/line-to-polygon/index.js new file mode 100644 index 0000000000..5f8429b162 --- /dev/null +++ b/src/line-to-polygon/index.js @@ -0,0 +1,126 @@ +import turfBBox from '../bbox'; +import { getCoords, getType, getGeom } from '../invariant'; +import { polygon, multiPolygon, lineString, isObject} from '../helpers'; + +/** + * Converts (Multi)LineString(s) to Polygon(s). + * + * @name lineToPolygon + * @param {FeatureCollection|Feature} lines Features to convert + * @param {Object} [options={}] Optional parameters + * @param {Object} [options.properties={}] translates GeoJSON properties to Feature + * @param {boolean} [options.autoComplete=true] auto complete linestrings (matches first & last coordinates) + * @param {boolean} [options.orderCoords=true] sorts linestrings to place outer ring at the first position of the coordinates + * @returns {Feature} converted to Polygons + * @example + * var line = turf.lineString([[125, -30], [145, -30], [145, -20], [125, -20], [125, -30]]); + * + * var polygon = turf.lineToPolygon(line); + * + * //addToMap + * var addToMap = [polygon]; + */ +function lineToPolygon(lines, options) { + // Optional parameters + var properties = options.properties; + var autoComplete = options.autoComplete; + var orderCoords = options.orderCoords; + + // default params + autoComplete = (autoComplete !== undefined) ? autoComplete : true; + orderCoords = (orderCoords !== undefined) ? orderCoords : true; + + switch (lines.type) { + case 'FeatureCollection': + var coords = []; + lines.features.forEach(function (line) { + coords.push(getCoords(lineStringToPolygon(line, {}, autoComplete, orderCoords))); + }); + return multiPolygon(coords, properties); + default: + return lineStringToPolygon(lines, properties, autoComplete, orderCoords); + } +} + +/** + * LineString to Polygon + * + * @private + * @param {Feature} line line + * @param {Object} [properties] translates GeoJSON properties to Feature + * @param {boolean} [autoComplete=true] auto complete linestrings + * @param {boolean} [orderCoords=true] sorts linestrings to place outer ring at the first position of the coordinates + * @returns {Feature} line converted to Polygon + */ +function lineStringToPolygon(line, properties, autoComplete, orderCoords) { + properties = properties ? properties : (line.type === 'Feature') ? line.properties : {}; + var geom = getGeom(line); + var coords = geom.coordinates; + var type = geom.type; + + if (!coords.length) throw new Error('line must contain coordinates'); + + switch (type) { + case 'LineString': + if (autoComplete) coords = autoCompleteCoords(coords); + return polygon([coords], properties); + case 'MultiLineString': + var multiCoords = []; + var largestArea = 0; + + coords.forEach(function (coord) { + if (autoComplete) coord = autoCompleteCoords(coord); + + // Largest LineString to be placed in the first position of the coordinates array + if (orderCoords) { + var area = calculateArea(turfBBox(lineString(coord))); + if (area > largestArea) { + multiCoords.unshift(coord); + largestArea = area; + } else multiCoords.push(coord); + } else { + multiCoords.push(coord); + } + }); + return polygon(multiCoords, properties); + default: + throw new Error('geometry type ' + type + ' is not supported'); + } +} + +/** + * Auto Complete Coords - matches first & last coordinates + * + * @private + * @param {Array>} coords Coordinates + * @returns {Array>} auto completed coordinates + */ +function autoCompleteCoords(coords) { + var first = coords[0]; + var x1 = first[0]; + var y1 = first[1]; + var last = coords[coords.length - 1]; + var x2 = last[0]; + var y2 = last[1]; + if (x1 !== x2 || y1 !== y2) { + coords.push(first); + } + return coords; +} + +/** + * area - quick approximate area calculation (used to sort) + * + * @private + * @param {Array} bbox BBox [west, south, east, north] + * @returns {number} very quick area calculation + */ +function calculateArea(bbox) { + var west = bbox[0]; + var south = bbox[1]; + var east = bbox[2]; + var north = bbox[3]; + return Math.abs(west - east) * Math.abs(south - north); +} + +export default lineToPolygon; diff --git a/src/line-to-polygon/test.js b/src/line-to-polygon/test.js new file mode 100644 index 0000000000..d09969810b --- /dev/null +++ b/src/line-to-polygon/test.js @@ -0,0 +1,41 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { point, lineString } = require('../helpers'); +const lineToPolygon = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); +// fixtures = fixtures.filter(fixture => fixture.name === 'multi-linestrings-with-holes'); + +test('turf-linestring-to-polygon', t => { + for (const {name, filename, geojson} of fixtures) { + let {autoComplete, properties, orderCoords} = geojson.properties || {}; + properties = properties || {stroke: '#F0F', 'stroke-width': 6}; + const results = lineToPolygon(geojson, { + properties: properties, + autoComplete: autoComplete, + orderCoords: orderCoords + }); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(load.sync(directories.out + filename), results, name); + } + // Handle Errors + t.throws(() => lineToPolygon(point([10, 5])), 'throws - invalid geometry'); + t.throws(() => lineToPolygon(lineString([])), 'throws - empty coordinates'); + t.assert(lineToPolygon(lineString([[10, 5], [20, 10], [30, 20]]), {autocomplete: false}), 'is valid - autoComplete=false'); + t.end(); +}); diff --git a/packages/turf-line-to-polygon/test/in/collection-linestring.geojson b/src/line-to-polygon/test/in/collection-linestring.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/in/collection-linestring.geojson rename to src/line-to-polygon/test/in/collection-linestring.geojson diff --git a/packages/turf-line-to-polygon/test/in/geometry-linestring.geojson b/src/line-to-polygon/test/in/geometry-linestring.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/in/geometry-linestring.geojson rename to src/line-to-polygon/test/in/geometry-linestring.geojson diff --git a/packages/turf-line-to-polygon/test/in/linestring-incomplete.geojson b/src/line-to-polygon/test/in/linestring-incomplete.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/in/linestring-incomplete.geojson rename to src/line-to-polygon/test/in/linestring-incomplete.geojson diff --git a/packages/turf-line-to-polygon/test/in/linestring.geojson b/src/line-to-polygon/test/in/linestring.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/in/linestring.geojson rename to src/line-to-polygon/test/in/linestring.geojson diff --git a/packages/turf-line-to-polygon/test/in/linestrings-to-multipolygons.geojson b/src/line-to-polygon/test/in/linestrings-to-multipolygons.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/in/linestrings-to-multipolygons.geojson rename to src/line-to-polygon/test/in/linestrings-to-multipolygons.geojson diff --git a/packages/turf-line-to-polygon/test/in/multi-linestring-incomplete.geojson b/src/line-to-polygon/test/in/multi-linestring-incomplete.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/in/multi-linestring-incomplete.geojson rename to src/line-to-polygon/test/in/multi-linestring-incomplete.geojson diff --git a/packages/turf-line-to-polygon/test/in/multi-linestring-nested.geojson b/src/line-to-polygon/test/in/multi-linestring-nested.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/in/multi-linestring-nested.geojson rename to src/line-to-polygon/test/in/multi-linestring-nested.geojson diff --git a/packages/turf-line-to-polygon/test/in/multi-linestring-nested2.geojson b/src/line-to-polygon/test/in/multi-linestring-nested2.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/in/multi-linestring-nested2.geojson rename to src/line-to-polygon/test/in/multi-linestring-nested2.geojson diff --git a/packages/turf-line-to-polygon/test/in/multi-linestring-outer-ring-middle-position.geojson b/src/line-to-polygon/test/in/multi-linestring-outer-ring-middle-position.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/in/multi-linestring-outer-ring-middle-position.geojson rename to src/line-to-polygon/test/in/multi-linestring-outer-ring-middle-position.geojson diff --git a/packages/turf-line-to-polygon/test/in/multi-linestring-with-hole.geojson b/src/line-to-polygon/test/in/multi-linestring-with-hole.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/in/multi-linestring-with-hole.geojson rename to src/line-to-polygon/test/in/multi-linestring-with-hole.geojson diff --git a/packages/turf-line-to-polygon/test/in/multi-linestrings-nested.geojson b/src/line-to-polygon/test/in/multi-linestrings-nested.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/in/multi-linestrings-nested.geojson rename to src/line-to-polygon/test/in/multi-linestrings-nested.geojson diff --git a/packages/turf-line-to-polygon/test/in/multi-linestrings-outer-doughnut.geojson b/src/line-to-polygon/test/in/multi-linestrings-outer-doughnut.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/in/multi-linestrings-outer-doughnut.geojson rename to src/line-to-polygon/test/in/multi-linestrings-outer-doughnut.geojson diff --git a/packages/turf-line-to-polygon/test/in/multi-linestrings-with-holes.geojson b/src/line-to-polygon/test/in/multi-linestrings-with-holes.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/in/multi-linestrings-with-holes.geojson rename to src/line-to-polygon/test/in/multi-linestrings-with-holes.geojson diff --git a/packages/turf-line-to-polygon/test/out/collection-linestring.geojson b/src/line-to-polygon/test/out/collection-linestring.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/out/collection-linestring.geojson rename to src/line-to-polygon/test/out/collection-linestring.geojson diff --git a/packages/turf-line-to-polygon/test/out/geometry-linestring.geojson b/src/line-to-polygon/test/out/geometry-linestring.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/out/geometry-linestring.geojson rename to src/line-to-polygon/test/out/geometry-linestring.geojson diff --git a/packages/turf-line-to-polygon/test/out/linestring-incomplete.geojson b/src/line-to-polygon/test/out/linestring-incomplete.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/out/linestring-incomplete.geojson rename to src/line-to-polygon/test/out/linestring-incomplete.geojson diff --git a/packages/turf-line-to-polygon/test/out/linestring.geojson b/src/line-to-polygon/test/out/linestring.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/out/linestring.geojson rename to src/line-to-polygon/test/out/linestring.geojson diff --git a/packages/turf-line-to-polygon/test/out/linestrings-to-multipolygons.geojson b/src/line-to-polygon/test/out/linestrings-to-multipolygons.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/out/linestrings-to-multipolygons.geojson rename to src/line-to-polygon/test/out/linestrings-to-multipolygons.geojson diff --git a/packages/turf-line-to-polygon/test/out/multi-linestring-incomplete.geojson b/src/line-to-polygon/test/out/multi-linestring-incomplete.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/out/multi-linestring-incomplete.geojson rename to src/line-to-polygon/test/out/multi-linestring-incomplete.geojson diff --git a/packages/turf-line-to-polygon/test/out/multi-linestring-nested.geojson b/src/line-to-polygon/test/out/multi-linestring-nested.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/out/multi-linestring-nested.geojson rename to src/line-to-polygon/test/out/multi-linestring-nested.geojson diff --git a/packages/turf-line-to-polygon/test/out/multi-linestring-nested2.geojson b/src/line-to-polygon/test/out/multi-linestring-nested2.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/out/multi-linestring-nested2.geojson rename to src/line-to-polygon/test/out/multi-linestring-nested2.geojson diff --git a/packages/turf-line-to-polygon/test/out/multi-linestring-outer-ring-middle-position.geojson b/src/line-to-polygon/test/out/multi-linestring-outer-ring-middle-position.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/out/multi-linestring-outer-ring-middle-position.geojson rename to src/line-to-polygon/test/out/multi-linestring-outer-ring-middle-position.geojson diff --git a/packages/turf-line-to-polygon/test/out/multi-linestring-with-hole.geojson b/src/line-to-polygon/test/out/multi-linestring-with-hole.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/out/multi-linestring-with-hole.geojson rename to src/line-to-polygon/test/out/multi-linestring-with-hole.geojson diff --git a/packages/turf-line-to-polygon/test/out/multi-linestrings-nested.geojson b/src/line-to-polygon/test/out/multi-linestrings-nested.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/out/multi-linestrings-nested.geojson rename to src/line-to-polygon/test/out/multi-linestrings-nested.geojson diff --git a/packages/turf-line-to-polygon/test/out/multi-linestrings-outer-doughnut.geojson b/src/line-to-polygon/test/out/multi-linestrings-outer-doughnut.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/out/multi-linestrings-outer-doughnut.geojson rename to src/line-to-polygon/test/out/multi-linestrings-outer-doughnut.geojson diff --git a/packages/turf-line-to-polygon/test/out/multi-linestrings-with-holes.geojson b/src/line-to-polygon/test/out/multi-linestrings-with-holes.geojson similarity index 100% rename from packages/turf-line-to-polygon/test/out/multi-linestrings-with-holes.geojson rename to src/line-to-polygon/test/out/multi-linestrings-with-holes.geojson diff --git a/packages/turf-mask/bench.js b/src/mask/bench.js similarity index 100% rename from packages/turf-mask/bench.js rename to src/mask/bench.js diff --git a/src/mask/index.d.ts b/src/mask/index.d.ts new file mode 100644 index 0000000000..a28aa7357a --- /dev/null +++ b/src/mask/index.d.ts @@ -0,0 +1,9 @@ +import { Feature, Polygon, MultiPolygon, FeatureCollection } from '../helpers' + +/** + * http://turfjs.org/docs/#mask + */ +export default function ( + poly: Feature | FeatureCollection | T, + mask?: Feature | Polygon +): Feature; diff --git a/src/mask/index.js b/src/mask/index.js new file mode 100644 index 0000000000..223ceb4641 --- /dev/null +++ b/src/mask/index.js @@ -0,0 +1,49 @@ +import union from '../union'; +import { polygon, featureCollection } from '../helpers'; + +/** + * Takes any type of {@link Polygon|polygon} and an optional mask and returns a {@link Polygon|polygon} exterior ring with holes. + * + * @name mask + * @param {FeatureCollection|Feature} polygon GeoJSON Polygon or a Feature Collection of polygons, used as interior rings or holes. + * @param {FeatureCollection|Feature} [mask] GeoJSON Polygon used as the exterior ring (if undefined, the world extent is used) + * @returns {Feature} Masked Polygon (exterior ring with holes). + * @example + * var polygon = turf.polygon([[[112, -21], [116, -36], [146, -39], [153, -24], [133, -10], [112, -21]]]); + * var mask = turf.polygon([[[90, -55], [170, -55], [170, 10], [90, 10], [90, -55]]]); + * + * var masked = turf.mask(polygon, mask); + * + * //addToMap + * var addToMap = [masked] + */ +function mask(polygon, mask) { + // Define mask + const maskPolygon = createMask(mask); + + let polygonOuters = null; + if (polygon.type === 'FeatureCollection') polygonOuters = union(polygon); + else polygonOuters = union(featureCollection([polygon])); + + polygonOuters.geometry.coordinates.forEach(function (contour) { + maskPolygon.geometry.coordinates.push(contour[0]); + }); + + return maskPolygon; +} + +/** + * Create Mask Coordinates + * + * @private + * @param {Feature} [mask] default to world if undefined + * @returns {Feature} mask coordinate + */ +function createMask(mask) { + const world = [[[180, 90], [-180, 90], [-180, -90], [180, -90], [180, 90]]]; + const coordinates = mask && mask.geometry.coordinates || world; + return polygon(coordinates); +} + +export default mask; + diff --git a/src/mask/test.js b/src/mask/test.js new file mode 100644 index 0000000000..dc45cb6511 --- /dev/null +++ b/src/mask/test.js @@ -0,0 +1,40 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import mask from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(path.join(directories.in, filename)) + }; +}); + +test('turf-mask', t => { + for (const {name, filename, geojson} of fixtures) { + let masking, polygon + + if (geojson.features.length > 2) { + polygon = geojson + masking = geojson.features.pop() + } else { + polygon = geojson.features[0] + masking = geojson.features[1] + } + + // const + const results = mask(polygon, masking); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEquals(results, load.sync(directories.out + filename), name); + } + t.end(); +}); diff --git a/packages/turf-mask/test/in/basic.geojson b/src/mask/test/in/basic.geojson similarity index 100% rename from packages/turf-mask/test/in/basic.geojson rename to src/mask/test/in/basic.geojson diff --git a/src/mask/test/in/issue-1454.geojson b/src/mask/test/in/issue-1454.geojson new file mode 100644 index 0000000000..adebca09d1 --- /dev/null +++ b/src/mask/test/in/issue-1454.geojson @@ -0,0 +1,7811 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.1962044601525, + -38.070781985126125 + ], + [ + 145.1964469001104, + -38.070915178704816 + ], + [ + 145.19656398535707, + -38.07076741191429 + ], + [ + 145.19632403176286, + -38.070636329016494 + ], + [ + 145.1962044601525, + -38.070781985126125 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10076, + "ZONE_STATU": "g", + "ZONE_CODE": "HO76", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO76", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.20040874245777, + -37.98583631024065 + ], + [ + 145.20121615551554, + -37.98639917584917 + ], + [ + 145.20130120367136, + -37.98604998788433 + ], + [ + 145.20122318383144, + -37.986038342763464 + ], + [ + 145.20129757319532, + -37.98571421972205 + ], + [ + 145.20143032604523, + -37.98573372981032 + ], + [ + 145.20150351389745, + -37.98542031013467 + ], + [ + 145.20162298077736, + -37.98543790488453 + ], + [ + 145.2016587284229, + -37.98528122708929 + ], + [ + 145.200950412855, + -37.98478988847401 + ], + [ + 145.20044405907424, + -37.985136323236226 + ], + [ + 145.20035796989782, + -37.985405035365346 + ], + [ + 145.2002539884307, + -37.98572969595075 + ], + [ + 145.20040874245777, + -37.98583631024065 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2751, + "ZONE_STATU": "g", + "ZONE_CODE": "HO1", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO1", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.20093034750982, + -37.98166734481136 + ], + [ + 145.20096221292363, + -37.98150430073155 + ], + [ + 145.20099407818216, + -37.98134125663524 + ], + [ + 145.20102594108602, + -37.98117830258885 + ], + [ + 145.20106575153397, + -37.98097438448268 + ], + [ + 145.20109964132843, + -37.98080146030431 + ], + [ + 145.20107474727226, + -37.98076747213593 + ], + [ + 145.2007615342388, + -37.980729793486574 + ], + [ + 145.20050429968532, + -37.98069882718384 + ], + [ + 145.20024715701794, + -37.980667951826284 + ], + [ + 145.19993862411016, + -37.98063088322311 + ], + [ + 145.1998979348281, + -37.98065548835381 + ], + [ + 145.19986493677234, + -37.980830227814856 + ], + [ + 145.19982643258624, + -37.98103434568451 + ], + [ + 145.19979569550117, + -37.98119722651923 + ], + [ + 145.19976495386402, + -37.98136028747089 + ], + [ + 145.19973421427756, + -37.98152325834044 + ], + [ + 145.19970380011037, + -37.98168443217787 + ], + [ + 145.19967263640217, + -37.98184937872799 + ], + [ + 145.2002692297477, + -37.981920320066024 + ], + [ + 145.20086673646247, + -37.98199235356064 + ], + [ + 145.20089913082367, + -37.98182688490043 + ], + [ + 145.20093034750982, + -37.98166734481136 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2752, + "ZONE_STATU": "g", + "ZONE_CODE": "HO2", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-11-21T13:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO2", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.17376632369604, + -37.966737840227786 + ], + [ + 145.17433600348826, + -37.96680552070668 + ], + [ + 145.1743532090789, + -37.966717219565 + ], + [ + 145.17438805567042, + -37.966538191329946 + ], + [ + 145.17432096791347, + -37.966529581461685 + ], + [ + 145.17381962878358, + -37.96646548498017 + ], + [ + 145.17381906804383, + -37.966465386172736 + ], + [ + 145.17378429609468, + -37.9666451361861 + ], + [ + 145.17376632369604, + -37.966737840227786 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2753, + "ZONE_STATU": "g", + "ZONE_CODE": "HO3", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO3", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.15602548829676, + -38.01934869445461 + ], + [ + 145.1559304836285, + -38.02008097020962 + ], + [ + 145.15764627780985, + -38.02034285330762 + ], + [ + 145.15777911061562, + -38.01962972927903 + ], + [ + 145.15602548829676, + -38.01934869445461 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2758, + "ZONE_STATU": "g", + "ZONE_CODE": "HO8", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO8", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.16065383570765, + -37.99021833008073 + ], + [ + 145.16074578617176, + -37.99022850814726 + ], + [ + 145.1611464380814, + -37.99027351764025 + ], + [ + 145.16144185017657, + -37.990306608832775 + ], + [ + 145.16192911517854, + -37.99036125916263 + ], + [ + 145.1620906319748, + -37.99037937124756 + ], + [ + 145.16253735396, + -37.99042951102648 + ], + [ + 145.16294119275472, + -37.99047483452103 + ], + [ + 145.1629510254348, + -37.990475889144875 + ], + [ + 145.16330327223983, + -37.99051544982795 + ], + [ + 145.1633038353915, + -37.99051545862511 + ], + [ + 145.1635489036119, + -37.98927285029522 + ], + [ + 145.16356009087335, + -37.989215811846464 + ], + [ + 145.16357126014887, + -37.989159493911075 + ], + [ + 145.16357069700743, + -37.989159485115465 + ], + [ + 145.1632238867023, + -37.98912055081495 + ], + [ + 145.1630519789186, + -37.989101286874785 + ], + [ + 145.16287932262748, + -37.98908192088917 + ], + [ + 145.16270825750803, + -37.98906275971358 + ], + [ + 145.16253672545128, + -37.98904350089309 + ], + [ + 145.16236491192433, + -37.98902423742385 + ], + [ + 145.16219178675203, + -37.98900486310291 + ], + [ + 145.16194918867316, + -37.98897764504338 + ], + [ + 145.1616568721265, + -37.98894487386917 + ], + [ + 145.16148271944445, + -37.988925302242556 + ], + [ + 145.16126727510775, + -37.988901120252955 + ], + [ + 145.1610752365602, + -37.988879646525774 + ], + [ + 145.16092177700247, + -37.988862379898336 + ], + [ + 145.16065383570765, + -37.99021833008073 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2762, + "ZONE_STATU": "g", + "ZONE_CODE": "HO12", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO12", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.208447717051, + -37.983808020969256 + ], + [ + 145.20846644153363, + -37.983810198360445 + ], + [ + 145.20852629056705, + -37.98381615581488 + ], + [ + 145.20853051376142, + -37.983793064425875 + ], + [ + 145.2085334354877, + -37.98377716121801 + ], + [ + 145.20856436020694, + -37.9836096857341 + ], + [ + 145.20856446720157, + -37.98360914676343 + ], + [ + 145.208510358647, + -37.98360264608906 + ], + [ + 145.20834083272084, + -37.983581953004624 + ], + [ + 145.208340730106, + -37.98358231184156 + ], + [ + 145.20833018059218, + -37.98364161717846 + ], + [ + 145.2083159318353, + -37.98372176937543 + ], + [ + 145.20829831794376, + -37.98382061111822 + ], + [ + 145.20829451828143, + -37.983841726748985 + ], + [ + 145.20843841682841, + -37.983858425436836 + ], + [ + 145.208447717051, + -37.983808020969256 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2770, + "ZONE_STATU": "g", + "ZONE_CODE": "HO20", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO20", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.20853051376142, + -37.983793064425875 + ], + [ + 145.20857396051903, + -37.98379787095667 + ], + [ + 145.2085728818085, + -37.983803620930274 + ], + [ + 145.2086131441642, + -37.98380810863142 + ], + [ + 145.2086082505516, + -37.983835604715914 + ], + [ + 145.20869233075138, + -37.983845084746 + ], + [ + 145.20869570067956, + -37.98384549648437 + ], + [ + 145.20874166397667, + -37.98385106209172 + ], + [ + 145.2087472082637, + -37.983819971908396 + ], + [ + 145.20875599520434, + -37.98377136159735 + ], + [ + 145.20878032089058, + -37.98363586117022 + ], + [ + 145.20878042350338, + -37.98363550233284 + ], + [ + 145.20874822156821, + -37.98363158798009 + ], + [ + 145.2087353966685, + -37.98363004110773 + ], + [ + 145.20856446720157, + -37.98360914676343 + ], + [ + 145.20856436020694, + -37.9836096857341 + ], + [ + 145.2085334354877, + -37.98377716121801 + ], + [ + 145.20853051376142, + -37.983793064425875 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2769, + "ZONE_STATU": "g", + "ZONE_CODE": "HO19", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO19", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.14623999710878, + -38.01774391842125 + ], + [ + 145.1475527795656, + -38.01659413890841 + ], + [ + 145.14746204895653, + -38.01650071805776 + ], + [ + 145.14837614886983, + -38.011835650229294 + ], + [ + 145.1481035522985, + -38.01180342549216 + ], + [ + 145.14723448395105, + -38.016361802910474 + ], + [ + 145.14589982713082, + -38.017473842833084 + ], + [ + 145.14574665929277, + -38.01736826357449 + ], + [ + 145.1449608214699, + -38.01800628866028 + ], + [ + 145.1457030785069, + -38.01860913872286 + ], + [ + 145.1464651507225, + -38.01792271127711 + ], + [ + 145.14623999710878, + -38.01774391842125 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10022, + "ZONE_STATU": "g", + "ZONE_CODE": "HO22", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO22", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.1498073030163, + -38.01200504535165 + ], + [ + 145.14935337394604, + -38.01440633627869 + ], + [ + 145.15173012990834, + -38.01468420436961 + ], + [ + 145.15217331738788, + -38.01232616248385 + ], + [ + 145.15213211478303, + -38.01228010489715 + ], + [ + 145.1498073030163, + -38.01200504535165 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10023, + "ZONE_STATU": "g", + "ZONE_CODE": "HO23", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO23", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21419440214066, + -37.98949516254397 + ], + [ + 145.21417933837708, + -37.98935744098182 + ], + [ + 145.214173868981, + -37.98930807314931 + ], + [ + 145.2136198904963, + -37.98935074467011 + ], + [ + 145.21362545338175, + -37.989400113944875 + ], + [ + 145.21364114918123, + -37.98953496196609 + ], + [ + 145.2136404899767, + -37.98953504205106 + ], + [ + 145.21365282700125, + -37.98964578231171 + ], + [ + 145.213653390162, + -37.989645790867634 + ], + [ + 145.21420582541919, + -37.989604897776076 + ], + [ + 145.21420648243992, + -37.98960490775488 + ], + [ + 145.21419440214066, + -37.98949516254397 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10036, + "ZONE_STATU": "g", + "ZONE_CODE": "HO36", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO36", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.16993505665968, + -37.95807535844177 + ], + [ + 145.1698757106477, + -37.958375278891644 + ], + [ + 145.16983192181632, + -37.958596693986955 + ], + [ + 145.1705063528857, + -37.958430591161445 + ], + [ + 145.1707045856875, + -37.95848304944971 + ], + [ + 145.17087418661714, + -37.958497940904316 + ], + [ + 145.17257785051802, + -37.96137491909324 + ], + [ + 145.17349512527986, + -37.96101507331575 + ], + [ + 145.17290373431427, + -37.960401316107586 + ], + [ + 145.17273472487702, + -37.96024876391026 + ], + [ + 145.1725877444984, + -37.96014277507405 + ], + [ + 145.17207935444972, + -37.959626710445946 + ], + [ + 145.1709837709993, + -37.95772009979153 + ], + [ + 145.17080625253985, + -37.957786085291055 + ], + [ + 145.16998420095163, + -37.95810324324417 + ], + [ + 145.16993561062338, + -37.95807572746175 + ], + [ + 145.16993505665968, + -37.95807535844177 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10044, + "ZONE_STATU": "g", + "ZONE_CODE": "HO44", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO44", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.1464070697804, + -37.943935049622155 + ], + [ + 145.148452122342, + -37.945482740093816 + ], + [ + 145.14848122524822, + -37.94550464199583 + ], + [ + 145.14851347426537, + -37.945337653888814 + ], + [ + 145.14853526811402, + -37.945224561146674 + ], + [ + 145.14663610748119, + -37.9437489083303 + ], + [ + 145.1464070697804, + -37.943935049622155 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10046, + "ZONE_STATU": "g", + "ZONE_CODE": "HO46", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO46", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.1462173578213, + -37.94359805947292 + ], + [ + 145.14644912946454, + -37.94377362268094 + ], + [ + 145.14656081070345, + -37.943765471553625 + ], + [ + 145.14658914680464, + -37.943616171993376 + ], + [ + 145.14659120604463, + -37.943534213515726 + ], + [ + 145.14665530961042, + -37.94322365805874 + ], + [ + 145.14629404249038, + -37.94317525781493 + ], + [ + 145.1462173578213, + -37.94359805947292 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10046, + "ZONE_STATU": "g", + "ZONE_CODE": "HO46", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO46", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.20575499371057, + -37.980860874280445 + ], + [ + 145.20578191026922, + -37.98072325158858 + ], + [ + 145.2058083833248, + -37.98058841522374 + ], + [ + 145.2058347690063, + -37.98045330721563 + ], + [ + 145.20583487162827, + -37.98045294838088 + ], + [ + 145.20561313363532, + -37.98042541805682 + ], + [ + 145.20561257054754, + -37.98042540946416 + ], + [ + 145.205605356961, + -37.98046332164203 + ], + [ + 145.20557834585426, + -37.98060481715947 + ], + [ + 145.20555121226442, + -37.980747482099126 + ], + [ + 145.20552559866573, + -37.980881700812546 + ], + [ + 145.20547393213818, + -37.9811527444104 + ], + [ + 145.20547392116822, + -37.981153194743605 + ], + [ + 145.20611392343702, + -37.98123044517957 + ], + [ + 145.20614796440645, + -37.981212764268236 + ], + [ + 145.2062045184023, + -37.980914404469516 + ], + [ + 145.2062039553106, + -37.980914395879594 + ], + [ + 145.20575499371057, + -37.980860874280445 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10048, + "ZONE_STATU": "g", + "ZONE_CODE": "HO48", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO48", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.1500250061197, + -37.95363548939198 + ], + [ + 145.14995227726533, + -37.954046822365775 + ], + [ + 145.150461676871, + -37.954107092006346 + ], + [ + 145.15054254074747, + -37.953693093520755 + ], + [ + 145.1500250061197, + -37.95363548939198 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10062, + "ZONE_STATU": "g", + "ZONE_CODE": "HO62", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO62", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21314805036354, + -37.98608141000037 + ], + [ + 145.21325430378468, + -37.986074915619724 + ], + [ + 145.21323834176098, + -37.985896905471805 + ], + [ + 145.21312882551007, + -37.985902449255185 + ], + [ + 145.21314805036354, + -37.98608141000037 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10063, + "ZONE_STATU": "g", + "ZONE_CODE": "HO63", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO63", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21311406618847, + -37.98590321606372 + ], + [ + 145.2130025942577, + -37.98590809930817 + ], + [ + 145.213006956213, + -37.98595276517272 + ], + [ + 145.21302017955688, + -37.98608883715651 + ], + [ + 145.2130201686311, + -37.98608928749119 + ], + [ + 145.21314805036354, + -37.98608141000037 + ], + [ + 145.21312882551007, + -37.985902449255185 + ], + [ + 145.21311406618847, + -37.98590321606372 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10064, + "ZONE_STATU": "g", + "ZONE_CODE": "HO64", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO64", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21135105897775, + -37.98581964774277 + ], + [ + 145.21127919251973, + -37.98619634433079 + ], + [ + 145.21175711347178, + -37.986168474645524 + ], + [ + 145.2117261675482, + -37.98582274030334 + ], + [ + 145.21135105897775, + -37.98581964774277 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10065, + "ZONE_STATU": "g", + "ZONE_CODE": "HO65", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO65", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21153707829595, + -37.990168545743614 + ], + [ + 145.21160161926107, + -37.99017484334661 + ], + [ + 145.2116577881608, + -37.98988404373354 + ], + [ + 145.2115925146263, + -37.98986539131069 + ], + [ + 145.21151390659927, + -37.98984293201988 + ], + [ + 145.21145208409558, + -37.989825233013576 + ], + [ + 145.21140081567927, + -37.99009979895651 + ], + [ + 145.21145275024128, + -37.99016122631573 + ], + [ + 145.21153707829595, + -37.990168545743614 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2764, + "ZONE_STATU": "g", + "ZONE_CODE": "HO14", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-11-06T13:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO14", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21887265859021, + -37.99073526267574 + ], + [ + 145.2185575470827, + -37.99092141102858 + ], + [ + 145.21883200924344, + -37.99121244797558 + ], + [ + 145.21883258113155, + -37.99121209623843 + ], + [ + 145.21913884862798, + -37.99103058851695 + ], + [ + 145.21914599501525, + -37.991026281849756 + ], + [ + 145.2191456304569, + -37.99102582582737 + ], + [ + 145.21887265859021, + -37.99073526267574 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10032, + "ZONE_STATU": "g", + "ZONE_CODE": "HO32", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": null, + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO32", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.2175973851073, + -37.989900170730486 + ], + [ + 145.21759681322396, + -37.98990052246182 + ], + [ + 145.21787319970224, + -37.99019321259413 + ], + [ + 145.21787376940708, + -37.9901929509286 + ], + [ + 145.21845819406852, + -37.9898544713981 + ], + [ + 145.21845782952002, + -37.989854015373744 + ], + [ + 145.2181865472224, + -37.9895559979311 + ], + [ + 145.2175973851073, + -37.989900170730486 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10029, + "ZONE_STATU": "g", + "ZONE_CODE": "HO29", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": null, + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO29", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.218527796312, + -37.98935655127855 + ], + [ + 145.21849770080786, + -37.98937411532626 + ], + [ + 145.2181865472224, + -37.9895559979311 + ], + [ + 145.21845782952002, + -37.989854015373744 + ], + [ + 145.21845819406852, + -37.9898544713981 + ], + [ + 145.21880406699074, + -37.98965410291594 + ], + [ + 145.21880463668822, + -37.9896538412457 + ], + [ + 145.21852836818675, + -37.989356199542456 + ], + [ + 145.218527796312, + -37.98935655127855 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10040, + "ZONE_STATU": "g", + "ZONE_CODE": "HO40", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": null, + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO40", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.20971813943157, + -37.9816819057111 + ], + [ + 145.21012383021332, + -37.98151896367714 + ], + [ + 145.2097566781485, + -37.98118937422853 + ], + [ + 145.20941784648852, + -37.98140973584238 + ], + [ + 145.20971813943157, + -37.9816819057111 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10049, + "ZONE_STATU": "g", + "ZONE_CODE": "HO49", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "https://objappsvr1.cgd.vic.gov.au/id:A558624/document/versions/latest|Document", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.22448790488335, + -37.95274453817248 + ], + [ + 145.22446945129806, + -37.95284445162972 + ], + [ + 145.22444991205313, + -37.95295047554337 + ], + [ + 145.2247427209448, + -37.95298543957695 + ], + [ + 145.2248828071493, + -37.95300224030942 + ], + [ + 145.22531682651737, + -37.95305411055084 + ], + [ + 145.22531738723464, + -37.95305420911205 + ], + [ + 145.22538370942183, + -37.95269660880357 + ], + [ + 145.22538314870715, + -37.95269651024274 + ], + [ + 145.2249533659978, + -37.95264416359744 + ], + [ + 145.22474509508785, + -37.952711388939086 + ], + [ + 145.22460407182467, + -37.95275692361969 + ], + [ + 145.22448790488335, + -37.95274453817248 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10074, + "ZONE_STATU": "g", + "ZONE_CODE": "HO74", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO74", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "https://objective.cgd.vic.gov.au/id:A1293661/document/versions/published|Heritage Site" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.1506109109806, + -37.95182387609682 + ], + [ + 145.1505599417122, + -37.952086256309975 + ], + [ + 145.15053127958575, + -37.95223374955999 + ], + [ + 145.15082114172407, + -37.952268580780014 + ], + [ + 145.1509012406048, + -37.95185871445616 + ], + [ + 145.1506109109806, + -37.95182387609682 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10077, + "ZONE_STATU": "g", + "ZONE_CODE": "HO77", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO77", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "https://objective.cgd.vic.gov.au/id:A1293663/document/versions/published|Heritage Site" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21079240337662, + -37.9888695962072 + ], + [ + 145.2107659998465, + -37.989028851762825 + ], + [ + 145.21076656300164, + -37.989028860332446 + ], + [ + 145.21123424559187, + -37.98900191837058 + ], + [ + 145.21123480874692, + -37.98900192693796 + ], + [ + 145.21121839864358, + -37.98883868623474 + ], + [ + 145.21121783548975, + -37.988838677667324 + ], + [ + 145.21079296871866, + -37.98886951470988 + ], + [ + 145.21079240337662, + -37.9888695962072 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10043, + "ZONE_STATU": "g", + "ZONE_CODE": "HO43", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO43", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21322633729847, + -37.985795720785596 + ], + [ + 145.21323834176098, + -37.985896905471805 + ], + [ + 145.2132803781156, + -37.98589412043091 + ], + [ + 145.2138156707884, + -37.98585819419702 + ], + [ + 145.21381623392023, + -37.985858202751444 + ], + [ + 145.21380554912628, + -37.98576064216925 + ], + [ + 145.21379602318552, + -37.98567337060724 + ], + [ + 145.21379545787093, + -37.98567345211974 + ], + [ + 145.21322221412538, + -37.985710243186325 + ], + [ + 145.21321629033048, + -37.98571060366998 + ], + [ + 145.21321637326113, + -37.98571105543095 + ], + [ + 145.21322633729847, + -37.985795720785596 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10038, + "ZONE_STATU": "g", + "ZONE_CODE": "HO38", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO38", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21330008623698, + -37.98520938841569 + ], + [ + 145.2132995231103, + -37.98520937985893 + ], + [ + 145.21331603865062, + -37.98533360863324 + ], + [ + 145.21375526142836, + -37.98530613383067 + ], + [ + 145.21375582455596, + -37.98530614238527 + ], + [ + 145.21374591462296, + -37.98521535107446 + ], + [ + 145.21374534931186, + -37.98521543258681 + ], + [ + 145.21339380692314, + -37.98523955442483 + ], + [ + 145.21336324304136, + -37.98524161282846 + ], + [ + 145.21335932596222, + -37.98520569344593 + ], + [ + 145.21330008623698, + -37.98520938841569 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10039, + "ZONE_STATU": "g", + "ZONE_CODE": "HO39", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO39", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21787376940708, + -37.9901929509286 + ], + [ + 145.21787319970224, + -37.99019321259413 + ], + [ + 145.21841938238012, + -37.99077182366466 + ], + [ + 145.21934107453143, + -37.99023175988644 + ], + [ + 145.21880463668822, + -37.9896538412457 + ], + [ + 145.21880406699074, + -37.98965410291594 + ], + [ + 145.21845819406852, + -37.9898544713981 + ], + [ + 145.21787376940708, + -37.9901929509286 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10031, + "ZONE_STATU": "g", + "ZONE_CODE": "HO31", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO31", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21733907103456, + -37.99084699127799 + ], + [ + 145.21779743218806, + -37.99056931347228 + ], + [ + 145.21759608146, + -37.99035362499263 + ], + [ + 145.21713150200478, + -37.990628324534235 + ], + [ + 145.21733907103456, + -37.99084699127799 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10028, + "ZONE_STATU": "g", + "ZONE_CODE": "HO28", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO28", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.20236327082486, + -37.97830987516298 + ], + [ + 145.20236358532372, + -37.978308528468936 + ], + [ + 145.20239570888202, + -37.97813855010694 + ], + [ + 145.2023952396576, + -37.97813854293392 + ], + [ + 145.2017986991778, + -37.9780627480352 + ], + [ + 145.20179813830748, + -37.978062649358236 + ], + [ + 145.20176551561408, + -37.9782337912141 + ], + [ + 145.2017306164338, + -37.978417422157456 + ], + [ + 145.20173117950503, + -37.97841743076831 + ], + [ + 145.20205026263503, + -37.97845654800909 + ], + [ + 145.20232919197315, + -37.97849072573319 + ], + [ + 145.20232941043056, + -37.97848946767117 + ], + [ + 145.20236327082486, + -37.97830987516298 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10026, + "ZONE_STATU": "g", + "ZONE_CODE": "HO26", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO26", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21008086339805, + -37.97598795866059 + ], + [ + 145.21005209854798, + -37.97614411505087 + ], + [ + 145.21008732875254, + -37.976181682505626 + ], + [ + 145.21028221284587, + -37.97620510148112 + ], + [ + 145.21029702293524, + -37.97612486736057 + ], + [ + 145.21035124849536, + -37.97613019764452 + ], + [ + 145.21037102715908, + -37.97602318925412 + ], + [ + 145.21008086339805, + -37.97598795866059 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10024, + "ZONE_STATU": "g", + "ZONE_CODE": "HO24", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO24", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.2073114795161, + -37.983280106191465 + ], + [ + 145.20731137251295, + -37.983280645160804 + ], + [ + 145.207479384814, + -37.983301767148376 + ], + [ + 145.2075434916191, + -37.983263911248585 + ], + [ + 145.20756243561914, + -37.98316445919405 + ], + [ + 145.20758987645377, + -37.983020627195174 + ], + [ + 145.20758931334552, + -37.983020618611484 + ], + [ + 145.2073644653941, + -37.98299322431506 + ], + [ + 145.20733807403522, + -37.98313635145658 + ], + [ + 145.2073114795161, + -37.983280106191465 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10021, + "ZONE_STATU": "g", + "ZONE_CODE": "HO21", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO21", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.20513619170652, + -37.96901857061151 + ], + [ + 145.20510474145854, + -37.96918063151438 + ], + [ + 145.2055385787759, + -37.96923554601165 + ], + [ + 145.2055815651207, + -37.96901987113658 + ], + [ + 145.20521599268847, + -37.96897563940124 + ], + [ + 145.20513619170652, + -37.96901857061151 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2767, + "ZONE_STATU": "g", + "ZONE_CODE": "HO17", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO17", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21889161277386, + -37.961251650057086 + ], + [ + 145.2188865241092, + -37.96127968436695 + ], + [ + 145.21930148747262, + -37.961566631270955 + ], + [ + 145.21942408525004, + -37.96165137996893 + ], + [ + 145.21946675840496, + -37.96165662115735 + ], + [ + 145.21954117044757, + -37.96133870159937 + ], + [ + 145.21958668463898, + -37.96114468329524 + ], + [ + 145.21965051877598, + -37.96087219439044 + ], + [ + 145.21897720180422, + -37.960789739217894 + ], + [ + 145.218894993779, + -37.96123602376279 + ], + [ + 145.21889161277386, + -37.961251650057086 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2754, + "ZONE_STATU": "g", + "ZONE_CODE": "HO4", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO4", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.186983160765, + -37.9425198549391 + ], + [ + 145.1870535124562, + -37.9421886488679 + ], + [ + 145.1870584986758, + -37.942165209504665 + ], + [ + 145.18706275083522, + -37.94214491234264 + ], + [ + 145.1871339428724, + -37.94181002503076 + ], + [ + 145.18720440901282, + -37.941477919578986 + ], + [ + 145.18721014023572, + -37.94145088766929 + ], + [ + 145.18723125806784, + -37.94135138182081 + ], + [ + 145.18722428452708, + -37.94124567662025 + ], + [ + 145.18720887455717, + -37.94101361066394 + ], + [ + 145.18719730972, + -37.940838907848864 + ], + [ + 145.18719290050763, + -37.94078541032484 + ], + [ + 145.1871816135731, + -37.94069486561619 + ], + [ + 145.18718137202, + -37.94069324008521 + ], + [ + 145.18716590938078, + -37.94060461323053 + ], + [ + 145.18715236928705, + -37.94054466794961 + ], + [ + 145.1871456852979, + -37.94051501198636 + ], + [ + 145.18712094134065, + -37.94042606188182 + ], + [ + 145.1871126459762, + -37.940400886105174 + ], + [ + 145.1870918584773, + -37.940338036004725 + ], + [ + 145.18706134607487, + -37.94025854763147 + ], + [ + 145.18705834513986, + -37.940250842840264 + ], + [ + 145.18702058008168, + -37.9401648455418 + ], + [ + 145.1869984054621, + -37.940120264439294 + ], + [ + 145.1869784673071, + -37.940080132726266 + ], + [ + 145.18693219220702, + -37.93999679734715 + ], + [ + 145.18692479092422, + -37.93998488010627 + ], + [ + 145.18688175257992, + -37.93991492946626 + ], + [ + 145.18683982602383, + -37.93985319509051 + ], + [ + 145.1868273293873, + -37.939834802169194 + ], + [ + 145.18676892485234, + -37.93975632538437 + ], + [ + 145.1867440580869, + -37.939725848508395 + ], + [ + 145.1867066239249, + -37.93967986081741 + ], + [ + 145.18664052262122, + -37.93960531984197 + ], + [ + 145.18662871748361, + -37.93959315449218 + ], + [ + 145.18657080189672, + -37.93953297554286 + ], + [ + 145.1864972785944, + -37.939462644889076 + ], + [ + 145.18642068758012, + -37.939394969906836 + ], + [ + 145.18634066031797, + -37.93932967460662 + ], + [ + 145.18625738218495, + -37.939266851940275 + ], + [ + 145.18617103412782, + -37.93920677499257 + ], + [ + 145.18616503269666, + -37.939202808131135 + ], + [ + 145.18613916658848, + -37.939186281291825 + ], + [ + 145.1860817099395, + -37.93914944520309 + ], + [ + 145.18598959720615, + -37.93909486545798 + ], + [ + 145.18589487686907, + -37.93904330884258 + ], + [ + 145.18579736576356, + -37.93899459232472 + ], + [ + 145.18548369489534, + -37.93885334205985 + ], + [ + 145.18528185279442, + -37.93876238039074 + ], + [ + 145.1851261326619, + -37.9386922223912 + ], + [ + 145.18492911555444, + -37.93860349697698 + ], + [ + 145.18480810264705, + -37.93854901097691 + ], + [ + 145.18477434065147, + -37.938544525558626 + ], + [ + 145.18447993166225, + -37.93850529330144 + ], + [ + 145.18419459216702, + -37.93846737161767 + ], + [ + 145.18402419480404, + -37.93844464874444 + ], + [ + 145.18384912118768, + -37.93842131282356 + ], + [ + 145.18367395389902, + -37.938397975196494 + ], + [ + 145.18342293988155, + -37.93836454608026 + ], + [ + 145.1831075826602, + -37.93832255417896 + ], + [ + 145.18309757561656, + -37.938321228306116 + ], + [ + 145.1831506520348, + -37.93803669999425 + ], + [ + 145.18318383545852, + -37.93785890373111 + ], + [ + 145.1832134445249, + -37.93770051394487 + ], + [ + 145.1832562480623, + -37.937471148567255 + ], + [ + 145.18328229151442, + -37.93733180497966 + ], + [ + 145.183318825293, + -37.93713604030373 + ], + [ + 145.18336476716212, + -37.93688969433981 + ], + [ + 145.18338950948726, + -37.936757448555085 + ], + [ + 145.1834208554938, + -37.9365894447544 + ], + [ + 145.18342247966376, + -37.936580639990105 + ], + [ + 145.18342032912196, + -37.93658033647812 + ], + [ + 145.1805435398889, + -37.936255662976706 + ], + [ + 145.17730541419886, + -37.93584143752818 + ], + [ + 145.1742683132225, + -37.93541528673238 + ], + [ + 145.17421002302086, + -37.935719642078766 + ], + [ + 145.1741874033205, + -37.93583750267676 + ], + [ + 145.17416177187235, + -37.93597090388378 + ], + [ + 145.17413570275892, + -37.93610682109836 + ], + [ + 145.1741104796956, + -37.93623887712026 + ], + [ + 145.1740848412536, + -37.93637254849203 + ], + [ + 145.1740589972976, + -37.936506937467264 + ], + [ + 145.17403302378543, + -37.93664276602771 + ], + [ + 145.1740069630635, + -37.9367783229238 + ], + [ + 145.17398045128812, + -37.93691693622043 + ], + [ + 145.17395449528863, + -37.93705204422115 + ], + [ + 145.1739283070211, + -37.93718895061362 + ], + [ + 145.17390266785, + -37.93732262190819 + ], + [ + 145.17387670484834, + -37.937458000072766 + ], + [ + 145.17385041801208, + -37.937595085106935 + ], + [ + 145.1738242360059, + -37.93773172125712 + ], + [ + 145.1737981699772, + -37.937867458194845 + ], + [ + 145.17377199444527, + -37.93800382412526 + ], + [ + 145.17374635019007, + -37.938137675485045 + ], + [ + 145.17372048480627, + -37.938272874907334 + ], + [ + 145.17369463938243, + -37.938407263727115 + ], + [ + 145.173674489453, + -37.93851245836087 + ], + [ + 145.17366842329764, + -37.93854525079552 + ], + [ + 145.17364309583306, + -37.93868144964479 + ], + [ + 145.17361797368793, + -37.93881693087015 + ], + [ + 145.17359306578248, + -37.93895133420906 + ], + [ + 145.1735676219195, + -37.93908843222662 + ], + [ + 145.17354229404216, + -37.939224631032666 + ], + [ + 145.1735170665444, + -37.93936056108717 + ], + [ + 145.1734925958415, + -37.939492448369904 + ], + [ + 145.17340990486366, + -37.9399066168423 + ], + [ + 145.17309831580383, + -37.94146681991059 + ], + [ + 145.17276700151783, + -37.94312573540423 + ], + [ + 145.17257827469166, + -37.94410021090414 + ], + [ + 145.17124866547258, + -37.94517318274583 + ], + [ + 145.17090577478376, + -37.94544977463579 + ], + [ + 145.1707937019107, + -37.94544343667801 + ], + [ + 145.17209064237926, + -37.94661697156749 + ], + [ + 145.1730394858274, + -37.947475591819384 + ], + [ + 145.1730854689889, + -37.947517211539235 + ], + [ + 145.17350560246615, + -37.947891975918814 + ], + [ + 145.17640633592387, + -37.950479793060836 + ], + [ + 145.1788041558151, + -37.9507570625165 + ], + [ + 145.18018040471856, + -37.9509161276437 + ], + [ + 145.18071605943413, + -37.95097748331506 + ], + [ + 145.18072803590653, + -37.95097892996779 + ], + [ + 145.1809953052096, + -37.94950271656176 + ], + [ + 145.18117818363964, + -37.94853705686008 + ], + [ + 145.18134648322575, + -37.94764865751769 + ], + [ + 145.1815511568741, + -37.94643799071711 + ], + [ + 145.18262590124476, + -37.946578759721376 + ], + [ + 145.18268464132476, + -37.94658651492364 + ], + [ + 145.18310752777262, + -37.94664179224377 + ], + [ + 145.18458041851795, + -37.94629160927093 + ], + [ + 145.18468759847852, + -37.94626046694377 + ], + [ + 145.18479307809775, + -37.94622596456417 + ], + [ + 145.18485054203666, + -37.94620549757836 + ], + [ + 145.1849535191251, + -37.94616591081377 + ], + [ + 145.18505441619627, + -37.946123138349826 + ], + [ + 145.18515304563388, + -37.94607717729691 + ], + [ + 145.18524940299713, + -37.94602820779277 + ], + [ + 145.18534311306587, + -37.94597622405406 + ], + [ + 145.18543417361806, + -37.94592131615307 + ], + [ + 145.18552239482682, + -37.94586357126787 + ], + [ + 145.18560767845426, + -37.94580316809011 + ], + [ + 145.18568983910762, + -37.9457400136661 + ], + [ + 145.18576877633674, + -37.945674376754056 + ], + [ + 145.1858443941239, + -37.94560634597985 + ], + [ + 145.18591650486528, + -37.94553591845643 + ], + [ + 145.18598501033097, + -37.94546327287604 + ], + [ + 145.18604981229277, + -37.945388587930914 + ], + [ + 145.18611090854128, + -37.94531195369344 + ], + [ + 145.18616801767615, + -37.945233365830035 + ], + [ + 145.1862211330611, + -37.94515309454532 + ], + [ + 145.1862701586886, + -37.945071228464755 + ], + [ + 145.186290188977, + -37.945035136768546 + ], + [ + 145.18656012064713, + -37.944487073369196 + ], + [ + 145.1868334020327, + -37.943226096305835 + ], + [ + 145.1868941939787, + -37.942944118051834 + ], + [ + 145.18691227961932, + -37.942853485495554 + ], + [ + 145.1869168398271, + -37.9428321118849 + ], + [ + 145.186983160765, + -37.9425198549391 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10055, + "ZONE_STATU": "g", + "ZONE_CODE": "HO55", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-27T13:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO55", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.15033732303152, + -37.9531831448711 + ], + [ + 145.1505823811117, + -37.953208442304515 + ], + [ + 145.15063960721352, + -37.95283506741284 + ], + [ + 145.150531733439, + -37.95282183837974 + ], + [ + 145.15048297303542, + -37.953104615806694 + ], + [ + 145.150355267597, + -37.95308882225125 + ], + [ + 145.15033732303152, + -37.9531831448711 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10062, + "ZONE_STATU": "g", + "ZONE_CODE": "HO62", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO62", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.1520925948851, + -37.94996434755506 + ], + [ + 145.15209315546687, + -37.949964446462374 + ], + [ + 145.15253244178473, + -37.9500166676144 + ], + [ + 145.1525423805539, + -37.94996456578261 + ], + [ + 145.1525517803354, + -37.949915248580446 + ], + [ + 145.1524505480841, + -37.949903026662376 + ], + [ + 145.15239946294065, + -37.94989690830313 + ], + [ + 145.15234959503246, + -37.949890899143256 + ], + [ + 145.1522909319038, + -37.949883850794905 + ], + [ + 145.15229350592796, + -37.94987100694549 + ], + [ + 145.15229294309015, + -37.949870998103584 + ], + [ + 145.15223849224077, + -37.94986437630158 + ], + [ + 145.15217449798433, + -37.949856613444155 + ], + [ + 145.15211490135385, + -37.94984937014275 + ], + [ + 145.15210218032195, + -37.949915123408694 + ], + [ + 145.1520925948851, + -37.94996434755506 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10067, + "ZONE_STATU": "g", + "ZONE_CODE": "HO67", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": null, + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO67", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.15850353199522, + -37.953063783345556 + ], + [ + 145.15933880346697, + -37.9536942231038 + ], + [ + 145.15984432068373, + -37.9540757778542 + ], + [ + 145.16115145688065, + -37.95506506654863 + ], + [ + 145.1611557874975, + -37.95506828775497 + ], + [ + 145.161852060192, + -37.95559535436808 + ], + [ + 145.16266291234064, + -37.956206197893145 + ], + [ + 145.16297458406655, + -37.95624422323659 + ], + [ + 145.16325524665203, + -37.95645709798918 + ], + [ + 145.16328490773535, + -37.956479545593616 + ], + [ + 145.16337232988448, + -37.95654551248508 + ], + [ + 145.16346085329894, + -37.95661248760853 + ], + [ + 145.16354735331097, + -37.956677809272435 + ], + [ + 145.16363541693826, + -37.95674441668703 + ], + [ + 145.16370727197153, + -37.956798607474525 + ], + [ + 145.1637800450816, + -37.956853623451906 + ], + [ + 145.16384830431093, + -37.95690523521549 + ], + [ + 145.1639134344511, + -37.956954365391326 + ], + [ + 145.1639773652552, + -37.95700266590913 + ], + [ + 145.16402885973173, + -37.95704158205964 + ], + [ + 145.164078880117, + -37.95707939397767 + ], + [ + 145.16412982301696, + -37.9571178509746 + ], + [ + 145.1641798435059, + -37.95715566285187 + ], + [ + 145.16422894158111, + -37.957192829610584 + ], + [ + 145.16428043856612, + -37.95723165559163 + ], + [ + 145.16433091932217, + -37.95726983498936 + ], + [ + 145.16438121698232, + -37.95730783130813 + ], + [ + 145.16443068604204, + -37.95734518397385 + ], + [ + 145.1644818124585, + -37.95738382388441 + ], + [ + 145.16453054454067, + -37.9574206244071 + ], + [ + 145.16461741499245, + -37.95748622137546 + ], + [ + 145.1646641191146, + -37.957521548596624 + ], + [ + 145.16471561431734, + -37.957560464461764 + ], + [ + 145.16476452978324, + -37.957597447950356 + ], + [ + 145.16481187955546, + -37.957633235688384 + ], + [ + 145.1648251470677, + -37.957643173509126 + ], + [ + 145.16490543569086, + -37.95765271549497 + ], + [ + 145.16500846131711, + -37.957665044878176 + ], + [ + 145.16510400180195, + -37.95767644649218 + ], + [ + 145.16520665447518, + -37.95768867978363 + ], + [ + 145.1653120189128, + -37.957701315688524 + ], + [ + 145.16539792100585, + -37.95771157560759 + ], + [ + 145.16541977231688, + -37.95770092427064 + ], + [ + 145.1654873970297, + -37.957333019779426 + ], + [ + 145.16549138668447, + -37.957274517034264 + ], + [ + 145.1659442596012, + -37.95732978365114 + ], + [ + 145.16615113908364, + -37.957355084115505 + ], + [ + 145.16635511936786, + -37.95737997861606 + ], + [ + 145.16636400954545, + -37.95738101822109 + ], + [ + 145.16636522468147, + -37.95738121736596 + ], + [ + 145.16656173114907, + -37.95740473358661 + ], + [ + 145.16676824702753, + -37.95742957680026 + ], + [ + 145.16697504450994, + -37.957454424041224 + ], + [ + 145.1671792242325, + -37.957478869724795 + ], + [ + 145.1673874270341, + -37.957503828242885 + ], + [ + 145.16759132337, + -37.95752835889716 + ], + [ + 145.1677962518416, + -37.95755290527817 + ], + [ + 145.16800314390582, + -37.95757775218968 + ], + [ + 145.16820807044297, + -37.95760238792489 + ], + [ + 145.168412063436, + -37.95762682856554 + ], + [ + 145.1686181138423, + -37.957651571190645 + ], + [ + 145.1688252879697, + -37.95767642105195 + ], + [ + 145.16903816944063, + -37.957701990101846 + ], + [ + 145.169133418134, + -37.957203598063685 + ], + [ + 145.1692936272494, + -37.95722240006553 + ], + [ + 145.1694021615123, + -37.95723589254507 + ], + [ + 145.16975259690827, + -37.95727792713107 + ], + [ + 145.16978474173925, + -37.95731383666976 + ], + [ + 145.16982991284462, + -37.957074513148086 + ], + [ + 145.1710883383243, + -37.95043560293798 + ], + [ + 145.17151177668177, + -37.948243472580636 + ], + [ + 145.17181995568595, + -37.948016165021045 + ], + [ + 145.17215550142356, + -37.94764629293109 + ], + [ + 145.1721745331169, + -37.94754099127438 + ], + [ + 145.16960697249402, + -37.94520747343099 + ], + [ + 145.16924597209805, + -37.94487884600173 + ], + [ + 145.16915333128227, + -37.944838210470024 + ], + [ + 145.16906575217672, + -37.94476377598928 + ], + [ + 145.1690319769734, + -37.944684142276664 + ], + [ + 145.1677825421705, + -37.94354690368938 + ], + [ + 145.16768892571628, + -37.943609867030666 + ], + [ + 145.1673824630929, + -37.94385899495085 + ], + [ + 145.16698767345176, + -37.94413179345852 + ], + [ + 145.16658992385112, + -37.94440652666511 + ], + [ + 145.1663679520038, + -37.944559480416345 + ], + [ + 145.1661198166439, + -37.944730586448614 + ], + [ + 145.16584511309122, + -37.94492100958247 + ], + [ + 145.1656048488008, + -37.94489248523098 + ], + [ + 145.16528384311593, + -37.9448543216771 + ], + [ + 145.16525382048948, + -37.944850339466264 + ], + [ + 145.165018889895, + -37.94482243771965 + ], + [ + 145.16475241819248, + -37.944791250275436 + ], + [ + 145.1645114066746, + -37.94476262193735 + ], + [ + 145.16433766751382, + -37.94474189060992 + ], + [ + 145.16416663746438, + -37.94472165181042 + ], + [ + 145.16399738748368, + -37.94470153064848 + ], + [ + 145.16382645368336, + -37.944681202757884 + ], + [ + 145.16365308790657, + -37.944660566350855 + ], + [ + 145.16348402583634, + -37.944640447385886 + ], + [ + 145.16331168758856, + -37.944620006720626 + ], + [ + 145.16313626301195, + -37.94459915720537 + ], + [ + 145.1629740912501, + -37.94541013835874 + ], + [ + 145.16270953436054, + -37.946824001326846 + ], + [ + 145.16261395809417, + -37.94733445693716 + ], + [ + 145.16254770546965, + -37.94768859641047 + ], + [ + 145.1624776641114, + -37.94806294914321 + ], + [ + 145.16244972731002, + -37.948204960877945 + ], + [ + 145.16234480919704, + -37.94875122009503 + ], + [ + 145.16228852724953, + -37.94902145176411 + ], + [ + 145.16225442043063, + -37.949185081130175 + ], + [ + 145.16223225158268, + -37.94929141318891 + ], + [ + 145.16218051092517, + -37.94956766233462 + ], + [ + 145.1621492195506, + -37.94973502974489 + ], + [ + 145.16212854631368, + -37.94984534954288 + ], + [ + 145.16210775451208, + -37.949956658582316 + ], + [ + 145.16207939284527, + -37.950108124036625 + ], + [ + 145.16205102880488, + -37.950259679542334 + ], + [ + 145.16202266687995, + -37.95041114496955 + ], + [ + 145.16199430258132, + -37.95056270044814 + ], + [ + 145.16196593815357, + -37.95071425591317 + ], + [ + 145.16193757584142, + -37.950865721299714 + ], + [ + 145.1619092111554, + -37.95101727673763 + ], + [ + 145.16188084858513, + -37.95116874209705 + ], + [ + 145.16185789243832, + -37.95129155003779 + ], + [ + 145.1618423052114, + -37.951374739035884 + ], + [ + 145.16182682746896, + -37.951457299041586 + ], + [ + 145.16181145696683, + -37.95153932011989 + ], + [ + 145.16179618697086, + -37.95162107246563 + ], + [ + 145.1617624060306, + -37.95180164549254 + ], + [ + 145.16175742851402, + -37.95182814719596 + ], + [ + 145.16173501504744, + -37.95194799027812 + ], + [ + 145.1616859724895, + -37.95220995532794 + ], + [ + 145.16164407973167, + -37.952433559404035 + ], + [ + 145.16121698539507, + -37.95210982118915 + ], + [ + 145.16039901205897, + -37.95148948610349 + ], + [ + 145.16026609295963, + -37.95159994194714 + ], + [ + 145.1601326016189, + -37.95171074908283 + ], + [ + 145.15999910762912, + -37.95182164611943 + ], + [ + 145.15986561323703, + -37.95193254299214 + ], + [ + 145.15973212069025, + -37.952043349636114 + ], + [ + 145.15959862549389, + -37.952154246181 + ], + [ + 145.15946522595283, + -37.952265053965185 + ], + [ + 145.15933172995227, + -37.95237595018234 + ], + [ + 145.1591982335494, + -37.95248684623559 + ], + [ + 145.15911188734492, + -37.95255856585071 + ], + [ + 145.15902554097215, + -37.952630285397255 + ], + [ + 145.15893910062087, + -37.95270200340679 + ], + [ + 145.1588527516628, + -37.95277381288087 + ], + [ + 145.15876640478504, + -37.95284553222161 + ], + [ + 145.15867996392848, + -37.9529172500251 + ], + [ + 145.15858211654742, + -37.95299851997111 + ], + [ + 145.15850353199522, + -37.953063783345556 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10054, + "ZONE_STATU": "g", + "ZONE_CODE": "HO54", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO54", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21312758120672, + -37.989804396326605 + ], + [ + 145.2131230671711, + -37.98980468812634 + ], + [ + 145.21306391321883, + -37.989808564441695 + ], + [ + 145.2130968802913, + -37.99010612546564 + ], + [ + 145.21311915105952, + -37.990120879937265 + ], + [ + 145.21316025122798, + -37.990118080737396 + ], + [ + 145.2131601682938, + -37.99011762897659 + ], + [ + 145.21312879232457, + -37.989816398044766 + ], + [ + 145.21312758120672, + -37.989804396326605 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10075, + "ZONE_STATU": "g", + "ZONE_CODE": "HO75", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-11-05T13:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO75", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.20677941769117, + -37.981660552622756 + ], + [ + 145.20670820207212, + -37.98202518297419 + ], + [ + 145.20670208741532, + -37.98205653466448 + ], + [ + 145.2066824242597, + -37.9821584984242 + ], + [ + 145.20667135880194, + -37.98221581354263 + ], + [ + 145.20664125892498, + -37.98237239899304 + ], + [ + 145.20680909673618, + -37.982311888547905 + ], + [ + 145.20683778115966, + -37.982302144666676 + ], + [ + 145.20686673397273, + -37.98229294547191 + ], + [ + 145.20689621699606, + -37.98228510585708 + ], + [ + 145.20692614953458, + -37.98227808399053 + ], + [ + 145.2069566100937, + -37.98227251176992 + ], + [ + 145.20698740001322, + -37.98226883666622 + ], + [ + 145.20701854518794, + -37.98226985217797 + ], + [ + 145.20702592867795, + -37.98227122616421 + ], + [ + 145.2070975335152, + -37.98228015669156 + ], + [ + 145.20711443598904, + -37.98219130538463 + ], + [ + 145.20715253222536, + -37.98219603085072 + ], + [ + 145.20715908640227, + -37.982196761483095 + ], + [ + 145.20716573223763, + -37.982197583612745 + ], + [ + 145.20723687434813, + -37.98220623669919 + ], + [ + 145.20724267772442, + -37.98220695587998 + ], + [ + 145.2073263629224, + -37.98221715164879 + ], + [ + 145.20733722483, + -37.98216046406137 + ], + [ + 145.20740131273897, + -37.981826268592606 + ], + [ + 145.20741507666335, + -37.98175448841106 + ], + [ + 145.2074215295201, + -37.98172079923112 + ], + [ + 145.20720730992952, + -37.981696630098035 + ], + [ + 145.2068131246209, + -37.98166431025751 + ], + [ + 145.20677941769117, + -37.981660552622756 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2760, + "ZONE_STATU": "g", + "ZONE_CODE": "HO10", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO10", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.20443507780703, + -37.97161581984758 + ], + [ + 145.20443418841745, + -37.97164076403479 + ], + [ + 145.20443884417332, + -37.971665432488365 + ], + [ + 145.20444888154614, + -37.97168883160819 + ], + [ + 145.20446393836025, + -37.9717104152616 + ], + [ + 145.20448366341083, + -37.97172918698175 + ], + [ + 145.20450712930293, + -37.971744682105516 + ], + [ + 145.20453369453858, + -37.971756260134626 + ], + [ + 145.204562335687, + -37.9717635450406 + ], + [ + 145.2045920271211, + -37.97176625086246 + ], + [ + 145.20462192649777, + -37.97176427463892 + ], + [ + 145.20465080954338, + -37.971757777879354 + ], + [ + 145.2046778273325, + -37.97174692782464 + ], + [ + 145.2047018450421, + -37.97173206755222 + ], + [ + 145.20472219264713, + -37.97171372743652 + ], + [ + 145.20473810189966, + -37.97169261655318 + ], + [ + 145.20474598404095, + -37.97167732974121 + ], + [ + 145.20475333270298, + -37.971653114860196 + ], + [ + 145.20475515815804, + -37.9716282750598 + ], + [ + 145.20475144285862, + -37.971603530874425 + ], + [ + 145.2047423525423, + -37.97157978583621 + ], + [ + 145.20472805513998, + -37.97155785340988 + ], + [ + 145.20470909392748, + -37.97153855278968 + ], + [ + 145.2046862042399, + -37.97152252590121 + ], + [ + 145.20466012579828, + -37.97151023453658 + ], + [ + 145.20463168996392, + -37.97150223198763 + ], + [ + 145.2046021100249, + -37.971498807076976 + ], + [ + 145.20457213666836, + -37.9714999712649 + ], + [ + 145.20453864475553, + -37.97150684814011 + ], + [ + 145.20451570809155, + -37.97151586836965 + ], + [ + 145.20449104892307, + -37.971530088109176 + ], + [ + 145.2044700576252, + -37.97154787775565 + ], + [ + 145.20445340860962, + -37.97156852680635 + ], + [ + 145.20444158422814, + -37.97159150202657 + ], + [ + 145.20443507780703, + -37.97161581984758 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2766, + "ZONE_STATU": "g", + "ZONE_CODE": "HO16", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-11-21T13:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO16", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.20907450329943, + -37.97976107986052 + ], + [ + 145.2093111550838, + -37.979596016355615 + ], + [ + 145.2092199440342, + -37.97951317675847 + ], + [ + 145.20955155288064, + -37.97928063216867 + ], + [ + 145.20943230345998, + -37.9791694347508 + ], + [ + 145.2092175927635, + -37.97932023643985 + ], + [ + 145.20913448899626, + -37.97925148577319 + ], + [ + 145.20922801804798, + -37.97918101020606 + ], + [ + 145.2091345108959, + -37.979107686196734 + ], + [ + 145.20875127550173, + -37.97938620518955 + ], + [ + 145.20817979070628, + -37.9788816770375 + ], + [ + 145.20829342511516, + -37.97881060757321 + ], + [ + 145.20819603145358, + -37.978723438279346 + ], + [ + 145.20968132719062, + -37.9777301814487 + ], + [ + 145.21063039088438, + -37.97855976377801 + ], + [ + 145.2107307200557, + -37.97849524697565 + ], + [ + 145.20965122446563, + -37.977512491498125 + ], + [ + 145.20791522290853, + -37.978716185766324 + ], + [ + 145.20907450329943, + -37.97976107986052 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10050, + "ZONE_STATU": "g", + "ZONE_CODE": "HO50", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-11-21T13:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO50", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.22218747148145, + -37.97490236896328 + ], + [ + 145.22215040596586, + -37.97492118018448 + ], + [ + 145.2221290428371, + -37.97494284170514 + ], + [ + 145.22210340505066, + -37.97497047532126 + ], + [ + 145.2220581120009, + -37.97501123672123 + ], + [ + 145.22201935585062, + -37.975037861074135 + ], + [ + 145.2219751651432, + -37.975060168524706 + ], + [ + 145.22193094499818, + -37.975072023866275 + ], + [ + 145.221877931564, + -37.975078700607355 + ], + [ + 145.2218217771047, + -37.97507938320159 + ], + [ + 145.2217331634362, + -37.97507137578833 + ], + [ + 145.22171106927277, + -37.97507275358571 + ], + [ + 145.22168686350943, + -37.975083830289854 + ], + [ + 145.221671737246, + -37.97510378403328 + ], + [ + 145.22163178866245, + -37.97521481429804 + ], + [ + 145.22158259044704, + -37.975273446430826 + ], + [ + 145.22157737443777, + -37.97529508174314 + ], + [ + 145.2215857851202, + -37.975316112232846 + ], + [ + 145.22160587970907, + -37.9753314628939 + ], + [ + 145.2216280772273, + -37.97533747491274 + ], + [ + 145.22167000411602, + -37.975350632918364 + ], + [ + 145.22173160238492, + -37.97535778135473 + ], + [ + 145.22178519325945, + -37.97536219576296 + ], + [ + 145.22183257929828, + -37.9753630925072 + ], + [ + 145.22188273241048, + -37.97536213896427 + ], + [ + 145.2219437451543, + -37.97536243080565 + ], + [ + 145.2220216244486, + -37.975352345784536 + ], + [ + 145.2220837417711, + -37.97533409357094 + ], + [ + 145.22212038038418, + -37.97532131264698 + ], + [ + 145.22217628805853, + -37.97529584856967 + ], + [ + 145.22223281782195, + -37.97527183547638 + ], + [ + 145.22228902433184, + -37.975245655058956 + ], + [ + 145.22234448359652, + -37.975211534482305 + ], + [ + 145.2223848881374, + -37.97517105947756 + ], + [ + 145.22242391853274, + -37.97511749912704 + ], + [ + 145.22243690889616, + -37.97508489894108 + ], + [ + 145.2224429783189, + -37.975066790403474 + ], + [ + 145.22244861950608, + -37.97502362747796 + ], + [ + 145.22244358526308, + -37.974987150814314 + ], + [ + 145.22242400254015, + -37.97494279569963 + ], + [ + 145.22241158117964, + -37.97492846217152 + ], + [ + 145.22238981040846, + -37.97491254570643 + ], + [ + 145.22237313399577, + -37.97490337367709 + ], + [ + 145.22235613260457, + -37.974895998741026 + ], + [ + 145.22233489095393, + -37.97488928050649 + ], + [ + 145.22231265873958, + -37.97488470970361 + ], + [ + 145.22229196316843, + -37.97488259483746 + ], + [ + 145.2222668987263, + -37.974882576331474 + ], + [ + 145.22224044444445, + -37.97488569032339 + ], + [ + 145.22221844893156, + -37.97489076382507 + ], + [ + 145.22218747148145, + -37.97490236896328 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10073, + "ZONE_STATU": "g", + "ZONE_CODE": "HO73", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO73", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21909498196857, + -37.99346956538113 + ], + [ + 145.21909555387344, + -37.99346921364324 + ], + [ + 145.2194013327221, + -37.99328886928597 + ], + [ + 145.21945010597076, + -37.993260055068916 + ], + [ + 145.21954193334759, + -37.99320594397289 + ], + [ + 145.21954147273374, + -37.99320557659732 + ], + [ + 145.21943070363199, + -37.99309163441149 + ], + [ + 145.2194253901455, + -37.993086147936715 + ], + [ + 145.21942491210996, + -37.99308650109784 + ], + [ + 145.21898119387606, + -37.99334845914159 + ], + [ + 145.21909498196857, + -37.99346956538113 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10061, + "ZONE_STATU": "g", + "ZONE_CODE": "HO61", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO61", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21747867991465, + -37.99197644062946 + ], + [ + 145.2174735279871, + -37.9919642891083 + ], + [ + 145.21746322666314, + -37.99195151891864 + ], + [ + 145.21744873867496, + -37.99194102785859 + ], + [ + 145.21743117730057, + -37.991933373405494 + ], + [ + 145.21741156413322, + -37.99192902154692 + ], + [ + 145.21739101680825, + -37.991928349626974 + ], + [ + 145.21737094327108, + -37.99193137899146 + ], + [ + 145.2173553250201, + -37.99193654820392 + ], + [ + 145.21734029185865, + -37.99194469958896 + ], + [ + 145.2173273390561, + -37.99195612611801 + ], + [ + 145.21731865817227, + -37.99196950951796 + ], + [ + 145.21731493023583, + -37.99198386901411 + ], + [ + 145.21730257330788, + -37.991993953073084 + ], + [ + 145.2172944707512, + -37.9920028402339 + ], + [ + 145.2172879464258, + -37.992012472124294 + ], + [ + 145.21728328846336, + -37.99202258281282 + ], + [ + 145.21728040954244, + -37.99203290067541 + ], + [ + 145.21727949521, + -37.9920435186256 + ], + [ + 145.2172804603252, + -37.992054074972074 + ], + [ + 145.2172833070693, + -37.99206447964774 + ], + [ + 145.21728794594043, + -37.992074551095236 + ], + [ + 145.21729447516353, + -37.99208411060337 + ], + [ + 145.21730261532932, + -37.9920930638354 + ], + [ + 145.21731763161966, + -37.99210500452515 + ], + [ + 145.2173293909305, + -37.99211185022535 + ], + [ + 145.21734230276923, + -37.99211763219719 + ], + [ + 145.21735608990585, + -37.992122166036864 + ], + [ + 145.2173705602523, + -37.99212562903196 + ], + [ + 145.2173856264854, + -37.99212774955795 + ], + [ + 145.21740091315053, + -37.99212852192232 + ], + [ + 145.2174162303396, + -37.99212803334587 + ], + [ + 145.21743129646146, + -37.99212627955944 + ], + [ + 145.217446019832, + -37.99212316907298 + ], + [ + 145.21746002063625, + -37.99211887632866 + ], + [ + 145.2174731111467, + -37.99211339848065 + ], + [ + 145.21748510145574, + -37.99210682275031 + ], + [ + 145.2175028041178, + -37.99209312561021 + ], + [ + 145.21751293883602, + -37.99208174643961 + ], + [ + 145.217518996002, + -37.99207201735432 + ], + [ + 145.21752318461884, + -37.992061899540936 + ], + [ + 145.21752559855057, + -37.99205139442264 + ], + [ + 145.21752604135077, + -37.99204085942187 + ], + [ + 145.21752460688356, + -37.99203029596166 + ], + [ + 145.2175212886094, + -37.992019974243156 + ], + [ + 145.21751617821232, + -37.992009985756255 + ], + [ + 145.2175092691526, + -37.99200060070196 + ], + [ + 145.21750074915738, + -37.99199182192592 + ], + [ + 145.21749070773004, + -37.991983830984935 + ], + [ + 145.21747867991465, + -37.99197644062946 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10060, + "ZONE_STATU": "g", + "ZONE_CODE": "HO60", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-11-24T13:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO60", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21504901983653, + -37.99030138083628 + ], + [ + 145.2153642522579, + -37.99091253966255 + ], + [ + 145.21562648428116, + -37.990828131392156 + ], + [ + 145.21580241311113, + -37.99100775778118 + ], + [ + 145.21546797458385, + -37.99111539757998 + ], + [ + 145.2155649546002, + -37.99130589946577 + ], + [ + 145.2157891228799, + -37.99174619676741 + ], + [ + 145.21618875502134, + -37.99235457958424 + ], + [ + 145.216225752297, + -37.992331264354995 + ], + [ + 145.2162982036695, + -37.99229794526436 + ], + [ + 145.21640664418078, + -37.99227517318501 + ], + [ + 145.21653028834913, + -37.99225272172299 + ], + [ + 145.21660564758892, + -37.99224665677931 + ], + [ + 145.21671259680292, + -37.99221178838187 + ], + [ + 145.21678004076023, + -37.99219911606703 + ], + [ + 145.21685761977545, + -37.99218668751932 + ], + [ + 145.21692179390385, + -37.99218108344167 + ], + [ + 145.21707152168113, + -37.99219047190452 + ], + [ + 145.2171751475321, + -37.992211414755886 + ], + [ + 145.21725198327738, + -37.99224132172909 + ], + [ + 145.2174337459165, + -37.99228498299442 + ], + [ + 145.21754159865594, + -37.992325271031824 + ], + [ + 145.21757950494876, + -37.992345847907565 + ], + [ + 145.21757332920004, + -37.99233332046988 + ], + [ + 145.21757061975092, + -37.99231724157538 + ], + [ + 145.2175732627142, + -37.99230115372155 + ], + [ + 145.21758123410575, + -37.99228604764563 + ], + [ + 145.21759385289636, + -37.99227290412373 + ], + [ + 145.2176104445988, + -37.99226243373052 + ], + [ + 145.21762995927315, + -37.99225534134899 + ], + [ + 145.21765257374875, + -37.99225208015886 + ], + [ + 145.2175028041178, + -37.99209312561021 + ], + [ + 145.21748510145574, + -37.99210682275031 + ], + [ + 145.2174731111467, + -37.99211339848065 + ], + [ + 145.21746002063625, + -37.99211887632866 + ], + [ + 145.217446019832, + -37.99212316907298 + ], + [ + 145.21743129646146, + -37.99212627955944 + ], + [ + 145.2174162303396, + -37.99212803334587 + ], + [ + 145.21740091315053, + -37.99212852192232 + ], + [ + 145.2173856264854, + -37.99212774955795 + ], + [ + 145.2173705602523, + -37.99212562903196 + ], + [ + 145.21735608990585, + -37.992122166036864 + ], + [ + 145.21734230276923, + -37.99211763219719 + ], + [ + 145.2173293909305, + -37.99211185022535 + ], + [ + 145.21731763161966, + -37.99210500452515 + ], + [ + 145.21730261532932, + -37.9920930638354 + ], + [ + 145.21729447516353, + -37.99208411060337 + ], + [ + 145.21728794594043, + -37.992074551095236 + ], + [ + 145.2172833070693, + -37.99206447964774 + ], + [ + 145.2172804603252, + -37.992054074972074 + ], + [ + 145.21727949521, + -37.9920435186256 + ], + [ + 145.21728040954244, + -37.99203290067541 + ], + [ + 145.21728328846336, + -37.99202258281282 + ], + [ + 145.2172879464258, + -37.992012472124294 + ], + [ + 145.2172944707512, + -37.9920028402339 + ], + [ + 145.21730257330788, + -37.991993953073084 + ], + [ + 145.21731493023583, + -37.99198386901411 + ], + [ + 145.21731865817227, + -37.99196950951796 + ], + [ + 145.2173273390561, + -37.99195612611801 + ], + [ + 145.21734029185865, + -37.99194469958896 + ], + [ + 145.2173553250201, + -37.99193654820392 + ], + [ + 145.21699125121194, + -37.991550084464635 + ], + [ + 145.21570755250048, + -37.99018721813129 + ], + [ + 145.2156818957114, + -37.99018430597669 + ], + [ + 145.21563648228326, + -37.99017911179145 + ], + [ + 145.21553195851507, + -37.99021473685538 + ], + [ + 145.21524475498842, + -37.990240921624896 + ], + [ + 145.21510506801738, + -37.99026682233959 + ], + [ + 145.21504901983653, + -37.99030138083628 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10035, + "ZONE_STATU": "g", + "ZONE_CODE": "HO35", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-11-24T13:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO35", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21764586338875, + -37.99238190280104 + ], + [ + 145.21765077277124, + -37.99238468022591 + ], + [ + 145.2177139074669, + -37.992429786324045 + ], + [ + 145.21772010633111, + -37.992414202869476 + ], + [ + 145.21773005987464, + -37.99240255063415 + ], + [ + 145.21774362396718, + -37.99239302543011 + ], + [ + 145.21775993857526, + -37.99238624492046 + ], + [ + 145.21777579489137, + -37.9923828812661 + ], + [ + 145.21773825897296, + -37.9923431187429 + ], + [ + 145.21773058650848, + -37.99235363425498 + ], + [ + 145.2177163938418, + -37.992365852932856 + ], + [ + 145.2176985163757, + -37.99237513254894 + ], + [ + 145.2176781917802, + -37.99238077106226 + ], + [ + 145.21765664464746, + -37.992382606834866 + ], + [ + 145.21764586338875, + -37.99238190280104 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10035, + "ZONE_STATU": "g", + "ZONE_CODE": "HO35", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-11-24T13:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO35", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.15183930985006, + -37.955787125535714 + ], + [ + 145.15184279753308, + -37.95580898449705 + ], + [ + 145.15185316974905, + -37.95582951004529 + ], + [ + 145.15186970759657, + -37.95584742948452 + ], + [ + 145.1518913124009, + -37.95586164435015 + ], + [ + 145.15191688096888, + -37.955871236306166 + ], + [ + 145.1519446443772, + -37.95587563695555 + ], + [ + 145.15197291848452, + -37.95587463963407 + ], + [ + 145.15200010844814, + -37.95586821928184 + ], + [ + 145.15202432669793, + -37.95585679674002 + ], + [ + 145.1520442417779, + -37.955841071888536 + ], + [ + 145.15205851546378, + -37.95582201480094 + ], + [ + 145.1520663656462, + -37.95580087458806 + ], + [ + 145.15206720010343, + -37.95577881324372 + ], + [ + 145.15206107654012, + -37.95575727327191 + ], + [ + 145.15204833861608, + -37.955737521468805 + ], + [ + 145.15202979680072, + -37.955720922064096 + ], + [ + 145.1520064627311, + -37.95570830184905 + ], + [ + 145.15196597105665, + -37.95569874572525 + ], + [ + 145.15192367362883, + -37.955701324688434 + ], + [ + 145.15189138969478, + -37.95571253036877 + ], + [ + 145.1518696367211, + -37.95572669461733 + ], + [ + 145.15185313856642, + -37.95574463552878 + ], + [ + 145.15184276890304, + -37.955765195536735 + ], + [ + 145.15183930985006, + -37.955787125535714 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10070, + "ZONE_STATU": "g", + "ZONE_CODE": "HO70", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2003-02-09T13:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO70", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21757061975092, + -37.99231724157538 + ], + [ + 145.21757332920004, + -37.99233332046988 + ], + [ + 145.21757950494876, + -37.992345847907565 + ], + [ + 145.2175902778447, + -37.99235853513567 + ], + [ + 145.21760596872252, + -37.99236976521459 + ], + [ + 145.21762493163547, + -37.99237771118882 + ], + [ + 145.21764586338875, + -37.99238190280104 + ], + [ + 145.21765664464746, + -37.992382606834866 + ], + [ + 145.2176781917802, + -37.99238077106226 + ], + [ + 145.2176985163757, + -37.99237513254894 + ], + [ + 145.2177163938418, + -37.992365852932856 + ], + [ + 145.21773058650848, + -37.99235363425498 + ], + [ + 145.21773825897296, + -37.9923431187429 + ], + [ + 145.2177450295966, + -37.99232330924814 + ], + [ + 145.21774438729193, + -37.99230717159131 + ], + [ + 145.2177383794972, + -37.99229158330394 + ], + [ + 145.21772745155545, + -37.992277542237154 + ], + [ + 145.2177122387155, + -37.992265959020166 + ], + [ + 145.21769366217512, + -37.99225756841639 + ], + [ + 145.2176729312609, + -37.9922528392567 + ], + [ + 145.21765257374875, + -37.99225208015886 + ], + [ + 145.21762995927315, + -37.99225534134899 + ], + [ + 145.2176104445988, + -37.99226243373052 + ], + [ + 145.21759385289636, + -37.99227290412373 + ], + [ + 145.21758123410575, + -37.99228604764563 + ], + [ + 145.2175732627142, + -37.99230115372155 + ], + [ + 145.21757061975092, + -37.99231724157538 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10060, + "ZONE_STATU": "g", + "ZONE_CODE": "HO60", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2003-02-09T13:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO60", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.2213721112921, + -37.98576523875484 + ], + [ + 145.22132858082333, + -37.986032087918126 + ], + [ + 145.221100121252, + -37.9861730625026 + ], + [ + 145.22123898224098, + -37.98632869403788 + ], + [ + 145.221538450061, + -37.986143833195555 + ], + [ + 145.2213924637433, + -37.985979985204956 + ], + [ + 145.22142417320026, + -37.98577107187052 + ], + [ + 145.2213721112921, + -37.98576523875484 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2761, + "ZONE_STATU": "g", + "ZONE_CODE": "HO11", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO11", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21779730435927, + -37.992557190623195 + ], + [ + 145.21779693959627, + -37.99261493926613 + ], + [ + 145.2202617640968, + -37.99528058539587 + ], + [ + 145.2205125222545, + -37.995135175116616 + ], + [ + 145.21802120445017, + -37.99248544074261 + ], + [ + 145.21797691521024, + -37.99246476726663 + ], + [ + 145.21796467338422, + -37.99245845491801 + ], + [ + 145.217951645775, + -37.992453572260295 + ], + [ + 145.21793792842553, + -37.992450030648804 + ], + [ + 145.21792389461115, + -37.99244792584099 + ], + [ + 145.21790954215138, + -37.99244734790385 + ], + [ + 145.21789534036495, + -37.99244830395064 + ], + [ + 145.21788128925093, + -37.99245079398142 + ], + [ + 145.21785866613845, + -37.99245828978947 + ], + [ + 145.21786225667398, + -37.99244960450092 + ], + [ + 145.21786408981586, + -37.99243593706875 + ], + [ + 145.21786113371954, + -37.99242228714518 + ], + [ + 145.21785373986594, + -37.992409651158646 + ], + [ + 145.2178423623181, + -37.99239866669153 + ], + [ + 145.21782763850592, + -37.9923901543056 + ], + [ + 145.2178105922121, + -37.99238448991819 + ], + [ + 145.2177921511744, + -37.99238213809133 + ], + [ + 145.21777579489137, + -37.9923828812661 + ], + [ + 145.21775993857526, + -37.99238624492046 + ], + [ + 145.21774362396718, + -37.99239302543011 + ], + [ + 145.21773005987464, + -37.99240255063415 + ], + [ + 145.21772010633111, + -37.992414202869476 + ], + [ + 145.2177139074669, + -37.992429786324045 + ], + [ + 145.21771306076707, + -37.99243761219922 + ], + [ + 145.21771545147294, + -37.99245134365588 + ], + [ + 145.217722277763, + -37.992464151247724 + ], + [ + 145.2177331794428, + -37.992475398813255 + ], + [ + 145.21774751908498, + -37.99248426578811 + ], + [ + 145.21776436894902, + -37.99249028760772 + ], + [ + 145.21778270742934, + -37.99249299828505 + ], + [ + 145.21780140815605, + -37.99249238074618 + ], + [ + 145.2178173583575, + -37.992489018509545 + ], + [ + 145.21781036909354, + -37.992498463180894 + ], + [ + 145.21780437527477, + -37.9925094546424 + ], + [ + 145.2177999640632, + -37.99252101069301 + ], + [ + 145.21779732754715, + -37.99253295404435 + ], + [ + 145.21779647008708, + -37.99254510456239 + ], + [ + 145.21779730435927, + -37.992557190623195 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10060, + "ZONE_STATU": "g", + "ZONE_CODE": "HO60", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2003-07-14T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO60", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.18146857700313, + -37.95416380218659 + ], + [ + 145.1809490850608, + -37.95452292702894 + ], + [ + 145.18203068899274, + -37.955478854962664 + ], + [ + 145.18254908143044, + -37.955118717313226 + ], + [ + 145.18146857700313, + -37.95416380218659 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10052, + "ZONE_STATU": "g", + "ZONE_CODE": "HO52", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO52", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "https://objective.cgd.vic.gov.au/id:A1293662/document/versions/published|Heritage Site" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.20564913789886, + -37.95235764255714 + ], + [ + 145.20564979297237, + -37.95239243135296 + ], + [ + 145.20566174278179, + -37.95242586075031 + ], + [ + 145.20568428724698, + -37.95245584775375 + ], + [ + 145.20571541071664, + -37.95248037939638 + ], + [ + 145.20575345305727, + -37.95249825903933 + ], + [ + 145.2057957178078, + -37.952508454436575 + ], + [ + 145.2058381775954, + -37.952510633847254 + ], + [ + 145.20588346791982, + -37.952504477070605 + ], + [ + 145.2059240706234, + -37.952490410027906 + ], + [ + 145.20595912385465, + -37.952469140382014 + ], + [ + 145.20598644362983, + -37.95244171603178 + ], + [ + 145.2060040160697, + -37.95240990827565 + ], + [ + 145.20601067380557, + -37.9523754112224 + ], + [ + 145.2060056988161, + -37.95234073673693 + ], + [ + 145.20598968426162, + -37.95230850678072 + ], + [ + 145.20596362264897, + -37.95228035829782 + ], + [ + 145.20592962565055, + -37.95225821560317 + ], + [ + 145.2058897308377, + -37.952243190977036 + ], + [ + 145.2058489843352, + -37.95223617229267 + ], + [ + 145.20579140082012, + -37.952238447408504 + ], + [ + 145.20574936736392, + -37.95224960936404 + ], + [ + 145.20571193861724, + -37.95226822979398 + ], + [ + 145.20568360044498, + -37.9522912236188 + ], + [ + 145.2056613789272, + -37.95232124849135 + ], + [ + 145.20564913789886, + -37.95235764255714 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10025, + "ZONE_STATU": "g", + "ZONE_CODE": "HO25", + "MUN_NUM": 326, + "AMD_NUM": "C51", + "AMD_FILE": "P1-SP/03/0027", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-09-24T14:00:00.000Z", + "OBJ_CREATE": "2003-07-29T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO25", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.20518445739117, + -37.95216278304474 + ], + [ + 145.20518617222962, + -37.95220029102943 + ], + [ + 145.20519335142882, + -37.95222535842648 + ], + [ + 145.20520572756217, + -37.95224897341767 + ], + [ + 145.2052240752433, + -37.95227015671592 + ], + [ + 145.20525011597402, + -37.95228758307951 + ], + [ + 145.20526629242426, + -37.95229386665404 + ], + [ + 145.20529545440982, + -37.95229872656249 + ], + [ + 145.20532838949183, + -37.952295084486515 + ], + [ + 145.2053596850485, + -37.95228168652856 + ], + [ + 145.2053826733964, + -37.95226257557752 + ], + [ + 145.205398700347, + -37.95224029498727 + ], + [ + 145.2054090485879, + -37.95221612573914 + ], + [ + 145.20541436736343, + -37.952198096687255 + ], + [ + 145.20541524452952, + -37.95217747705109 + ], + [ + 145.20541325341017, + -37.95215131751901 + ], + [ + 145.2054062683411, + -37.9521259827949 + ], + [ + 145.20538727403212, + -37.95209280628845 + ], + [ + 145.2053722549158, + -37.95207753033713 + ], + [ + 145.2053451669539, + -37.95206071872505 + ], + [ + 145.20532841452453, + -37.95205496697612 + ], + [ + 145.20529415172226, + -37.95205147085244 + ], + [ + 145.2052717368265, + -37.95205473284542 + ], + [ + 145.20523949885018, + -37.952068296601595 + ], + [ + 145.2052241057962, + -37.95207995498188 + ], + [ + 145.20521400127532, + -37.952090252452486 + ], + [ + 145.2051989102315, + -37.952112637399985 + ], + [ + 145.20518921204572, + -37.95213708685073 + ], + [ + 145.20518445739117, + -37.95216278304474 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10025, + "ZONE_STATU": "g", + "ZONE_CODE": "HO25", + "MUN_NUM": 326, + "AMD_NUM": "C51", + "AMD_FILE": "P1-SP/03/0027", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-09-24T14:00:00.000Z", + "OBJ_CREATE": "2003-07-29T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO25", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.2204494078052, + -37.99522116646589 + ], + [ + 145.22047659862048, + -37.99525004964489 + ], + [ + 145.22066464688277, + -37.99514279333268 + ], + [ + 145.22063745602992, + -37.995113910195826 + ], + [ + 145.2204494078052, + -37.99522116646589 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10059, + "ZONE_STATU": "g", + "ZONE_CODE": "HO59", + "MUN_NUM": 326, + "AMD_NUM": "C51", + "AMD_FILE": "P1-SP/03/0027", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-09-24T14:00:00.000Z", + "OBJ_CREATE": "2003-07-29T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO59", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.15888496575775, + -38.0080424709703 + ], + [ + 145.1588122897877, + -38.00840596413176 + ], + [ + 145.15994355582984, + -38.00854774308194 + ], + [ + 145.1600176067339, + -38.00817787365064 + ], + [ + 145.15888496575775, + -38.0080424709703 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2757, + "ZONE_STATU": "g", + "ZONE_CODE": "HO7", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO7", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.15332400368888, + -37.94990827440971 + ], + [ + 145.1532773725088, + -37.950159011113165 + ], + [ + 145.1533098323576, + -37.95030557272086 + ], + [ + 145.15330809915656, + -37.95031482579867 + ], + [ + 145.1534432825843, + -37.950331634511144 + ], + [ + 145.1535344025082, + -37.95034297602852 + ], + [ + 145.15362561626998, + -37.95035431894861 + ], + [ + 145.15371673625566, + -37.95036566032611 + ], + [ + 145.1538076709128, + -37.95037690862425 + ], + [ + 145.15384930005553, + -37.95038215715197 + ], + [ + 145.1538504987726, + -37.95037550857371 + ], + [ + 145.1538621720606, + -37.95031406345839 + ], + [ + 145.15332400368888, + -37.94990827440971 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10033, + "ZONE_STATU": "g", + "ZONE_CODE": "HO33", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO33", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.23666902188967, + -38.00276411058489 + ], + [ + 145.2362535442452, + -38.00461457266636 + ], + [ + 145.23706379342397, + -38.00472610593744 + ], + [ + 145.2369798764222, + -38.005100745444146 + ], + [ + 145.2371233667406, + -38.00512082709171 + ], + [ + 145.23698455374057, + -38.00574061683481 + ], + [ + 145.23683732355485, + -38.00639803205686 + ], + [ + 145.2371748626129, + -38.00665276133496 + ], + [ + 145.24001839913439, + -38.00793622442819 + ], + [ + 145.24073888554642, + -38.00449265699381 + ], + [ + 145.24113047749313, + -38.002674166569186 + ], + [ + 145.2396581005892, + -38.0024986891435 + ], + [ + 145.23901807686204, + -38.00242089844304 + ], + [ + 145.23897274409754, + -38.002631774749155 + ], + [ + 145.23888630908124, + -38.00303367850445 + ], + [ + 145.23831576267898, + -38.00296431288916 + ], + [ + 145.23810994193357, + -38.002939334236835 + ], + [ + 145.23762002140927, + -38.00287973302585 + ], + [ + 145.23698093359866, + -38.00280203534917 + ], + [ + 145.23675198422617, + -38.00277427478487 + ], + [ + 145.23666902188967, + -38.00276411058489 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10057, + "ZONE_STATU": "g", + "ZONE_CODE": "HO57", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO57", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.15255423337106, + -37.95173908914106 + ], + [ + 145.15242678072434, + -37.95238751809745 + ], + [ + 145.15268876826792, + -37.952418753352035 + ], + [ + 145.15338840579025, + -37.952508217108424 + ], + [ + 145.1535760649058, + -37.95253206648053 + ], + [ + 145.153684149726, + -37.95183593961448 + ], + [ + 145.15357656493606, + -37.951822447620806 + ], + [ + 145.15299513336186, + -37.95174979796001 + ], + [ + 145.1529941037216, + -37.95174969169088 + ], + [ + 145.1529626697093, + -37.95174577425789 + ], + [ + 145.15256320082406, + -37.95169580185479 + ], + [ + 145.15256264022852, + -37.95169570294938 + ], + [ + 145.15255423337106, + -37.95173908914106 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10068, + "ZONE_STATU": "g", + "ZONE_CODE": "HO68", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO68", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21503764278964, + -37.98764055130305 + ], + [ + 145.21451677629415, + -37.98767733273828 + ], + [ + 145.21452040168543, + -37.987694326616534 + ], + [ + 145.21452743882813, + -37.98769452357574 + ], + [ + 145.21453155519526, + -37.98772999543792 + ], + [ + 145.21452496113645, + -37.98773088640884 + ], + [ + 145.21452903177249, + -37.98775275245534 + ], + [ + 145.21454063519946, + -37.98775437025473 + ], + [ + 145.2145457053488, + -37.98780084881628 + ], + [ + 145.2145378103749, + -37.98780117943282 + ], + [ + 145.21454128942656, + -37.98783195640938 + ], + [ + 145.21454850556452, + -37.987832516486016 + ], + [ + 145.21455454923617, + -37.987877568227276 + ], + [ + 145.21454107733513, + -37.98787943596195 + ], + [ + 145.21454965927109, + -37.987959214799425 + ], + [ + 145.2145633690924, + -37.9879591526794 + ], + [ + 145.21456771684225, + -37.98799670035582 + ], + [ + 145.21461895245818, + -37.98799405453554 + ], + [ + 145.21462843207206, + -37.98800194708774 + ], + [ + 145.215119126522, + -37.987722517981844 + ], + [ + 145.21503764278964, + -37.98764055130305 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10037, + "ZONE_STATU": "g", + "ZONE_CODE": "HO37", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO37", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21307951647813, + -38.00115635793286 + ], + [ + 145.21306386728892, + -38.001232344624846 + ], + [ + 145.21317238186845, + -38.00124579700144 + ], + [ + 145.21389068896121, + -38.00133509879017 + ], + [ + 145.21409760654055, + -38.00136076712324 + ], + [ + 145.21433869693814, + -38.00139073832538 + ], + [ + 145.21445938303052, + -38.00140572588135 + ], + [ + 145.21457885098397, + -38.00142060471478 + ], + [ + 145.21468717842203, + -38.00143405285501 + ], + [ + 145.2147965363468, + -38.001447606643055 + ], + [ + 145.2149976474576, + -38.00147264462827 + ], + [ + 145.2151027920393, + -38.00148568366215 + ], + [ + 145.21520821828778, + -38.00149872687821 + ], + [ + 145.21530933504638, + -38.00151134418164 + ], + [ + 145.21533283661535, + -38.00151422373493 + ], + [ + 145.21535602427215, + -38.00140222106956 + ], + [ + 145.21549302439422, + -38.00074035395639 + ], + [ + 145.2156491741319, + -37.99998570394548 + ], + [ + 145.21571019784676, + -37.99966479293587 + ], + [ + 145.21542237241945, + -37.99962988051319 + ], + [ + 145.21344084649422, + -37.99939706146724 + ], + [ + 145.21335683130613, + -37.99980591978903 + ], + [ + 145.21332967172302, + -37.99993831439229 + ], + [ + 145.21332700794153, + -37.9999513384051 + ], + [ + 145.21330209719304, + -38.00007232447884 + ], + [ + 145.21327450943744, + -38.00020687495389 + ], + [ + 145.21324661590424, + -38.000342411871095 + ], + [ + 145.21321892749478, + -38.00047723109566 + ], + [ + 145.21319122585774, + -38.00061259070857 + ], + [ + 145.21316343023489, + -38.00074794888269 + ], + [ + 145.21313574805012, + -38.000882497871046 + ], + [ + 145.21310805700972, + -38.00101740711426 + ], + [ + 145.21307951647813, + -38.00115635793286 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10027, + "ZONE_STATU": "g", + "ZONE_CODE": "HO27", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO27", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.23366716883766, + -38.003408405268544 + ], + [ + 145.23395408578963, + -38.00181857337455 + ], + [ + 145.23167461768338, + -38.00155185190109 + ], + [ + 145.23153722584058, + -38.00153627030896 + ], + [ + 145.22884024046664, + -38.001231047222596 + ], + [ + 145.2286296125861, + -38.00120715091267 + ], + [ + 145.22625838331373, + -38.00093867180835 + ], + [ + 145.22600092241777, + -38.001069576988634 + ], + [ + 145.2261993897914, + -38.00148117542492 + ], + [ + 145.22724228251565, + -38.002158780681214 + ], + [ + 145.2285657150609, + -38.002758072463656 + ], + [ + 145.22931782958915, + -38.00309871839819 + ], + [ + 145.22940004726553, + -38.003135906599766 + ], + [ + 145.23339021329116, + -38.00494261366147 + ], + [ + 145.23339140162162, + -38.00493614430904 + ], + [ + 145.2334977766272, + -38.00434650566031 + ], + [ + 145.23366716883766, + -38.003408405268544 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10056, + "ZONE_STATU": "g", + "ZONE_CODE": "HO56", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-27T13:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO56", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.21443639285826, + -37.99055138711708 + ], + [ + 145.21435698798683, + -37.99039520906532 + ], + [ + 145.21427130582697, + -37.990226862209596 + ], + [ + 145.21412702836443, + -37.99023683442242 + ], + [ + 145.21398463464084, + -37.990246564771226 + ], + [ + 145.21387967180007, + -37.99025380015569 + ], + [ + 145.21378430241654, + -37.99026037028601 + ], + [ + 145.21370633442763, + -37.99026567300563 + ], + [ + 145.21383916238713, + -37.990530332670346 + ], + [ + 145.21385376273696, + -37.990559386496216 + ], + [ + 145.2138278306588, + -37.99056782236604 + ], + [ + 145.21372911626347, + -37.99060002015806 + ], + [ + 145.21362955047783, + -37.99063247523122 + ], + [ + 145.21332659169656, + -37.99073130688487 + ], + [ + 145.2134052328696, + -37.99088792450325 + ], + [ + 145.21443639285826, + -37.99055138711708 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10034, + "ZONE_STATU": "g", + "ZONE_CODE": "HO34", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO34", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.24587857991145, + -38.00804065776047 + ], + [ + 145.2456065005008, + -38.00915158801968 + ], + [ + 145.24576523568751, + -38.009178734314496 + ], + [ + 145.24604481991906, + -38.008064131427965 + ], + [ + 145.24644109088663, + -38.00631669203843 + ], + [ + 145.2486083708422, + -38.00664155433339 + ], + [ + 145.2485463789764, + -38.00691021083599 + ], + [ + 145.25048910507687, + -38.00717682196374 + ], + [ + 145.25056656608092, + -38.00688136448408 + ], + [ + 145.25085756732827, + -38.00692290586137 + ], + [ + 145.25095042271312, + -38.0064933375779 + ], + [ + 145.2486889653457, + -38.00617522456908 + ], + [ + 145.2486585592151, + -38.006284784067965 + ], + [ + 145.2468920371931, + -38.006038430239414 + ], + [ + 145.24673106427275, + -38.005794020392656 + ], + [ + 145.24659657264002, + -38.00578237388089 + ], + [ + 145.24711982977237, + -38.003469193247916 + ], + [ + 145.24714117412657, + -38.00336950013923 + ], + [ + 145.24715321175808, + -38.00333724350124 + ], + [ + 145.2471545750278, + -38.00330365641075 + ], + [ + 145.24714512074152, + -38.0032708090405 + ], + [ + 145.24712545673754, + -38.00324078275776 + ], + [ + 145.2470968522928, + -38.00321548858877 + ], + [ + 145.247060871183, + -38.00319630134782 + ], + [ + 145.24701992423257, + -38.003184518379 + ], + [ + 145.24697643512775, + -38.003180896618716 + ], + [ + 145.24693321808167, + -38.00318556812761 + ], + [ + 145.24689272037108, + -38.00319829909758 + ], + [ + 145.2468575899048, + -38.003218318113696 + ], + [ + 145.24683001592862, + -38.00324439642256 + ], + [ + 145.2468115412685, + -38.00327484513055 + ], + [ + 145.24680342926555, + -38.003307881075195 + ], + [ + 145.24680610693414, + -38.00334134821913 + ], + [ + 145.2468195254583, + -38.003373353727376 + ], + [ + 145.246842701517, + -38.003401810626094 + ], + [ + 145.2468743594193, + -38.003425078081406 + ], + [ + 145.2469110325679, + -38.00343886968031 + ], + [ + 145.2463208914062, + -38.00604414782383 + ], + [ + 145.24456558854513, + -38.00579657497827 + ], + [ + 145.2445039041953, + -38.00604388008234 + ], + [ + 145.24521023157018, + -38.00614299354577 + ], + [ + 145.245160154836, + -38.00634470133252 + ], + [ + 145.24549200983313, + -38.00639389357963 + ], + [ + 145.24546238193895, + -38.006517879854705 + ], + [ + 145.2457012629851, + -38.00655514219687 + ], + [ + 145.24573644148182, + -38.00642285936024 + ], + [ + 145.24623653971892, + -38.0064941116362 + ], + [ + 145.24587857991145, + -38.00804065776047 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10058, + "ZONE_STATU": "g", + "ZONE_CODE": "HO58", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO58", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "https://objective.cgd.vic.gov.au/id:A1293664/document/versions/published|Heritage Site" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.14821269021115, + -37.97316571431642 + ], + [ + 145.14819488181834, + -37.97325427201658 + ], + [ + 145.14805385119115, + -37.97395780061168 + ], + [ + 145.14804794524957, + -37.97403591398129 + ], + [ + 145.14817139914, + -37.97405047211268 + ], + [ + 145.14827444870315, + -37.974062636521055 + ], + [ + 145.1484101636415, + -37.97407864886957 + ], + [ + 145.14843537661588, + -37.97386352780688 + ], + [ + 145.14839751843343, + -37.97377121038542 + ], + [ + 145.1484241917339, + -37.97366981791258 + ], + [ + 145.14840040196952, + -37.9735929488261 + ], + [ + 145.14840659782726, + -37.97347339421083 + ], + [ + 145.14846457355537, + -37.97327689899562 + ], + [ + 145.14846731716978, + -37.973234955811975 + ], + [ + 145.14845556254784, + -37.97319467643969 + ], + [ + 145.14821325322546, + -37.973165723182426 + ], + [ + 145.14821269021115, + -37.97316571431642 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10071, + "ZONE_STATU": "g", + "ZONE_CODE": "HO71", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-27T13:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO71", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.24403068878664, + -38.0101641232751 + ], + [ + 145.2441922792711, + -38.010236995146926 + ], + [ + 145.24508237481476, + -38.01063861753115 + ], + [ + 145.24528020598734, + -38.010727886545475 + ], + [ + 145.24532973319955, + -38.01075024983374 + ], + [ + 145.24566713442792, + -38.01090250904144 + ], + [ + 145.24588252604838, + -38.01058217333108 + ], + [ + 145.24447615693714, + -38.009947598132534 + ], + [ + 145.24427321876445, + -38.00985599900676 + ], + [ + 145.24403068878664, + -38.0101641232751 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10058, + "ZONE_STATU": "g", + "ZONE_CODE": "HO58", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2004-11-18T13:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO58", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "https://objective.cgd.vic.gov.au/id:A1293664/document/versions/published|Heritage Site" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.2475364641762, + -38.00392914953629 + ], + [ + 145.24751471998772, + -38.0039312581205 + ], + [ + 145.24747316187054, + -38.003941180369885 + ], + [ + 145.2474363246718, + -38.003957930502175 + ], + [ + 145.24740658112088, + -38.003980462688936 + ], + [ + 145.24738565322716, + -38.00400745110171 + ], + [ + 145.2473748000403, + -38.00403729270907 + ], + [ + 145.24737481979275, + -38.00406801720691 + ], + [ + 145.24738566150853, + -38.00409782182936 + ], + [ + 145.24740661704837, + -38.00412489401107 + ], + [ + 145.2474204203079, + -38.0041368128186 + ], + [ + 145.2474540399465, + -38.00415659545192 + ], + [ + 145.24749344682226, + -38.00416997712178 + ], + [ + 145.24753640495456, + -38.00417620368996 + ], + [ + 145.24758020252293, + -38.00417478422917 + ], + [ + 145.24762220871958, + -38.00416576962526 + ], + [ + 145.24765968384867, + -38.004149839846995 + ], + [ + 145.2476904450694, + -38.00412795346702 + ], + [ + 145.24771258261237, + -38.00410143353066 + ], + [ + 145.2477247435649, + -38.004071881683764 + ], + [ + 145.24772604013333, + -38.00404108670347 + ], + [ + 145.24771661077656, + -38.00401112296101 + ], + [ + 145.24769688631363, + -38.00398361868074 + ], + [ + 145.24768356101302, + -38.003971346627964 + ], + [ + 145.2476508973472, + -38.00395085750647 + ], + [ + 145.24761198139927, + -38.0039365822043 + ], + [ + 145.2475693264817, + -38.00392945918139 + ], + [ + 145.2475364641762, + -38.00392914953629 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10058, + "ZONE_STATU": "g", + "ZONE_CODE": "HO58", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003?056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "0203-07-16T14:20:08.000Z", + "OBJ_CREATE": null, + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO58", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "https://objective.cgd.vic.gov.au/id:A1293664/document/versions/published|Heritage Site" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.2244311359828, + -37.986801312871776 + ], + [ + 145.22419226368757, + -37.98694204614835 + ], + [ + 145.22407882707904, + -37.987008899204255 + ], + [ + 145.22396072392746, + -37.9870784747698 + ], + [ + 145.2238132845641, + -37.98716535681912 + ], + [ + 145.2239492904636, + -37.98731121124447 + ], + [ + 145.2239556954377, + -37.98731815560948 + ], + [ + 145.22408071693388, + -37.98745231113493 + ], + [ + 145.2240852030388, + -37.98745706410482 + ], + [ + 145.22411739608484, + -37.98743808867561 + ], + [ + 145.22431512432942, + -37.987321601916705 + ], + [ + 145.2243988455499, + -37.987272229865475 + ], + [ + 145.22460857481533, + -37.98714862570484 + ], + [ + 145.22477944299018, + -37.98704795062725 + ], + [ + 145.2248271601942, + -37.987019838947624 + ], + [ + 145.22462914670575, + -37.98691062110389 + ], + [ + 145.2244311359828, + -37.986801312871776 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10041, + "ZONE_STATU": "g", + "ZONE_CODE": "HO41", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO41", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "https://objective.cgd.vic.gov.au/id:A1293666/document/versions/published|Heritage Site" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.17711100988356, + -37.9684573026577 + ], + [ + 145.17717464705888, + -37.96814248872295 + ], + [ + 145.17670702954018, + -37.96779231917217 + ], + [ + 145.17658803797815, + -37.96839432412315 + ], + [ + 145.176588600965, + -37.96839433285242 + ], + [ + 145.17711100988356, + -37.9684573026577 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2763, + "ZONE_STATU": "g", + "ZONE_CODE": "HO13", + "MUN_NUM": 326, + "AMD_NUM": "C31Pt 3", + "AMD_FILE": "PL-SP/03/0613", + "ZONE_NUM_P": 0, + "EXH_DATE": "2003-10-01T14:00:00.000Z", + "GAZ_DATE": null, + "OBJ_CREATE": "2005-02-21T13:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO13", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.1601476917319, + -38.00752759140306 + ], + [ + 145.15890867947897, + -38.007387370760654 + ], + [ + 145.15888006498557, + -38.007551353650335 + ], + [ + 145.15879610278233, + -38.00803188911362 + ], + [ + 145.15888496575775, + -38.0080424709703 + ], + [ + 145.1600176067339, + -38.00817787365064 + ], + [ + 145.16011496044314, + -38.00769105969145 + ], + [ + 145.1601476917319, + -38.00752759140306 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2756, + "ZONE_STATU": "g", + "ZONE_CODE": "HO6", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO6", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.22496866083588, + -37.98792342832014 + ], + [ + 145.22468341011268, + -37.98809112317879 + ], + [ + 145.22479499951143, + -37.98821002840415 + ], + [ + 145.22508134854922, + -37.98804352116231 + ], + [ + 145.22496866083588, + -37.98792342832014 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 10042, + "ZONE_STATU": "g", + "ZONE_CODE": "HO42", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-20T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO42", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "https://objective.cgd.vic.gov.au/id:A1293665/document/versions/published|Heritage Site" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.2206228557259, + -37.98722325733046 + ], + [ + 145.22008958649414, + -37.987536483490395 + ], + [ + 145.21935962790107, + -37.98796539065381 + ], + [ + 145.2200451207515, + -37.98869260685857 + ], + [ + 145.22004578865, + -37.98869216646837 + ], + [ + 145.2207794529178, + -37.988265473599505 + ], + [ + 145.22091840588277, + -37.98841353846979 + ], + [ + 145.22105635088175, + -37.98856059682546 + ], + [ + 145.22119521109065, + -37.98870865996912 + ], + [ + 145.2214621317807, + -37.98899326978668 + ], + [ + 145.2214625923789, + -37.98899363715457 + ], + [ + 145.2219939001202, + -37.98868019501719 + ], + [ + 145.22238205553168, + -37.98845459642113 + ], + [ + 145.22238272124062, + -37.98845424608458 + ], + [ + 145.22237548898357, + -37.98844656832661 + ], + [ + 145.22226839145, + -37.988332323866814 + ], + [ + 145.2221614776148, + -37.9882182622886 + ], + [ + 145.222055295408, + -37.98810502257928 + ], + [ + 145.22194600279033, + -37.98798840203161 + ], + [ + 145.22183689170853, + -37.98787205442956 + ], + [ + 145.22172933958763, + -37.98775726200855 + ], + [ + 145.22162535692013, + -37.98764630768631 + ], + [ + 145.2215178011027, + -37.98753169521862 + ], + [ + 145.22145583401957, + -37.98746552535724 + ], + [ + 145.22145516831554, + -37.98746587568871 + ], + [ + 145.22106586995693, + -37.98769613919915 + ], + [ + 145.2206228557259, + -37.98722325733046 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2765, + "ZONE_STATU": "g", + "ZONE_CODE": "HO15", + "MUN_NUM": 326, + "AMD_NUM": "C41", + "AMD_FILE": "STA/2003/056", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2003-07-16T14:00:00.000Z", + "OBJ_CREATE": "2002-10-17T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO15", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.16257062485835, + -38.00379690460374 + ], + [ + 145.16291958061512, + -38.003831640296696 + ], + [ + 145.16298311316146, + -38.003521159802254 + ], + [ + 145.16267793665472, + -38.003482062956785 + ], + [ + 145.16257685583685, + -38.00353976851907 + ], + [ + 145.16254560763352, + -38.00370055785753 + ], + [ + 145.16258952727284, + -38.00370556905808 + ], + [ + 145.16257062485835, + -38.00379690460374 + ] + ] + ] + }, + "properties": { + "ZONE_NUM": 2755, + "ZONE_STATU": "g", + "ZONE_CODE": "HO5", + "MUN_NUM": 0, + "AMD_NUM": "C134", + "AMD_FILE": "11/005660", + "ZONE_NUM_P": 0, + "EXH_DATE": null, + "GAZ_DATE": "2011-06-15T14:00:00.000Z", + "OBJ_CREATE": "2011-05-19T14:00:00.000Z", + "URL": "http://planningschemes.dpcd.vic.gov.au/greaterdandenong/ordinance/43_01s_gdan.pdf|HO5", + "DOCUMENT": "https://objective.cgd.vic.gov.au/id:A558624/document/versions/published|Heritage Study", + "DOCUMENT_2": "" + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.0813293457031, + -38.086742982814656 + ], + [ + 145.3044891357422, + -38.086742982814656 + ], + [ + 145.3044891357422, + -37.91955532485734 + ], + [ + 145.0813293457031, + -37.91955532485734 + ], + [ + 145.0813293457031, + -38.086742982814656 + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-mask/test/in/mask-outside.geojson b/src/mask/test/in/mask-outside.geojson similarity index 100% rename from packages/turf-mask/test/in/mask-outside.geojson rename to src/mask/test/in/mask-outside.geojson diff --git a/packages/turf-mask/test/in/multi-polygon.geojson b/src/mask/test/in/multi-polygon.geojson similarity index 100% rename from packages/turf-mask/test/in/multi-polygon.geojson rename to src/mask/test/in/multi-polygon.geojson diff --git a/packages/turf-mask/test/in/overlapping.geojson b/src/mask/test/in/overlapping.geojson similarity index 100% rename from packages/turf-mask/test/in/overlapping.geojson rename to src/mask/test/in/overlapping.geojson diff --git a/packages/turf-mask/test/out/basic.geojson b/src/mask/test/out/basic.geojson similarity index 100% rename from packages/turf-mask/test/out/basic.geojson rename to src/mask/test/out/basic.geojson diff --git a/src/mask/test/out/issue-1454.geojson b/src/mask/test/out/issue-1454.geojson new file mode 100644 index 0000000000..60663ad3bc --- /dev/null +++ b/src/mask/test/out/issue-1454.geojson @@ -0,0 +1,5555 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145.0813293457031, + -38.086742982814656 + ], + [ + 145.3044891357422, + -38.086742982814656 + ], + [ + 145.3044891357422, + -37.91955532485734 + ], + [ + 145.0813293457031, + -37.91955532485734 + ], + [ + 145.0813293457031, + -38.086742982814656 + ] + ], + [ + [ + 145.1449608214699, + -38.01800628866028 + ], + [ + 145.1457030785069, + -38.01860913872286 + ], + [ + 145.1464651507225, + -38.01792271127711 + ], + [ + 145.14623999710878, + -38.01774391842125 + ], + [ + 145.1475527795656, + -38.01659413890841 + ], + [ + 145.14746204895653, + -38.01650071805776 + ], + [ + 145.14837614886983, + -38.011835650229294 + ], + [ + 145.1481035522985, + -38.01180342549216 + ], + [ + 145.14723448395105, + -38.016361802910474 + ], + [ + 145.14589982713082, + -38.017473842833084 + ], + [ + 145.14574665929277, + -38.01736826357449 + ], + [ + 145.1449608214699, + -38.01800628866028 + ] + ], + [ + [ + 145.1462173578213, + -37.94359805947292 + ], + [ + 145.14644912946454, + -37.94377362268094 + ], + [ + 145.14656081070345, + -37.943765471553625 + ], + [ + 145.14658914680464, + -37.943616171993376 + ], + [ + 145.14659120604463, + -37.943534213515726 + ], + [ + 145.14665530961042, + -37.94322365805874 + ], + [ + 145.14629404249038, + -37.94317525781493 + ], + [ + 145.1462173578213, + -37.94359805947292 + ] + ], + [ + [ + 145.1464070697804, + -37.943935049622155 + ], + [ + 145.148452122342, + -37.945482740093816 + ], + [ + 145.14848122524822, + -37.94550464199583 + ], + [ + 145.14851347426537, + -37.945337653888814 + ], + [ + 145.14853526811402, + -37.945224561146674 + ], + [ + 145.14663610748119, + -37.9437489083303 + ], + [ + 145.1464070697804, + -37.943935049622155 + ] + ], + [ + [ + 145.14804794524957, + -37.97403591398129 + ], + [ + 145.14817139914, + -37.97405047211268 + ], + [ + 145.14827444870315, + -37.974062636521055 + ], + [ + 145.1484101636415, + -37.97407864886957 + ], + [ + 145.14843537661588, + -37.97386352780688 + ], + [ + 145.14839751843343, + -37.97377121038542 + ], + [ + 145.1484241917339, + -37.97366981791258 + ], + [ + 145.14840040196952, + -37.9735929488261 + ], + [ + 145.14840659782726, + -37.97347339421083 + ], + [ + 145.14846457355537, + -37.97327689899562 + ], + [ + 145.14846731716978, + -37.973234955811975 + ], + [ + 145.14845556254784, + -37.97319467643969 + ], + [ + 145.14821325322546, + -37.973165723182426 + ], + [ + 145.14821269021115, + -37.97316571431642 + ], + [ + 145.14819488181834, + -37.97325427201658 + ], + [ + 145.14805385119115, + -37.97395780061168 + ], + [ + 145.14804794524957, + -37.97403591398129 + ] + ], + [ + [ + 145.14935337394604, + -38.01440633627869 + ], + [ + 145.15173012990834, + -38.01468420436961 + ], + [ + 145.15217331738788, + -38.01232616248385 + ], + [ + 145.15213211478303, + -38.01228010489715 + ], + [ + 145.1498073030163, + -38.01200504535165 + ], + [ + 145.14935337394604, + -38.01440633627869 + ] + ], + [ + [ + 145.14995227726533, + -37.954046822365775 + ], + [ + 145.150461676871, + -37.954107092006346 + ], + [ + 145.15054254074747, + -37.953693093520755 + ], + [ + 145.1500250061197, + -37.95363548939198 + ], + [ + 145.14995227726533, + -37.954046822365775 + ] + ], + [ + [ + 145.15033732303152, + -37.9531831448711 + ], + [ + 145.1505823811117, + -37.953208442304515 + ], + [ + 145.15063960721352, + -37.95283506741284 + ], + [ + 145.150531733439, + -37.95282183837974 + ], + [ + 145.15048297303542, + -37.953104615806694 + ], + [ + 145.150355267597, + -37.95308882225125 + ], + [ + 145.15033732303152, + -37.9531831448711 + ] + ], + [ + [ + 145.15053127958575, + -37.95223374955999 + ], + [ + 145.15082114172407, + -37.952268580780014 + ], + [ + 145.1509012406048, + -37.95185871445616 + ], + [ + 145.1506109109806, + -37.95182387609682 + ], + [ + 145.1505599417122, + -37.952086256309975 + ], + [ + 145.15053127958575, + -37.95223374955999 + ] + ], + [ + [ + 145.15183930985006, + -37.955787125535714 + ], + [ + 145.15184279753308, + -37.95580898449705 + ], + [ + 145.15185316974905, + -37.95582951004529 + ], + [ + 145.15186970759657, + -37.95584742948452 + ], + [ + 145.1518913124009, + -37.95586164435015 + ], + [ + 145.15191688096888, + -37.955871236306166 + ], + [ + 145.1519446443772, + -37.95587563695555 + ], + [ + 145.15197291848452, + -37.95587463963407 + ], + [ + 145.15200010844814, + -37.95586821928184 + ], + [ + 145.15202432669793, + -37.95585679674002 + ], + [ + 145.1520442417779, + -37.955841071888536 + ], + [ + 145.15205851546378, + -37.95582201480094 + ], + [ + 145.1520663656462, + -37.95580087458806 + ], + [ + 145.15206720010343, + -37.95577881324372 + ], + [ + 145.15206107654012, + -37.95575727327191 + ], + [ + 145.15204833861608, + -37.955737521468805 + ], + [ + 145.15202979680072, + -37.955720922064096 + ], + [ + 145.1520064627311, + -37.95570830184905 + ], + [ + 145.15196597105665, + -37.95569874572525 + ], + [ + 145.15192367362883, + -37.955701324688434 + ], + [ + 145.15189138969478, + -37.95571253036877 + ], + [ + 145.1518696367211, + -37.95572669461733 + ], + [ + 145.15185313856642, + -37.95574463552878 + ], + [ + 145.15184276890304, + -37.955765195536735 + ], + [ + 145.15183930985006, + -37.955787125535714 + ] + ], + [ + [ + 145.1520925948851, + -37.94996434755506 + ], + [ + 145.15209315546687, + -37.949964446462374 + ], + [ + 145.15253244178473, + -37.9500166676144 + ], + [ + 145.1525423805539, + -37.94996456578261 + ], + [ + 145.1525517803354, + -37.949915248580446 + ], + [ + 145.1524505480841, + -37.949903026662376 + ], + [ + 145.15239946294065, + -37.94989690830313 + ], + [ + 145.15234959503246, + -37.949890899143256 + ], + [ + 145.1522909319038, + -37.949883850794905 + ], + [ + 145.15229350592796, + -37.94987100694549 + ], + [ + 145.15229294309015, + -37.949870998103584 + ], + [ + 145.15223849224077, + -37.94986437630158 + ], + [ + 145.15217449798433, + -37.949856613444155 + ], + [ + 145.15211490135385, + -37.94984937014275 + ], + [ + 145.15210218032195, + -37.949915123408694 + ], + [ + 145.1520925948851, + -37.94996434755506 + ] + ], + [ + [ + 145.15242678072434, + -37.95238751809745 + ], + [ + 145.15268876826792, + -37.952418753352035 + ], + [ + 145.15338840579025, + -37.952508217108424 + ], + [ + 145.1535760649058, + -37.95253206648053 + ], + [ + 145.153684149726, + -37.95183593961448 + ], + [ + 145.15357656493606, + -37.951822447620806 + ], + [ + 145.15299513336186, + -37.95174979796001 + ], + [ + 145.1529941037216, + -37.95174969169088 + ], + [ + 145.1529626697093, + -37.95174577425789 + ], + [ + 145.15256320082406, + -37.95169580185479 + ], + [ + 145.15256264022852, + -37.95169570294938 + ], + [ + 145.15255423337106, + -37.95173908914106 + ], + [ + 145.15242678072434, + -37.95238751809745 + ] + ], + [ + [ + 145.1532773725088, + -37.950159011113165 + ], + [ + 145.1533098323576, + -37.95030557272086 + ], + [ + 145.15330809915656, + -37.95031482579867 + ], + [ + 145.1534432825843, + -37.950331634511144 + ], + [ + 145.1535344025082, + -37.95034297602852 + ], + [ + 145.15362561626998, + -37.95035431894861 + ], + [ + 145.15371673625566, + -37.95036566032611 + ], + [ + 145.1538076709128, + -37.95037690862425 + ], + [ + 145.15384930005553, + -37.95038215715197 + ], + [ + 145.1538504987726, + -37.95037550857371 + ], + [ + 145.1538621720606, + -37.95031406345839 + ], + [ + 145.15332400368888, + -37.94990827440971 + ], + [ + 145.1532773725088, + -37.950159011113165 + ] + ], + [ + [ + 145.1559304836285, + -38.02008097020962 + ], + [ + 145.15764627780985, + -38.02034285330762 + ], + [ + 145.15777911061562, + -38.01962972927903 + ], + [ + 145.15602548829676, + -38.01934869445461 + ], + [ + 145.1559304836285, + -38.02008097020962 + ] + ], + [ + [ + 145.15850353199522, + -37.953063783345556 + ], + [ + 145.15933880346697, + -37.9536942231038 + ], + [ + 145.15984432068373, + -37.9540757778542 + ], + [ + 145.16115145688065, + -37.95506506654863 + ], + [ + 145.1611557874975, + -37.95506828775497 + ], + [ + 145.161852060192, + -37.95559535436808 + ], + [ + 145.16266291234064, + -37.956206197893145 + ], + [ + 145.16297458406655, + -37.95624422323659 + ], + [ + 145.16325524665203, + -37.95645709798918 + ], + [ + 145.16328490773535, + -37.956479545593616 + ], + [ + 145.16337232988448, + -37.95654551248508 + ], + [ + 145.16346085329894, + -37.95661248760853 + ], + [ + 145.16354735331097, + -37.956677809272435 + ], + [ + 145.16363541693826, + -37.95674441668703 + ], + [ + 145.16370727197153, + -37.956798607474525 + ], + [ + 145.1637800450816, + -37.956853623451906 + ], + [ + 145.16384830431093, + -37.95690523521549 + ], + [ + 145.1639134344511, + -37.956954365391326 + ], + [ + 145.1639773652552, + -37.95700266590913 + ], + [ + 145.16402885973173, + -37.95704158205964 + ], + [ + 145.164078880117, + -37.95707939397767 + ], + [ + 145.16412982301696, + -37.9571178509746 + ], + [ + 145.1641798435059, + -37.95715566285187 + ], + [ + 145.16422894158111, + -37.957192829610584 + ], + [ + 145.16428043856612, + -37.95723165559163 + ], + [ + 145.16433091932217, + -37.95726983498936 + ], + [ + 145.16438121698232, + -37.95730783130813 + ], + [ + 145.16443068604204, + -37.95734518397385 + ], + [ + 145.1644818124585, + -37.95738382388441 + ], + [ + 145.16453054454067, + -37.9574206244071 + ], + [ + 145.16461741499245, + -37.95748622137546 + ], + [ + 145.1646641191146, + -37.957521548596624 + ], + [ + 145.16471561431734, + -37.957560464461764 + ], + [ + 145.16476452978324, + -37.957597447950356 + ], + [ + 145.16481187955546, + -37.957633235688384 + ], + [ + 145.1648251470677, + -37.957643173509126 + ], + [ + 145.16490543569086, + -37.95765271549497 + ], + [ + 145.16500846131711, + -37.957665044878176 + ], + [ + 145.16510400180195, + -37.95767644649218 + ], + [ + 145.16520665447518, + -37.95768867978363 + ], + [ + 145.1653120189128, + -37.957701315688524 + ], + [ + 145.16539792100585, + -37.95771157560759 + ], + [ + 145.16541977231688, + -37.95770092427064 + ], + [ + 145.1654873970297, + -37.957333019779426 + ], + [ + 145.16549138668447, + -37.957274517034264 + ], + [ + 145.1659442596012, + -37.95732978365114 + ], + [ + 145.16615113908364, + -37.957355084115505 + ], + [ + 145.16635511936786, + -37.95737997861606 + ], + [ + 145.16636400954545, + -37.95738101822109 + ], + [ + 145.16636522468147, + -37.95738121736596 + ], + [ + 145.16656173114907, + -37.95740473358661 + ], + [ + 145.16676824702753, + -37.95742957680026 + ], + [ + 145.16697504450994, + -37.957454424041224 + ], + [ + 145.1671792242325, + -37.957478869724795 + ], + [ + 145.1673874270341, + -37.957503828242885 + ], + [ + 145.16759132337, + -37.95752835889716 + ], + [ + 145.1677962518416, + -37.95755290527817 + ], + [ + 145.16800314390582, + -37.95757775218968 + ], + [ + 145.16820807044297, + -37.95760238792489 + ], + [ + 145.168412063436, + -37.95762682856554 + ], + [ + 145.1686181138423, + -37.957651571190645 + ], + [ + 145.1688252879697, + -37.95767642105195 + ], + [ + 145.16903816944063, + -37.957701990101846 + ], + [ + 145.169133418134, + -37.957203598063685 + ], + [ + 145.1692936272494, + -37.95722240006553 + ], + [ + 145.1694021615123, + -37.95723589254507 + ], + [ + 145.16975259690827, + -37.95727792713107 + ], + [ + 145.16978474173925, + -37.95731383666976 + ], + [ + 145.16982991284462, + -37.957074513148086 + ], + [ + 145.1710883383243, + -37.95043560293798 + ], + [ + 145.17151177668177, + -37.948243472580636 + ], + [ + 145.17181995568595, + -37.948016165021045 + ], + [ + 145.17215550142356, + -37.94764629293109 + ], + [ + 145.1721745331169, + -37.94754099127438 + ], + [ + 145.16960697249402, + -37.94520747343099 + ], + [ + 145.16924597209805, + -37.94487884600173 + ], + [ + 145.16915333128227, + -37.944838210470024 + ], + [ + 145.16906575217672, + -37.94476377598928 + ], + [ + 145.1690319769734, + -37.944684142276664 + ], + [ + 145.1677825421705, + -37.94354690368938 + ], + [ + 145.16768892571628, + -37.943609867030666 + ], + [ + 145.1673824630929, + -37.94385899495085 + ], + [ + 145.16698767345176, + -37.94413179345852 + ], + [ + 145.16658992385112, + -37.94440652666511 + ], + [ + 145.1663679520038, + -37.944559480416345 + ], + [ + 145.1661198166439, + -37.944730586448614 + ], + [ + 145.16584511309122, + -37.94492100958247 + ], + [ + 145.1656048488008, + -37.94489248523098 + ], + [ + 145.16528384311593, + -37.9448543216771 + ], + [ + 145.16525382048948, + -37.944850339466264 + ], + [ + 145.165018889895, + -37.94482243771965 + ], + [ + 145.16475241819248, + -37.944791250275436 + ], + [ + 145.1645114066746, + -37.94476262193735 + ], + [ + 145.16433766751382, + -37.94474189060992 + ], + [ + 145.16416663746438, + -37.94472165181042 + ], + [ + 145.16399738748368, + -37.94470153064848 + ], + [ + 145.16382645368336, + -37.944681202757884 + ], + [ + 145.16365308790657, + -37.944660566350855 + ], + [ + 145.16348402583634, + -37.944640447385886 + ], + [ + 145.16331168758856, + -37.944620006720626 + ], + [ + 145.16313626301195, + -37.94459915720537 + ], + [ + 145.1629740912501, + -37.94541013835874 + ], + [ + 145.16270953436054, + -37.946824001326846 + ], + [ + 145.16261395809417, + -37.94733445693716 + ], + [ + 145.16254770546965, + -37.94768859641047 + ], + [ + 145.1624776641114, + -37.94806294914321 + ], + [ + 145.16244972731002, + -37.948204960877945 + ], + [ + 145.16234480919704, + -37.94875122009503 + ], + [ + 145.16228852724953, + -37.94902145176411 + ], + [ + 145.16225442043063, + -37.949185081130175 + ], + [ + 145.16223225158268, + -37.94929141318891 + ], + [ + 145.16218051092517, + -37.94956766233462 + ], + [ + 145.1621492195506, + -37.94973502974489 + ], + [ + 145.16212854631368, + -37.94984534954288 + ], + [ + 145.16210775451208, + -37.949956658582316 + ], + [ + 145.16207939284527, + -37.950108124036625 + ], + [ + 145.16205102880488, + -37.950259679542334 + ], + [ + 145.16202266687995, + -37.95041114496955 + ], + [ + 145.16199430258132, + -37.95056270044814 + ], + [ + 145.16196593815357, + -37.95071425591317 + ], + [ + 145.16193757584142, + -37.950865721299714 + ], + [ + 145.1619092111554, + -37.95101727673763 + ], + [ + 145.16188084858513, + -37.95116874209705 + ], + [ + 145.16185789243832, + -37.95129155003779 + ], + [ + 145.1618423052114, + -37.951374739035884 + ], + [ + 145.16182682746896, + -37.951457299041586 + ], + [ + 145.16181145696683, + -37.95153932011989 + ], + [ + 145.16179618697086, + -37.95162107246563 + ], + [ + 145.1617624060306, + -37.95180164549254 + ], + [ + 145.16175742851402, + -37.95182814719596 + ], + [ + 145.16173501504744, + -37.95194799027812 + ], + [ + 145.1616859724895, + -37.95220995532794 + ], + [ + 145.16164407973167, + -37.952433559404035 + ], + [ + 145.16121698539507, + -37.95210982118915 + ], + [ + 145.16039901205897, + -37.95148948610349 + ], + [ + 145.16026609295963, + -37.95159994194714 + ], + [ + 145.1601326016189, + -37.95171074908283 + ], + [ + 145.15999910762912, + -37.95182164611943 + ], + [ + 145.15986561323703, + -37.95193254299214 + ], + [ + 145.15973212069025, + -37.952043349636114 + ], + [ + 145.15959862549389, + -37.952154246181 + ], + [ + 145.15946522595283, + -37.952265053965185 + ], + [ + 145.15933172995227, + -37.95237595018234 + ], + [ + 145.1591982335494, + -37.95248684623559 + ], + [ + 145.15911188734492, + -37.95255856585071 + ], + [ + 145.15902554097215, + -37.952630285397255 + ], + [ + 145.15893910062087, + -37.95270200340679 + ], + [ + 145.1588527516628, + -37.95277381288087 + ], + [ + 145.15876640478504, + -37.95284553222161 + ], + [ + 145.15867996392848, + -37.9529172500251 + ], + [ + 145.15858211654742, + -37.95299851997111 + ], + [ + 145.15850353199522, + -37.953063783345556 + ] + ], + [ + [ + 145.15879610278233, + -38.00803188911362 + ], + [ + 145.15888496575775, + -38.0080424709703 + ], + [ + 145.1588122897877, + -38.00840596413176 + ], + [ + 145.15994355582984, + -38.00854774308194 + ], + [ + 145.1600176067339, + -38.00817787365064 + ], + [ + 145.16011496044314, + -38.00769105969145 + ], + [ + 145.1601476917319, + -38.00752759140306 + ], + [ + 145.15890867947897, + -38.007387370760654 + ], + [ + 145.15888006498557, + -38.007551353650335 + ], + [ + 145.15879610278233, + -38.00803188911362 + ] + ], + [ + [ + 145.16065383570765, + -37.99021833008073 + ], + [ + 145.16074578617176, + -37.99022850814726 + ], + [ + 145.1611464380814, + -37.99027351764025 + ], + [ + 145.16144185017657, + -37.990306608832775 + ], + [ + 145.16192911517854, + -37.99036125916263 + ], + [ + 145.1620906319748, + -37.99037937124756 + ], + [ + 145.16253735396, + -37.99042951102648 + ], + [ + 145.16294119275472, + -37.99047483452103 + ], + [ + 145.1629510254348, + -37.990475889144875 + ], + [ + 145.16330327223983, + -37.99051544982795 + ], + [ + 145.1633038353915, + -37.99051545862511 + ], + [ + 145.1635489036119, + -37.98927285029522 + ], + [ + 145.16356009087335, + -37.989215811846464 + ], + [ + 145.16357126014887, + -37.989159493911075 + ], + [ + 145.16357069700743, + -37.989159485115465 + ], + [ + 145.1632238867023, + -37.98912055081495 + ], + [ + 145.1630519789186, + -37.989101286874785 + ], + [ + 145.16287932262748, + -37.98908192088917 + ], + [ + 145.16270825750803, + -37.98906275971358 + ], + [ + 145.16253672545128, + -37.98904350089309 + ], + [ + 145.16236491192433, + -37.98902423742385 + ], + [ + 145.16219178675203, + -37.98900486310291 + ], + [ + 145.16194918867316, + -37.98897764504338 + ], + [ + 145.1616568721265, + -37.98894487386917 + ], + [ + 145.16148271944445, + -37.988925302242556 + ], + [ + 145.16126727510775, + -37.988901120252955 + ], + [ + 145.1610752365602, + -37.988879646525774 + ], + [ + 145.16092177700247, + -37.988862379898336 + ], + [ + 145.16065383570765, + -37.99021833008073 + ] + ], + [ + [ + 145.16254560763352, + -38.00370055785753 + ], + [ + 145.16258952727284, + -38.00370556905808 + ], + [ + 145.16257062485835, + -38.00379690460374 + ], + [ + 145.16291958061512, + -38.003831640296696 + ], + [ + 145.16298311316146, + -38.003521159802254 + ], + [ + 145.16267793665472, + -38.003482062956785 + ], + [ + 145.16257685583685, + -38.00353976851907 + ], + [ + 145.16254560763352, + -38.00370055785753 + ] + ], + [ + [ + 145.16983192181632, + -37.958596693986955 + ], + [ + 145.1705063528857, + -37.958430591161445 + ], + [ + 145.1707045856875, + -37.95848304944971 + ], + [ + 145.17087418661714, + -37.958497940904316 + ], + [ + 145.17257785051802, + -37.96137491909324 + ], + [ + 145.17349512527986, + -37.96101507331575 + ], + [ + 145.17290373431427, + -37.960401316107586 + ], + [ + 145.17273472487702, + -37.96024876391026 + ], + [ + 145.1725877444984, + -37.96014277507405 + ], + [ + 145.17207935444972, + -37.959626710445946 + ], + [ + 145.1709837709993, + -37.95772009979153 + ], + [ + 145.17080625253985, + -37.957786085291055 + ], + [ + 145.16998420095163, + -37.95810324324417 + ], + [ + 145.16993561062338, + -37.95807572746175 + ], + [ + 145.16993505665968, + -37.95807535844177 + ], + [ + 145.1698757106477, + -37.958375278891644 + ], + [ + 145.16983192181632, + -37.958596693986955 + ] + ], + [ + [ + 145.1707937019107, + -37.94544343667801 + ], + [ + 145.17209064237926, + -37.94661697156749 + ], + [ + 145.1730394858274, + -37.947475591819384 + ], + [ + 145.1730854689889, + -37.947517211539235 + ], + [ + 145.17350560246615, + -37.947891975918814 + ], + [ + 145.17640633592387, + -37.950479793060836 + ], + [ + 145.1788041558151, + -37.9507570625165 + ], + [ + 145.18018040471856, + -37.9509161276437 + ], + [ + 145.18071605943413, + -37.95097748331506 + ], + [ + 145.18072803590653, + -37.95097892996779 + ], + [ + 145.1809953052096, + -37.94950271656176 + ], + [ + 145.18117818363964, + -37.94853705686008 + ], + [ + 145.18134648322575, + -37.94764865751769 + ], + [ + 145.1815511568741, + -37.94643799071711 + ], + [ + 145.18262590124476, + -37.946578759721376 + ], + [ + 145.18268464132476, + -37.94658651492364 + ], + [ + 145.18310752777262, + -37.94664179224377 + ], + [ + 145.18458041851795, + -37.94629160927093 + ], + [ + 145.18468759847852, + -37.94626046694377 + ], + [ + 145.18479307809775, + -37.94622596456417 + ], + [ + 145.18485054203666, + -37.94620549757836 + ], + [ + 145.1849535191251, + -37.94616591081377 + ], + [ + 145.18505441619627, + -37.946123138349826 + ], + [ + 145.18515304563388, + -37.94607717729691 + ], + [ + 145.18524940299713, + -37.94602820779277 + ], + [ + 145.18534311306587, + -37.94597622405406 + ], + [ + 145.18543417361806, + -37.94592131615307 + ], + [ + 145.18552239482682, + -37.94586357126787 + ], + [ + 145.18560767845426, + -37.94580316809011 + ], + [ + 145.18568983910762, + -37.9457400136661 + ], + [ + 145.18576877633674, + -37.945674376754056 + ], + [ + 145.1858443941239, + -37.94560634597985 + ], + [ + 145.18591650486528, + -37.94553591845643 + ], + [ + 145.18598501033097, + -37.94546327287604 + ], + [ + 145.18604981229277, + -37.945388587930914 + ], + [ + 145.18611090854128, + -37.94531195369344 + ], + [ + 145.18616801767615, + -37.945233365830035 + ], + [ + 145.1862211330611, + -37.94515309454532 + ], + [ + 145.1862701586886, + -37.945071228464755 + ], + [ + 145.186290188977, + -37.945035136768546 + ], + [ + 145.18656012064713, + -37.944487073369196 + ], + [ + 145.1868334020327, + -37.943226096305835 + ], + [ + 145.1868941939787, + -37.942944118051834 + ], + [ + 145.18691227961932, + -37.942853485495554 + ], + [ + 145.1869168398271, + -37.9428321118849 + ], + [ + 145.186983160765, + -37.9425198549391 + ], + [ + 145.1870535124562, + -37.9421886488679 + ], + [ + 145.1870584986758, + -37.942165209504665 + ], + [ + 145.18706275083522, + -37.94214491234264 + ], + [ + 145.1871339428724, + -37.94181002503076 + ], + [ + 145.18720440901282, + -37.941477919578986 + ], + [ + 145.18721014023572, + -37.94145088766929 + ], + [ + 145.18723125806784, + -37.94135138182081 + ], + [ + 145.18722428452708, + -37.94124567662025 + ], + [ + 145.18720887455717, + -37.94101361066394 + ], + [ + 145.18719730972, + -37.940838907848864 + ], + [ + 145.18719290050763, + -37.94078541032484 + ], + [ + 145.1871816135731, + -37.94069486561619 + ], + [ + 145.18718137202, + -37.94069324008521 + ], + [ + 145.18716590938078, + -37.94060461323053 + ], + [ + 145.18715236928705, + -37.94054466794961 + ], + [ + 145.1871456852979, + -37.94051501198636 + ], + [ + 145.18712094134065, + -37.94042606188182 + ], + [ + 145.1871126459762, + -37.940400886105174 + ], + [ + 145.1870918584773, + -37.940338036004725 + ], + [ + 145.18706134607487, + -37.94025854763147 + ], + [ + 145.18705834513986, + -37.940250842840264 + ], + [ + 145.18702058008168, + -37.9401648455418 + ], + [ + 145.1869984054621, + -37.940120264439294 + ], + [ + 145.1869784673071, + -37.940080132726266 + ], + [ + 145.18693219220702, + -37.93999679734715 + ], + [ + 145.18692479092422, + -37.93998488010627 + ], + [ + 145.18688175257992, + -37.93991492946626 + ], + [ + 145.18683982602383, + -37.93985319509051 + ], + [ + 145.1868273293873, + -37.939834802169194 + ], + [ + 145.18676892485234, + -37.93975632538437 + ], + [ + 145.1867440580869, + -37.939725848508395 + ], + [ + 145.1867066239249, + -37.93967986081741 + ], + [ + 145.18664052262122, + -37.93960531984197 + ], + [ + 145.18662871748361, + -37.93959315449218 + ], + [ + 145.18657080189672, + -37.93953297554286 + ], + [ + 145.1864972785944, + -37.939462644889076 + ], + [ + 145.18642068758012, + -37.939394969906836 + ], + [ + 145.18634066031797, + -37.93932967460662 + ], + [ + 145.18625738218495, + -37.939266851940275 + ], + [ + 145.18617103412782, + -37.93920677499257 + ], + [ + 145.18616503269666, + -37.939202808131135 + ], + [ + 145.18613916658848, + -37.939186281291825 + ], + [ + 145.1860817099395, + -37.93914944520309 + ], + [ + 145.18598959720615, + -37.93909486545798 + ], + [ + 145.18589487686907, + -37.93904330884258 + ], + [ + 145.18579736576356, + -37.93899459232472 + ], + [ + 145.18548369489534, + -37.93885334205985 + ], + [ + 145.18528185279442, + -37.93876238039074 + ], + [ + 145.1851261326619, + -37.9386922223912 + ], + [ + 145.18492911555444, + -37.93860349697698 + ], + [ + 145.18480810264705, + -37.93854901097691 + ], + [ + 145.18477434065147, + -37.938544525558626 + ], + [ + 145.18447993166225, + -37.93850529330144 + ], + [ + 145.18419459216702, + -37.93846737161767 + ], + [ + 145.18402419480404, + -37.93844464874444 + ], + [ + 145.18384912118768, + -37.93842131282356 + ], + [ + 145.18367395389902, + -37.938397975196494 + ], + [ + 145.18342293988155, + -37.93836454608026 + ], + [ + 145.1831075826602, + -37.93832255417896 + ], + [ + 145.18309757561656, + -37.938321228306116 + ], + [ + 145.1831506520348, + -37.93803669999425 + ], + [ + 145.18318383545852, + -37.93785890373111 + ], + [ + 145.1832134445249, + -37.93770051394487 + ], + [ + 145.1832562480623, + -37.937471148567255 + ], + [ + 145.18328229151442, + -37.93733180497966 + ], + [ + 145.183318825293, + -37.93713604030373 + ], + [ + 145.18336476716212, + -37.93688969433981 + ], + [ + 145.18338950948726, + -37.936757448555085 + ], + [ + 145.1834208554938, + -37.9365894447544 + ], + [ + 145.18342247966376, + -37.936580639990105 + ], + [ + 145.18342032912196, + -37.93658033647812 + ], + [ + 145.1805435398889, + -37.936255662976706 + ], + [ + 145.17730541419886, + -37.93584143752818 + ], + [ + 145.1742683132225, + -37.93541528673238 + ], + [ + 145.17421002302086, + -37.935719642078766 + ], + [ + 145.1741874033205, + -37.93583750267676 + ], + [ + 145.17416177187235, + -37.93597090388378 + ], + [ + 145.17413570275892, + -37.93610682109836 + ], + [ + 145.1741104796956, + -37.93623887712026 + ], + [ + 145.1740848412536, + -37.93637254849203 + ], + [ + 145.1740589972976, + -37.936506937467264 + ], + [ + 145.17403302378543, + -37.93664276602771 + ], + [ + 145.1740069630635, + -37.9367783229238 + ], + [ + 145.17398045128812, + -37.93691693622043 + ], + [ + 145.17395449528863, + -37.93705204422115 + ], + [ + 145.1739283070211, + -37.93718895061362 + ], + [ + 145.17390266785, + -37.93732262190819 + ], + [ + 145.17387670484834, + -37.937458000072766 + ], + [ + 145.17385041801208, + -37.937595085106935 + ], + [ + 145.1738242360059, + -37.93773172125712 + ], + [ + 145.1737981699772, + -37.937867458194845 + ], + [ + 145.17377199444527, + -37.93800382412526 + ], + [ + 145.17374635019007, + -37.938137675485045 + ], + [ + 145.17372048480627, + -37.938272874907334 + ], + [ + 145.17369463938243, + -37.938407263727115 + ], + [ + 145.173674489453, + -37.93851245836087 + ], + [ + 145.17366842329764, + -37.93854525079552 + ], + [ + 145.17364309583306, + -37.93868144964479 + ], + [ + 145.17361797368793, + -37.93881693087015 + ], + [ + 145.17359306578248, + -37.93895133420906 + ], + [ + 145.1735676219195, + -37.93908843222662 + ], + [ + 145.17354229404216, + -37.939224631032666 + ], + [ + 145.1735170665444, + -37.93936056108717 + ], + [ + 145.1734925958415, + -37.939492448369904 + ], + [ + 145.17340990486366, + -37.9399066168423 + ], + [ + 145.17309831580383, + -37.94146681991059 + ], + [ + 145.17276700151783, + -37.94312573540423 + ], + [ + 145.17257827469166, + -37.94410021090414 + ], + [ + 145.17124866547258, + -37.94517318274583 + ], + [ + 145.17090577478376, + -37.94544977463579 + ], + [ + 145.1707937019107, + -37.94544343667801 + ] + ], + [ + [ + 145.17376632369604, + -37.966737840227786 + ], + [ + 145.17433600348826, + -37.96680552070668 + ], + [ + 145.1743532090789, + -37.966717219565 + ], + [ + 145.17438805567042, + -37.966538191329946 + ], + [ + 145.17432096791347, + -37.966529581461685 + ], + [ + 145.17381962878358, + -37.96646548498017 + ], + [ + 145.17381906804383, + -37.966465386172736 + ], + [ + 145.17378429609468, + -37.9666451361861 + ], + [ + 145.17376632369604, + -37.966737840227786 + ] + ], + [ + [ + 145.17658803797815, + -37.96839432412315 + ], + [ + 145.176588600965, + -37.96839433285242 + ], + [ + 145.17711100988356, + -37.9684573026577 + ], + [ + 145.17717464705888, + -37.96814248872295 + ], + [ + 145.17670702954018, + -37.96779231917217 + ], + [ + 145.17658803797815, + -37.96839432412315 + ] + ], + [ + [ + 145.1809490850608, + -37.95452292702894 + ], + [ + 145.18203068899274, + -37.955478854962664 + ], + [ + 145.18254908143044, + -37.955118717313226 + ], + [ + 145.18146857700313, + -37.95416380218659 + ], + [ + 145.1809490850608, + -37.95452292702894 + ] + ], + [ + [ + 145.1962044601525, + -38.070781985126125 + ], + [ + 145.1964469001104, + -38.070915178704816 + ], + [ + 145.19656398535707, + -38.07076741191429 + ], + [ + 145.19632403176286, + -38.070636329016494 + ], + [ + 145.1962044601525, + -38.070781985126125 + ] + ], + [ + [ + 145.19967263640217, + -37.98184937872799 + ], + [ + 145.2002692297477, + -37.981920320066024 + ], + [ + 145.20086673646247, + -37.98199235356064 + ], + [ + 145.20089913082367, + -37.98182688490043 + ], + [ + 145.20093034750982, + -37.98166734481136 + ], + [ + 145.20096221292363, + -37.98150430073155 + ], + [ + 145.20099407818216, + -37.98134125663524 + ], + [ + 145.20102594108602, + -37.98117830258885 + ], + [ + 145.20106575153397, + -37.98097438448268 + ], + [ + 145.20109964132843, + -37.98080146030431 + ], + [ + 145.20107474727226, + -37.98076747213593 + ], + [ + 145.2007615342388, + -37.980729793486574 + ], + [ + 145.20050429968532, + -37.98069882718384 + ], + [ + 145.20024715701794, + -37.980667951826284 + ], + [ + 145.19993862411016, + -37.98063088322311 + ], + [ + 145.1998979348281, + -37.98065548835381 + ], + [ + 145.19986493677234, + -37.980830227814856 + ], + [ + 145.19982643258624, + -37.98103434568451 + ], + [ + 145.19979569550117, + -37.98119722651923 + ], + [ + 145.19976495386402, + -37.98136028747089 + ], + [ + 145.19973421427756, + -37.98152325834044 + ], + [ + 145.19970380011037, + -37.98168443217787 + ], + [ + 145.19967263640217, + -37.98184937872799 + ] + ], + [ + [ + 145.2002539884307, + -37.98572969595075 + ], + [ + 145.20040874245777, + -37.98583631024065 + ], + [ + 145.20121615551554, + -37.98639917584917 + ], + [ + 145.20130120367136, + -37.98604998788433 + ], + [ + 145.20122318383144, + -37.986038342763464 + ], + [ + 145.20129757319532, + -37.98571421972205 + ], + [ + 145.20143032604523, + -37.98573372981032 + ], + [ + 145.20150351389745, + -37.98542031013467 + ], + [ + 145.20162298077736, + -37.98543790488453 + ], + [ + 145.2016587284229, + -37.98528122708929 + ], + [ + 145.200950412855, + -37.98478988847401 + ], + [ + 145.20044405907424, + -37.985136323236226 + ], + [ + 145.20035796989782, + -37.985405035365346 + ], + [ + 145.2002539884307, + -37.98572969595075 + ] + ], + [ + [ + 145.2017306164338, + -37.978417422157456 + ], + [ + 145.20173117950503, + -37.97841743076831 + ], + [ + 145.20205026263503, + -37.97845654800909 + ], + [ + 145.20232919197315, + -37.97849072573319 + ], + [ + 145.20232941043056, + -37.97848946767117 + ], + [ + 145.20236327082486, + -37.97830987516298 + ], + [ + 145.20236358532372, + -37.978308528468936 + ], + [ + 145.20239570888202, + -37.97813855010694 + ], + [ + 145.2023952396576, + -37.97813854293392 + ], + [ + 145.2017986991778, + -37.9780627480352 + ], + [ + 145.20179813830748, + -37.978062649358236 + ], + [ + 145.20176551561408, + -37.9782337912141 + ], + [ + 145.2017306164338, + -37.978417422157456 + ] + ], + [ + [ + 145.20443418841745, + -37.97164076403479 + ], + [ + 145.20443884417332, + -37.971665432488365 + ], + [ + 145.20444888154614, + -37.97168883160819 + ], + [ + 145.20446393836025, + -37.9717104152616 + ], + [ + 145.20448366341083, + -37.97172918698175 + ], + [ + 145.20450712930293, + -37.971744682105516 + ], + [ + 145.20453369453858, + -37.971756260134626 + ], + [ + 145.204562335687, + -37.9717635450406 + ], + [ + 145.2045920271211, + -37.97176625086246 + ], + [ + 145.20462192649777, + -37.97176427463892 + ], + [ + 145.20465080954338, + -37.971757777879354 + ], + [ + 145.2046778273325, + -37.97174692782464 + ], + [ + 145.2047018450421, + -37.97173206755222 + ], + [ + 145.20472219264713, + -37.97171372743652 + ], + [ + 145.20473810189966, + -37.97169261655318 + ], + [ + 145.20474598404095, + -37.97167732974121 + ], + [ + 145.20475333270298, + -37.971653114860196 + ], + [ + 145.20475515815804, + -37.9716282750598 + ], + [ + 145.20475144285862, + -37.971603530874425 + ], + [ + 145.2047423525423, + -37.97157978583621 + ], + [ + 145.20472805513998, + -37.97155785340988 + ], + [ + 145.20470909392748, + -37.97153855278968 + ], + [ + 145.2046862042399, + -37.97152252590121 + ], + [ + 145.20466012579828, + -37.97151023453658 + ], + [ + 145.20463168996392, + -37.97150223198763 + ], + [ + 145.2046021100249, + -37.971498807076976 + ], + [ + 145.20457213666836, + -37.9714999712649 + ], + [ + 145.20453864475553, + -37.97150684814011 + ], + [ + 145.20451570809155, + -37.97151586836965 + ], + [ + 145.20449104892307, + -37.971530088109176 + ], + [ + 145.2044700576252, + -37.97154787775565 + ], + [ + 145.20445340860962, + -37.97156852680635 + ], + [ + 145.20444158422814, + -37.97159150202657 + ], + [ + 145.20443507780703, + -37.97161581984758 + ], + [ + 145.20443418841745, + -37.97164076403479 + ] + ], + [ + [ + 145.20510474145854, + -37.96918063151438 + ], + [ + 145.2055385787759, + -37.96923554601165 + ], + [ + 145.2055815651207, + -37.96901987113658 + ], + [ + 145.20521599268847, + -37.96897563940124 + ], + [ + 145.20513619170652, + -37.96901857061151 + ], + [ + 145.20510474145854, + -37.96918063151438 + ] + ], + [ + [ + 145.20518445739117, + -37.95216278304474 + ], + [ + 145.20518617222962, + -37.95220029102943 + ], + [ + 145.20519335142882, + -37.95222535842648 + ], + [ + 145.20520572756217, + -37.95224897341767 + ], + [ + 145.2052240752433, + -37.95227015671592 + ], + [ + 145.20525011597402, + -37.95228758307951 + ], + [ + 145.20526629242426, + -37.95229386665404 + ], + [ + 145.20529545440982, + -37.95229872656249 + ], + [ + 145.20532838949183, + -37.952295084486515 + ], + [ + 145.2053596850485, + -37.95228168652856 + ], + [ + 145.2053826733964, + -37.95226257557752 + ], + [ + 145.205398700347, + -37.95224029498727 + ], + [ + 145.2054090485879, + -37.95221612573914 + ], + [ + 145.20541436736343, + -37.952198096687255 + ], + [ + 145.20541524452952, + -37.95217747705109 + ], + [ + 145.20541325341017, + -37.95215131751901 + ], + [ + 145.2054062683411, + -37.9521259827949 + ], + [ + 145.20538727403212, + -37.95209280628845 + ], + [ + 145.2053722549158, + -37.95207753033713 + ], + [ + 145.2053451669539, + -37.95206071872505 + ], + [ + 145.20532841452453, + -37.95205496697612 + ], + [ + 145.20529415172226, + -37.95205147085244 + ], + [ + 145.2052717368265, + -37.95205473284542 + ], + [ + 145.20523949885018, + -37.952068296601595 + ], + [ + 145.2052241057962, + -37.95207995498188 + ], + [ + 145.20521400127532, + -37.952090252452486 + ], + [ + 145.2051989102315, + -37.952112637399985 + ], + [ + 145.20518921204572, + -37.95213708685073 + ], + [ + 145.20518445739117, + -37.95216278304474 + ] + ], + [ + [ + 145.20547392116822, + -37.981153194743605 + ], + [ + 145.20611392343702, + -37.98123044517957 + ], + [ + 145.20614796440645, + -37.981212764268236 + ], + [ + 145.2062045184023, + -37.980914404469516 + ], + [ + 145.2062039553106, + -37.980914395879594 + ], + [ + 145.20575499371057, + -37.980860874280445 + ], + [ + 145.20578191026922, + -37.98072325158858 + ], + [ + 145.2058083833248, + -37.98058841522374 + ], + [ + 145.2058347690063, + -37.98045330721563 + ], + [ + 145.20583487162827, + -37.98045294838088 + ], + [ + 145.20561313363532, + -37.98042541805682 + ], + [ + 145.20561257054754, + -37.98042540946416 + ], + [ + 145.205605356961, + -37.98046332164203 + ], + [ + 145.20557834585426, + -37.98060481715947 + ], + [ + 145.20555121226442, + -37.980747482099126 + ], + [ + 145.20552559866573, + -37.980881700812546 + ], + [ + 145.20547393213818, + -37.9811527444104 + ], + [ + 145.20547392116822, + -37.981153194743605 + ] + ], + [ + [ + 145.20564913789886, + -37.95235764255714 + ], + [ + 145.20564979297237, + -37.95239243135296 + ], + [ + 145.20566174278179, + -37.95242586075031 + ], + [ + 145.20568428724698, + -37.95245584775375 + ], + [ + 145.20571541071664, + -37.95248037939638 + ], + [ + 145.20575345305727, + -37.95249825903933 + ], + [ + 145.2057957178078, + -37.952508454436575 + ], + [ + 145.2058381775954, + -37.952510633847254 + ], + [ + 145.20588346791982, + -37.952504477070605 + ], + [ + 145.2059240706234, + -37.952490410027906 + ], + [ + 145.20595912385465, + -37.952469140382014 + ], + [ + 145.20598644362983, + -37.95244171603178 + ], + [ + 145.2060040160697, + -37.95240990827565 + ], + [ + 145.20601067380557, + -37.9523754112224 + ], + [ + 145.2060056988161, + -37.95234073673693 + ], + [ + 145.20598968426162, + -37.95230850678072 + ], + [ + 145.20596362264897, + -37.95228035829782 + ], + [ + 145.20592962565055, + -37.95225821560317 + ], + [ + 145.2058897308377, + -37.952243190977036 + ], + [ + 145.2058489843352, + -37.95223617229267 + ], + [ + 145.20579140082012, + -37.952238447408504 + ], + [ + 145.20574936736392, + -37.95224960936404 + ], + [ + 145.20571193861724, + -37.95226822979398 + ], + [ + 145.20568360044498, + -37.9522912236188 + ], + [ + 145.2056613789272, + -37.95232124849135 + ], + [ + 145.20564913789886, + -37.95235764255714 + ] + ], + [ + [ + 145.20664125892498, + -37.98237239899304 + ], + [ + 145.20680909673618, + -37.982311888547905 + ], + [ + 145.20683778115966, + -37.982302144666676 + ], + [ + 145.20686673397273, + -37.98229294547191 + ], + [ + 145.20689621699606, + -37.98228510585708 + ], + [ + 145.20692614953458, + -37.98227808399053 + ], + [ + 145.2069566100937, + -37.98227251176992 + ], + [ + 145.20698740001322, + -37.98226883666622 + ], + [ + 145.20701854518794, + -37.98226985217797 + ], + [ + 145.20702592867795, + -37.98227122616421 + ], + [ + 145.2070975335152, + -37.98228015669156 + ], + [ + 145.20711443598904, + -37.98219130538463 + ], + [ + 145.20715253222536, + -37.98219603085072 + ], + [ + 145.20715908640227, + -37.982196761483095 + ], + [ + 145.20716573223763, + -37.982197583612745 + ], + [ + 145.20723687434813, + -37.98220623669919 + ], + [ + 145.20724267772442, + -37.98220695587998 + ], + [ + 145.2073263629224, + -37.98221715164879 + ], + [ + 145.20733722483, + -37.98216046406137 + ], + [ + 145.20740131273897, + -37.981826268592606 + ], + [ + 145.20741507666335, + -37.98175448841106 + ], + [ + 145.2074215295201, + -37.98172079923112 + ], + [ + 145.20720730992952, + -37.981696630098035 + ], + [ + 145.2068131246209, + -37.98166431025751 + ], + [ + 145.20677941769117, + -37.981660552622756 + ], + [ + 145.20670820207212, + -37.98202518297419 + ], + [ + 145.20670208741532, + -37.98205653466448 + ], + [ + 145.2066824242597, + -37.9821584984242 + ], + [ + 145.20667135880194, + -37.98221581354263 + ], + [ + 145.20664125892498, + -37.98237239899304 + ] + ], + [ + [ + 145.20731137251295, + -37.983280645160804 + ], + [ + 145.207479384814, + -37.983301767148376 + ], + [ + 145.2075434916191, + -37.983263911248585 + ], + [ + 145.20756243561914, + -37.98316445919405 + ], + [ + 145.20758987645377, + -37.983020627195174 + ], + [ + 145.20758931334552, + -37.983020618611484 + ], + [ + 145.2073644653941, + -37.98299322431506 + ], + [ + 145.20733807403522, + -37.98313635145658 + ], + [ + 145.2073114795161, + -37.983280106191465 + ], + [ + 145.20731137251295, + -37.983280645160804 + ] + ], + [ + [ + 145.20791522290853, + -37.978716185766324 + ], + [ + 145.20907450329943, + -37.97976107986052 + ], + [ + 145.2093111550838, + -37.979596016355615 + ], + [ + 145.2092199440342, + -37.97951317675847 + ], + [ + 145.20955155288064, + -37.97928063216867 + ], + [ + 145.20943230345998, + -37.9791694347508 + ], + [ + 145.2092175927635, + -37.97932023643985 + ], + [ + 145.20913448899626, + -37.97925148577319 + ], + [ + 145.20922801804798, + -37.97918101020606 + ], + [ + 145.2091345108959, + -37.979107686196734 + ], + [ + 145.20875127550173, + -37.97938620518955 + ], + [ + 145.20817979070628, + -37.9788816770375 + ], + [ + 145.20829342511516, + -37.97881060757321 + ], + [ + 145.20819603145358, + -37.978723438279346 + ], + [ + 145.20968132719062, + -37.9777301814487 + ], + [ + 145.21063039088438, + -37.97855976377801 + ], + [ + 145.2107307200557, + -37.97849524697565 + ], + [ + 145.20965122446563, + -37.977512491498125 + ], + [ + 145.20791522290853, + -37.978716185766324 + ] + ], + [ + [ + 145.20829451828143, + -37.983841726748985 + ], + [ + 145.20843841682841, + -37.983858425436836 + ], + [ + 145.208447717051, + -37.983808020969256 + ], + [ + 145.20846644153363, + -37.983810198360445 + ], + [ + 145.20852629056705, + -37.98381615581488 + ], + [ + 145.20853051376142, + -37.983793064425875 + ], + [ + 145.20857396051903, + -37.98379787095667 + ], + [ + 145.2085728818085, + -37.983803620930274 + ], + [ + 145.2086131441642, + -37.98380810863142 + ], + [ + 145.2086082505516, + -37.983835604715914 + ], + [ + 145.20869233075138, + -37.983845084746 + ], + [ + 145.20869570067956, + -37.98384549648437 + ], + [ + 145.20874166397667, + -37.98385106209172 + ], + [ + 145.2087472082637, + -37.983819971908396 + ], + [ + 145.20875599520434, + -37.98377136159735 + ], + [ + 145.20878032089058, + -37.98363586117022 + ], + [ + 145.20878042350338, + -37.98363550233284 + ], + [ + 145.20874822156821, + -37.98363158798009 + ], + [ + 145.2087353966685, + -37.98363004110773 + ], + [ + 145.20856446720157, + -37.98360914676343 + ], + [ + 145.208510358647, + -37.98360264608906 + ], + [ + 145.20834083272084, + -37.983581953004624 + ], + [ + 145.208340730106, + -37.98358231184156 + ], + [ + 145.20833018059218, + -37.98364161717846 + ], + [ + 145.2083159318353, + -37.98372176937543 + ], + [ + 145.20829831794376, + -37.98382061111822 + ], + [ + 145.20829451828143, + -37.983841726748985 + ] + ], + [ + [ + 145.20941784648852, + -37.98140973584238 + ], + [ + 145.20971813943157, + -37.9816819057111 + ], + [ + 145.21012383021332, + -37.98151896367714 + ], + [ + 145.2097566781485, + -37.98118937422853 + ], + [ + 145.20941784648852, + -37.98140973584238 + ] + ], + [ + [ + 145.21005209854798, + -37.97614411505087 + ], + [ + 145.21008732875254, + -37.976181682505626 + ], + [ + 145.21028221284587, + -37.97620510148112 + ], + [ + 145.21029702293524, + -37.97612486736057 + ], + [ + 145.21035124849536, + -37.97613019764452 + ], + [ + 145.21037102715908, + -37.97602318925412 + ], + [ + 145.21008086339805, + -37.97598795866059 + ], + [ + 145.21005209854798, + -37.97614411505087 + ] + ], + [ + [ + 145.2107659998465, + -37.989028851762825 + ], + [ + 145.21076656300164, + -37.989028860332446 + ], + [ + 145.21123424559187, + -37.98900191837058 + ], + [ + 145.21123480874692, + -37.98900192693796 + ], + [ + 145.21121839864358, + -37.98883868623474 + ], + [ + 145.21121783548975, + -37.988838677667324 + ], + [ + 145.21079296871866, + -37.98886951470988 + ], + [ + 145.21079240337662, + -37.9888695962072 + ], + [ + 145.2107659998465, + -37.989028851762825 + ] + ], + [ + [ + 145.21127919251973, + -37.98619634433079 + ], + [ + 145.21175711347178, + -37.986168474645524 + ], + [ + 145.2117261675482, + -37.98582274030334 + ], + [ + 145.21135105897775, + -37.98581964774277 + ], + [ + 145.21127919251973, + -37.98619634433079 + ] + ], + [ + [ + 145.21140081567927, + -37.99009979895651 + ], + [ + 145.21145275024128, + -37.99016122631573 + ], + [ + 145.21153707829595, + -37.990168545743614 + ], + [ + 145.21160161926107, + -37.99017484334661 + ], + [ + 145.2116577881608, + -37.98988404373354 + ], + [ + 145.2115925146263, + -37.98986539131069 + ], + [ + 145.21151390659927, + -37.98984293201988 + ], + [ + 145.21145208409558, + -37.989825233013576 + ], + [ + 145.21140081567927, + -37.99009979895651 + ] + ], + [ + [ + 145.2130025942577, + -37.98590809930817 + ], + [ + 145.213006956213, + -37.98595276517272 + ], + [ + 145.21302017955688, + -37.98608883715651 + ], + [ + 145.2130201686311, + -37.98608928749119 + ], + [ + 145.21314805036354, + -37.98608141000037 + ], + [ + 145.21325430378468, + -37.986074915619724 + ], + [ + 145.21323834176098, + -37.985896905471805 + ], + [ + 145.21312882551007, + -37.985902449255185 + ], + [ + 145.21311406618847, + -37.98590321606372 + ], + [ + 145.2130025942577, + -37.98590809930817 + ] + ], + [ + [ + 145.21306386728892, + -38.001232344624846 + ], + [ + 145.21317238186845, + -38.00124579700144 + ], + [ + 145.21389068896121, + -38.00133509879017 + ], + [ + 145.21409760654055, + -38.00136076712324 + ], + [ + 145.21433869693814, + -38.00139073832538 + ], + [ + 145.21445938303052, + -38.00140572588135 + ], + [ + 145.21457885098397, + -38.00142060471478 + ], + [ + 145.21468717842203, + -38.00143405285501 + ], + [ + 145.2147965363468, + -38.001447606643055 + ], + [ + 145.2149976474576, + -38.00147264462827 + ], + [ + 145.2151027920393, + -38.00148568366215 + ], + [ + 145.21520821828778, + -38.00149872687821 + ], + [ + 145.21530933504638, + -38.00151134418164 + ], + [ + 145.21533283661535, + -38.00151422373493 + ], + [ + 145.21535602427215, + -38.00140222106956 + ], + [ + 145.21549302439422, + -38.00074035395639 + ], + [ + 145.2156491741319, + -37.99998570394548 + ], + [ + 145.21571019784676, + -37.99966479293587 + ], + [ + 145.21542237241945, + -37.99962988051319 + ], + [ + 145.21344084649422, + -37.99939706146724 + ], + [ + 145.21335683130613, + -37.99980591978903 + ], + [ + 145.21332967172302, + -37.99993831439229 + ], + [ + 145.21332700794153, + -37.9999513384051 + ], + [ + 145.21330209719304, + -38.00007232447884 + ], + [ + 145.21327450943744, + -38.00020687495389 + ], + [ + 145.21324661590424, + -38.000342411871095 + ], + [ + 145.21321892749478, + -38.00047723109566 + ], + [ + 145.21319122585774, + -38.00061259070857 + ], + [ + 145.21316343023489, + -38.00074794888269 + ], + [ + 145.21313574805012, + -38.000882497871046 + ], + [ + 145.21310805700972, + -38.00101740711426 + ], + [ + 145.21307951647813, + -38.00115635793286 + ], + [ + 145.21306386728892, + -38.001232344624846 + ] + ], + [ + [ + 145.21306391321883, + -37.989808564441695 + ], + [ + 145.2130968802913, + -37.99010612546564 + ], + [ + 145.21311915105952, + -37.990120879937265 + ], + [ + 145.21316025122798, + -37.990118080737396 + ], + [ + 145.2131601682938, + -37.99011762897659 + ], + [ + 145.21312879232457, + -37.989816398044766 + ], + [ + 145.21312758120672, + -37.989804396326605 + ], + [ + 145.2131230671711, + -37.98980468812634 + ], + [ + 145.21306391321883, + -37.989808564441695 + ] + ], + [ + [ + 145.21321629033048, + -37.98571060366998 + ], + [ + 145.21321637326113, + -37.98571105543095 + ], + [ + 145.21322633729847, + -37.985795720785596 + ], + [ + 145.21323834176098, + -37.985896905471805 + ], + [ + 145.2132803781156, + -37.98589412043091 + ], + [ + 145.2138156707884, + -37.98585819419702 + ], + [ + 145.21381623392023, + -37.985858202751444 + ], + [ + 145.21380554912628, + -37.98576064216925 + ], + [ + 145.21379602318552, + -37.98567337060724 + ], + [ + 145.21379545787093, + -37.98567345211974 + ], + [ + 145.21322221412538, + -37.985710243186325 + ], + [ + 145.21321629033048, + -37.98571060366998 + ] + ], + [ + [ + 145.2132995231103, + -37.98520937985893 + ], + [ + 145.21331603865062, + -37.98533360863324 + ], + [ + 145.21375526142836, + -37.98530613383067 + ], + [ + 145.21375582455596, + -37.98530614238527 + ], + [ + 145.21374591462296, + -37.98521535107446 + ], + [ + 145.21374534931186, + -37.98521543258681 + ], + [ + 145.21339380692314, + -37.98523955442483 + ], + [ + 145.21336324304136, + -37.98524161282846 + ], + [ + 145.21335932596222, + -37.98520569344593 + ], + [ + 145.21330008623698, + -37.98520938841569 + ], + [ + 145.2132995231103, + -37.98520937985893 + ] + ], + [ + [ + 145.21332659169656, + -37.99073130688487 + ], + [ + 145.2134052328696, + -37.99088792450325 + ], + [ + 145.21443639285826, + -37.99055138711708 + ], + [ + 145.21435698798683, + -37.99039520906532 + ], + [ + 145.21427130582697, + -37.990226862209596 + ], + [ + 145.21412702836443, + -37.99023683442242 + ], + [ + 145.21398463464084, + -37.990246564771226 + ], + [ + 145.21387967180007, + -37.99025380015569 + ], + [ + 145.21378430241654, + -37.99026037028601 + ], + [ + 145.21370633442763, + -37.99026567300563 + ], + [ + 145.21383916238713, + -37.990530332670346 + ], + [ + 145.21385376273696, + -37.990559386496216 + ], + [ + 145.2138278306588, + -37.99056782236604 + ], + [ + 145.21372911626347, + -37.99060002015806 + ], + [ + 145.21362955047783, + -37.99063247523122 + ], + [ + 145.21332659169656, + -37.99073130688487 + ] + ], + [ + [ + 145.2136198904963, + -37.98935074467011 + ], + [ + 145.21362545338175, + -37.989400113944875 + ], + [ + 145.21364114918123, + -37.98953496196609 + ], + [ + 145.2136404899767, + -37.98953504205106 + ], + [ + 145.21365282700125, + -37.98964578231171 + ], + [ + 145.213653390162, + -37.989645790867634 + ], + [ + 145.21420582541919, + -37.989604897776076 + ], + [ + 145.21420648243992, + -37.98960490775488 + ], + [ + 145.21419440214066, + -37.98949516254397 + ], + [ + 145.21417933837708, + -37.98935744098182 + ], + [ + 145.214173868981, + -37.98930807314931 + ], + [ + 145.2136198904963, + -37.98935074467011 + ] + ], + [ + [ + 145.21451677629415, + -37.98767733273828 + ], + [ + 145.21452040168543, + -37.987694326616534 + ], + [ + 145.21452743882813, + -37.98769452357574 + ], + [ + 145.21453155519526, + -37.98772999543792 + ], + [ + 145.21452496113645, + -37.98773088640884 + ], + [ + 145.21452903177249, + -37.98775275245534 + ], + [ + 145.21454063519946, + -37.98775437025473 + ], + [ + 145.2145457053488, + -37.98780084881628 + ], + [ + 145.2145378103749, + -37.98780117943282 + ], + [ + 145.21454128942656, + -37.98783195640938 + ], + [ + 145.21454850556452, + -37.987832516486016 + ], + [ + 145.21455454923617, + -37.987877568227276 + ], + [ + 145.21454107733513, + -37.98787943596195 + ], + [ + 145.21454965927109, + -37.987959214799425 + ], + [ + 145.2145633690924, + -37.9879591526794 + ], + [ + 145.21456771684225, + -37.98799670035582 + ], + [ + 145.21461895245818, + -37.98799405453554 + ], + [ + 145.21462843207206, + -37.98800194708774 + ], + [ + 145.215119126522, + -37.987722517981844 + ], + [ + 145.21503764278964, + -37.98764055130305 + ], + [ + 145.21451677629415, + -37.98767733273828 + ] + ], + [ + [ + 145.21504901983653, + -37.99030138083628 + ], + [ + 145.2153642522579, + -37.99091253966255 + ], + [ + 145.21562648428116, + -37.990828131392156 + ], + [ + 145.21580241311113, + -37.99100775778118 + ], + [ + 145.21546797458385, + -37.99111539757998 + ], + [ + 145.2155649546002, + -37.99130589946577 + ], + [ + 145.2157891228799, + -37.99174619676741 + ], + [ + 145.21618875502134, + -37.99235457958424 + ], + [ + 145.216225752297, + -37.992331264354995 + ], + [ + 145.2162982036695, + -37.99229794526436 + ], + [ + 145.21640664418078, + -37.99227517318501 + ], + [ + 145.21653028834913, + -37.99225272172299 + ], + [ + 145.21660564758892, + -37.99224665677931 + ], + [ + 145.21671259680292, + -37.99221178838187 + ], + [ + 145.21678004076023, + -37.99219911606703 + ], + [ + 145.21685761977545, + -37.99218668751932 + ], + [ + 145.21692179390385, + -37.99218108344167 + ], + [ + 145.21707152168113, + -37.99219047190452 + ], + [ + 145.2171751475321, + -37.992211414755886 + ], + [ + 145.21725198327738, + -37.99224132172909 + ], + [ + 145.2174337459165, + -37.99228498299442 + ], + [ + 145.21754159865594, + -37.992325271031824 + ], + [ + 145.21757950494876, + -37.992345847907565 + ], + [ + 145.2175902778447, + -37.99235853513567 + ], + [ + 145.21760596872252, + -37.99236976521459 + ], + [ + 145.21762493163547, + -37.99237771118882 + ], + [ + 145.21764586338875, + -37.99238190280104 + ], + [ + 145.21765077277124, + -37.99238468022591 + ], + [ + 145.2177139074669, + -37.992429786324045 + ], + [ + 145.21771306076707, + -37.99243761219922 + ], + [ + 145.21771545147294, + -37.99245134365588 + ], + [ + 145.217722277763, + -37.992464151247724 + ], + [ + 145.2177331794428, + -37.992475398813255 + ], + [ + 145.21774751908498, + -37.99248426578811 + ], + [ + 145.21776436894902, + -37.99249028760772 + ], + [ + 145.21778270742934, + -37.99249299828505 + ], + [ + 145.21780140815605, + -37.99249238074618 + ], + [ + 145.2178173583575, + -37.992489018509545 + ], + [ + 145.21781036909354, + -37.992498463180894 + ], + [ + 145.21780437527477, + -37.9925094546424 + ], + [ + 145.2177999640632, + -37.99252101069301 + ], + [ + 145.21779732754715, + -37.99253295404435 + ], + [ + 145.21779647008708, + -37.99254510456239 + ], + [ + 145.21779730435927, + -37.992557190623195 + ], + [ + 145.21779693959627, + -37.99261493926613 + ], + [ + 145.2202617640968, + -37.99528058539587 + ], + [ + 145.2205125222545, + -37.995135175116616 + ], + [ + 145.21802120445017, + -37.99248544074261 + ], + [ + 145.21797691521024, + -37.99246476726663 + ], + [ + 145.21796467338422, + -37.99245845491801 + ], + [ + 145.217951645775, + -37.992453572260295 + ], + [ + 145.21793792842553, + -37.992450030648804 + ], + [ + 145.21792389461115, + -37.99244792584099 + ], + [ + 145.21790954215138, + -37.99244734790385 + ], + [ + 145.21789534036495, + -37.99244830395064 + ], + [ + 145.21788128925093, + -37.99245079398142 + ], + [ + 145.21785866613845, + -37.99245828978947 + ], + [ + 145.21786225667398, + -37.99244960450092 + ], + [ + 145.21786408981586, + -37.99243593706875 + ], + [ + 145.21786113371954, + -37.99242228714518 + ], + [ + 145.21785373986594, + -37.992409651158646 + ], + [ + 145.2178423623181, + -37.99239866669153 + ], + [ + 145.21782763850592, + -37.9923901543056 + ], + [ + 145.2178105922121, + -37.99238448991819 + ], + [ + 145.2177921511744, + -37.99238213809133 + ], + [ + 145.21777579489137, + -37.9923828812661 + ], + [ + 145.21773825897296, + -37.9923431187429 + ], + [ + 145.2177450295966, + -37.99232330924814 + ], + [ + 145.21774438729193, + -37.99230717159131 + ], + [ + 145.2177383794972, + -37.99229158330394 + ], + [ + 145.21772745155545, + -37.992277542237154 + ], + [ + 145.2177122387155, + -37.992265959020166 + ], + [ + 145.21769366217512, + -37.99225756841639 + ], + [ + 145.2176729312609, + -37.9922528392567 + ], + [ + 145.21765257374875, + -37.99225208015886 + ], + [ + 145.2175028041178, + -37.99209312561021 + ], + [ + 145.21751293883602, + -37.99208174643961 + ], + [ + 145.217518996002, + -37.99207201735432 + ], + [ + 145.21752318461884, + -37.992061899540936 + ], + [ + 145.21752559855057, + -37.99205139442264 + ], + [ + 145.21752604135077, + -37.99204085942187 + ], + [ + 145.21752460688356, + -37.99203029596166 + ], + [ + 145.2175212886094, + -37.992019974243156 + ], + [ + 145.21751617821232, + -37.992009985756255 + ], + [ + 145.2175092691526, + -37.99200060070196 + ], + [ + 145.21750074915738, + -37.99199182192592 + ], + [ + 145.21749070773004, + -37.991983830984935 + ], + [ + 145.21747867991465, + -37.99197644062946 + ], + [ + 145.2174735279871, + -37.9919642891083 + ], + [ + 145.21746322666314, + -37.99195151891864 + ], + [ + 145.21744873867496, + -37.99194102785859 + ], + [ + 145.21743117730057, + -37.991933373405494 + ], + [ + 145.21741156413322, + -37.99192902154692 + ], + [ + 145.21739101680825, + -37.991928349626974 + ], + [ + 145.21737094327108, + -37.99193137899146 + ], + [ + 145.2173553250201, + -37.99193654820392 + ], + [ + 145.21699125121194, + -37.991550084464635 + ], + [ + 145.21570755250048, + -37.99018721813129 + ], + [ + 145.2156818957114, + -37.99018430597669 + ], + [ + 145.21563648228326, + -37.99017911179145 + ], + [ + 145.21553195851507, + -37.99021473685538 + ], + [ + 145.21524475498842, + -37.990240921624896 + ], + [ + 145.21510506801738, + -37.99026682233959 + ], + [ + 145.21504901983653, + -37.99030138083628 + ] + ], + [ + [ + 145.21713150200478, + -37.990628324534235 + ], + [ + 145.21733907103456, + -37.99084699127799 + ], + [ + 145.21779743218806, + -37.99056931347228 + ], + [ + 145.21759608146, + -37.99035362499263 + ], + [ + 145.21713150200478, + -37.990628324534235 + ] + ], + [ + [ + 145.21759681322396, + -37.98990052246182 + ], + [ + 145.21787319970224, + -37.99019321259413 + ], + [ + 145.21841938238012, + -37.99077182366466 + ], + [ + 145.21934107453143, + -37.99023175988644 + ], + [ + 145.21880463668822, + -37.9896538412457 + ], + [ + 145.21852836818675, + -37.989356199542456 + ], + [ + 145.218527796312, + -37.98935655127855 + ], + [ + 145.21849770080786, + -37.98937411532626 + ], + [ + 145.2181865472224, + -37.9895559979311 + ], + [ + 145.2175973851073, + -37.989900170730486 + ], + [ + 145.21759681322396, + -37.98990052246182 + ] + ], + [ + [ + 145.2185575470827, + -37.99092141102858 + ], + [ + 145.21883200924344, + -37.99121244797558 + ], + [ + 145.21883258113155, + -37.99121209623843 + ], + [ + 145.21913884862798, + -37.99103058851695 + ], + [ + 145.21914599501525, + -37.991026281849756 + ], + [ + 145.2191456304569, + -37.99102582582737 + ], + [ + 145.21887265859021, + -37.99073526267574 + ], + [ + 145.2185575470827, + -37.99092141102858 + ] + ], + [ + [ + 145.2188865241092, + -37.96127968436695 + ], + [ + 145.21930148747262, + -37.961566631270955 + ], + [ + 145.21942408525004, + -37.96165137996893 + ], + [ + 145.21946675840496, + -37.96165662115735 + ], + [ + 145.21954117044757, + -37.96133870159937 + ], + [ + 145.21958668463898, + -37.96114468329524 + ], + [ + 145.21965051877598, + -37.96087219439044 + ], + [ + 145.21897720180422, + -37.960789739217894 + ], + [ + 145.218894993779, + -37.96123602376279 + ], + [ + 145.21889161277386, + -37.961251650057086 + ], + [ + 145.2188865241092, + -37.96127968436695 + ] + ], + [ + [ + 145.21898119387606, + -37.99334845914159 + ], + [ + 145.21909498196857, + -37.99346956538113 + ], + [ + 145.21909555387344, + -37.99346921364324 + ], + [ + 145.2194013327221, + -37.99328886928597 + ], + [ + 145.21945010597076, + -37.993260055068916 + ], + [ + 145.21954193334759, + -37.99320594397289 + ], + [ + 145.21954147273374, + -37.99320557659732 + ], + [ + 145.21943070363199, + -37.99309163441149 + ], + [ + 145.2194253901455, + -37.993086147936715 + ], + [ + 145.21942491210996, + -37.99308650109784 + ], + [ + 145.21898119387606, + -37.99334845914159 + ] + ], + [ + [ + 145.21935962790107, + -37.98796539065381 + ], + [ + 145.2200451207515, + -37.98869260685857 + ], + [ + 145.22004578865, + -37.98869216646837 + ], + [ + 145.2207794529178, + -37.988265473599505 + ], + [ + 145.22091840588277, + -37.98841353846979 + ], + [ + 145.22105635088175, + -37.98856059682546 + ], + [ + 145.22119521109065, + -37.98870865996912 + ], + [ + 145.2214621317807, + -37.98899326978668 + ], + [ + 145.2214625923789, + -37.98899363715457 + ], + [ + 145.2219939001202, + -37.98868019501719 + ], + [ + 145.22238205553168, + -37.98845459642113 + ], + [ + 145.22238272124062, + -37.98845424608458 + ], + [ + 145.22237548898357, + -37.98844656832661 + ], + [ + 145.22226839145, + -37.988332323866814 + ], + [ + 145.2221614776148, + -37.9882182622886 + ], + [ + 145.222055295408, + -37.98810502257928 + ], + [ + 145.22194600279033, + -37.98798840203161 + ], + [ + 145.22183689170853, + -37.98787205442956 + ], + [ + 145.22172933958763, + -37.98775726200855 + ], + [ + 145.22162535692013, + -37.98764630768631 + ], + [ + 145.2215178011027, + -37.98753169521862 + ], + [ + 145.22145583401957, + -37.98746552535724 + ], + [ + 145.22145516831554, + -37.98746587568871 + ], + [ + 145.22106586995693, + -37.98769613919915 + ], + [ + 145.2206228557259, + -37.98722325733046 + ], + [ + 145.22008958649414, + -37.987536483490395 + ], + [ + 145.21935962790107, + -37.98796539065381 + ] + ], + [ + [ + 145.2204494078052, + -37.99522116646589 + ], + [ + 145.22047659862048, + -37.99525004964489 + ], + [ + 145.22066464688277, + -37.99514279333268 + ], + [ + 145.22063745602992, + -37.995113910195826 + ], + [ + 145.2204494078052, + -37.99522116646589 + ] + ], + [ + [ + 145.221100121252, + -37.9861730625026 + ], + [ + 145.22123898224098, + -37.98632869403788 + ], + [ + 145.221538450061, + -37.986143833195555 + ], + [ + 145.2213924637433, + -37.985979985204956 + ], + [ + 145.22142417320026, + -37.98577107187052 + ], + [ + 145.2213721112921, + -37.98576523875484 + ], + [ + 145.22132858082333, + -37.986032087918126 + ], + [ + 145.221100121252, + -37.9861730625026 + ] + ], + [ + [ + 145.22157737443777, + -37.97529508174314 + ], + [ + 145.2215857851202, + -37.975316112232846 + ], + [ + 145.22160587970907, + -37.9753314628939 + ], + [ + 145.2216280772273, + -37.97533747491274 + ], + [ + 145.22167000411602, + -37.975350632918364 + ], + [ + 145.22173160238492, + -37.97535778135473 + ], + [ + 145.22178519325945, + -37.97536219576296 + ], + [ + 145.22183257929828, + -37.9753630925072 + ], + [ + 145.22188273241048, + -37.97536213896427 + ], + [ + 145.2219437451543, + -37.97536243080565 + ], + [ + 145.2220216244486, + -37.975352345784536 + ], + [ + 145.2220837417711, + -37.97533409357094 + ], + [ + 145.22212038038418, + -37.97532131264698 + ], + [ + 145.22217628805853, + -37.97529584856967 + ], + [ + 145.22223281782195, + -37.97527183547638 + ], + [ + 145.22228902433184, + -37.975245655058956 + ], + [ + 145.22234448359652, + -37.975211534482305 + ], + [ + 145.2223848881374, + -37.97517105947756 + ], + [ + 145.22242391853274, + -37.97511749912704 + ], + [ + 145.22243690889616, + -37.97508489894108 + ], + [ + 145.2224429783189, + -37.975066790403474 + ], + [ + 145.22244861950608, + -37.97502362747796 + ], + [ + 145.22244358526308, + -37.974987150814314 + ], + [ + 145.22242400254015, + -37.97494279569963 + ], + [ + 145.22241158117964, + -37.97492846217152 + ], + [ + 145.22238981040846, + -37.97491254570643 + ], + [ + 145.22237313399577, + -37.97490337367709 + ], + [ + 145.22235613260457, + -37.974895998741026 + ], + [ + 145.22233489095393, + -37.97488928050649 + ], + [ + 145.22231265873958, + -37.97488470970361 + ], + [ + 145.22229196316843, + -37.97488259483746 + ], + [ + 145.2222668987263, + -37.974882576331474 + ], + [ + 145.22224044444445, + -37.97488569032339 + ], + [ + 145.22221844893156, + -37.97489076382507 + ], + [ + 145.22218747148145, + -37.97490236896328 + ], + [ + 145.22215040596586, + -37.97492118018448 + ], + [ + 145.2221290428371, + -37.97494284170514 + ], + [ + 145.22210340505066, + -37.97497047532126 + ], + [ + 145.2220581120009, + -37.97501123672123 + ], + [ + 145.22201935585062, + -37.975037861074135 + ], + [ + 145.2219751651432, + -37.975060168524706 + ], + [ + 145.22193094499818, + -37.975072023866275 + ], + [ + 145.221877931564, + -37.975078700607355 + ], + [ + 145.2218217771047, + -37.97507938320159 + ], + [ + 145.2217331634362, + -37.97507137578833 + ], + [ + 145.22171106927277, + -37.97507275358571 + ], + [ + 145.22168686350943, + -37.975083830289854 + ], + [ + 145.221671737246, + -37.97510378403328 + ], + [ + 145.22163178866245, + -37.97521481429804 + ], + [ + 145.22158259044704, + -37.975273446430826 + ], + [ + 145.22157737443777, + -37.97529508174314 + ] + ], + [ + [ + 145.2238132845641, + -37.98716535681912 + ], + [ + 145.2239492904636, + -37.98731121124447 + ], + [ + 145.2239556954377, + -37.98731815560948 + ], + [ + 145.22408071693388, + -37.98745231113493 + ], + [ + 145.2240852030388, + -37.98745706410482 + ], + [ + 145.22411739608484, + -37.98743808867561 + ], + [ + 145.22431512432942, + -37.987321601916705 + ], + [ + 145.2243988455499, + -37.987272229865475 + ], + [ + 145.22460857481533, + -37.98714862570484 + ], + [ + 145.22477944299018, + -37.98704795062725 + ], + [ + 145.2248271601942, + -37.987019838947624 + ], + [ + 145.22462914670575, + -37.98691062110389 + ], + [ + 145.2244311359828, + -37.986801312871776 + ], + [ + 145.22419226368757, + -37.98694204614835 + ], + [ + 145.22407882707904, + -37.987008899204255 + ], + [ + 145.22396072392746, + -37.9870784747698 + ], + [ + 145.2238132845641, + -37.98716535681912 + ] + ], + [ + [ + 145.22444991205313, + -37.95295047554337 + ], + [ + 145.2247427209448, + -37.95298543957695 + ], + [ + 145.2248828071493, + -37.95300224030942 + ], + [ + 145.22531682651737, + -37.95305411055084 + ], + [ + 145.22531738723464, + -37.95305420911205 + ], + [ + 145.22538370942183, + -37.95269660880357 + ], + [ + 145.22538314870715, + -37.95269651024274 + ], + [ + 145.2249533659978, + -37.95264416359744 + ], + [ + 145.22474509508785, + -37.952711388939086 + ], + [ + 145.22460407182467, + -37.95275692361969 + ], + [ + 145.22448790488335, + -37.95274453817248 + ], + [ + 145.22446945129806, + -37.95284445162972 + ], + [ + 145.22444991205313, + -37.95295047554337 + ] + ], + [ + [ + 145.22468341011268, + -37.98809112317879 + ], + [ + 145.22479499951143, + -37.98821002840415 + ], + [ + 145.22508134854922, + -37.98804352116231 + ], + [ + 145.22496866083588, + -37.98792342832014 + ], + [ + 145.22468341011268, + -37.98809112317879 + ] + ], + [ + [ + 145.22600092241777, + -38.001069576988634 + ], + [ + 145.2261993897914, + -38.00148117542492 + ], + [ + 145.22724228251565, + -38.002158780681214 + ], + [ + 145.2285657150609, + -38.002758072463656 + ], + [ + 145.22931782958915, + -38.00309871839819 + ], + [ + 145.22940004726553, + -38.003135906599766 + ], + [ + 145.23339021329116, + -38.00494261366147 + ], + [ + 145.23339140162162, + -38.00493614430904 + ], + [ + 145.2334977766272, + -38.00434650566031 + ], + [ + 145.23366716883766, + -38.003408405268544 + ], + [ + 145.23395408578963, + -38.00181857337455 + ], + [ + 145.23167461768338, + -38.00155185190109 + ], + [ + 145.23153722584058, + -38.00153627030896 + ], + [ + 145.22884024046664, + -38.001231047222596 + ], + [ + 145.2286296125861, + -38.00120715091267 + ], + [ + 145.22625838331373, + -38.00093867180835 + ], + [ + 145.22600092241777, + -38.001069576988634 + ] + ], + [ + [ + 145.2362535442452, + -38.00461457266636 + ], + [ + 145.23706379342397, + -38.00472610593744 + ], + [ + 145.2369798764222, + -38.005100745444146 + ], + [ + 145.2371233667406, + -38.00512082709171 + ], + [ + 145.23698455374057, + -38.00574061683481 + ], + [ + 145.23683732355485, + -38.00639803205686 + ], + [ + 145.2371748626129, + -38.00665276133496 + ], + [ + 145.24001839913439, + -38.00793622442819 + ], + [ + 145.24073888554642, + -38.00449265699381 + ], + [ + 145.24113047749313, + -38.002674166569186 + ], + [ + 145.2396581005892, + -38.0024986891435 + ], + [ + 145.23901807686204, + -38.00242089844304 + ], + [ + 145.23897274409754, + -38.002631774749155 + ], + [ + 145.23888630908124, + -38.00303367850445 + ], + [ + 145.23831576267898, + -38.00296431288916 + ], + [ + 145.23810994193357, + -38.002939334236835 + ], + [ + 145.23762002140927, + -38.00287973302585 + ], + [ + 145.23698093359866, + -38.00280203534917 + ], + [ + 145.23675198422617, + -38.00277427478487 + ], + [ + 145.23666902188967, + -38.00276411058489 + ], + [ + 145.2362535442452, + -38.00461457266636 + ] + ], + [ + [ + 145.24403068878664, + -38.0101641232751 + ], + [ + 145.2441922792711, + -38.010236995146926 + ], + [ + 145.24508237481476, + -38.01063861753115 + ], + [ + 145.24528020598734, + -38.010727886545475 + ], + [ + 145.24532973319955, + -38.01075024983374 + ], + [ + 145.24566713442792, + -38.01090250904144 + ], + [ + 145.24588252604838, + -38.01058217333108 + ], + [ + 145.24447615693714, + -38.009947598132534 + ], + [ + 145.24427321876445, + -38.00985599900676 + ], + [ + 145.24403068878664, + -38.0101641232751 + ] + ], + [ + [ + 145.2445039041953, + -38.00604388008234 + ], + [ + 145.24521023157018, + -38.00614299354577 + ], + [ + 145.245160154836, + -38.00634470133252 + ], + [ + 145.24549200983313, + -38.00639389357963 + ], + [ + 145.24546238193895, + -38.006517879854705 + ], + [ + 145.2457012629851, + -38.00655514219687 + ], + [ + 145.24573644148182, + -38.00642285936024 + ], + [ + 145.24623653971892, + -38.0064941116362 + ], + [ + 145.24587857991145, + -38.00804065776047 + ], + [ + 145.2456065005008, + -38.00915158801968 + ], + [ + 145.24576523568751, + -38.009178734314496 + ], + [ + 145.24604481991906, + -38.008064131427965 + ], + [ + 145.24644109088663, + -38.00631669203843 + ], + [ + 145.2486083708422, + -38.00664155433339 + ], + [ + 145.2485463789764, + -38.00691021083599 + ], + [ + 145.25048910507687, + -38.00717682196374 + ], + [ + 145.25056656608092, + -38.00688136448408 + ], + [ + 145.25085756732827, + -38.00692290586137 + ], + [ + 145.25095042271312, + -38.0064933375779 + ], + [ + 145.2486889653457, + -38.00617522456908 + ], + [ + 145.2486585592151, + -38.006284784067965 + ], + [ + 145.2468920371931, + -38.006038430239414 + ], + [ + 145.24673106427275, + -38.005794020392656 + ], + [ + 145.24659657264002, + -38.00578237388089 + ], + [ + 145.24711982977237, + -38.003469193247916 + ], + [ + 145.24714117412657, + -38.00336950013923 + ], + [ + 145.24715321175808, + -38.00333724350124 + ], + [ + 145.2471545750278, + -38.00330365641075 + ], + [ + 145.24714512074152, + -38.0032708090405 + ], + [ + 145.24712545673754, + -38.00324078275776 + ], + [ + 145.2470968522928, + -38.00321548858877 + ], + [ + 145.247060871183, + -38.00319630134782 + ], + [ + 145.24701992423257, + -38.003184518379 + ], + [ + 145.24697643512775, + -38.003180896618716 + ], + [ + 145.24693321808167, + -38.00318556812761 + ], + [ + 145.24689272037108, + -38.00319829909758 + ], + [ + 145.2468575899048, + -38.003218318113696 + ], + [ + 145.24683001592862, + -38.00324439642256 + ], + [ + 145.2468115412685, + -38.00327484513055 + ], + [ + 145.24680342926555, + -38.003307881075195 + ], + [ + 145.24680610693414, + -38.00334134821913 + ], + [ + 145.2468195254583, + -38.003373353727376 + ], + [ + 145.246842701517, + -38.003401810626094 + ], + [ + 145.2468743594193, + -38.003425078081406 + ], + [ + 145.2469110325679, + -38.00343886968031 + ], + [ + 145.2463208914062, + -38.00604414782383 + ], + [ + 145.24456558854513, + -38.00579657497827 + ], + [ + 145.2445039041953, + -38.00604388008234 + ] + ], + [ + [ + 145.2473748000403, + -38.00403729270907 + ], + [ + 145.24737481979275, + -38.00406801720691 + ], + [ + 145.24738566150853, + -38.00409782182936 + ], + [ + 145.24740661704837, + -38.00412489401107 + ], + [ + 145.2474204203079, + -38.0041368128186 + ], + [ + 145.2474540399465, + -38.00415659545192 + ], + [ + 145.24749344682226, + -38.00416997712178 + ], + [ + 145.24753640495456, + -38.00417620368996 + ], + [ + 145.24758020252293, + -38.00417478422917 + ], + [ + 145.24762220871958, + -38.00416576962526 + ], + [ + 145.24765968384867, + -38.004149839846995 + ], + [ + 145.2476904450694, + -38.00412795346702 + ], + [ + 145.24771258261237, + -38.00410143353066 + ], + [ + 145.2477247435649, + -38.004071881683764 + ], + [ + 145.24772604013333, + -38.00404108670347 + ], + [ + 145.24771661077656, + -38.00401112296101 + ], + [ + 145.24769688631363, + -38.00398361868074 + ], + [ + 145.24768356101302, + -38.003971346627964 + ], + [ + 145.2476508973472, + -38.00395085750647 + ], + [ + 145.24761198139927, + -38.0039365822043 + ], + [ + 145.2475693264817, + -38.00392945918139 + ], + [ + 145.2475364641762, + -38.00392914953629 + ], + [ + 145.24751471998772, + -38.0039312581205 + ], + [ + 145.24747316187054, + -38.003941180369885 + ], + [ + 145.2474363246718, + -38.003957930502175 + ], + [ + 145.24740658112088, + -38.003980462688936 + ], + [ + 145.24738565322716, + -38.00400745110171 + ], + [ + 145.2473748000403, + -38.00403729270907 + ] + ] + ] + } +} diff --git a/packages/turf-mask/test/out/mask-outside.geojson b/src/mask/test/out/mask-outside.geojson similarity index 96% rename from packages/turf-mask/test/out/mask-outside.geojson rename to src/mask/test/out/mask-outside.geojson index 807e3dcc7a..c9cba55420 100644 --- a/packages/turf-mask/test/out/mask-outside.geojson +++ b/src/mask/test/out/mask-outside.geojson @@ -27,10 +27,6 @@ ] ], [ - [ - 113.115234375, - -22.105998799750566 - ], [ 112.587890625, -24.766784522874428 @@ -82,6 +78,10 @@ [ 113.115234375, -22.105998799750566 + ], + [ + 112.587890625, + -24.766784522874428 ] ] ] diff --git a/src/mask/test/out/multi-polygon.geojson b/src/mask/test/out/multi-polygon.geojson new file mode 100644 index 0000000000..529750dc90 --- /dev/null +++ b/src/mask/test/out/multi-polygon.geojson @@ -0,0 +1,523 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 180, + 90 + ], + [ + -180, + 90 + ], + [ + -180, + -90 + ], + [ + 180, + -90 + ], + [ + 180, + 90 + ] + ], + [ + [ + 174.8257084, + -36.8869965 + ], + [ + 174.8276109, + -36.887539 + ], + [ + 174.8278042, + -36.8875561 + ], + [ + 174.8296591, + -36.8874264 + ], + [ + 174.8311438, + -36.8878347 + ], + [ + 174.8314673, + -36.8878689 + ], + [ + 174.8336846, + -36.8865436 + ], + [ + 174.8341202, + -36.8862468 + ], + [ + 174.834388, + -36.885941 + ], + [ + 174.8354962, + -36.8846273 + ], + [ + 174.8356801, + -36.8844927 + ], + [ + 174.8367548, + -36.8837641 + ], + [ + 174.8373321, + -36.8831729 + ], + [ + 174.8373394, + -36.8830989 + ], + [ + 174.8369142, + -36.88283 + ], + [ + 174.8367485, + -36.8829628 + ], + [ + 174.836428, + -36.8830636 + ], + [ + 174.8340081, + -36.8834433 + ], + [ + 174.8332402, + -36.8837406 + ], + [ + 174.8321967, + -36.8848087 + ], + [ + 174.8315144, + -36.8849051 + ], + [ + 174.8311496, + -36.8842651 + ], + [ + 174.8319151, + -36.8828293 + ], + [ + 174.8321192, + -36.8820636 + ], + [ + 174.8324179, + -36.8806023 + ], + [ + 174.8325982, + -36.8803963 + ], + [ + 174.8346312, + -36.8804379 + ], + [ + 174.8346495, + -36.8804375 + ], + [ + 174.8348716, + -36.8800115 + ], + [ + 174.8349119, + -36.8798696 + ], + [ + 174.8347595, + -36.8798408 + ], + [ + 174.8342416, + -36.8795988 + ], + [ + 174.8328699, + -36.878784 + ], + [ + 174.8331132, + -36.8782542 + ], + [ + 174.8333146, + -36.878309 + ], + [ + 174.8337539, + -36.8777781 + ], + [ + 174.8343234, + -36.8772656 + ], + [ + 174.8347697, + -36.8769085 + ], + [ + 174.8349499, + -36.8768261 + ], + [ + 174.8351645, + -36.8767575 + ], + [ + 174.8353877, + -36.8766751 + ], + [ + 174.8355399, + -36.8764449 + ], + [ + 174.8357051, + -36.8761931 + ], + [ + 174.8357668, + -36.876134 + ], + [ + 174.8356795, + -36.8760915 + ], + [ + 174.8353743, + -36.8758963 + ], + [ + 174.8352751, + -36.8760453 + ], + [ + 174.8347802, + -36.8758729 + ], + [ + 174.8346298, + -36.8755945 + ], + [ + 174.8350415, + -36.8755096 + ], + [ + 174.8350096, + -36.8753835 + ], + [ + 174.8350022, + -36.8752449 + ], + [ + 174.8350149, + -36.875154 + ], + [ + 174.8345392, + -36.8752539 + ], + [ + 174.8345787, + -36.8753974 + ], + [ + 174.8343983, + -36.8756894 + ], + [ + 174.833726, + -36.8754489 + ], + [ + 174.8331871, + -36.8758692 + ], + [ + 174.8329038, + -36.8761774 + ], + [ + 174.8325172, + -36.8766213 + ], + [ + 174.8322845, + -36.8767656 + ], + [ + 174.8322194, + -36.876702 + ], + [ + 174.8320384, + -36.8768042 + ], + [ + 174.8319464, + -36.8770175 + ], + [ + 174.8315081, + -36.8771832 + ], + [ + 174.8313365, + -36.8770253 + ], + [ + 174.8312077, + -36.8771008 + ], + [ + 174.8312421, + -36.8772587 + ], + [ + 174.8309073, + -36.8774235 + ], + [ + 174.8305018, + -36.8776747 + ], + [ + 174.8302808, + -36.8777874 + ], + [ + 174.8291478, + -36.8782886 + ], + [ + 174.8291478, + -36.8783915 + ], + [ + 174.8291735, + -36.8785151 + ], + [ + 174.8290963, + -36.8787142 + ], + [ + 174.829062, + -36.8788584 + ], + [ + 174.8293809, + -36.8815138 + ], + [ + 174.8294238, + -36.8818914 + ], + [ + 174.8291049, + -36.8820989 + ], + [ + 174.8290019, + -36.8821676 + ], + [ + 174.829225, + -36.8827923 + ], + [ + 174.829535, + -36.8828012 + ], + [ + 174.8295855, + -36.8828026 + ], + [ + 174.8294482, + -36.8835612 + ], + [ + 174.8290133, + -36.8842478 + ], + [ + 174.828547, + -36.8850853 + ], + [ + 174.8285298, + -36.8854835 + ], + [ + 174.8285583, + -36.8859898 + ], + [ + 174.827812, + -36.8862177 + ], + [ + 174.8272938, + -36.8863759 + ], + [ + 174.8268918, + -36.8864866 + ], + [ + 174.8265485, + -36.8865621 + ], + [ + 174.8263768, + -36.8866582 + ], + [ + 174.8261688, + -36.886697 + ], + [ + 174.8261552, + -36.8866995 + ], + [ + 174.8261193, + -36.8867062 + ], + [ + 174.8259044, + -36.8868107 + ], + [ + 174.8257084, + -36.8869965 + ] + ], + [ + [ + 174.8347149, + -36.8815236 + ], + [ + 174.8347774, + -36.881634 + ], + [ + 174.8347409, + -36.8819051 + ], + [ + 174.8350392, + -36.8821049 + ], + [ + 174.8355443, + -36.8821803 + ], + [ + 174.8362531, + -36.881711 + ], + [ + 174.8371047, + -36.8807158 + ], + [ + 174.8376266, + -36.8798969 + ], + [ + 174.8384676, + -36.878055 + ], + [ + 174.837355, + -36.8776834 + ], + [ + 174.8369669, + -36.8778472 + ], + [ + 174.8360445, + -36.8784047 + ], + [ + 174.8360549, + -36.8784168 + ], + [ + 174.8357777, + -36.8790427 + ], + [ + 174.8357201, + -36.8790301 + ], + [ + 174.8355874, + -36.8793891 + ], + [ + 174.8354683, + -36.8795601 + ], + [ + 174.8355479, + -36.8795814 + ], + [ + 174.8353415, + -36.8797934 + ], + [ + 174.8351245, + -36.8798054 + ], + [ + 174.8350004, + -36.8802174 + ], + [ + 174.8347295, + -36.8806857 + ], + [ + 174.835116, + -36.8807968 + ], + [ + 174.8347149, + -36.8815236 + ] + ] + ] + } +} diff --git a/packages/turf-mask/test/out/overlapping.geojson b/src/mask/test/out/overlapping.geojson similarity index 94% rename from packages/turf-mask/test/out/overlapping.geojson rename to src/mask/test/out/overlapping.geojson index 5f09f90dda..8d5243b7d1 100644 --- a/packages/turf-mask/test/out/overlapping.geojson +++ b/src/mask/test/out/overlapping.geojson @@ -28,80 +28,80 @@ ], [ [ - 132.17629902699358, - -13.364967199604362 + 113.02734374999999, + -27.527758206861886 ], [ - 144.931640625, - -12.726084296948184 + 118.30078125, + -34.30714385628803 ], [ - 153.544921875, - -22.75592068148639 + 122.16796875, + -34.59704151614416 ], [ - 150.380859375, - -35.02999636902566 + 123.29894671677008, + -32.162843535475524 ], [ - 146.42578125, - -38.8225909761771 + 126.73828125, + -34.234512362369856 ], [ - 135.35156249999997, - -36.738884124394296 + 131.8359375, + -34.59704151614416 ], [ 132.9837069753474, -33.32471360739497 ], [ - 131.8359375, - -34.59704151614416 + 135.35156249999997, + -36.738884124394296 ], [ - 126.73828125, - -34.234512362369856 + 146.42578125, + -38.8225909761771 ], [ - 123.29894671677008, - -32.162843535475524 + 150.380859375, + -35.02999636902566 ], [ - 122.16796875, - -34.59704151614416 + 153.544921875, + -22.75592068148639 ], [ - 118.30078125, - -34.30714385628803 + 144.931640625, + -12.726084296948184 ], [ - 113.02734374999999, - -27.527758206861886 + 132.17629902699358, + -13.364967199604362 ], [ - 114.9609375, - -19.973348786110602 + 130.078125, + -11.436955216143177 ], [ - 119.70703125, - -16.467694748288956 + 121.55273437499999, + -15.029685756555674 ], [ 120.4266908193729, - -17.582874301397172 + -17.58287430139717 ], [ - 121.55273437499999, - -15.029685756555674 + 119.70703125, + -16.467694748288956 ], [ - 130.078125, - -11.436955216143177 + 114.9609375, + -19.973348786110602 ], [ - 132.17629902699358, - -13.364967199604362 + 113.02734374999999, + -27.527758206861886 ] ] ] diff --git a/src/meta/bench.js b/src/meta/bench.js new file mode 100644 index 0000000000..6f73d5e84e --- /dev/null +++ b/src/meta/bench.js @@ -0,0 +1,98 @@ +const Benchmark = require('benchmark'); +const random = require('../random'); +const meta = require('./'); + +const fixtures = { + point: random.randomPoint(), + points: random.randomPoint(1000), + polygon: random.randomPolygon(), + polygons: random.randomPolygon(1000) +}; + +const suite = new Benchmark.Suite('turf-meta'); + +/** + * Benchmark Results + * segmentEach - point x 3,541,484 ops/sec ±6.03% (88 runs sampled) + * segmentReduce - point x 3,245,821 ops/sec ±0.95% (86 runs sampled) + * flattenEach - point x 6,447,234 ops/sec ±5.56% (79 runs sampled) + * flattenReduce - point x 5,415,555 ops/sec ±1.28% (85 runs sampled) + * coordEach - point x 19,941,547 ops/sec ±0.64% (84 runs sampled) + * coordReduce - point x 11,959,189 ops/sec ±1.53% (85 runs sampled) + * propEach - point x 29,317,809 ops/sec ±1.38% (85 runs sampled) + * propReduce - point x 14,552,839 ops/sec ±1.06% (90 runs sampled) + * geomEach - point x 22,137,140 ops/sec ±0.95% (88 runs sampled) + * geomReduce - point x 12,416,033 ops/sec ±0.94% (88 runs sampled) + * featureEach - point x 29,588,658 ops/sec ±1.02% (88 runs sampled) + * featureReduce - point x 15,372,497 ops/sec ±1.11% (89 runs sampled) + * coordAll - point x 8,348,718 ops/sec ±0.68% (92 runs sampled) + * segmentEach - points x 7,568 ops/sec ±1.42% (90 runs sampled) + * segmentReduce - points x 7,719 ops/sec ±0.88% (90 runs sampled) + * flattenEach - points x 18,821 ops/sec ±7.17% (76 runs sampled) + * flattenReduce - points x 17,848 ops/sec ±1.10% (88 runs sampled) + * coordEach - points x 71,017 ops/sec ±0.80% (90 runs sampled) + * coordReduce - points x 46,986 ops/sec ±1.24% (91 runs sampled) + * propEach - points x 137,509 ops/sec ±0.38% (96 runs sampled) + * propReduce - points x 67,197 ops/sec ±1.44% (92 runs sampled) + * geomEach - points x 69,417 ops/sec ±0.77% (93 runs sampled) + * geomReduce - points x 45,830 ops/sec ±1.18% (92 runs sampled) + * featureEach - points x 151,234 ops/sec ±0.45% (92 runs sampled) + * featureReduce - points x 71,235 ops/sec ±1.51% (92 runs sampled) + * coordAll - points x 40,960 ops/sec ±0.88% (94 runs sampled) + * segmentEach - polygon x 884,579 ops/sec ±2.06% (82 runs sampled) + * segmentReduce - polygon x 770,112 ops/sec ±1.65% (85 runs sampled) + * flattenEach - polygon x 6,262,904 ops/sec ±2.84% (85 runs sampled) + * flattenReduce - polygon x 4,944,606 ops/sec ±4.15% (82 runs sampled) + * coordEach - polygon x 6,153,922 ops/sec ±2.36% (87 runs sampled) + * coordReduce - polygon x 3,348,489 ops/sec ±2.08% (91 runs sampled) + * propEach - polygon x 30,816,868 ops/sec ±0.96% (88 runs sampled) + * propReduce - polygon x 15,664,358 ops/sec ±0.88% (91 runs sampled) + * geomEach - polygon x 21,426,447 ops/sec ±1.19% (91 runs sampled) + * geomReduce - polygon x 11,585,812 ops/sec ±2.61% (84 runs sampled) + * featureEach - polygon x 29,478,632 ops/sec ±1.86% (87 runs sampled) + * featureReduce - polygon x 14,642,632 ops/sec ±2.62% (81 runs sampled) + * coordAll - polygon x 2,080,425 ops/sec ±13.27% (61 runs sampled) + * segmentEach - polygons x 1,042 ops/sec ±3.16% (76 runs sampled) + * segmentReduce - polygons x 912 ops/sec ±4.70% (80 runs sampled) + * flattenEach - polygons x 17,587 ops/sec ±3.05% (85 runs sampled) + * flattenReduce - polygons x 16,576 ops/sec ±1.33% (86 runs sampled) + * coordEach - polygons x 3,040 ops/sec ±15.62% (41 runs sampled) + * coordReduce - polygons x 4,100 ops/sec ±7.31% (85 runs sampled) + * propEach - polygons x 126,455 ops/sec ±0.85% (87 runs sampled) + * propReduce - polygons x 61,469 ops/sec ±2.96% (83 runs sampled) + * geomEach - polygons x 59,267 ops/sec ±5.22% (81 runs sampled) + * geomReduce - polygons x 24,424 ops/sec ±12.17% (52 runs sampled) + * featureEach - polygons x 110,212 ops/sec ±7.42% (71 runs sampled) + * featureReduce - polygons x 63,244 ops/sec ±3.74% (81 runs sampled) + * coordAll - polygons x 1,662 ops/sec ±19.73% (44 runs sampled) + * findSegment - polygon x 2,558,258 ops/sec ±0.80% (84 runs sampled) + * findSegment - polygons x 2,512,410 ops/sec ±0.72% (93 runs sampled) + * findPoint - point x 2,339,238 ops/sec ±0.86% (85 runs sampled) + * findPoint - points x 2,298,279 ops/sec ±1.13% (88 runs sampled) + * findPoint - polygon x 2,216,808 ops/sec ±1.63% (86 runs sampled) + * findPoint - polygons x 2,160,583 ops/sec ±1.06% (87 runs sampled) + */ +Object.keys(fixtures).forEach(name => { + const geojson = fixtures[name]; + suite + .add('segmentEach - ' + name, () => meta.segmentEach(geojson, () => {})) + .add('segmentReduce - ' + name, () => meta.segmentReduce(geojson, () => {})) + .add('flattenEach - ' + name, () => meta.flattenEach(geojson, () => {})) + .add('flattenReduce - ' + name, () => meta.flattenReduce(geojson, () => {})) + .add('coordEach - ' + name, () => meta.coordEach(geojson, () => {})) + .add('coordReduce - ' + name, () => meta.coordReduce(geojson, () => {})) + .add('propEach - ' + name, () => meta.propEach(geojson, () => {})) + .add('propReduce - ' + name, () => meta.propReduce(geojson, () => {})) + .add('geomEach - ' + name, () => meta.geomEach(geojson, () => {})) + .add('geomReduce - ' + name, () => meta.geomReduce(geojson, () => {})) + .add('featureEach - ' + name, () => meta.featureEach(geojson, () => {})) + .add('featureReduce - ' + name, () => meta.featureReduce(geojson, () => {})) + .add('coordAll - ' + name, () => meta.coordAll(geojson)) + .add('findSegment - ' + name, () => meta.findSegment(geojson)) + .add('findPoint - ' + name, () => meta.findPoint(geojson)); +}); + +suite + .on('cycle', e => console.log(String(e.target))) + .on('complete', () => {}) + .run(); diff --git a/src/meta/index.d.ts b/src/meta/index.d.ts new file mode 100644 index 0000000000..9bfc6ab3c5 --- /dev/null +++ b/src/meta/index.d.ts @@ -0,0 +1,220 @@ +import { + Point, + LineString, + Polygon, + MultiPoint, + MultiLineString, + MultiPolygon, + FeatureCollection, + Feature, + GeometryObject, + GeometryCollection, + AllGeoJSON, + Properties, + Geometries, + Lines, + BBox, + Id +} from '../helpers'; + +/** + * http://turfjs.org/docs/#coordreduce + */ +export function coordReduce( + geojson: AllGeoJSON, + callback: (previousValue: Reducer, + currentCoord: number[], + coordIndex: number, + featureIndex: number, + multiFeatureIndex: number, + geometryIndex: number) => Reducer, + initialValue?: Reducer +): Reducer; + +/** + * http://turfjs.org/docs/#coordeach + */ +export function coordEach( + geojson: AllGeoJSON, + callback: (currentCoord: number[], + coordIndex: number, + featureIndex: number, + multiFeatureIndex: number, + geometryIndex: number) => void +): void; + +/** + * http://turfjs.org/docs/#propeach + */ +export function propEach( + geojson: Feature | FeatureCollection | Feature, + callback: (currentProperties: Props, + featureIndex: number) => void +): void; + +/** + * http://turfjs.org/docs/#propreduce + */ +export function propReduce( + geojson: Feature | FeatureCollection | Geometries | GeometryCollection, + callback: (previousValue: Reducer, + currentProperties: P, + featureIndex: number) => Reducer, + initialValue?: Reducer +): Reducer; + +/** + * http://turfjs.org/docs/#featurereduce + */ +export function featureReduce( + geojson: Feature | FeatureCollection | Feature, + callback: (previousValue: Reducer, + currentFeature: Feature, + featureIndex: number) => Reducer, + initialValue?: Reducer +): Reducer; + +/** + * http://turfjs.org/docs/#featureeach + */ +export function featureEach( + geojson: Feature | FeatureCollection | Feature, + callback: (currentFeature: Feature, + featureIndex: number) => void +): void; + +/** + * http://turfjs.org/docs/#coordall + */ +export function coordAll(geojson: AllGeoJSON): number[][]; + +/** + * http://turfjs.org/docs/#geomreduce + */ +export function geomReduce( + geojson: Feature | FeatureCollection | G | GeometryCollection | Feature, + callback: (previousValue: Reducer, + currentGeometry: G, + featureIndex: number, + featureProperties: P, + featureBBox: BBox, + featureId: Id) => Reducer, + initialValue?: Reducer +): Reducer; + +/** + * http://turfjs.org/docs/#geomeach + */ +export function geomEach( + geojson: Feature | FeatureCollection | G | GeometryCollection | Feature, + callback: (currentGeometry: G, + featureIndex: number, + featureProperties: P, + featureBBox: BBox, + featureId: Id) => void +): void; + +/** + * http://turfjs.org/docs/#flattenreduce + */ +export function flattenReduce( + geojson: Feature | FeatureCollection | G | GeometryCollection | Feature, + callback: (previousValue: Reducer, + currentFeature: Feature, + featureIndex: number, + multiFeatureIndex: number) => Reducer, + initialValue?: Reducer +): Reducer; + +/** + * http://turfjs.org/docs/#flatteneach + */ +export function flattenEach( + geojson: Feature | FeatureCollection | G | GeometryCollection | Feature, + callback: (currentFeature: Feature, + featureIndex: number, + multiFeatureIndex: number) => void +): void; + +/** + * http://turfjs.org/docs/#segmentreduce + */ +export function segmentReduce( + geojson: FeatureCollection | Feature | Lines | Feature | GeometryCollection, + callback: (previousValue?: Reducer, + currentSegment?: Feature, + featureIndex?: number, + multiFeatureIndex?: number, + segmentIndex?: number, + geometryIndex?: number) => Reducer, + initialValue?: Reducer +): Reducer; + +/** + * http://turfjs.org/docs/#segmenteach + */ +export function segmentEach

( + geojson: AllGeoJSON, + callback: (currentSegment?: Feature, + featureIndex?: number, + multiFeatureIndex?: number, + segmentIndex?: number, + geometryIndex?: number) => void +): void; + +/** + * http://turfjs.org/docs/#linereduce + */ +export function lineReduce( + geojson: FeatureCollection | Feature | Lines | Feature | GeometryCollection, + callback: (previousValue?: Reducer, + currentLine?: Feature, + featureIndex?: number, + multiFeatureIndex?: number, + geometryIndex?: number) => Reducer, + initialValue?: Reducer +): Reducer; + +/** + * http://turfjs.org/docs/#lineeach + */ +export function lineEach

( + geojson: FeatureCollection | Feature | Lines | Feature | GeometryCollection, + callback: (currentLine?: Feature, + featureIndex?: number, + multiFeatureIndex?: number, + geometryIndex?: number) => void +): void; + + +/** + * http://turfjs.org/docs/#findsegment + */ +export function findSegment( + geojson: Feature | FeatureCollection | G, + options?: { + featureIndex?: number, + multiFeatureIndex?: number, + geometryIndex?: number, + segmentIndex?: number, + properties?: P, + bbox?: BBox, + id?: Id + } +): Feature; + +/** + * http://turfjs.org/docs/#findpoint + */ +export function findPoint( + geojson: Feature | FeatureCollection | G, + options?: { + featureIndex?: number, + multiFeatureIndex?: number, + geometryIndex?: number, + coordIndex?: number, + properties?: P, + bbox?: BBox, + id?: Id + } +): Feature; diff --git a/src/meta/index.js b/src/meta/index.js new file mode 100644 index 0000000000..1e29b8e212 --- /dev/null +++ b/src/meta/index.js @@ -0,0 +1,1110 @@ +import { feature, point, lineString, isObject } from '../helpers'; + +/** + * Callback for coordEach + * + * @callback coordEachCallback + * @param {Array} currentCoord The current coordinate being processed. + * @param {number} coordIndex The current index of the coordinate being processed. + * @param {number} featureIndex The current index of the Feature being processed. + * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. + * @param {number} geometryIndex The current index of the Geometry being processed. + */ + +/** + * Iterate over coordinates in any GeoJSON object, similar to Array.forEach() + * + * @name coordEach + * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object + * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex) + * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration. + * @returns {void} + * @example + * var features = turf.featureCollection([ + * turf.point([26, 37], {"foo": "bar"}), + * turf.point([36, 53], {"hello": "world"}) + * ]); + * + * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) { + * //=currentCoord + * //=coordIndex + * //=featureIndex + * //=multiFeatureIndex + * //=geometryIndex + * }); + */ +export function coordEach(geojson, callback, excludeWrapCoord) { + // Handles null Geometry -- Skips this GeoJSON + if (geojson === null) return; + var j, k, l, geometry, stopG, coords, + geometryMaybeCollection, + wrapShrink = 0, + coordIndex = 0, + isGeometryCollection, + type = geojson.type, + isFeatureCollection = type === 'FeatureCollection', + isFeature = type === 'Feature', + stop = isFeatureCollection ? geojson.features.length : 1; + + // This logic may look a little weird. The reason why it is that way + // is because it's trying to be fast. GeoJSON supports multiple kinds + // of objects at its root: FeatureCollection, Features, Geometries. + // This function has the responsibility of handling all of them, and that + // means that some of the `for` loops you see below actually just don't apply + // to certain inputs. For instance, if you give this just a + // Point geometry, then both loops are short-circuited and all we do + // is gradually rename the input until it's called 'geometry'. + // + // This also aims to allocate as few resources as possible: just a + // few numbers and booleans, rather than any temporary arrays as would + // be required with the normalization approach. + for (var featureIndex = 0; featureIndex < stop; featureIndex++) { + geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry : + (isFeature ? geojson.geometry : geojson)); + isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false; + stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1; + + for (var geomIndex = 0; geomIndex < stopG; geomIndex++) { + var multiFeatureIndex = 0; + var geometryIndex = 0; + geometry = isGeometryCollection ? + geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection; + + // Handles null Geometry -- Skips this geometry + if (geometry === null) continue; + coords = geometry.coordinates; + var geomType = geometry.type; + + wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0; + + switch (geomType) { + case null: + break; + case 'Point': + if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false; + coordIndex++; + multiFeatureIndex++; + break; + case 'LineString': + case 'MultiPoint': + for (j = 0; j < coords.length; j++) { + if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false; + coordIndex++; + if (geomType === 'MultiPoint') multiFeatureIndex++; + } + if (geomType === 'LineString') multiFeatureIndex++; + break; + case 'Polygon': + case 'MultiLineString': + for (j = 0; j < coords.length; j++) { + for (k = 0; k < coords[j].length - wrapShrink; k++) { + if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false; + coordIndex++; + } + if (geomType === 'MultiLineString') multiFeatureIndex++; + if (geomType === 'Polygon') geometryIndex++; + } + if (geomType === 'Polygon') multiFeatureIndex++; + break; + case 'MultiPolygon': + for (j = 0; j < coords.length; j++) { + geometryIndex = 0; + for (k = 0; k < coords[j].length; k++) { + for (l = 0; l < coords[j][k].length - wrapShrink; l++) { + if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false; + coordIndex++; + } + geometryIndex++; + } + multiFeatureIndex++; + } + break; + case 'GeometryCollection': + for (j = 0; j < geometry.geometries.length; j++) + if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false; + break; + default: + throw new Error('Unknown Geometry Type'); + } + } + } +} + +/** + * Callback for coordReduce + * + * The first time the callback function is called, the values provided as arguments depend + * on whether the reduce method has an initialValue argument. + * + * If an initialValue is provided to the reduce method: + * - The previousValue argument is initialValue. + * - The currentValue argument is the value of the first element present in the array. + * + * If an initialValue is not provided: + * - The previousValue argument is the value of the first element present in the array. + * - The currentValue argument is the value of the second element present in the array. + * + * @callback coordReduceCallback + * @param {*} previousValue The accumulated value previously returned in the last invocation + * of the callback, or initialValue, if supplied. + * @param {Array} currentCoord The current coordinate being processed. + * @param {number} coordIndex The current index of the coordinate being processed. + * Starts at index 0, if an initialValue is provided, and at index 1 otherwise. + * @param {number} featureIndex The current index of the Feature being processed. + * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. + * @param {number} geometryIndex The current index of the Geometry being processed. + */ + +/** + * Reduce coordinates in any GeoJSON object, similar to Array.reduce() + * + * @name coordReduce + * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object + * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex) + * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. + * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration. + * @returns {*} The value that results from the reduction. + * @example + * var features = turf.featureCollection([ + * turf.point([26, 37], {"foo": "bar"}), + * turf.point([36, 53], {"hello": "world"}) + * ]); + * + * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) { + * //=previousValue + * //=currentCoord + * //=coordIndex + * //=featureIndex + * //=multiFeatureIndex + * //=geometryIndex + * return currentCoord; + * }); + */ +export function coordReduce(geojson, callback, initialValue, excludeWrapCoord) { + var previousValue = initialValue; + coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) { + if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord; + else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex); + }, excludeWrapCoord); + return previousValue; +} + +/** + * Callback for propEach + * + * @callback propEachCallback + * @param {Object} currentProperties The current Properties being processed. + * @param {number} featureIndex The current index of the Feature being processed. + */ + +/** + * Iterate over properties in any GeoJSON object, similar to Array.forEach() + * + * @name propEach + * @param {FeatureCollection|Feature} geojson any GeoJSON object + * @param {Function} callback a method that takes (currentProperties, featureIndex) + * @returns {void} + * @example + * var features = turf.featureCollection([ + * turf.point([26, 37], {foo: 'bar'}), + * turf.point([36, 53], {hello: 'world'}) + * ]); + * + * turf.propEach(features, function (currentProperties, featureIndex) { + * //=currentProperties + * //=featureIndex + * }); + */ +export function propEach(geojson, callback) { + var i; + switch (geojson.type) { + case 'FeatureCollection': + for (i = 0; i < geojson.features.length; i++) { + if (callback(geojson.features[i].properties, i) === false) break; + } + break; + case 'Feature': + callback(geojson.properties, 0); + break; + } +} + + +/** + * Callback for propReduce + * + * The first time the callback function is called, the values provided as arguments depend + * on whether the reduce method has an initialValue argument. + * + * If an initialValue is provided to the reduce method: + * - The previousValue argument is initialValue. + * - The currentValue argument is the value of the first element present in the array. + * + * If an initialValue is not provided: + * - The previousValue argument is the value of the first element present in the array. + * - The currentValue argument is the value of the second element present in the array. + * + * @callback propReduceCallback + * @param {*} previousValue The accumulated value previously returned in the last invocation + * of the callback, or initialValue, if supplied. + * @param {*} currentProperties The current Properties being processed. + * @param {number} featureIndex The current index of the Feature being processed. + */ + +/** + * Reduce properties in any GeoJSON object into a single value, + * similar to how Array.reduce works. However, in this case we lazily run + * the reduction, so an array of all properties is unnecessary. + * + * @name propReduce + * @param {FeatureCollection|Feature} geojson any GeoJSON object + * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex) + * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. + * @returns {*} The value that results from the reduction. + * @example + * var features = turf.featureCollection([ + * turf.point([26, 37], {foo: 'bar'}), + * turf.point([36, 53], {hello: 'world'}) + * ]); + * + * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) { + * //=previousValue + * //=currentProperties + * //=featureIndex + * return currentProperties + * }); + */ +export function propReduce(geojson, callback, initialValue) { + var previousValue = initialValue; + propEach(geojson, function (currentProperties, featureIndex) { + if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties; + else previousValue = callback(previousValue, currentProperties, featureIndex); + }); + return previousValue; +} + +/** + * Callback for featureEach + * + * @callback featureEachCallback + * @param {Feature} currentFeature The current Feature being processed. + * @param {number} featureIndex The current index of the Feature being processed. + */ + +/** + * Iterate over features in any GeoJSON object, similar to + * Array.forEach. + * + * @name featureEach + * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object + * @param {Function} callback a method that takes (currentFeature, featureIndex) + * @returns {void} + * @example + * var features = turf.featureCollection([ + * turf.point([26, 37], {foo: 'bar'}), + * turf.point([36, 53], {hello: 'world'}) + * ]); + * + * turf.featureEach(features, function (currentFeature, featureIndex) { + * //=currentFeature + * //=featureIndex + * }); + */ +export function featureEach(geojson, callback) { + if (geojson.type === 'Feature') { + callback(geojson, 0); + } else if (geojson.type === 'FeatureCollection') { + for (var i = 0; i < geojson.features.length; i++) { + if (callback(geojson.features[i], i) === false) break; + } + } +} + +/** + * Callback for featureReduce + * + * The first time the callback function is called, the values provided as arguments depend + * on whether the reduce method has an initialValue argument. + * + * If an initialValue is provided to the reduce method: + * - The previousValue argument is initialValue. + * - The currentValue argument is the value of the first element present in the array. + * + * If an initialValue is not provided: + * - The previousValue argument is the value of the first element present in the array. + * - The currentValue argument is the value of the second element present in the array. + * + * @callback featureReduceCallback + * @param {*} previousValue The accumulated value previously returned in the last invocation + * of the callback, or initialValue, if supplied. + * @param {Feature} currentFeature The current Feature being processed. + * @param {number} featureIndex The current index of the Feature being processed. + */ + +/** + * Reduce features in any GeoJSON object, similar to Array.reduce(). + * + * @name featureReduce + * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object + * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex) + * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. + * @returns {*} The value that results from the reduction. + * @example + * var features = turf.featureCollection([ + * turf.point([26, 37], {"foo": "bar"}), + * turf.point([36, 53], {"hello": "world"}) + * ]); + * + * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) { + * //=previousValue + * //=currentFeature + * //=featureIndex + * return currentFeature + * }); + */ +export function featureReduce(geojson, callback, initialValue) { + var previousValue = initialValue; + featureEach(geojson, function (currentFeature, featureIndex) { + if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature; + else previousValue = callback(previousValue, currentFeature, featureIndex); + }); + return previousValue; +} + +/** + * Get all coordinates from any GeoJSON object. + * + * @name coordAll + * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object + * @returns {Array>} coordinate position array + * @example + * var features = turf.featureCollection([ + * turf.point([26, 37], {foo: 'bar'}), + * turf.point([36, 53], {hello: 'world'}) + * ]); + * + * var coords = turf.coordAll(features); + * //= [[26, 37], [36, 53]] + */ +export function coordAll(geojson) { + var coords = []; + coordEach(geojson, function (coord) { + coords.push(coord); + }); + return coords; +} + +/** + * Callback for geomEach + * + * @callback geomEachCallback + * @param {Geometry} currentGeometry The current Geometry being processed. + * @param {number} featureIndex The current index of the Feature being processed. + * @param {Object} featureProperties The current Feature Properties being processed. + * @param {Array} featureBBox The current Feature BBox being processed. + * @param {number|string} featureId The current Feature Id being processed. + */ + +/** + * Iterate over each geometry in any GeoJSON object, similar to Array.forEach() + * + * @name geomEach + * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object + * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) + * @returns {void} + * @example + * var features = turf.featureCollection([ + * turf.point([26, 37], {foo: 'bar'}), + * turf.point([36, 53], {hello: 'world'}) + * ]); + * + * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) { + * //=currentGeometry + * //=featureIndex + * //=featureProperties + * //=featureBBox + * //=featureId + * }); + */ +export function geomEach(geojson, callback) { + var i, j, g, geometry, stopG, + geometryMaybeCollection, + isGeometryCollection, + featureProperties, + featureBBox, + featureId, + featureIndex = 0, + isFeatureCollection = geojson.type === 'FeatureCollection', + isFeature = geojson.type === 'Feature', + stop = isFeatureCollection ? geojson.features.length : 1; + + // This logic may look a little weird. The reason why it is that way + // is because it's trying to be fast. GeoJSON supports multiple kinds + // of objects at its root: FeatureCollection, Features, Geometries. + // This function has the responsibility of handling all of them, and that + // means that some of the `for` loops you see below actually just don't apply + // to certain inputs. For instance, if you give this just a + // Point geometry, then both loops are short-circuited and all we do + // is gradually rename the input until it's called 'geometry'. + // + // This also aims to allocate as few resources as possible: just a + // few numbers and booleans, rather than any temporary arrays as would + // be required with the normalization approach. + for (i = 0; i < stop; i++) { + + geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry : + (isFeature ? geojson.geometry : geojson)); + featureProperties = (isFeatureCollection ? geojson.features[i].properties : + (isFeature ? geojson.properties : {})); + featureBBox = (isFeatureCollection ? geojson.features[i].bbox : + (isFeature ? geojson.bbox : undefined)); + featureId = (isFeatureCollection ? geojson.features[i].id : + (isFeature ? geojson.id : undefined)); + isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false; + stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1; + + for (g = 0; g < stopG; g++) { + geometry = isGeometryCollection ? + geometryMaybeCollection.geometries[g] : geometryMaybeCollection; + + // Handle null Geometry + if (geometry === null) { + if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false; + continue; + } + switch (geometry.type) { + case 'Point': + case 'LineString': + case 'MultiPoint': + case 'Polygon': + case 'MultiLineString': + case 'MultiPolygon': { + if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false; + break; + } + case 'GeometryCollection': { + for (j = 0; j < geometry.geometries.length; j++) { + if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false; + } + break; + } + default: + throw new Error('Unknown Geometry Type'); + } + } + // Only increase `featureIndex` per each feature + featureIndex++; + } +} + +/** + * Callback for geomReduce + * + * The first time the callback function is called, the values provided as arguments depend + * on whether the reduce method has an initialValue argument. + * + * If an initialValue is provided to the reduce method: + * - The previousValue argument is initialValue. + * - The currentValue argument is the value of the first element present in the array. + * + * If an initialValue is not provided: + * - The previousValue argument is the value of the first element present in the array. + * - The currentValue argument is the value of the second element present in the array. + * + * @callback geomReduceCallback + * @param {*} previousValue The accumulated value previously returned in the last invocation + * of the callback, or initialValue, if supplied. + * @param {Geometry} currentGeometry The current Geometry being processed. + * @param {number} featureIndex The current index of the Feature being processed. + * @param {Object} featureProperties The current Feature Properties being processed. + * @param {Array} featureBBox The current Feature BBox being processed. + * @param {number|string} featureId The current Feature Id being processed. + */ + +/** + * Reduce geometry in any GeoJSON object, similar to Array.reduce(). + * + * @name geomReduce + * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object + * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) + * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. + * @returns {*} The value that results from the reduction. + * @example + * var features = turf.featureCollection([ + * turf.point([26, 37], {foo: 'bar'}), + * turf.point([36, 53], {hello: 'world'}) + * ]); + * + * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) { + * //=previousValue + * //=currentGeometry + * //=featureIndex + * //=featureProperties + * //=featureBBox + * //=featureId + * return currentGeometry + * }); + */ +export function geomReduce(geojson, callback, initialValue) { + var previousValue = initialValue; + geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) { + if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry; + else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId); + }); + return previousValue; +} + +/** + * Callback for flattenEach + * + * @callback flattenEachCallback + * @param {Feature} currentFeature The current flattened feature being processed. + * @param {number} featureIndex The current index of the Feature being processed. + * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. + */ + +/** + * Iterate over flattened features in any GeoJSON object, similar to + * Array.forEach. + * + * @name flattenEach + * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object + * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex) + * @example + * var features = turf.featureCollection([ + * turf.point([26, 37], {foo: 'bar'}), + * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'}) + * ]); + * + * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) { + * //=currentFeature + * //=featureIndex + * //=multiFeatureIndex + * }); + */ +export function flattenEach(geojson, callback) { + geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) { + // Callback for single geometry + var type = (geometry === null) ? null : geometry.type; + switch (type) { + case null: + case 'Point': + case 'LineString': + case 'Polygon': + if (callback(feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false; + return; + } + + var geomType; + + // Callback for multi-geometry + switch (type) { + case 'MultiPoint': + geomType = 'Point'; + break; + case 'MultiLineString': + geomType = 'LineString'; + break; + case 'MultiPolygon': + geomType = 'Polygon'; + break; + } + + for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) { + var coordinate = geometry.coordinates[multiFeatureIndex]; + var geom = { + type: geomType, + coordinates: coordinate + }; + if (callback(feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false; + } + }); +} + +/** + * Callback for flattenReduce + * + * The first time the callback function is called, the values provided as arguments depend + * on whether the reduce method has an initialValue argument. + * + * If an initialValue is provided to the reduce method: + * - The previousValue argument is initialValue. + * - The currentValue argument is the value of the first element present in the array. + * + * If an initialValue is not provided: + * - The previousValue argument is the value of the first element present in the array. + * - The currentValue argument is the value of the second element present in the array. + * + * @callback flattenReduceCallback + * @param {*} previousValue The accumulated value previously returned in the last invocation + * of the callback, or initialValue, if supplied. + * @param {Feature} currentFeature The current Feature being processed. + * @param {number} featureIndex The current index of the Feature being processed. + * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. + */ + +/** + * Reduce flattened features in any GeoJSON object, similar to Array.reduce(). + * + * @name flattenReduce + * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object + * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex) + * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. + * @returns {*} The value that results from the reduction. + * @example + * var features = turf.featureCollection([ + * turf.point([26, 37], {foo: 'bar'}), + * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'}) + * ]); + * + * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) { + * //=previousValue + * //=currentFeature + * //=featureIndex + * //=multiFeatureIndex + * return currentFeature + * }); + */ +export function flattenReduce(geojson, callback, initialValue) { + var previousValue = initialValue; + flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) { + if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature; + else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex); + }); + return previousValue; +} + +/** + * Callback for segmentEach + * + * @callback segmentEachCallback + * @param {Feature} currentSegment The current Segment being processed. + * @param {number} featureIndex The current index of the Feature being processed. + * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. + * @param {number} geometryIndex The current index of the Geometry being processed. + * @param {number} segmentIndex The current index of the Segment being processed. + * @returns {void} + */ + +/** + * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach() + * (Multi)Point geometries do not contain segments therefore they are ignored during this operation. + * + * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON + * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) + * @returns {void} + * @example + * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]); + * + * // Iterate over GeoJSON by 2-vertex segments + * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) { + * //=currentSegment + * //=featureIndex + * //=multiFeatureIndex + * //=geometryIndex + * //=segmentIndex + * }); + * + * // Calculate the total number of segments + * var total = 0; + * turf.segmentEach(polygon, function () { + * total++; + * }); + */ +export function segmentEach(geojson, callback) { + flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) { + var segmentIndex = 0; + + // Exclude null Geometries + if (!feature.geometry) return; + // (Multi)Point geometries do not contain segments therefore they are ignored during this operation. + var type = feature.geometry.type; + if (type === 'Point' || type === 'MultiPoint') return; + + // Generate 2-vertex line segments + var previousCoords; + var previousFeatureIndex = 0; + var previousMultiIndex = 0; + var prevGeomIndex = 0; + if (coordEach(feature, function (currentCoord, coordIndex, featureIndexCoord, multiPartIndexCoord, geometryIndex) { + // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false` + if (previousCoords === undefined || featureIndex > previousFeatureIndex || multiPartIndexCoord > previousMultiIndex || geometryIndex > prevGeomIndex) { + previousCoords = currentCoord; + previousFeatureIndex = featureIndex; + previousMultiIndex = multiPartIndexCoord; + prevGeomIndex = geometryIndex; + segmentIndex = 0; + return; + } + var currentSegment = lineString([previousCoords, currentCoord], feature.properties); + if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false; + segmentIndex++; + previousCoords = currentCoord; + }) === false) return false; + }); +} + +/** + * Callback for segmentReduce + * + * The first time the callback function is called, the values provided as arguments depend + * on whether the reduce method has an initialValue argument. + * + * If an initialValue is provided to the reduce method: + * - The previousValue argument is initialValue. + * - The currentValue argument is the value of the first element present in the array. + * + * If an initialValue is not provided: + * - The previousValue argument is the value of the first element present in the array. + * - The currentValue argument is the value of the second element present in the array. + * + * @callback segmentReduceCallback + * @param {*} previousValue The accumulated value previously returned in the last invocation + * of the callback, or initialValue, if supplied. + * @param {Feature} currentSegment The current Segment being processed. + * @param {number} featureIndex The current index of the Feature being processed. + * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed. + * @param {number} geometryIndex The current index of the Geometry being processed. + * @param {number} segmentIndex The current index of the Segment being processed. + */ + +/** + * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce() + * (Multi)Point geometries do not contain segments therefore they are ignored during this operation. + * + * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON + * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex) + * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. + * @returns {void} + * @example + * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]); + * + * // Iterate over GeoJSON by 2-vertex segments + * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) { + * //= previousSegment + * //= currentSegment + * //= featureIndex + * //= multiFeatureIndex + * //= geometryIndex + * //= segmentInex + * return currentSegment + * }); + * + * // Calculate the total number of segments + * var initialValue = 0 + * var total = turf.segmentReduce(polygon, function (previousValue) { + * previousValue++; + * return previousValue; + * }, initialValue); + */ +export function segmentReduce(geojson, callback, initialValue) { + var previousValue = initialValue; + var started = false; + segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) { + if (started === false && initialValue === undefined) previousValue = currentSegment; + else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex); + started = true; + }); + return previousValue; +} + +/** + * Callback for lineEach + * + * @callback lineEachCallback + * @param {Feature} currentLine The current LineString|LinearRing being processed + * @param {number} featureIndex The current index of the Feature being processed + * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed + * @param {number} geometryIndex The current index of the Geometry being processed + */ + +/** + * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries, + * similar to Array.forEach. + * + * @name lineEach + * @param {Geometry|Feature} geojson object + * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex) + * @example + * var multiLine = turf.multiLineString([ + * [[26, 37], [35, 45]], + * [[36, 53], [38, 50], [41, 55]] + * ]); + * + * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) { + * //=currentLine + * //=featureIndex + * //=multiFeatureIndex + * //=geometryIndex + * }); + */ +export function lineEach(geojson, callback) { + // validation + if (!geojson) throw new Error('geojson is required'); + + flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) { + if (feature.geometry === null) return; + var type = feature.geometry.type; + var coords = feature.geometry.coordinates; + switch (type) { + case 'LineString': + if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) return false; + break; + case 'Polygon': + for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) { + if (callback(lineString(coords[geometryIndex], feature.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false; + } + break; + } + }); +} + +/** + * Callback for lineReduce + * + * The first time the callback function is called, the values provided as arguments depend + * on whether the reduce method has an initialValue argument. + * + * If an initialValue is provided to the reduce method: + * - The previousValue argument is initialValue. + * - The currentValue argument is the value of the first element present in the array. + * + * If an initialValue is not provided: + * - The previousValue argument is the value of the first element present in the array. + * - The currentValue argument is the value of the second element present in the array. + * + * @callback lineReduceCallback + * @param {*} previousValue The accumulated value previously returned in the last invocation + * of the callback, or initialValue, if supplied. + * @param {Feature} currentLine The current LineString|LinearRing being processed. + * @param {number} featureIndex The current index of the Feature being processed + * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed + * @param {number} geometryIndex The current index of the Geometry being processed + */ + +/** + * Reduce features in any GeoJSON object, similar to Array.reduce(). + * + * @name lineReduce + * @param {Geometry|Feature} geojson object + * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) + * @param {*} [initialValue] Value to use as the first argument to the first call of the callback. + * @returns {*} The value that results from the reduction. + * @example + * var multiPoly = turf.multiPolygon([ + * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]), + * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]]) + * ]); + * + * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) { + * //=previousValue + * //=currentLine + * //=featureIndex + * //=multiFeatureIndex + * //=geometryIndex + * return currentLine + * }); + */ +export function lineReduce(geojson, callback, initialValue) { + var previousValue = initialValue; + lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) { + if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine; + else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex); + }); + return previousValue; +} + +/** + * Finds a particular 2-vertex LineString Segment from a GeoJSON using `../meta` indexes. + * + * Negative indexes are permitted. + * Point & MultiPoint will always return null. + * + * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry + * @param {Object} [options={}] Optional parameters + * @param {number} [options.featureIndex=0] Feature Index + * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index + * @param {number} [options.geometryIndex=0] Geometry Index + * @param {number} [options.segmentIndex=0] Segment Index + * @param {Object} [options.properties={}] Translate Properties to output LineString + * @param {BBox} [options.bbox={}] Translate BBox to output LineString + * @param {number|string} [options.id={}] Translate Id to output LineString + * @returns {Feature} 2-vertex GeoJSON Feature LineString + * @example + * var multiLine = turf.multiLineString([ + * [[10, 10], [50, 30], [30, 40]], + * [[-10, -10], [-50, -30], [-30, -40]] + * ]); + * + * // First Segment (defaults are 0) + * turf.findSegment(multiLine); + * // => Feature> + * + * // First Segment of 2nd Multi Feature + * turf.findSegment(multiLine, {multiFeatureIndex: 1}); + * // => Feature> + * + * // Last Segment of Last Multi Feature + * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1}); + * // => Feature> + */ +export function findSegment(geojson, options) { + // Optional Parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var featureIndex = options.featureIndex || 0; + var multiFeatureIndex = options.multiFeatureIndex || 0; + var geometryIndex = options.geometryIndex || 0; + var segmentIndex = options.segmentIndex || 0; + + // Find FeatureIndex + var properties = options.properties; + var geometry; + + switch (geojson.type) { + case 'FeatureCollection': + if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex; + properties = properties || geojson.features[featureIndex].properties; + geometry = geojson.features[featureIndex].geometry; + break; + case 'Feature': + properties = properties || geojson.properties; + geometry = geojson.geometry; + break; + case 'Point': + case 'MultiPoint': + return null; + case 'LineString': + case 'Polygon': + case 'MultiLineString': + case 'MultiPolygon': + geometry = geojson; + break; + default: + throw new Error('geojson is invalid'); + } + + // Find SegmentIndex + if (geometry === null) return null; + var coords = geometry.coordinates; + switch (geometry.type) { + case 'Point': + case 'MultiPoint': + return null; + case 'LineString': + if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1; + return lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options); + case 'Polygon': + if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex; + if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1; + return lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options); + case 'MultiLineString': + if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex; + if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1; + return lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options); + case 'MultiPolygon': + if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex; + if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex; + if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1; + return lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options); + } + throw new Error('geojson is invalid'); +} + +/** + * Finds a particular Point from a GeoJSON using `../meta` indexes. + * + * Negative indexes are permitted. + * + * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry + * @param {Object} [options={}] Optional parameters + * @param {number} [options.featureIndex=0] Feature Index + * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index + * @param {number} [options.geometryIndex=0] Geometry Index + * @param {number} [options.coordIndex=0] Coord Index + * @param {Object} [options.properties={}] Translate Properties to output Point + * @param {BBox} [options.bbox={}] Translate BBox to output Point + * @param {number|string} [options.id={}] Translate Id to output Point + * @returns {Feature} 2-vertex GeoJSON Feature Point + * @example + * var multiLine = turf.multiLineString([ + * [[10, 10], [50, 30], [30, 40]], + * [[-10, -10], [-50, -30], [-30, -40]] + * ]); + * + * // First Segment (defaults are 0) + * turf.findPoint(multiLine); + * // => Feature> + * + * // First Segment of the 2nd Multi-Feature + * turf.findPoint(multiLine, {multiFeatureIndex: 1}); + * // => Feature> + * + * // Last Segment of last Multi-Feature + * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1}); + * // => Feature> + */ +export function findPoint(geojson, options) { + // Optional Parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var featureIndex = options.featureIndex || 0; + var multiFeatureIndex = options.multiFeatureIndex || 0; + var geometryIndex = options.geometryIndex || 0; + var coordIndex = options.coordIndex || 0; + + // Find FeatureIndex + var properties = options.properties; + var geometry; + + switch (geojson.type) { + case 'FeatureCollection': + if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex; + properties = properties || geojson.features[featureIndex].properties; + geometry = geojson.features[featureIndex].geometry; + break; + case 'Feature': + properties = properties || geojson.properties; + geometry = geojson.geometry; + break; + case 'Point': + case 'MultiPoint': + return null; + case 'LineString': + case 'Polygon': + case 'MultiLineString': + case 'MultiPolygon': + geometry = geojson; + break; + default: + throw new Error('geojson is invalid'); + } + + // Find Coord Index + if (geometry === null) return null; + var coords = geometry.coordinates; + switch (geometry.type) { + case 'Point': + return point(coords, properties, options); + case 'MultiPoint': + if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex; + return point(coords[multiFeatureIndex], properties, options); + case 'LineString': + if (coordIndex < 0) coordIndex = coords.length + coordIndex; + return point(coords[coordIndex], properties, options); + case 'Polygon': + if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex; + if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex; + return point(coords[geometryIndex][coordIndex], properties, options); + case 'MultiLineString': + if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex; + if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex; + return point(coords[multiFeatureIndex][coordIndex], properties, options); + case 'MultiPolygon': + if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex; + if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex; + if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex; + return point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options); + } + throw new Error('geojson is invalid'); +} diff --git a/src/meta/test.js b/src/meta/test.js new file mode 100644 index 0000000000..102f9bff72 --- /dev/null +++ b/src/meta/test.js @@ -0,0 +1,1020 @@ +const test = require('tape'); +const { + point, + lineString, + feature, + polygon, + multiPoint, + multiPolygon, + multiLineString, + geometryCollection, + featureCollection, + points, + lineStrings, + polygons +} = require('../helpers'); +const meta = require('./'); + +const pt = point([0, 0], {a: 1}); +const pt2 = point([1, 1]); +const line = lineString([[0, 0], [1, 1]]); +const poly = polygon([[[0, 0], [1, 1], [0, 1], [0, 0]]]); +const polyWithHole = polygon([[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], + [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]]); +const multiPt = multiPoint([[0, 0], [1, 1]]); +const multiLine = multiLineString([[[0, 0], [1, 1]], [[3, 3], [4, 4]]]); +const multiPoly = multiPolygon([[[[0, 0], [1, 1], [0, 1], [0, 0]]], [[[3, 3], [2, 2], [1, 2], [3, 3]]]]); +const geomCollection = geometryCollection([pt.geometry, line.geometry, multiLine.geometry], {a: 0}); +const fcNull = featureCollection([feature(null), feature(null)]); +const fcMixed = featureCollection([ + point([0, 0]), + lineString([[1, 1], [2, 2]]), + multiLineString([[[1, 1], [0, 0]], [[4, 4], [5, 5]]]) +]); + +function collection(feature) { + const featureCollection = { + type: 'FeatureCollection', + features: [feature] + }; + + return [feature, featureCollection]; +} + +function featureAndCollection(geometry) { + const feature = { + type: 'Feature', + geometry: geometry, + properties: {a: 1} + }; + + const featureCollection = { + type: 'FeatureCollection', + features: [feature] + }; + + return [geometry, feature, featureCollection]; +} + +test('propEach', t => { + collection(pt).forEach(input => { + meta.propEach(input, (prop, i) => { + t.deepEqual(prop, {a: 1}); + t.equal(i, 0); + }); + }); + t.end(); +}); + +test('coordEach -- Point', t => { + featureAndCollection(pt.geometry).forEach(input => { + meta.coordEach(input, (coord, index) => { + t.deepEqual(coord, [0, 0]); + t.equal(index, 0); + }); + }); + t.end(); +}); + +test('coordEach -- LineString', t => { + featureAndCollection(line.geometry).forEach(input => { + const output = []; + let lastIndex; + meta.coordEach(input, (coord, index) => { + output.push(coord); + lastIndex = index; + }); + t.deepEqual(output, [[0, 0], [1, 1]]); + t.equal(lastIndex, 1); + }); + t.end(); +}); + +test('coordEach -- Polygon', t => { + featureAndCollection(poly.geometry).forEach(input => { + const output = []; + let lastIndex; + meta.coordEach(input, (coord, index) => { + output.push(coord); + lastIndex = index; + }); + t.deepEqual(output, [[0, 0], [1, 1], [0, 1], [0, 0]]); + t.equal(lastIndex, 3); + }); + t.end(); +}); + +test('coordEach -- Polygon excludeWrapCoord', t => { + featureAndCollection(poly.geometry).forEach(input => { + const output = []; + let lastIndex; + meta.coordEach(input, (coord, index) => { + output.push(coord); + lastIndex = index; + }, true); + t.equal(lastIndex, 2); + }); + t.end(); +}); + +test('coordEach -- MultiPolygon', t => { + const coords = []; + const coordIndexes = []; + const featureIndexes = []; + const multiFeatureIndexes = []; + meta.coordEach(multiPoly, (coord, coordIndex, featureIndex, multiFeatureIndex) => { + coords.push(coord); + coordIndexes.push(coordIndex); + featureIndexes.push(featureIndex); + multiFeatureIndexes.push(multiFeatureIndex); + }); + t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 5, 6, 7]); + t.deepEqual(featureIndexes, [0, 0, 0, 0, 0, 0, 0, 0]); + t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 1, 1, 1, 1]); + t.equal(coords.length, 8); + t.end(); +}); + +test('coordEach -- FeatureCollection', t => { + const coords = []; + const coordIndexes = []; + const featureIndexes = []; + const multiFeatureIndexes = []; + meta.coordEach(fcMixed, (coord, coordIndex, featureIndex, multiFeatureIndex) => { + coords.push(coord); + coordIndexes.push(coordIndex); + featureIndexes.push(featureIndex); + multiFeatureIndexes.push(multiFeatureIndex); + }); + t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 5, 6]); + t.deepEqual(featureIndexes, [0, 1, 1, 2, 2, 2, 2]); + t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 1, 1]); + t.equal(coords.length, 7); + t.end(); +}); + +test('coordReduce -- initialValue', t => { + let lastIndex; + const line = lineString([[126, -11], [129, -21], [135, -31]]); + const sum = meta.coordReduce(line, (previous, currentCoords, index) => { + lastIndex = index; + return previous + currentCoords[0]; + }, 0); + t.equal(lastIndex, 2); + t.equal(sum, 390); + t.end(); +}); + +test('Array.reduce() -- initialValue', t => { + let lastIndex; + const line = [[126, -11], [129, -21], [135, -31]]; + const sum = line.reduce((previous, currentCoords, index) => { + lastIndex = index; + return previous + currentCoords[0]; + }, 0); + t.equal(lastIndex, 2); + t.equal(sum, 390); + t.end(); +}); + +test('coordReduce -- previous-coordinates', t => { + let lastIndex; + const coords = []; + const line = lineString([[126, -11], [129, -21], [135, -31]]); + meta.coordReduce(line, (previousCoords, currentCoords, index) => { + lastIndex = index; + coords.push(currentCoords); + return currentCoords; + }); + t.equal(lastIndex, 2); + t.equal(coords.length, 2); + t.end(); +}); + +test('Array.reduce() -- previous-coordinates', t => { + let lastIndex; + const coords = []; + const line = [[126, -11], [129, -21], [135, -31]]; + line.reduce((previousCoords, currentCoords, index) => { + lastIndex = index; + coords.push(currentCoords); + return currentCoords; + }); + t.equal(lastIndex, 2); + t.equal(coords.length, 2); + t.end(); +}); + + +test('coordReduce -- previous-coordinates+initialValue', t => { + let lastIndex; + const coords = []; + meta.coordReduce(line, (previousCoords, currentCoords, index) => { + lastIndex = index; + coords.push(currentCoords); + return currentCoords; + }, line.geometry.coordinates[0]); + t.equal(lastIndex, 1); + t.equal(coords.length, 2); + t.end(); +}); + +test('Array.reduce() -- previous-coordinates+initialValue', t => { + let lastIndex; + const coords = []; + line.geometry.coordinates.reduce((previousCoords, currentCoords, index) => { + lastIndex = index; + coords.push(currentCoords); + return currentCoords; + }, line[0]); + t.equal(lastIndex, 1); + t.equal(coords.length, 2); + t.end(); +}); + +test('unknown', t => { + t.throws(function () { + meta.coordEach({}); + }); + t.end(); +}); + +test('geomEach -- GeometryCollection', t => { + featureAndCollection(geomCollection.geometry).forEach(input => { + const output = []; + meta.geomEach(input, geom => { + output.push(geom); + }); + t.deepEqual(output, geomCollection.geometry.geometries); + }); + t.end(); +}); + +test('geomEach -- bare-GeometryCollection', t => { + const output = []; + meta.geomEach(geomCollection, geom => { + output.push(geom); + }); + t.deepEqual(output, geomCollection.geometry.geometries); + t.end(); +}); + +test('geomEach -- bare-pointGeometry', t => { + const output = []; + meta.geomEach(pt.geometry, geom => { + output.push(geom); + }); + t.deepEqual(output, [pt.geometry]); + t.end(); +}); + +test('geomEach -- bare-pointFeature', t => { + const output = []; + meta.geomEach(pt, geom => { + output.push(geom); + }); + t.deepEqual(output, [pt.geometry]); + t.end(); +}); + +test('geomEach -- multiGeometryFeature-properties', t => { + let lastProperties; + meta.geomEach(geomCollection, (geom, index, properties) => { + lastProperties = properties; + }); + t.deepEqual(lastProperties, geomCollection.properties); + t.end(); +}); + +test('flattenEach -- MultiPoint', t => { + featureAndCollection(multiPt.geometry).forEach(input => { + const output = []; + meta.flattenEach(input, feature => { + output.push(feature.geometry); + }); + t.deepEqual(output, [pt.geometry, pt2.geometry]); + }); + t.end(); +}); + +test('flattenEach -- Mixed FeatureCollection', t => { + const features = []; + const featureIndexes = []; + const multiFeatureIndexes = []; + meta.flattenEach(fcMixed, (feature, featureIndex, multiFeatureIndex) => { + features.push(feature); + featureIndexes.push(featureIndex); + multiFeatureIndexes.push(multiFeatureIndex); + }); + t.deepEqual(featureIndexes, [0, 1, 2, 2]); + t.deepEqual(multiFeatureIndexes, [0, 0, 0, 1]); + t.equal(features.length, 4); + t.end(); +}); + +test('flattenEach -- Point-properties', t => { + collection(pt).forEach(input => { + let lastProperties; + meta.flattenEach(input, feature => { + lastProperties = feature.properties; + }); + t.deepEqual(lastProperties, pt.properties); + }); + t.end(); +}); + +test('flattenEach -- multiGeometryFeature-properties', t => { + collection(geomCollection).forEach(input => { + let lastProperties; + meta.flattenEach(input, feature => { + lastProperties = feature.properties; + }); + t.deepEqual(lastProperties, geomCollection.properties); + }); + t.end(); +}); + +test('flattenReduce -- initialValue', t => { + let lastIndex; + let lastSubIndex; + const sum = meta.flattenReduce(multiPt.geometry, (previous, current, index, subIndex) => { + lastIndex = index; + lastSubIndex = subIndex; + return previous + current.geometry.coordinates[0]; + }, 0); + t.equal(lastIndex, 0); + t.equal(lastSubIndex, 1); + t.equal(sum, 1); + t.end(); +}); + +test('flattenReduce -- previous-feature', t => { + const features = []; + const featureIndexes = []; + const multiFeatureIndexes = []; + meta.flattenReduce(multiLine, (previous, current, featureIndex, multiFeatureIndex) => { + featureIndexes.push(featureIndex); + multiFeatureIndexes.push(multiFeatureIndex); + features.push(current); + return current; + }); + t.deepEqual(featureIndexes, [0]); + t.deepEqual(multiFeatureIndexes, [1]); + t.equal(features.length, 1); + t.end(); +}); + +test('flattenReduce -- previous-feature+initialValue', t => { + const features = []; + const featureIndexes = []; + const multiFeatureIndexes = []; + const sum = meta.flattenReduce(multiPt.geometry, (previous, current, featureIndex, multiFeatureIndex) => { + featureIndexes.push(featureIndex); + multiFeatureIndexes.push(multiFeatureIndex); + features.push(current); + return current; + }, null); + t.deepEqual(featureIndexes, [0, 0]); + t.deepEqual(multiFeatureIndexes, [0, 1]); + t.equal(features.length, 2); + t.deepEqual(sum, features[features.length - 1]); + t.end(); +}); + +// https://github.com/Turfjs/turf/issues/853 +test('null geometries', t => { + // Each operations + meta.featureEach(fcNull, feature => t.equal(feature.geometry, null, 'featureEach')); + meta.geomEach(fcNull, geometry => t.equal(geometry, null), 'geomEach'); + meta.flattenEach(fcNull, feature => t.equal(feature.geometry, null, 'flattenEach')); + meta.coordEach(fcNull, () => t.fail('no coordinates should be found')); + + // Reduce operations + /* eslint-disable no-return-assign */ + t.equal(meta.featureReduce(fcNull, prev => prev += 1, 0), 2, 'featureReduce'); + t.equal(meta.geomReduce(fcNull, prev => prev += 1, 0), 2, 'geomReduce'); + t.equal(meta.flattenReduce(fcNull, prev => prev += 1, 0), 2, 'flattenReduce'); + t.equal(meta.coordReduce(fcNull, prev => prev += 1, 0), 0, 'coordReduce'); + /* eslint-enable no-return-assign */ + t.end(); +}); + +test('null geometries -- index', t => { + const fc = featureCollection([ + feature(null), // index 0 + point([0, 0]), // index 1 + feature(null), // index 2 + lineString([[1, 1], [0, 0]]) // index 3 + ]); + t.deepEqual(meta.coordReduce(fc, (prev, coords, coordIndex) => prev.concat(coordIndex), []), [0, 1, 2], 'coordReduce'); + t.deepEqual(meta.geomReduce(fc, (prev, geom, featureIndex) => prev.concat(featureIndex), []), [0, 1, 2, 3], 'geomReduce'); + t.deepEqual(meta.flattenReduce(fc, (prev, feature, featureIndex) => prev.concat(featureIndex), []), [0, 1, 2, 3], 'flattenReduce'); + t.end(); +}); + +test('segmentEach', t => { + const segments = []; + let total = 0; + meta.segmentEach(poly.geometry, currentSegment => { + segments.push(currentSegment); + total++; + }); + t.equal(segments[0].geometry.coordinates.length, 2); + t.equal(total, 3); + t.end(); +}); + +test('segmentEach -- MultiPoint', t => { + const segments = []; + let total = 0; + meta.segmentEach(multiPt.geometry, currentSegment => { + segments.push(currentSegment); + total++; + }); + t.equal(total, 0); // No segments are created from MultiPoint geometry + t.end(); +}); + +test('segmentReduce', t => { + const segments = []; + const total = meta.segmentReduce(poly.geometry, (previousValue, currentSegment) => { + segments.push(currentSegment); + previousValue++; + return previousValue; + }, 0); + t.equal(segments[0].geometry.coordinates.length, 2); + t.equal(total, 3); + t.end(); +}); + +test('segmentReduce -- no initialValue', t => { + const segments = []; + var total = 0; + meta.segmentReduce(poly.geometry, (previousValue, currentSegment) => { + segments.push(currentSegment); + total++; + }); + t.equal(segments[0].geometry.coordinates.length, 2); + t.equal(total, 2); + t.end(); +}); + +const geojsonSegments = featureCollection([ + point([0, 1]), // ignored + lineString([[0, 0], [2, 2], [4, 4]]), + polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]]), + point([0, 1]), // ignored + multiLineString([ + [[0, 0], [2, 2], [4, 4]], + [[0, 0], [2, 2], [4, 4]] + ]) +]); + +test('segmentEach -- index & subIndex', t => { + const featureIndexes = []; + const multiFeatureIndexes = []; + const geometryIndexes = []; + const segmentIndexes = []; + let total = 0; + + meta.segmentEach(geojsonSegments, (segment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) => { + featureIndexes.push(featureIndex); + multiFeatureIndexes.push(multiFeatureIndex); + geometryIndexes.push(geometryIndex); + segmentIndexes.push(segmentIndex); + total++; + }); + t.equal(total, 10, 'total'); + t.deepEqual(featureIndexes, [1, 1, 2, 2, 2, 2, 4, 4, 4, 4], 'segmentEach.featureIndex'); + t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 1, 1], 'segmentEach.multiFeatureIndex'); + t.deepEqual(geometryIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'segmentEach.geometryIndex'); + t.deepEqual(segmentIndexes, [0, 1, 0, 1, 2, 3, 0, 1, 0, 1], 'segmentEach.segmentIndex'); + t.end(); +}); + +test('segmentReduce -- index & subIndex', t => { + const featureIndexes = []; + const multiFeatureIndexes = []; + const geometryIndexes = []; + const segmentIndexes = []; + let total = 0; + + meta.segmentReduce(geojsonSegments, (previousValue, segment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) => { + featureIndexes.push(featureIndex); + multiFeatureIndexes.push(multiFeatureIndex); + geometryIndexes.push(geometryIndex); + segmentIndexes.push(segmentIndex); + total++; + }); + t.equal(total, 9, 'total'); + t.deepEqual(featureIndexes, [1, 2, 2, 2, 2, 4, 4, 4, 4], 'segmentReduce.featureIndex'); + t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 0, 0, 1, 1], 'segmentReduce.multiFeatureIndex'); + t.deepEqual(geometryIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0], 'segmentReduce.geometryIndex'); + t.deepEqual(segmentIndexes, [1, 0, 1, 2, 3, 0, 1, 0, 1], 'segmentReduce.segmentIndex'); + t.end(); +}); + +test('lineEach -- lineString', t => { + const line = lineString([[0, 0], [2, 2], [4, 4]]); + const featureIndexes = []; + const multiFeatureIndexes = []; + const lineIndexes = []; + let total = 0; + + meta.lineEach(line, (currentLine, featureIndex, multiFeatureIndex, lineIndex) => { + featureIndexes.push(featureIndex); + multiFeatureIndexes.push(multiFeatureIndex); + lineIndexes.push(lineIndex); + total++; + }); + t.equal(total, 1, 'total'); + t.deepEqual(featureIndexes, [0], 'featureIndex'); + t.deepEqual(multiFeatureIndexes, [0], 'multiFeatureIndex'); + t.deepEqual(lineIndexes, [0], 'lineIndex'); + t.end(); +}); + +test('lineEach -- multiLineString', t => { + const multiLine = multiLineString([ + [[0, 0], [2, 2], [4, 4]], + [[1, 1], [3, 3], [5, 5]] + ]); + const featureIndexes = []; + const multiFeatureIndexes = []; + const lineIndexes = []; + let total = 0; + + meta.lineEach(multiLine, (currentLine, featureIndex, multiFeatureIndex, lineIndex) => { + featureIndexes.push(featureIndex); + multiFeatureIndexes.push(multiFeatureIndex); + lineIndexes.push(lineIndex); + total++; + }); + t.equal(total, 2, 'total'); + t.deepEqual(featureIndexes, [0, 0], 'featureIndex'); + t.deepEqual(multiFeatureIndexes, [0, 1], 'multiFeatureIndex'); + t.deepEqual(lineIndexes, [0, 0], 'lineIndex'); + t.end(); +}); + +test('lineEach -- multiPolygon', t => { + const multiPoly = multiPolygon([ + [ + [[12, 48], [2, 41], [24, 38], [12, 48]], // outer + [[9, 44], [13, 41], [13, 45], [9, 44]] // inner + ], + [ + [[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]] // outer + ] + ]); + const featureIndexes = []; + const multiFeatureIndexes = []; + const lineIndexes = []; + let total = 0; + + meta.lineEach(multiPoly, (currentLine, featureIndex, multiFeatureIndex, lineIndex) => { + featureIndexes.push(featureIndex); + multiFeatureIndexes.push(multiFeatureIndex); + lineIndexes.push(lineIndex); + total++; + }); + t.equal(total, 3, 'total'); + t.deepEqual(featureIndexes, [0, 0, 0], 'featureIndex'); + t.deepEqual(multiFeatureIndexes, [0, 0, 1], 'multiFeatureIndex'); + t.deepEqual(lineIndexes, [0, 1, 0], 'lineIndex'); + t.end(); +}); + +test('lineEach -- featureCollection', t => { + const line = lineString([[0, 0], [2, 2], [4, 4]]); + const multiLine = multiLineString([ + [[0, 0], [2, 2], [4, 4]], + [[1, 1], [3, 3], [5, 5]] + ]); + const multiPoly = multiPolygon([ + [ + [[12, 48], [2, 41], [24, 38], [12, 48]], // outer + [[9, 44], [13, 41], [13, 45], [9, 44]] // inner + ], + [ + [[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]] // outer + ] + ]); + const featureIndexes = []; + const multiFeatureIndexes = []; + const lineIndexes = []; + let total = 0; + + meta.lineEach(featureCollection([line, multiLine, multiPoly]), (currentLine, featureIndex, multiFeatureIndex, lineIndex) => { + featureIndexes.push(featureIndex); + multiFeatureIndexes.push(multiFeatureIndex); + lineIndexes.push(lineIndex); + total++; + }); + t.equal(total, 6, 'total'); + t.deepEqual(featureIndexes, [0, 1, 1, 2, 2, 2], 'featureIndex'); + t.deepEqual(multiFeatureIndexes, [0, 0, 1, 0, 0, 1], 'multiFeatureIndex'); + t.deepEqual(lineIndexes, [0, 0, 0, 0, 1, 0], 'lineIndex'); + t.end(); +}); + +test('lineReduce -- multiLineString', t => { + const multiLine = multiLineString([ + [[0, 0], [2, 2], [4, 4]], + [[1, 1], [3, 3], [5, 5]] + ]); + + const total = meta.lineReduce(multiLine, previousValue => { + previousValue++; + return previousValue; + }, 0); + + t.equal(total, 2, 'total'); + t.end(); +}); + +test('lineReduce -- multiPolygon', t => { + const multiPoly = multiPolygon([ + [ + [[12, 48], [2, 41], [24, 38], [12, 48]], // outer + [[9, 44], [13, 41], [13, 45], [9, 44]]], // inner + [ + [[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]] // outer + ] + ]); + + const total = meta.lineReduce(multiPoly, previousValue => { + previousValue++; + return previousValue; + }, 0); + + t.equal(total, 3, 'total'); + t.end(); +}); + +test('lineEach & lineReduce -- assert', t => { + const pt = point([0, 0]); + const multiPt = multiPoint([[0, 0], [10, 10]]); + meta.lineEach(pt, () => {}); // Point geometry is supported + meta.lineEach(multiPt, () => {}); // MultiPoint geometry is supported + meta.lineReduce(pt, () => {}); // Point geometry is supported + meta.lineReduce(multiPt, () => {}); // MultiPoint geometry is supported + meta.lineReduce(geomCollection, () => {}); // GeometryCollection is is supported + meta.lineReduce(featureCollection([lineString([[10, 10], [0, 0]])]), () => {}); // FeatureCollection is is supported + meta.lineReduce(feature(null), () => {}); // Feature with null geometry is supported + t.end(); +}); + +test('geomEach -- callback BBox & Id', t => { + const properties = {foo: 'bar'}; + const bbox = [0, 0, 0, 0]; + const id = 'foo'; + const pt = point([0, 0], properties, {bbox, id}); + + meta.geomEach(pt, (currentGeometry, featureIndex, currentProperties, currentBBox, currentId) => { + t.equal(featureIndex, 0, 'featureIndex'); + t.deepEqual(currentProperties, properties, 'currentProperties'); + t.deepEqual(currentBBox, bbox, 'currentBBox'); + t.deepEqual(currentId, id, 'currentId'); + }); + t.end(); +}); + +test('lineEach -- callback BBox & Id', t => { + const properties = {foo: 'bar'}; + const bbox = [0, 0, 10, 10]; + const id = 'foo'; + const line = lineString([[0, 0], [10, 10]], properties, {bbox, id}); + + meta.lineEach(line, (currentLine, featureIndex) => { + t.equal(featureIndex, 0, 'featureIndex'); + t.deepEqual(currentLine.properties, properties, 'currentProperties'); + t.deepEqual(currentLine.bbox, bbox, 'currentBBox'); + t.deepEqual(currentLine.id, id, 'currentId'); + }); + t.end(); +}); + +test('lineEach -- return lineString', t => { + const properties = {foo: 'bar'}; + const bbox = [0, 0, 10, 10]; + const id = 'foo'; + const line = lineString([[0, 0], [10, 10]], properties, {bbox, id}); + + meta.lineEach(line, (currentLine) => { + t.deepEqual(line, currentLine, 'return itself'); + }); + t.end(); +}); + + +test('meta.coordEach -- indexes -- PolygonWithHole', t => { + const coordIndexes = []; + const featureIndexes = []; + const multiFeatureIndexes = []; + const geometryIndexes = []; + + meta.coordEach(polyWithHole, (coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) => { + coordIndexes.push(coordIndex) + featureIndexes.push(featureIndex) + multiFeatureIndexes.push(multiFeatureIndex) + geometryIndexes.push(geometryIndex) + }); + t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); + t.deepEqual(featureIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + t.deepEqual(geometryIndexes, [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]); + t.end(); +}); + +test('meta.lineEach -- indexes -- PolygonWithHole', t => { + const featureIndexes = []; + const multiFeatureIndexes = []; + const geometryIndexes = []; + + meta.lineEach(polyWithHole, (line, featureIndex, multiFeatureIndex, geometryIndex) => { + featureIndexes.push(featureIndex) + multiFeatureIndexes.push(multiFeatureIndex) + geometryIndexes.push(geometryIndex) + }); + t.deepEqual(featureIndexes, [0, 0]); + t.deepEqual(multiFeatureIndexes, [0, 0]); + t.deepEqual(geometryIndexes, [0, 1]); + t.end(); +}); + +test('meta.segmentEach -- indexes -- PolygonWithHole', t => { + const featureIndexes = []; + const multiFeatureIndexes = []; + const geometryIndexes = []; + const segmentIndexes = []; + + meta.segmentEach(polyWithHole, (segment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) => { + featureIndexes.push(featureIndex); + multiFeatureIndexes.push(multiFeatureIndex); + geometryIndexes.push(geometryIndex); + segmentIndexes.push(segmentIndex); + }); + + t.deepEqual(featureIndexes, [0, 0, 0, 0, 0, 0, 0, 0]); + t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 0, 0, 0]); + t.deepEqual(geometryIndexes, [0, 0, 0, 0, 1, 1, 1, 1]); + t.deepEqual(segmentIndexes, [0, 1, 2, 3, 0, 1, 2, 3]); + t.end(); +}); + +test('meta.coordEach -- indexes -- Multi-Polygon with hole', t => { + const featureIndexes = []; + const multiFeatureIndexes = []; + const geometryIndexes = []; + const coordIndexes = []; + + // MultiPolygon with hole + // ====================== + // FeatureIndex => 0 + const multiPolyWithHole = multiPolygon([ + // Polygon 1 + // --------- + // MultiFeature Index => 0 + [ + // Outer Ring + // ---------- + // Geometry Index => 0 + // Coord Index => [0, 1, 2, 3, 4] (Major Release Change v6.x) + [[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]] + ], + // Polygon 2 with Hole + // ------------------- + // MultiFeature Index => 1 + [ + // Outer Ring + // ---------- + // Geometry Index => 0 + // Coord Index => [0, 1, 2, 3, 4] (Major Release Change v6.x) + [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], + + // Inner Ring + // ---------- + // Geometry Index => 1 + // Coord Index => [0, 1, 2, 3, 4] (Major Release Change v6.x) + [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]] + ] + ]); + + meta.coordEach(multiPolyWithHole, (coord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) => { + featureIndexes.push(featureIndex); + multiFeatureIndexes.push(multiFeatureIndex); + geometryIndexes.push(geometryIndex); + coordIndexes.push(coordIndex); + }); + + t.deepEqual(featureIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]); + t.deepEqual(geometryIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1]); + t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]); + // Major Release Change v6.x + // t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4]); + t.end(); +}); + +test('meta.coordEach -- indexes -- Polygon with hole', t => { + const featureIndexes = []; + const multiFeatureIndexes = []; + const geometryIndexes = []; + const coordIndexes = []; + + // Polygon with Hole + // ================= + // Feature Index => 0 + const polyWithHole = polygon([ + // Outer Ring + // ---------- + // Geometry Index => 0 + // Coord Index => [0, 1, 2, 3, 4] (Major Release Change v6.x) + [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], + + // Inner Ring + // ---------- + // Geometry Index => 1 + // Coord Index => [0, 1, 2, 3, 4] (Major Release Change v6.x) + [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]] + ]); + + meta.coordEach(polyWithHole, (coord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) => { + featureIndexes.push(featureIndex); + multiFeatureIndexes.push(multiFeatureIndex); + geometryIndexes.push(geometryIndex); + coordIndexes.push(coordIndex); + }); + + t.deepEqual(featureIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + t.deepEqual(geometryIndexes, [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]); + t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); + // Major Release Change v6.x + // t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]); + t.end(); +}); + +test('meta.coordEach -- indexes -- FeatureCollection of LineString', t => { + const featureIndexes = []; + const multiFeatureIndexes = []; + const geometryIndexes = []; + const coordIndexes = []; + + // FeatureCollection of LineStrings + const line = lineStrings([ + // LineString 1 + // Feature Index => 0 + // Geometry Index => 0 + // Coord Index => [0, 1, 2, 3, 4] (Major Release Change v6.x) + [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], + + // LineString 2 + // Feature Index => 1 + // Geometry Index => 0 + // Coord Index => [0, 1, 2, 3, 4] (Major Release Change v6.x) + [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]] + ]); + + meta.coordEach(line, (coord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) => { + featureIndexes.push(featureIndex); + multiFeatureIndexes.push(multiFeatureIndex); + geometryIndexes.push(geometryIndex); + coordIndexes.push(coordIndex); + }); + + t.deepEqual(featureIndexes, [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]); + t.deepEqual(multiFeatureIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + t.deepEqual(geometryIndexes, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); + // Major Release Change v6.x + // t.deepEqual(coordIndexes, [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]); + t.end(); +}); + + +test('meta -- breaking of iterations', t => { + const lines = lineStrings([ + [[10, 10], [50, 30], [30, 40]], + [[-10, -10], [-50, -30], [-30, -40]] + ]); + const multiLine = multiLineString([ + [[10, 10], [50, 30], [30, 40]], + [[-10, -10], [-50, -30], [-30, -40]] + ]); + + // Each Iterators + // meta.segmentEach has been purposely excluded from this list + for (const func of [meta.coordEach, meta.featureEach, meta.flattenEach, meta.geomEach, meta.lineEach, meta.propEach, meta.segmentEach]) { + // Meta Each function should only a value of 1 after returning `false` + + // FeatureCollection + let count = 0; + func(lines, () => { + count += 1; + return false; + }); + t.equal(count, 1, func.name); + + // Multi Geometry + let multiCount = 0; + func(multiLine, () => { + multiCount += 1; + return false; + }); + t.equal(multiCount, 1, func.name); + } + t.end(); +}); + +test('meta -- findSegment', t => { + const nullFeature = feature(null); + const pt = point([10, 10]); + const line = lineString([[10, 10], [50, 30], [30, 40]]); + const poly = polygon([ + [[10, 10], [50, 30], [30, 40], [10, 10]], + [[-10, -10], [-50, -30], [-30, -40], [-10, -10]] + ]); + const multiLine = multiLineString([ + [[10, 10], [50, 30], [30, 40]], + [[-10, -10], [-50, -30], [-30, -40]] + ]); + const lines = lineStrings([ + [[10, 10], [50, 30], [30, 40], [10, 10]], + [[-10, -10], [-50, -30], [-30, -40], [-10, -10]] + ]); + // firstSegment + t.deepEqual(meta.findSegment(nullFeature), null, 'findSegment (default) -- nullFeature') + t.deepEqual(meta.findSegment(pt), null, 'findSegment (default) -- pt') + t.deepEqual(meta.findSegment(line), lineString([[10, 10], [50, 30]]), 'findSegment (default) -- line') + t.deepEqual(meta.findSegment(poly), lineString([[10, 10], [50, 30]]), 'findSegment (default) -- poly') + t.deepEqual(meta.findSegment(multiLine), lineString([[10, 10], [50, 30]]), 'findSegment (default) -- multiLine') + t.deepEqual(meta.findSegment(lines), lineString([[10, 10], [50, 30]]), 'findSegment (default) -- lines') + + // lastSegment + t.deepEqual(meta.findSegment(nullFeature), null, 'findSegment (last) -- nullFeature') + t.deepEqual(meta.findSegment(pt), null, 'findSegment (last) -- pt') + t.deepEqual(meta.findSegment(line, {segmentIndex: -1}), lineString([[50, 30], [30, 40]]), 'findSegment (last) -- line') + t.deepEqual(meta.findSegment(poly, {segmentIndex: -1, geometryIndex: -1}), lineString([[-30, -40], [-10, -10]]), 'findSegment (last) -- poly') + t.deepEqual(meta.findSegment(multiLine, {segmentIndex: -1, multiFeatureIndex: -1}), lineString([[-50, -30], [-30, -40]]), 'findSegment (last) -- multiLine') + t.deepEqual(meta.findSegment(lines, {segmentIndex: -1, featureIndex: -1}), lineString([[-30, -40], [-10, -10]]), 'findSegment (last) -- lines') + t.end() +}) + +test('meta -- findPoint', t => { + const nullFeature = feature(null); + const pt = point([10, 10]); + const line = lineString([[10, 10], [50, 30], [30, 40]]); + const poly = polygon([ + [[10, 10], [50, 30], [30, 40], [10, 10]], + [[-10, -10], [-50, -30], [-30, -40], [-10, -10]] + ]); + const multiLine = multiLineString([ + [[10, 10], [50, 30], [30, 40]], + [[-10, -10], [-50, -30], [-30, -40]] + ]); + const lines = lineStrings([ + [[10, 10], [50, 30], [30, 40], [10, 10]], + [[-10, -10], [-50, -30], [-30, -40], [-10, -10]] + ]); + // firstPoint + t.deepEqual(meta.findPoint(nullFeature), null, 'findPoint (default) -- nullFeature') + t.deepEqual(meta.findPoint(pt), point([10, 10]), 'findPoint (default) -- pt') + t.deepEqual(meta.findPoint(line), point([10, 10]), 'findPoint (default) -- line') + t.deepEqual(meta.findPoint(poly), point([10, 10]), 'findPoint (default) -- poly') + t.deepEqual(meta.findPoint(multiLine), point([10, 10]), 'findPoint (default) -- multiLine') + t.deepEqual(meta.findPoint(lines), point([10, 10]), 'findPoint (default) -- lines') + + // lastPoint + t.deepEqual(meta.findPoint(nullFeature), null, 'findPoint (last) -- nullFeature') + t.deepEqual(meta.findPoint(pt), point([10, 10]), 'findPoint (last) -- pt') + t.deepEqual(meta.findPoint(line, {coordIndex: -1}), point([30, 40]), 'findPoint (last) -- line') + t.deepEqual(meta.findPoint(poly, {coordIndex: -1, geometryIndex: -1}), point([-10, -10]), 'findPoint (last) -- poly') + t.deepEqual(meta.findPoint(multiLine, {coordIndex: -1, multiFeatureIndex: -1}), point([-30, -40]), 'findPoint (last) -- multiLine') + t.deepEqual(meta.findPoint(lines, {coordIndex: -1, featureIndex: -1}), point([-10, -10]), 'findPoint (last) -- lines') + t.end() +}) + +test('meta -- segmentEach -- Issue #1273', t => { + // https://github.com/Turfjs/turf/issues/1273 + const poly = polygon([ + // Outer Ring + // Segment = 0 + // Geometries = 0,1,2 + [[10, 10], [50, 30], [30, 40], [10, 10]], + // Inner Ring + // Segment => 1 + // Geometries => 0,1,2 + [[-10, -10], [-50, -30], [-30, -40], [-10, -10]] + ]); + const segmentIndexes = []; + const geometryIndexes = []; + meta.segmentEach(poly, (line, featureIndex, multiFeatureIndex, segmentIndex, geometryIndex) => { + segmentIndexes.push(segmentIndex); + geometryIndexes.push(geometryIndex); + }); + t.deepEqual(segmentIndexes, [0, 0, 0, 1, 1, 1]); + t.deepEqual(geometryIndexes, [0, 1, 2, 0, 1, 2]); + t.end(); +}); diff --git a/src/midpoint/bench.js b/src/midpoint/bench.js new file mode 100644 index 0000000000..d000344e49 --- /dev/null +++ b/src/midpoint/bench.js @@ -0,0 +1,16 @@ +import fs from 'fs'; +import Benchmark from 'benchmark'; +import { point } from '../helpers'; +import midpoint from './'; + +var pt1 = point([0,0]); +var pt2 = point([10,0]); + +new Benchmark.Suite('turf-midpoint') +.add('turf-midpoint',function () { + midpoint(pt1, pt2); +}) +.on('cycle', function (event) { + console.log(String(event.target)); +}) +.run(); \ No newline at end of file diff --git a/src/midpoint/index.d.ts b/src/midpoint/index.d.ts new file mode 100644 index 0000000000..19475a4182 --- /dev/null +++ b/src/midpoint/index.d.ts @@ -0,0 +1,9 @@ +import { Feature, Point, Coord } from '../helpers' + +/** + * http://turfjs.org/docs/#midpoint + */ +export default function midpoint( + point1: Coord, + point2: Coord +): Feature; \ No newline at end of file diff --git a/src/midpoint/index.js b/src/midpoint/index.js new file mode 100644 index 0000000000..ff2f143936 --- /dev/null +++ b/src/midpoint/index.js @@ -0,0 +1,31 @@ +import bearing from '../bearing'; +import destination from '../destination'; +import distance from '../distance'; + +/** + * Takes two {@link Point|points} and returns a point midway between them. + * The midpoint is calculated geodesically, meaning the curvature of the earth is taken into account. + * + * @name midpoint + * @param {Coord} point1 first point + * @param {Coord} point2 second point + * @returns {Feature} a point midway between `pt1` and `pt2` + * @example + * var point1 = turf.point([144.834823, -37.771257]); + * var point2 = turf.point([145.14244, -37.830937]); + * + * var midpoint = turf.midpoint(point1, point2); + * + * //addToMap + * var addToMap = [point1, point2, midpoint]; + * midpoint.properties['marker-color'] = '#f00'; + */ +function midpoint(point1, point2) { + var dist = distance(point1, point2); + var heading = bearing(point1, point2); + var midpoint = destination(point1, dist / 2, heading); + + return midpoint; +} + +export default midpoint; diff --git a/src/midpoint/test.js b/src/midpoint/test.js new file mode 100644 index 0000000000..53031b2429 --- /dev/null +++ b/src/midpoint/test.js @@ -0,0 +1,70 @@ +import test from 'tape'; +import midpoint from '.'; +import distance from '../distance'; +import { point } from '../helpers'; + +test('midpoint -- horizontal equator', function (t) { + var pt1 = point([0, 0]); + var pt2 = point([10, 0]); + + var mid = midpoint(pt1, pt2); + + t.equal(distance(pt1, mid).toFixed(6), distance(pt2, mid).toFixed(6)); + + t.end(); +}); + +test('midpoint -- vertical from equator', function (t) { + var pt1 = point([0, 0]); + var pt2 = point([0, 10]); + + var mid = midpoint(pt1, pt2); + + t.equal(distance(pt1, mid).toFixed(6), distance(pt2, mid).toFixed(6)); + + t.end(); +}); + +test('midpoint -- vertical to equator', function (t) { + var pt1 = point([0, 10]); + var pt2 = point([0, 0]); + + var mid = midpoint(pt1, pt2); + + t.equal(distance(pt1, mid).toFixed(6), distance(pt2, mid).toFixed(6)); + + t.end(); +}); + +test('midpoint -- diagonal back over equator', function (t) { + var pt1 = point([-1, 10]); + var pt2 = point([1, -1]); + + var mid = midpoint(pt1, pt2); + + t.equal(distance(pt1, mid).toFixed(6), distance(pt2, mid).toFixed(6)); + + t.end(); +}); + +test('midpoint -- diagonal forward over equator', function (t) { + var pt1 = point([-5, -1]); + var pt2 = point([5, 10]); + + var mid = midpoint(pt1, pt2); + + t.equal(distance(pt1, mid).toFixed(6), distance(pt2, mid).toFixed(6)); + + t.end(); +}); + +test('midpoint -- long distance', function (t) { + var pt1 = point([22.5, 21.94304553343818]); + var pt2 = point([92.10937499999999, 46.800059446787316]); + + var mid = midpoint(pt1, pt2); + + t.equal(distance(pt1, mid).toFixed(6), distance(pt2, mid).toFixed(6)); + + t.end(); +}); diff --git a/packages/turf-moran-index/bench.js b/src/moran-index/bench.js similarity index 100% rename from packages/turf-moran-index/bench.js rename to src/moran-index/bench.js diff --git a/src/moran-index/index.d.ts b/src/moran-index/index.d.ts new file mode 100644 index 0000000000..85cbd9b3f5 --- /dev/null +++ b/src/moran-index/index.d.ts @@ -0,0 +1,56 @@ +import { FeatureCollection } from "../helpers"; +/** + * Moran's I measures patterns of attribute values associated with features. + * The method reveal whether similar values tend to occur near each other, + * or whether high or low values are interspersed. + * + * Moran's I > 0 means a clusterd pattern. + * Moran's I < 0 means a dispersed pattern. + * Moran's I = 0 means a random pattern. + * + * In order to test the significance of the result. The z score is calculated. + * A positive enough z-score (ex. >1.96) indicates clustering, + * while a negative enough z-score (ex. <-1.96) indicates a dispersed pattern. + * + * the z-score can be calculated based on a normal or random assumption. + * + * **Bibliography*** + * + * 1. [Moran's I](https://en.wikipedia.org/wiki/Moran%27s_I) + * + * 2. [pysal](http://pysal.readthedocs.io/en/latest/index.html) + * + * 3. Andy Mitchell, The ESRI Guide to GIS Analysis Volume 2: Spatial Measurements & Statistics. + * + * @name moranIndex + * @param {FeatureCollection} fc + * @param {Object} options + * @param {string} options.inputField the property name, must contain numeric values + * @param {number} [options.threshold=100000] the distance threshold + * @param {number} [options.p=2] the Minkowski p-norm distance parameter + * @param {boolean} [options.binary=false] whether transfrom the distance to binary + * @param {number} [options.alpha=-1] the distance decay parameter + * @param {boolean} [options.standardization=true] wheter row standardization the distance + * @returns {MoranIndex} + * @example + * + * const bbox = [-65, 40, -63, 42]; + * const dataset = turf.randomPoint(100, { bbox: bbox }); + * + * const result = turf.moranIndex(dataset, { + * inputField: 'CRIME', + * }); + */ +export default function (fc: FeatureCollection, options: { + inputField: string; + threshold?: number; + p?: number; + binary?: boolean; + alpha?: number; + standardization?: boolean; +}): { + moranIndex: number; + expectedMoranIndex: number; + stdNorm: number; + zNorm: number; +}; diff --git a/src/moran-index/index.js b/src/moran-index/index.js new file mode 100644 index 0000000000..6746427a21 --- /dev/null +++ b/src/moran-index/index.js @@ -0,0 +1,142 @@ +import spatialWeight from "../distance-weight"; +import { featureEach } from "../meta"; + +/** + * Moran's I measures patterns of attribute values associated with features. + * The method reveal whether similar values tend to occur near each other, + * or whether high or low values are interspersed. + * + * Moran's I > 0 means a clusterd pattern. + * Moran's I < 0 means a dispersed pattern. + * Moran's I = 0 means a random pattern. + * + * In order to test the significance of the result. The z score is calculated. + * A positive enough z-score (ex. >1.96) indicates clustering, + * while a negative enough z-score (ex. <-1.96) indicates a dispersed pattern. + * + * the z-score can be calculated based on a normal or random assumption. + * + * **Bibliography*** + * + * 1. [Moran's I](https://en.wikipedia.org/wiki/Moran%27s_I) + * + * 2. [pysal](http://pysal.readthedocs.io/en/latest/index.html) + * + * 3. Andy Mitchell, The ESRI Guide to GIS Analysis Volume 2: Spatial Measurements & Statistics. + * + * @name moranIndex + * @param {FeatureCollection} fc + * @param {Object} options + * @param {string} options.inputField the property name, must contain numeric values + * @param {number} [options.threshold=100000] the distance threshold + * @param {number} [options.p=2] the Minkowski p-norm distance parameter + * @param {boolean} [options.binary=false] whether transfrom the distance to binary + * @param {number} [options.alpha=-1] the distance decay parameter + * @param {boolean} [options.standardization=true] wheter row standardization the distance + * @returns {MoranIndex} + * @example + * + * const bbox = [-65, 40, -63, 42]; + * const dataset = turf.randomPoint(100, { bbox: bbox }); + * + * const result = turf.moranIndex(dataset, { + * inputField: 'CRIME', + * }); + */ + +export default function(fc, options){ + + const inputField = options.inputField; + const threshold = options.threshold || 100000; + const p = options.p || 2; + const binary = options.binary || false; + const alpha = options.alpha || -1; + const standardization = options.standardization || true; + + const weight = spatialWeight(fc, { + alpha, + binary, + p, + standardization, + threshold, + }); + + const y = []; + featureEach(fc, function (feature) { + const feaProperties = feature.properties || {}; + // validate inputField exists + y.push(feaProperties[inputField]); + }); + + const yMean = mean(y); + const yVar = variance(y); + let weightSum = 0; + let s0 = 0; + let s1 = 0; + let s2 = 0; + const n = weight.length; + // validate y.length is the same as weight.length + for (let i = 0; i < n; i++) { + let subS2 = 0; + for (let j = 0; j < n; j++) { + weightSum += weight[i][j] * (y[i] - yMean) * (y[j] - yMean); + s0 += weight[i][j]; + s1 += Math.pow((weight[i][j] + weight[j][i]), 2); + subS2 += weight[i][j] + weight[j][i]; + } + s2 += Math.pow(subS2, 2); + } + s1 = 0.5 * s1; + + const moranIndex = weightSum / s0 / yVar; + const expectedMoranIndex = -1 / (n - 1); + const vNum = (n * n) * s1 - n * s2 + 3 * (s0 * s0); + const vDen = (n - 1) * (n + 1) * (s0 * s0); + const vNorm = vNum / vDen - (expectedMoranIndex * expectedMoranIndex); + const stdNorm = Math.sqrt(vNorm); + const zNorm = (moranIndex - expectedMoranIndex) / stdNorm; + + return { + expectedMoranIndex, + moranIndex, + stdNorm, + zNorm, + }; + +} + +/** + * get mean of a list + * @param {number[]} y + * @returns {number} + * + */ +function mean(y) { + let sum = 0; + for (const item of y) { + sum += item; + } + return sum / y.length; +} +/** + * get variance of a list + * @param {number[]} y + * @returns {number} + * + */ +function variance(y) { + const yMean = mean(y); + let sum = 0; + for (const item of y) { + sum += Math.pow(item - yMean, 2); + } + return sum / y.length; +} + +/** + * @typedef {Object} MoranIndex + * @property {number} moranIndex the moran's Index of the observed feature set + * @property {number} expectedMoranIndex the moran's Index of the random distribution + * @property {number} stdNorm the standard devitaion of the random distribution + * @property {number} zNorm the z-score of the observe samples with regard to the random distribution + */ diff --git a/src/moran-index/test.js b/src/moran-index/test.js new file mode 100644 index 0000000000..3d2a5a3b43 --- /dev/null +++ b/src/moran-index/test.js @@ -0,0 +1,36 @@ +const test = require('tape'); +const fs = require('fs'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { featureCollection } = require('../helpers'); +const { featureEach } = require('../meta'); + +const moranIndex = require('.').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('moran-index', t => { + for (const {filename, name, geojson} of fixtures) { + + const results = moranIndex(geojson, { + inputField: 'CRIME', + }); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEquals(results, load.sync(directories.out + filename), name); + + }; + t.end(); +}); diff --git a/packages/turf-moran-index/test/in/columbus.json b/src/moran-index/test/in/columbus.json similarity index 100% rename from packages/turf-moran-index/test/in/columbus.json rename to src/moran-index/test/in/columbus.json diff --git a/packages/turf-moran-index/test/in/point.json b/src/moran-index/test/in/point.json similarity index 100% rename from packages/turf-moran-index/test/in/point.json rename to src/moran-index/test/in/point.json diff --git a/src/moran-index/test/out/columbus.json b/src/moran-index/test/out/columbus.json new file mode 100644 index 0000000000..dc9f2fd9fa --- /dev/null +++ b/src/moran-index/test/out/columbus.json @@ -0,0 +1,6 @@ +{ + "expectedMoranIndex": -0.020833333333333332, + "moranIndex": 0.14834323679862615, + "stdNorm": 0.023841569242427897, + "zNorm": 7.0958655620241995 +} diff --git a/src/moran-index/test/out/point.json b/src/moran-index/test/out/point.json new file mode 100644 index 0000000000..5baa0cfecd --- /dev/null +++ b/src/moran-index/test/out/point.json @@ -0,0 +1,6 @@ +{ + "expectedMoranIndex": -0.020833333333333332, + "moranIndex": 0.15665417693293948, + "stdNorm": 0.022208244679327364, + "zNorm": 7.991964823383264 +} diff --git a/packages/turf-nearest-neighbor-analysis/bench.js b/src/nearest-neighbor-analysis/bench.js similarity index 100% rename from packages/turf-nearest-neighbor-analysis/bench.js rename to src/nearest-neighbor-analysis/bench.js diff --git a/src/nearest-neighbor-analysis/index.d.ts b/src/nearest-neighbor-analysis/index.d.ts new file mode 100644 index 0000000000..bac6aa98ff --- /dev/null +++ b/src/nearest-neighbor-analysis/index.d.ts @@ -0,0 +1,72 @@ +import { FeatureCollection, Feature, Polygon, Units, Properties } from '../helpers'; +export interface NearestNeighborStatistics { + units: Units; + arealUnits: string; + observedMeanDistance: number; + expectedMeanDistance: number; + numberOfPoints: number; + zScore: number; +} +export interface NearestNeighborStudyArea extends Feature { + properties: { + nearestNeighborAnalysis: NearestNeighborStatistics; + [key: string]: any; + }; +} +/** + * Nearest Neighbor Analysis calculates an index based the average distances + * between points in the dataset, thereby providing inference as to whether the + * data is clustered, dispersed, or randomly distributed within the study area. + * + * It returns a {@link Feature} of the study area, with the results of + * the analysis attached as part of of the `nearestNeighborAnalysis` property + * of the study area's `properties`. The attached + * [_z_-score](https://en.wikipedia.org/wiki/Standard_score) indicates how many + * standard deviations above or below the expected mean distance the data's + * observed mean distance is. The more negative, the more clustered. The more + * positive, the more evenly dispersed. A _z_-score between -2 and 2 indicates + * a seemingly random distribution. That is, within _p_ of less than 0.05, the + * distribution appears statistically significantly neither clustered nor + * dispersed. + * + * **Remarks** + * + * - Though the analysis will work on any {@link FeatureCollection} type, it + * works best with {@link Point} collections. + * + * - This analysis is _very_ sensitive to the study area provided. + * If no {@link Feature} is passed as the study area, the function draws a box + * around the data, which may distort the findings. This analysis works best + * with a bounded area of interest within with the data is either clustered, + * dispersed, or randomly distributed. For example, a city's subway stops may + * look extremely clustered if the study area is an entire state. On the other + * hand, they may look rather evenly dispersed if the study area is limited to + * the city's downtown. + * + * **Bibliography** + * + * Philip J. Clark and Francis C. Evans, “Distance to Nearest Neighbor as a + * Measure of Spatial Relationships in Populations,” _Ecology_ 35, no. 4 + * (1954): 445–453, doi:[10.2307/1931034](http://doi.org/10.2307/1931034). + * + * @name nearestNeighborAnalysis + * @param {FeatureCollection} dataset FeatureCollection (pref. of points) to study + * @param {Object} [options={}] Optional parameters + * @param {Feature} [options.studyArea] polygon representing the study area + * @param {string} [options.units='kilometers'] unit of measurement for distances and, squared, area. + * @param {Object} [options.properties={}] properties + * @returns {Feature} A polygon of the study area or an approximation of one. + * @example + * var bbox = [-65, 40, -63, 42]; + * var dataset = turf.randomPoint(100, { bbox: bbox }); + * var nearestNeighborStudyArea = turf.nearestNeighborAnalysis(dataset); + * + * //addToMap + * var addToMap = [dataset, nearestNeighborStudyArea]; + */ +declare function nearestNeighborAnalysis(dataset: FeatureCollection, options?: { + studyArea?: Feature; + units?: Units; + properties?: Properties; +}): NearestNeighborStudyArea; +export default nearestNeighborAnalysis; diff --git a/src/nearest-neighbor-analysis/index.js b/src/nearest-neighbor-analysis/index.js new file mode 100644 index 0000000000..72e2a15e2f --- /dev/null +++ b/src/nearest-neighbor-analysis/index.js @@ -0,0 +1,99 @@ +import area from '../area'; +import bbox from '../bbox'; +import bboxPolygon from '../bbox-polygon'; +import centroid from '../centroid'; +import distance from '../distance'; +import nearestPoint from '../nearest-point'; +import { featureEach } from '../meta'; +import { convertArea, featureCollection } from '../helpers'; + +/** + * Nearest Neighbor Analysis calculates an index based the average distances + * between points in the dataset, thereby providing inference as to whether the + * data is clustered, dispersed, or randomly distributed within the study area. + * + * It returns a {@link Feature} of the study area, with the results of + * the analysis attached as part of of the `nearestNeighborAnalysis` property + * of the study area's `properties`. The attached + * [_z_-score](https://en.wikipedia.org/wiki/Standard_score) indicates how many + * standard deviations above or below the expected mean distance the data's + * observed mean distance is. The more negative, the more clustered. The more + * positive, the more evenly dispersed. A _z_-score between -2 and 2 indicates + * a seemingly random distribution. That is, within _p_ of less than 0.05, the + * distribution appears statistically significantly neither clustered nor + * dispersed. + * + * **Remarks** + * + * - Though the analysis will work on any {@link FeatureCollection} type, it + * works best with {@link Point} collections. + * + * - This analysis is _very_ sensitive to the study area provided. + * If no {@link Feature} is passed as the study area, the function draws a box + * around the data, which may distort the findings. This analysis works best + * with a bounded area of interest within with the data is either clustered, + * dispersed, or randomly distributed. For example, a city's subway stops may + * look extremely clustered if the study area is an entire state. On the other + * hand, they may look rather evenly dispersed if the study area is limited to + * the city's downtown. + * + * **Bibliography** + * + * Philip J. Clark and Francis C. Evans, “Distance to Nearest Neighbor as a + * Measure of Spatial Relationships in Populations,” _Ecology_ 35, no. 4 + * (1954): 445–453, doi:[10.2307/1931034](http://doi.org/10.2307/1931034). + * + * @name nearestNeighborAnalysis + * @param {FeatureCollection} dataset FeatureCollection (pref. of points) to study + * @param {Object} [options={}] Optional parameters + * @param {Feature} [options.studyArea] polygon representing the study area + * @param {string} [options.units='kilometers'] unit of measurement for distances and, squared, area. + * @param {Object} [options.properties={}] properties + * @returns {Feature} A polygon of the study area or an approximation of one. + * @example + * var bbox = [-65, 40, -63, 42]; + * var dataset = turf.randomPoint(100, { bbox: bbox }); + * var nearestNeighborStudyArea = turf.nearestNeighborAnalysis(dataset); + * + * //addToMap + * var addToMap = [dataset, nearestNeighborStudyArea]; + */ +function nearestNeighborAnalysis(dataset, options) { + // Optional params + options = options || {}; + const studyArea = options.studyArea || bboxPolygon(bbox(dataset)); + const properties = options.properties || {}; + const units = options.units || 'kilometers'; + + const features = []; + featureEach(dataset, function (feature) { + features.push(centroid(feature)); + }); + const n = features.length; + const observedMeanDistance = features.map(function (feature, index) { + const otherFeatures = featureCollection(features.filter(function (f, i) { + return i !== index; + })); + // Have to add the ! to make typescript validation pass + // see https://stackoverflow.com/a/40350534/1979085 + return distance(feature, nearestPoint(feature, otherFeatures).geometry.coordinates, {units: units}); + }).reduce(function (sum, value) { return sum + value; }, 0) / n; + + const populationDensity = n / convertArea(area(studyArea), 'meters', units); + const expectedMeanDistance = 1 / (2 * Math.sqrt(populationDensity)); + const variance = 0.26136 / (Math.sqrt(n * populationDensity)); + properties.nearestNeighborAnalysis = { + units: units, + arealUnits: units + '²', + observedMeanDistance: observedMeanDistance, + expectedMeanDistance: expectedMeanDistance, + nearestNeighborIndex: observedMeanDistance / expectedMeanDistance, + numberOfPoints: n, + zScore: (observedMeanDistance - expectedMeanDistance) / variance, + }; + studyArea.properties = properties; + + return studyArea; +} + +export default nearestNeighborAnalysis; diff --git a/src/nearest-neighbor-analysis/test.js b/src/nearest-neighbor-analysis/test.js new file mode 100644 index 0000000000..b42c1fa0d2 --- /dev/null +++ b/src/nearest-neighbor-analysis/test.js @@ -0,0 +1,42 @@ +const test = require('tape'); +const fs = require('fs'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const truncate = require('../truncate').default; +const centroid = require('../centroid').default; +const { featureEach } = require('../meta'); +const { featureCollection } = require('../helpers'); +const nearestNeighborAnalysis = require('.').default; + + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-nearest-neighbor', t => { + for (const {filename, name, geojson} of fixtures) { + // Define params + const options = geojson.options; + const results = featureCollection([]); + featureEach(geojson, feature => results.features.push(truncate(feature))); + if (geojson.features[0].geometry.type === "Polygon") { + featureEach(geojson, feature => results.features.push(truncate(centroid(feature, {properties: {"marker-color": "#0a0"}})))); + } + results.features.push(truncate(nearestNeighborAnalysis(geojson, options))); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEquals(results, load.sync(directories.out + filename), name); + + }; + t.end(); +}); diff --git a/packages/turf-nearest-neighbor-analysis/test/in/brazil-states-bbox.json b/src/nearest-neighbor-analysis/test/in/brazil-states-bbox.json similarity index 100% rename from packages/turf-nearest-neighbor-analysis/test/in/brazil-states-bbox.json rename to src/nearest-neighbor-analysis/test/in/brazil-states-bbox.json diff --git a/packages/turf-nearest-neighbor-analysis/test/in/brazil-states-brazil-itself-as-study-area.json b/src/nearest-neighbor-analysis/test/in/brazil-states-brazil-itself-as-study-area.json similarity index 100% rename from packages/turf-nearest-neighbor-analysis/test/in/brazil-states-brazil-itself-as-study-area.json rename to src/nearest-neighbor-analysis/test/in/brazil-states-brazil-itself-as-study-area.json diff --git a/packages/turf-nearest-neighbor-analysis/test/in/random-large-study-area.json b/src/nearest-neighbor-analysis/test/in/random-large-study-area.json similarity index 100% rename from packages/turf-nearest-neighbor-analysis/test/in/random-large-study-area.json rename to src/nearest-neighbor-analysis/test/in/random-large-study-area.json diff --git a/packages/turf-nearest-neighbor-analysis/test/in/random-outlier.json b/src/nearest-neighbor-analysis/test/in/random-outlier.json similarity index 100% rename from packages/turf-nearest-neighbor-analysis/test/in/random-outlier.json rename to src/nearest-neighbor-analysis/test/in/random-outlier.json diff --git a/packages/turf-nearest-neighbor-analysis/test/in/random.json b/src/nearest-neighbor-analysis/test/in/random.json similarity index 100% rename from packages/turf-nearest-neighbor-analysis/test/in/random.json rename to src/nearest-neighbor-analysis/test/in/random.json diff --git a/packages/turf-nearest-neighbor-analysis/test/in/squares.json b/src/nearest-neighbor-analysis/test/in/squares.json similarity index 100% rename from packages/turf-nearest-neighbor-analysis/test/in/squares.json rename to src/nearest-neighbor-analysis/test/in/squares.json diff --git a/packages/turf-nearest-neighbor-analysis/test/out/brazil-states-bbox.json b/src/nearest-neighbor-analysis/test/out/brazil-states-bbox.json similarity index 95% rename from packages/turf-nearest-neighbor-analysis/test/out/brazil-states-bbox.json rename to src/nearest-neighbor-analysis/test/out/brazil-states-bbox.json index 7c86598204..95a61a3fdd 100644 --- a/packages/turf-nearest-neighbor-analysis/test/out/brazil-states-bbox.json +++ b/src/nearest-neighbor-analysis/test/out/brazil-states-bbox.json @@ -1306,8 +1306,8 @@ "geometry": { "type": "Point", "coordinates": [ - -71.16473, - -9.293904 + -70.711838, + -9.6667 ] } }, @@ -1319,8 +1319,8 @@ "geometry": { "type": "Point", "coordinates": [ - -65.424294, - -3.746817 + -64.895682, + -3.539922 ] } }, @@ -1332,8 +1332,8 @@ "geometry": { "type": "Point", "coordinates": [ - -61.285547, - 2.453608 + -61.034973, + 2.481296 ] } }, @@ -1345,8 +1345,8 @@ "geometry": { "type": "Point", "coordinates": [ - -54.422928, - -2.191542 + -54.04728, + -2.47827 ] } }, @@ -1358,8 +1358,8 @@ "geometry": { "type": "Point", "coordinates": [ - -52.344978, - 1.640776 + -51.93955, + 1.532991 ] } }, @@ -1371,8 +1371,8 @@ "geometry": { "type": "Point", "coordinates": [ - -45.302404, - -5.028014 + -45.204508, + -5.658899 ] } }, @@ -1384,8 +1384,8 @@ "geometry": { "type": "Point", "coordinates": [ - -43.040711, - -7.073743 + -43.190225, + -7.532436 ] } }, @@ -1397,8 +1397,8 @@ "geometry": { "type": "Point", "coordinates": [ - -39.514677, - -5.55507 + -39.369317, + -5.171595 ] } }, @@ -1410,8 +1410,8 @@ "geometry": { "type": "Point", "coordinates": [ - -36.807991, - -5.86253 + -36.481008, + -5.729062 ] } }, @@ -1423,8 +1423,8 @@ "geometry": { "type": "Point", "coordinates": [ - -36.41241, - -7.147744 + -36.701498, + -7.265543 ] } }, @@ -1436,8 +1436,8 @@ "geometry": { "type": "Point", "coordinates": [ - -38.00592, - -8.336776 + -38.37127, + -8.428198 ] } }, @@ -1449,8 +1449,8 @@ "geometry": { "type": "Point", "coordinates": [ - -36.960483, - -9.497112 + -36.559011, + -9.590558 ] } }, @@ -1462,8 +1462,8 @@ "geometry": { "type": "Point", "coordinates": [ - -37.136993, - -10.514637 + -37.375799, + -10.504254 ] } }, @@ -1475,8 +1475,8 @@ "geometry": { "type": "Point", "coordinates": [ - -41.385776, - -12.282741 + -41.611885, + -12.314066 ] } }, @@ -1488,8 +1488,8 @@ "geometry": { "type": "Point", "coordinates": [ - -47.76518, - -10.065892 + -47.69331, + -10.670411 ] } }, @@ -1501,8 +1501,8 @@ "geometry": { "type": "Point", "coordinates": [ - -63.448421, - -10.481181 + -63.02676, + -10.556168 ] } }, @@ -1514,8 +1514,8 @@ "geometry": { "type": "Point", "coordinates": [ - -57.510843, - -12.736578 + -57.236215, + -12.990613 ] } }, @@ -1527,8 +1527,8 @@ "geometry": { "type": "Point", "coordinates": [ - -54.874451, - -20.582591 + -54.533546, + -20.933879 ] } }, @@ -1540,8 +1540,8 @@ "geometry": { "type": "Point", "coordinates": [ - -47.675639, - -15.704011 + -47.78985, + -15.758002 ] } }, @@ -1553,8 +1553,8 @@ "geometry": { "type": "Point", "coordinates": [ - -48.883326, - -16.153424 + -48.723366, + -15.939895 ] } }, @@ -1566,8 +1566,8 @@ "geometry": { "type": "Point", "coordinates": [ - -46.210957, - -18.472785 + -45.869014, + -18.350761 ] } }, @@ -1579,8 +1579,8 @@ "geometry": { "type": "Point", "coordinates": [ - -40.580655, - -19.336643 + -40.573733, + -19.632901 ] } }, @@ -1592,8 +1592,8 @@ "geometry": { "type": "Point", "coordinates": [ - -42.491433, - -22.018389 + -42.755674, + -22.137708 ] } }, @@ -1605,8 +1605,8 @@ "geometry": { "type": "Point", "coordinates": [ - -47.848652, - -22.755909 + -48.227816, + -22.6959 ] } }, @@ -1618,8 +1618,8 @@ "geometry": { "type": "Point", "coordinates": [ - -50.681775, - -24.810943 + -50.990053, + -24.761505 ] } }, @@ -1631,8 +1631,8 @@ "geometry": { "type": "Point", "coordinates": [ - -51.304463, - -27.096132 + -50.980368, + -27.223693 ] } }, @@ -1644,8 +1644,8 @@ "geometry": { "type": "Point", "coordinates": [ - -53.199343, - -29.27135 + -53.104413, + -29.573196 ] } }, @@ -1664,11 +1664,11 @@ "nearestNeighborAnalysis": { "units": "kilometers", "arealUnits": "kilometers²", - "observedMeanDistance": 399.6743084940623, - "expectedMeanDistance": 406.77096141109115, - "nearestNeighborIndex": 0.982553688462887, + "observedMeanDistance": 397.83037100327755, + "expectedMeanDistance": 406.3163545616098, + "nearestNeighborIndex": 0.9791148363508821, "numberOfPoints": 27, - "zScore": -0.1734268709076832 + "zScore": -0.207611137308671 } }, "geometry": { diff --git a/packages/turf-nearest-neighbor-analysis/test/out/brazil-states-brazil-itself-as-study-area.json b/src/nearest-neighbor-analysis/test/out/brazil-states-brazil-itself-as-study-area.json similarity index 95% rename from packages/turf-nearest-neighbor-analysis/test/out/brazil-states-brazil-itself-as-study-area.json rename to src/nearest-neighbor-analysis/test/out/brazil-states-brazil-itself-as-study-area.json index da1bdba9fb..fa658aa067 100644 --- a/packages/turf-nearest-neighbor-analysis/test/out/brazil-states-brazil-itself-as-study-area.json +++ b/src/nearest-neighbor-analysis/test/out/brazil-states-brazil-itself-as-study-area.json @@ -1306,8 +1306,8 @@ "geometry": { "type": "Point", "coordinates": [ - -71.16473, - -9.293904 + -70.711838, + -9.6667 ] } }, @@ -1319,8 +1319,8 @@ "geometry": { "type": "Point", "coordinates": [ - -65.424294, - -3.746817 + -64.895682, + -3.539922 ] } }, @@ -1332,8 +1332,8 @@ "geometry": { "type": "Point", "coordinates": [ - -61.285547, - 2.453608 + -61.034973, + 2.481296 ] } }, @@ -1345,8 +1345,8 @@ "geometry": { "type": "Point", "coordinates": [ - -54.422928, - -2.191542 + -54.04728, + -2.47827 ] } }, @@ -1358,8 +1358,8 @@ "geometry": { "type": "Point", "coordinates": [ - -52.344978, - 1.640776 + -51.93955, + 1.532991 ] } }, @@ -1371,8 +1371,8 @@ "geometry": { "type": "Point", "coordinates": [ - -45.302404, - -5.028014 + -45.204508, + -5.658899 ] } }, @@ -1384,8 +1384,8 @@ "geometry": { "type": "Point", "coordinates": [ - -43.040711, - -7.073743 + -43.190225, + -7.532436 ] } }, @@ -1397,8 +1397,8 @@ "geometry": { "type": "Point", "coordinates": [ - -39.514677, - -5.55507 + -39.369317, + -5.171595 ] } }, @@ -1410,8 +1410,8 @@ "geometry": { "type": "Point", "coordinates": [ - -36.807991, - -5.86253 + -36.481008, + -5.729062 ] } }, @@ -1423,8 +1423,8 @@ "geometry": { "type": "Point", "coordinates": [ - -36.41241, - -7.147744 + -36.701498, + -7.265543 ] } }, @@ -1436,8 +1436,8 @@ "geometry": { "type": "Point", "coordinates": [ - -38.00592, - -8.336776 + -38.37127, + -8.428198 ] } }, @@ -1449,8 +1449,8 @@ "geometry": { "type": "Point", "coordinates": [ - -36.960483, - -9.497112 + -36.559011, + -9.590558 ] } }, @@ -1462,8 +1462,8 @@ "geometry": { "type": "Point", "coordinates": [ - -37.136993, - -10.514637 + -37.375799, + -10.504254 ] } }, @@ -1475,8 +1475,8 @@ "geometry": { "type": "Point", "coordinates": [ - -41.385776, - -12.282741 + -41.611885, + -12.314066 ] } }, @@ -1488,8 +1488,8 @@ "geometry": { "type": "Point", "coordinates": [ - -47.76518, - -10.065892 + -47.69331, + -10.670411 ] } }, @@ -1501,8 +1501,8 @@ "geometry": { "type": "Point", "coordinates": [ - -63.448421, - -10.481181 + -63.02676, + -10.556168 ] } }, @@ -1514,8 +1514,8 @@ "geometry": { "type": "Point", "coordinates": [ - -57.510843, - -12.736578 + -57.236215, + -12.990613 ] } }, @@ -1527,8 +1527,8 @@ "geometry": { "type": "Point", "coordinates": [ - -54.874451, - -20.582591 + -54.533546, + -20.933879 ] } }, @@ -1540,8 +1540,8 @@ "geometry": { "type": "Point", "coordinates": [ - -47.675639, - -15.704011 + -47.78985, + -15.758002 ] } }, @@ -1553,8 +1553,8 @@ "geometry": { "type": "Point", "coordinates": [ - -48.883326, - -16.153424 + -48.723366, + -15.939895 ] } }, @@ -1566,8 +1566,8 @@ "geometry": { "type": "Point", "coordinates": [ - -46.210957, - -18.472785 + -45.869014, + -18.350761 ] } }, @@ -1579,8 +1579,8 @@ "geometry": { "type": "Point", "coordinates": [ - -40.580655, - -19.336643 + -40.573733, + -19.632901 ] } }, @@ -1592,8 +1592,8 @@ "geometry": { "type": "Point", "coordinates": [ - -42.491433, - -22.018389 + -42.755674, + -22.137708 ] } }, @@ -1605,8 +1605,8 @@ "geometry": { "type": "Point", "coordinates": [ - -47.848652, - -22.755909 + -48.227816, + -22.6959 ] } }, @@ -1618,8 +1618,8 @@ "geometry": { "type": "Point", "coordinates": [ - -50.681775, - -24.810943 + -50.990053, + -24.761505 ] } }, @@ -1631,8 +1631,8 @@ "geometry": { "type": "Point", "coordinates": [ - -51.304463, - -27.096132 + -50.980368, + -27.223693 ] } }, @@ -1644,8 +1644,8 @@ "geometry": { "type": "Point", "coordinates": [ - -53.199343, - -29.27135 + -53.104413, + -29.573196 ] } }, @@ -1658,11 +1658,11 @@ "nearestNeighborAnalysis": { "units": "kilometers", "arealUnits": "kilometers²", - "observedMeanDistance": 399.6743084940623, - "expectedMeanDistance": 282.59626480707607, - "nearestNeighborIndex": 1.4142943777650903, + "observedMeanDistance": 397.83037100327755, + "expectedMeanDistance": 282.2804354834354, + "nearestNeighborIndex": 1.4093444709405756, "numberOfPoints": 27, - "zScore": 4.118336269394341 + "zScore": 4.069131206763539 } }, "geometry": { diff --git a/packages/turf-nearest-neighbor-analysis/test/out/random-large-study-area.json b/src/nearest-neighbor-analysis/test/out/random-large-study-area.json similarity index 99% rename from packages/turf-nearest-neighbor-analysis/test/out/random-large-study-area.json rename to src/nearest-neighbor-analysis/test/out/random-large-study-area.json index 960b1930e0..47f3179c63 100644 --- a/packages/turf-nearest-neighbor-analysis/test/out/random-large-study-area.json +++ b/src/nearest-neighbor-analysis/test/out/random-large-study-area.json @@ -1661,10 +1661,10 @@ "units": "kilometers", "arealUnits": "kilometers²", "observedMeanDistance": 1.6516270145942438, - "expectedMeanDistance": 25.489958462294293, - "nearestNeighborIndex": 0.06479520227690416, + "expectedMeanDistance": 25.461470908340697, + "nearestNeighborIndex": 0.06486769835646855, "numberOfPoints": 150, - "zScore": -21.912061518827862 + "zScore": -21.910362919163752 } }, "geometry": { diff --git a/packages/turf-nearest-neighbor-analysis/test/out/random-outlier.json b/src/nearest-neighbor-analysis/test/out/random-outlier.json similarity index 99% rename from packages/turf-nearest-neighbor-analysis/test/out/random-outlier.json rename to src/nearest-neighbor-analysis/test/out/random-outlier.json index ffffd1691f..46a739a4c2 100644 --- a/packages/turf-nearest-neighbor-analysis/test/out/random-outlier.json +++ b/src/nearest-neighbor-analysis/test/out/random-outlier.json @@ -1678,10 +1678,10 @@ "units": "kilometers", "arealUnits": "kilometers²", "observedMeanDistance": 7.363991103875287, - "expectedMeanDistance": 25.40541364652008, - "nearestNeighborIndex": 0.2898591302757227, + "expectedMeanDistance": 25.37702057977424, + "nearestNeighborIndex": 0.29018343901823007, "numberOfPoints": 151, - "zScore": -16.69413281037322 + "zScore": -16.68650889595032 } }, "geometry": { diff --git a/packages/turf-nearest-neighbor-analysis/test/out/random.json b/src/nearest-neighbor-analysis/test/out/random.json similarity index 99% rename from packages/turf-nearest-neighbor-analysis/test/out/random.json rename to src/nearest-neighbor-analysis/test/out/random.json index 9d20fb200c..8122907d48 100644 --- a/packages/turf-nearest-neighbor-analysis/test/out/random.json +++ b/src/nearest-neighbor-analysis/test/out/random.json @@ -1667,10 +1667,10 @@ "units": "kilometers", "arealUnits": "kilometers²", "observedMeanDistance": 1.6516270145942438, - "expectedMeanDistance": 1.5887228554425286, - "nearestNeighborIndex": 1.0395941676902443, + "expectedMeanDistance": 1.5869473002517003, + "nearestNeighborIndex": 1.0407573171032742, "numberOfPoints": 150, - "zScore": 0.9277003714349029 + "zScore": 0.9549532272328554 } }, "geometry": { diff --git a/src/nearest-neighbor-analysis/test/out/squares.json b/src/nearest-neighbor-analysis/test/out/squares.json new file mode 100644 index 0000000000..c7641163ea --- /dev/null +++ b/src/nearest-neighbor-analysis/test/out/squares.json @@ -0,0 +1,2519 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299993, + 38.120136 + ], + [ + -9.299993, + 38.165102 + ], + [ + -9.242852, + 38.165102 + ], + [ + -9.242852, + 38.120136 + ], + [ + -9.299993, + 38.120136 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299993, + 38.165102 + ], + [ + -9.299993, + 38.210068 + ], + [ + -9.242852, + 38.210068 + ], + [ + -9.242852, + 38.165102 + ], + [ + -9.299993, + 38.165102 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299993, + 38.210068 + ], + [ + -9.299993, + 38.255034 + ], + [ + -9.242852, + 38.255034 + ], + [ + -9.242852, + 38.210068 + ], + [ + -9.299993, + 38.210068 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299993, + 38.255034 + ], + [ + -9.299993, + 38.3 + ], + [ + -9.242852, + 38.3 + ], + [ + -9.242852, + 38.255034 + ], + [ + -9.299993, + 38.255034 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299993, + 38.3 + ], + [ + -9.299993, + 38.344966 + ], + [ + -9.242852, + 38.344966 + ], + [ + -9.242852, + 38.3 + ], + [ + -9.299993, + 38.3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299993, + 38.344966 + ], + [ + -9.299993, + 38.389932 + ], + [ + -9.242852, + 38.389932 + ], + [ + -9.242852, + 38.344966 + ], + [ + -9.299993, + 38.344966 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299993, + 38.389932 + ], + [ + -9.299993, + 38.434898 + ], + [ + -9.242852, + 38.434898 + ], + [ + -9.242852, + 38.389932 + ], + [ + -9.299993, + 38.389932 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299993, + 38.434898 + ], + [ + -9.299993, + 38.479864 + ], + [ + -9.242852, + 38.479864 + ], + [ + -9.242852, + 38.434898 + ], + [ + -9.299993, + 38.434898 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242852, + 38.120136 + ], + [ + -9.242852, + 38.165102 + ], + [ + -9.185711, + 38.165102 + ], + [ + -9.185711, + 38.120136 + ], + [ + -9.242852, + 38.120136 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242852, + 38.165102 + ], + [ + -9.242852, + 38.210068 + ], + [ + -9.185711, + 38.210068 + ], + [ + -9.185711, + 38.165102 + ], + [ + -9.242852, + 38.165102 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242852, + 38.210068 + ], + [ + -9.242852, + 38.255034 + ], + [ + -9.185711, + 38.255034 + ], + [ + -9.185711, + 38.210068 + ], + [ + -9.242852, + 38.210068 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242852, + 38.255034 + ], + [ + -9.242852, + 38.3 + ], + [ + -9.185711, + 38.3 + ], + [ + -9.185711, + 38.255034 + ], + [ + -9.242852, + 38.255034 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242852, + 38.3 + ], + [ + -9.242852, + 38.344966 + ], + [ + -9.185711, + 38.344966 + ], + [ + -9.185711, + 38.3 + ], + [ + -9.242852, + 38.3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242852, + 38.344966 + ], + [ + -9.242852, + 38.389932 + ], + [ + -9.185711, + 38.389932 + ], + [ + -9.185711, + 38.344966 + ], + [ + -9.242852, + 38.344966 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242852, + 38.389932 + ], + [ + -9.242852, + 38.434898 + ], + [ + -9.185711, + 38.434898 + ], + [ + -9.185711, + 38.389932 + ], + [ + -9.242852, + 38.389932 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.242852, + 38.434898 + ], + [ + -9.242852, + 38.479864 + ], + [ + -9.185711, + 38.479864 + ], + [ + -9.185711, + 38.434898 + ], + [ + -9.242852, + 38.434898 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711, + 38.120136 + ], + [ + -9.185711, + 38.165102 + ], + [ + -9.12857, + 38.165102 + ], + [ + -9.12857, + 38.120136 + ], + [ + -9.185711, + 38.120136 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711, + 38.165102 + ], + [ + -9.185711, + 38.210068 + ], + [ + -9.12857, + 38.210068 + ], + [ + -9.12857, + 38.165102 + ], + [ + -9.185711, + 38.165102 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711, + 38.210068 + ], + [ + -9.185711, + 38.255034 + ], + [ + -9.12857, + 38.255034 + ], + [ + -9.12857, + 38.210068 + ], + [ + -9.185711, + 38.210068 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711, + 38.255034 + ], + [ + -9.185711, + 38.3 + ], + [ + -9.12857, + 38.3 + ], + [ + -9.12857, + 38.255034 + ], + [ + -9.185711, + 38.255034 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711, + 38.3 + ], + [ + -9.185711, + 38.344966 + ], + [ + -9.12857, + 38.344966 + ], + [ + -9.12857, + 38.3 + ], + [ + -9.185711, + 38.3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711, + 38.344966 + ], + [ + -9.185711, + 38.389932 + ], + [ + -9.12857, + 38.389932 + ], + [ + -9.12857, + 38.344966 + ], + [ + -9.185711, + 38.344966 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711, + 38.389932 + ], + [ + -9.185711, + 38.434898 + ], + [ + -9.12857, + 38.434898 + ], + [ + -9.12857, + 38.389932 + ], + [ + -9.185711, + 38.389932 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.185711, + 38.434898 + ], + [ + -9.185711, + 38.479864 + ], + [ + -9.12857, + 38.479864 + ], + [ + -9.12857, + 38.434898 + ], + [ + -9.185711, + 38.434898 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857, + 38.120136 + ], + [ + -9.12857, + 38.165102 + ], + [ + -9.07143, + 38.165102 + ], + [ + -9.07143, + 38.120136 + ], + [ + -9.12857, + 38.120136 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857, + 38.165102 + ], + [ + -9.12857, + 38.210068 + ], + [ + -9.07143, + 38.210068 + ], + [ + -9.07143, + 38.165102 + ], + [ + -9.12857, + 38.165102 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857, + 38.210068 + ], + [ + -9.12857, + 38.255034 + ], + [ + -9.07143, + 38.255034 + ], + [ + -9.07143, + 38.210068 + ], + [ + -9.12857, + 38.210068 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857, + 38.255034 + ], + [ + -9.12857, + 38.3 + ], + [ + -9.07143, + 38.3 + ], + [ + -9.07143, + 38.255034 + ], + [ + -9.12857, + 38.255034 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857, + 38.3 + ], + [ + -9.12857, + 38.344966 + ], + [ + -9.07143, + 38.344966 + ], + [ + -9.07143, + 38.3 + ], + [ + -9.12857, + 38.3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857, + 38.344966 + ], + [ + -9.12857, + 38.389932 + ], + [ + -9.07143, + 38.389932 + ], + [ + -9.07143, + 38.344966 + ], + [ + -9.12857, + 38.344966 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857, + 38.389932 + ], + [ + -9.12857, + 38.434898 + ], + [ + -9.07143, + 38.434898 + ], + [ + -9.07143, + 38.389932 + ], + [ + -9.12857, + 38.389932 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.12857, + 38.434898 + ], + [ + -9.12857, + 38.479864 + ], + [ + -9.07143, + 38.479864 + ], + [ + -9.07143, + 38.434898 + ], + [ + -9.12857, + 38.434898 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.07143, + 38.120136 + ], + [ + -9.07143, + 38.165102 + ], + [ + -9.014289, + 38.165102 + ], + [ + -9.014289, + 38.120136 + ], + [ + -9.07143, + 38.120136 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.07143, + 38.165102 + ], + [ + -9.07143, + 38.210068 + ], + [ + -9.014289, + 38.210068 + ], + [ + -9.014289, + 38.165102 + ], + [ + -9.07143, + 38.165102 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.07143, + 38.210068 + ], + [ + -9.07143, + 38.255034 + ], + [ + -9.014289, + 38.255034 + ], + [ + -9.014289, + 38.210068 + ], + [ + -9.07143, + 38.210068 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.07143, + 38.255034 + ], + [ + -9.07143, + 38.3 + ], + [ + -9.014289, + 38.3 + ], + [ + -9.014289, + 38.255034 + ], + [ + -9.07143, + 38.255034 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.07143, + 38.3 + ], + [ + -9.07143, + 38.344966 + ], + [ + -9.014289, + 38.344966 + ], + [ + -9.014289, + 38.3 + ], + [ + -9.07143, + 38.3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.07143, + 38.344966 + ], + [ + -9.07143, + 38.389932 + ], + [ + -9.014289, + 38.389932 + ], + [ + -9.014289, + 38.344966 + ], + [ + -9.07143, + 38.344966 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.07143, + 38.389932 + ], + [ + -9.07143, + 38.434898 + ], + [ + -9.014289, + 38.434898 + ], + [ + -9.014289, + 38.389932 + ], + [ + -9.07143, + 38.389932 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.07143, + 38.434898 + ], + [ + -9.07143, + 38.479864 + ], + [ + -9.014289, + 38.479864 + ], + [ + -9.014289, + 38.434898 + ], + [ + -9.07143, + 38.434898 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.014289, + 38.120136 + ], + [ + -9.014289, + 38.165102 + ], + [ + -8.957148, + 38.165102 + ], + [ + -8.957148, + 38.120136 + ], + [ + -9.014289, + 38.120136 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.014289, + 38.165102 + ], + [ + -9.014289, + 38.210068 + ], + [ + -8.957148, + 38.210068 + ], + [ + -8.957148, + 38.165102 + ], + [ + -9.014289, + 38.165102 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.014289, + 38.210068 + ], + [ + -9.014289, + 38.255034 + ], + [ + -8.957148, + 38.255034 + ], + [ + -8.957148, + 38.210068 + ], + [ + -9.014289, + 38.210068 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.014289, + 38.255034 + ], + [ + -9.014289, + 38.3 + ], + [ + -8.957148, + 38.3 + ], + [ + -8.957148, + 38.255034 + ], + [ + -9.014289, + 38.255034 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.014289, + 38.3 + ], + [ + -9.014289, + 38.344966 + ], + [ + -8.957148, + 38.344966 + ], + [ + -8.957148, + 38.3 + ], + [ + -9.014289, + 38.3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.014289, + 38.344966 + ], + [ + -9.014289, + 38.389932 + ], + [ + -8.957148, + 38.389932 + ], + [ + -8.957148, + 38.344966 + ], + [ + -9.014289, + 38.344966 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.014289, + 38.389932 + ], + [ + -9.014289, + 38.434898 + ], + [ + -8.957148, + 38.434898 + ], + [ + -8.957148, + 38.389932 + ], + [ + -9.014289, + 38.389932 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.014289, + 38.434898 + ], + [ + -9.014289, + 38.479864 + ], + [ + -8.957148, + 38.479864 + ], + [ + -8.957148, + 38.434898 + ], + [ + -9.014289, + 38.434898 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -8.957148, + 38.120136 + ], + [ + -8.957148, + 38.165102 + ], + [ + -8.900007, + 38.165102 + ], + [ + -8.900007, + 38.120136 + ], + [ + -8.957148, + 38.120136 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -8.957148, + 38.165102 + ], + [ + -8.957148, + 38.210068 + ], + [ + -8.900007, + 38.210068 + ], + [ + -8.900007, + 38.165102 + ], + [ + -8.957148, + 38.165102 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -8.957148, + 38.210068 + ], + [ + -8.957148, + 38.255034 + ], + [ + -8.900007, + 38.255034 + ], + [ + -8.900007, + 38.210068 + ], + [ + -8.957148, + 38.210068 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -8.957148, + 38.255034 + ], + [ + -8.957148, + 38.3 + ], + [ + -8.900007, + 38.3 + ], + [ + -8.900007, + 38.255034 + ], + [ + -8.957148, + 38.255034 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -8.957148, + 38.3 + ], + [ + -8.957148, + 38.344966 + ], + [ + -8.900007, + 38.344966 + ], + [ + -8.900007, + 38.3 + ], + [ + -8.957148, + 38.3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -8.957148, + 38.344966 + ], + [ + -8.957148, + 38.389932 + ], + [ + -8.900007, + 38.389932 + ], + [ + -8.900007, + 38.344966 + ], + [ + -8.957148, + 38.344966 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -8.957148, + 38.389932 + ], + [ + -8.957148, + 38.434898 + ], + [ + -8.900007, + 38.434898 + ], + [ + -8.900007, + 38.389932 + ], + [ + -8.957148, + 38.389932 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -8.957148, + 38.434898 + ], + [ + -8.957148, + 38.479864 + ], + [ + -8.900007, + 38.479864 + ], + [ + -8.900007, + 38.434898 + ], + [ + -8.957148, + 38.434898 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.271422, + 38.142619 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.271422, + 38.187585 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.271422, + 38.232551 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.271422, + 38.277517 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.271422, + 38.322483 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.271422, + 38.367449 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.271422, + 38.412415 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.271422, + 38.457381 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.214281, + 38.142619 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.214281, + 38.187585 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.214281, + 38.232551 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.214281, + 38.277517 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.214281, + 38.322483 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.214281, + 38.367449 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.214281, + 38.412415 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.214281, + 38.457381 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.157141, + 38.142619 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.157141, + 38.187585 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.157141, + 38.232551 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.157141, + 38.277517 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.157141, + 38.322483 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.157141, + 38.367449 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.157141, + 38.412415 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.157141, + 38.457381 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.1, + 38.142619 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.1, + 38.187585 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.1, + 38.232551 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.1, + 38.277517 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.1, + 38.322483 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.1, + 38.367449 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.1, + 38.412415 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.1, + 38.457381 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.042859, + 38.142619 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.042859, + 38.187585 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.042859, + 38.232551 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.042859, + 38.277517 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.042859, + 38.322483 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.042859, + 38.367449 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.042859, + 38.412415 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -9.042859, + 38.457381 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.985719, + 38.142619 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.985719, + 38.187585 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.985719, + 38.232551 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.985719, + 38.277517 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.985719, + 38.322483 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.985719, + 38.367449 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.985719, + 38.412415 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.985719, + 38.457381 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.928578, + 38.142619 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.928578, + 38.187585 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.928578, + 38.232551 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.928578, + 38.277517 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.928578, + 38.322483 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.928578, + 38.367449 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.928578, + 38.412415 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#0a0" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -8.928578, + 38.457381 + ] + } + }, + { + "type": "Feature", + "bbox": [ + -9.299992605418552, + 38.12013592725509, + -8.900007394581449, + 38.47986407274493 + ], + "properties": { + "fill-opacity": 0, + "stroke-width": 5, + "stroke": "#a00", + "nearestNeighborAnalysis": { + "units": "kilometers", + "arealUnits": "kilometers²", + "observedMeanDistance": 4.986280150858801, + "expectedMeanDistance": 2.496567669388766, + "nearestNeighborIndex": 1.997254154973332, + "numberOfPoints": 56, + "zScore": 14.27679589626176 + } + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -9.299993, + 38.120136 + ], + [ + -8.900007, + 38.120136 + ], + [ + -8.900007, + 38.479864 + ], + [ + -9.299993, + 38.479864 + ], + [ + -9.299993, + 38.120136 + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-nearest-point-on-line/bench.js b/src/nearest-point-on-line/bench.js similarity index 100% rename from packages/turf-nearest-point-on-line/bench.js rename to src/nearest-point-on-line/bench.js diff --git a/src/nearest-point-on-line/index.js b/src/nearest-point-on-line/index.js new file mode 100644 index 0000000000..c779bf5547 --- /dev/null +++ b/src/nearest-point-on-line/index.js @@ -0,0 +1,93 @@ +import bearing from '../bearing'; +import distance from '../distance'; +import destination from '../destination'; +import lineIntersects from '../line-intersect'; +import { flattenEach } from '../meta'; +import { point, lineString } from '../helpers'; +import { getCoords } from '../invariant'; + + +/** + * Takes a {@link Point} and a {@link LineString} and calculates the closest Point on the (Multi)LineString. + * + * @name nearestPointOnLine + * @param {Geometry|Feature} lines lines to snap to + * @param {Geometry|Feature|number[]} pt point to snap from + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers + * @returns {Feature} closest point on the `line` to `point`. The properties object will contain three values: `index`: closest point was found on nth line part, `dist`: distance between pt and the closest point, `location`: distance along the line between start and the closest point. + * @example + * var line = turf.lineString([ + * [-77.031669, 38.878605], + * [-77.029609, 38.881946], + * [-77.020339, 38.884084], + * [-77.025661, 38.885821], + * [-77.021884, 38.889563], + * [-77.019824, 38.892368] + * ]); + * var pt = turf.point([-77.037076, 38.884017]); + * + * var snapped = turf.nearestPointOnLine(line, pt, {units: 'miles'}); + * + * //addToMap + * var addToMap = [line, pt, snapped]; + * snapped.properties['marker-color'] = '#00f'; + */ +function nearestPointOnLine(lines, pt, options) { + let closestPt = point([Infinity, Infinity], { + dist: Infinity + }); + + let length = 0.0; + flattenEach(lines, function (line) { + const coords = getCoords(line); + + for (let i = 0; i < coords.length - 1; i++) { + //start + const start = point(coords[i]); + start.properties.dist = distance(pt, start, options); + //stop + const stop = point(coords[i + 1]); + stop.properties.dist = distance(pt, stop, options); + // sectionLength + const sectionLength = distance(start, stop, options); + //perpendicular + const heightDistance = Math.max(start.properties.dist, stop.properties.dist); + const direction = bearing(start, stop); + const perpendicularPt1 = destination(pt, heightDistance, direction + 90, options); + const perpendicularPt2 = destination(pt, heightDistance, direction - 90, options); + const intersect = lineIntersects( + lineString([perpendicularPt1.geometry.coordinates, perpendicularPt2.geometry.coordinates]), + lineString([start.geometry.coordinates, stop.geometry.coordinates]) + ); + let intersectPt = null; + if (intersect.features.length > 0) { + intersectPt = intersect.features[0]; + intersectPt.properties.dist = distance(pt, intersectPt, options); + intersectPt.properties.location = length + distance(start, intersectPt, options); + } + + if (start.properties.dist < closestPt.properties.dist) { + closestPt = start; + closestPt.properties.index = i; + closestPt.properties.location = length; + } + if (stop.properties.dist < closestPt.properties.dist) { + closestPt = stop; + closestPt.properties.index = i + 1; + closestPt.properties.location = length + sectionLength; + } + if (intersectPt && intersectPt.properties.dist < closestPt.properties.dist) { + closestPt = intersectPt; + closestPt.properties.index = i; + } + // update length + length += sectionLength; + } + + }); + + return closestPt; +} + +export default nearestPointOnLine; diff --git a/src/nearest-point-on-line/test.js b/src/nearest-point-on-line/test.js new file mode 100644 index 0000000000..8a752b29a2 --- /dev/null +++ b/src/nearest-point-on-line/test.js @@ -0,0 +1,211 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const along = require('../along').default; +const distance = require('../distance').default; +const truncate = require('../truncate').default; +const length = require('../length').default; +const { lineString, multiLineString, point, featureCollection, round } = require('../helpers'); +const nearestPointOnLine = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-linestring-to-polygon', t => { + for (const {name, filename, geojson} of fixtures) { + const [line, point] = geojson.features; + const onLine = nearestPointOnLine(line, point); + onLine.properties['marker-color'] = '#F0F'; + onLine.properties.dist = round(onLine.properties.dist, 6); + onLine.properties.location = round(onLine.properties.location, 6); + const between = lineString([onLine.geometry.coordinates, point.geometry.coordinates], {stroke: '#F00', 'stroke-width': 6}); + const results = truncate(featureCollection([line, between, point, onLine])); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(load.sync(directories.out + filename), results, name); + } + t.end(); +}); + +test('turf-point-on-line - first point', t => { + const line = lineString([[-122.457175, 37.720033], [-122.457175, 37.718242]]); + const pt = point([-122.457175, 37.720033]); + + const snapped = truncate(nearestPointOnLine(line, pt)); + + t.deepEqual(pt.geometry.coordinates, snapped.geometry.coordinates, 'pt on start does not move'); + t.equal(Number(snapped.properties.location.toFixed(6)), 0, 'properties.location'); + + t.end(); +}); + +test('turf-point-on-line - points behind first point', t => { + const line = lineString([[-122.457175, 37.720033], [-122.457175, 37.718242]]); + const first = point(line.geometry.coordinates[0]); + const pts = [ + point([-122.457175, 37.720093]), + point([-122.457175, 37.820093]), + point([-122.457165, 37.720093]), + point([-122.455165, 37.720093]) + ]; + const expectedLocation = [0, 0, 0, 0]; + + pts.forEach(pt => { + const snapped = truncate(nearestPointOnLine(line, pt)); + t.deepEqual(first.geometry.coordinates, snapped.geometry.coordinates, 'pt behind start moves to first vertex'); + expectedLocation.push(Number(snapped.properties.location.toFixed(6))); + }); + + const filepath = directories.out + 'expectedLocation - points behind first point.json'; + if (process.env.REGEN) write.sync(filepath, expectedLocation); + t.deepEqual(load.sync(filepath), expectedLocation, 'properties.location'); + t.end(); +}); + +test('turf-point-on-line - points in front of last point', t => { + const line = lineString([[-122.456161, 37.721259], [-122.457175, 37.720033], [-122.457175, 37.718242]]); + const last = point(line.geometry.coordinates[line.geometry.coordinates.length - 1]); + const pts = [ + point([-122.456960, 37.718140]), + point([-122.457363, 37.718132]), + point([-122.457309, 37.717979]), + point([-122.457180, 37.717045]) + ]; + const expectedLocation = []; + + pts.forEach(pt => { + const snapped = truncate(nearestPointOnLine(line, pt)); + t.deepEqual(last.geometry.coordinates, snapped.geometry.coordinates, 'pt behind start moves to last vertex'); + expectedLocation.push(Number(snapped.properties.location.toFixed(6))); + }); + + const filepath = directories.out + 'expectedLocation - points in front of last point.json'; + if (process.env.REGEN) write.sync(filepath, expectedLocation); + t.deepEqual(load.sync(filepath), expectedLocation, 'properties.location'); + t.end(); +}); + +test('turf-point-on-line - points on joints', t => { + const lines = [ + lineString([[-122.456161, 37.721259], [-122.457175, 37.720033], [-122.457175, 37.718242]]), + lineString([[26.279296, 31.728167], [21.796875, 32.694865], [18.808593, 29.993002], [12.919921, 33.137551], [10.195312, 35.603718], [4.921875, 36.527294], [-1.669921, 36.527294], [-5.449218, 34.741612], [-8.789062, 32.990235]]), + lineString([[-0.109198, 51.522042], [-0.109230, 51.521942], [-0.109165, 51.521862], [-0.109047, 51.521775], [-0.108865, 51.521601], [-0.108747, 51.521381], [-0.108554, 51.520687], [-0.108436, 51.520279], [-0.108393, 51.519952], [-0.108178, 51.519578], [-0.108146, 51.519285], [-0.107899, 51.518624], [-0.107599, 51.517782]]) + ]; + const expectedLocation = []; + + lines.forEach((line, i) => { + line.geometry.coordinates.map(coord => { + return point(coord); + }).forEach((pt, j) => { + const snapped = truncate(nearestPointOnLine(line, pt)); + t.deepEqual(pt.geometry.coordinates, snapped.geometry.coordinates, 'pt on joint stayed in place'); + if (!expectedLocation[i]) expectedLocation[i] = []; + expectedLocation[i][j] = Number(snapped.properties.location.toFixed(6)); + }); + }); + + const filepath = directories.out + 'expectedLocation - points on joints.json'; + if (process.env.REGEN) write.sync(filepath, expectedLocation); + t.deepEqual(load.sync(filepath), expectedLocation, 'properties.location'); + t.end(); +}); + +test('turf-point-on-line - points on top of line', t => { + const line = lineString([[-0.109198, 51.522042], [-0.109230, 51.521942], [-0.109165, 51.521862], [-0.109047, 51.521775], [-0.108865, 51.521601], [-0.108747, 51.521381], [-0.108554, 51.520687], [-0.108436, 51.520279], [-0.108393, 51.519952], [-0.108178, 51.519578], [-0.108146, 51.519285], [-0.107899, 51.518624], [-0.107599, 51.517782]]); + const expectedLocation = []; + + const dist = length(line, {units: 'miles'}); + const increment = dist / 10; + + for (let i = 0; i < 10; i++) { + const pt = along(line, increment * i, {units: 'miles'}); + const snapped = nearestPointOnLine(line, pt, {units: 'miles'}); + const shift = distance(pt, snapped, {units: 'miles'}); + t.true(shift < 0.000001, 'pt did not shift far'); + expectedLocation.push(Number(snapped.properties.location.toFixed(6))); + } + + const filepath = directories.out + 'expectedLocation - points on top of line.json'; + if (process.env.REGEN) write.sync(filepath, expectedLocation); + t.deepEqual(load.sync(filepath), expectedLocation, 'properties.location'); + t.end(); +}); + +test('turf-point-on-line - point along line', t => { + const line = lineString([[-122.457175, 37.720033], [-122.457175, 37.718242]]); + + const pt = along(line, 0.019, {units: 'miles'}); + const snapped = nearestPointOnLine(line, pt); + const shift = distance(pt, snapped, {units: 'miles'}); + + t.true(shift < 0.00001, 'pt did not shift far'); + + t.end(); +}); + +test('turf-point-on-line - points on sides of lines', t => { + const line = lineString([[-122.456161, 37.721259], [-122.457175, 37.718242]]); + const first = line.geometry.coordinates[0]; + const last = line.geometry.coordinates[line.geometry.coordinates.length - 1]; + const pts = [ + point([-122.457025, 37.718810]), + point([-122.457336, 37.719235]), + point([-122.456864, 37.720270]), + point([-122.456520, 37.720635]) + ]; + + pts.forEach(pt => { + const snapped = nearestPointOnLine(line, pt); + t.notDeepEqual(snapped.geometry.coordinates, first, 'pt did not snap to first vertex'); + t.notDeepEqual(snapped.geometry.coordinates, last, 'pt did not snap to last vertex'); + }); + + t.end(); +}); + +test('turf-point-on-line - check dist and index', t => { + const line = lineString([[-92.090492, 41.102897], [-92.191085, 41.079868], [-92.228507, 41.056055], [-92.237091, 41.008143], [-92.225761, 40.966937], [-92.150230, 40.936858], [-92.112464, 40.977565], [-92.062683, 41.034564], [-92.100791, 41.040002]]); + const pt = point([-92.110576, 41.040649]); + const snapped = truncate(nearestPointOnLine(line, pt)); + + t.equal(snapped.properties.index, 8, 'properties.index'); + t.equal(Number(snapped.properties.dist.toFixed(6)), 0.823802, 'properties.dist'); + t.deepEqual(snapped.geometry.coordinates, [-92.100791, 41.040002], 'coordinates'); + + t.end(); +}); + +test('turf-point-on-line -- Issue #691', t => { + const line1 = lineString([[7, 50], [8, 50], [9, 50]]); + const pointAlong = along(line1, 10); + const {location} = nearestPointOnLine(line1, pointAlong).properties; + + t.false(isNaN(location)); + t.end(); +}); + +test('turf-point-on-line -- Geometry Support', t => { + const pt = point([7, 55]); + const line = lineString([[7, 50], [8, 50], [9, 50]]); + const multiLine = multiLineString([ + [[7, 50], [8, 50], [9, 50]], + [[17, 30], [4, 30], [2, 30]] + ]); + t.assert(nearestPointOnLine(line.geometry, pt), 'line Geometry'); + t.assert(nearestPointOnLine(multiLine.geometry, pt), 'multiLine Geometry'); + t.assert(nearestPointOnLine(line, pt.geometry), 'point Geometry'); + t.assert(nearestPointOnLine(line, pt.geometry.coordinates), 'point Coordinates'); + t.end(); +}); diff --git a/packages/turf-nearest-point-on-line/test/in/line-northern-latitude-#344.geojson b/src/nearest-point-on-line/test/in/line-northern-latitude-#344.geojson similarity index 100% rename from packages/turf-nearest-point-on-line/test/in/line-northern-latitude-#344.geojson rename to src/nearest-point-on-line/test/in/line-northern-latitude-#344.geojson diff --git a/packages/turf-nearest-point-on-line/test/in/line1.geojson b/src/nearest-point-on-line/test/in/line1.geojson similarity index 100% rename from packages/turf-nearest-point-on-line/test/in/line1.geojson rename to src/nearest-point-on-line/test/in/line1.geojson diff --git a/packages/turf-nearest-point-on-line/test/in/multiLine1.geojson b/src/nearest-point-on-line/test/in/multiLine1.geojson similarity index 100% rename from packages/turf-nearest-point-on-line/test/in/multiLine1.geojson rename to src/nearest-point-on-line/test/in/multiLine1.geojson diff --git a/packages/turf-nearest-point-on-line/test/in/multiLine2.geojson b/src/nearest-point-on-line/test/in/multiLine2.geojson similarity index 100% rename from packages/turf-nearest-point-on-line/test/in/multiLine2.geojson rename to src/nearest-point-on-line/test/in/multiLine2.geojson diff --git a/packages/turf-nearest-point-on-line/test/in/multiLine3.geojson b/src/nearest-point-on-line/test/in/multiLine3.geojson similarity index 100% rename from packages/turf-nearest-point-on-line/test/in/multiLine3.geojson rename to src/nearest-point-on-line/test/in/multiLine3.geojson diff --git a/packages/turf-nearest-point-on-line/test/in/route1.geojson b/src/nearest-point-on-line/test/in/route1.geojson similarity index 100% rename from packages/turf-nearest-point-on-line/test/in/route1.geojson rename to src/nearest-point-on-line/test/in/route1.geojson diff --git a/packages/turf-nearest-point-on-line/test/in/route2.geojson b/src/nearest-point-on-line/test/in/route2.geojson similarity index 100% rename from packages/turf-nearest-point-on-line/test/in/route2.geojson rename to src/nearest-point-on-line/test/in/route2.geojson diff --git a/packages/turf-nearest-point-on-line/test/out/expectedLocation - points behind first point.json b/src/nearest-point-on-line/test/out/expectedLocation - points behind first point.json similarity index 100% rename from packages/turf-nearest-point-on-line/test/out/expectedLocation - points behind first point.json rename to src/nearest-point-on-line/test/out/expectedLocation - points behind first point.json diff --git a/packages/turf-nearest-point-on-line/test/out/expectedLocation - points in front of last point.json b/src/nearest-point-on-line/test/out/expectedLocation - points in front of last point.json similarity index 100% rename from packages/turf-nearest-point-on-line/test/out/expectedLocation - points in front of last point.json rename to src/nearest-point-on-line/test/out/expectedLocation - points in front of last point.json diff --git a/packages/turf-nearest-point-on-line/test/out/expectedLocation - points on joints.json b/src/nearest-point-on-line/test/out/expectedLocation - points on joints.json similarity index 100% rename from packages/turf-nearest-point-on-line/test/out/expectedLocation - points on joints.json rename to src/nearest-point-on-line/test/out/expectedLocation - points on joints.json diff --git a/packages/turf-nearest-point-on-line/test/out/expectedLocation - points on top of line.json b/src/nearest-point-on-line/test/out/expectedLocation - points on top of line.json similarity index 100% rename from packages/turf-nearest-point-on-line/test/out/expectedLocation - points on top of line.json rename to src/nearest-point-on-line/test/out/expectedLocation - points on top of line.json diff --git a/packages/turf-nearest-point-on-line/test/out/line-northern-latitude-#344.geojson b/src/nearest-point-on-line/test/out/line-northern-latitude-#344.geojson similarity index 100% rename from packages/turf-nearest-point-on-line/test/out/line-northern-latitude-#344.geojson rename to src/nearest-point-on-line/test/out/line-northern-latitude-#344.geojson diff --git a/packages/turf-nearest-point-on-line/test/out/line1.geojson b/src/nearest-point-on-line/test/out/line1.geojson similarity index 100% rename from packages/turf-nearest-point-on-line/test/out/line1.geojson rename to src/nearest-point-on-line/test/out/line1.geojson diff --git a/packages/turf-nearest-point-on-line/test/out/multiLine1.geojson b/src/nearest-point-on-line/test/out/multiLine1.geojson similarity index 100% rename from packages/turf-nearest-point-on-line/test/out/multiLine1.geojson rename to src/nearest-point-on-line/test/out/multiLine1.geojson diff --git a/packages/turf-nearest-point-on-line/test/out/multiLine2.geojson b/src/nearest-point-on-line/test/out/multiLine2.geojson similarity index 100% rename from packages/turf-nearest-point-on-line/test/out/multiLine2.geojson rename to src/nearest-point-on-line/test/out/multiLine2.geojson diff --git a/packages/turf-nearest-point-on-line/test/out/multiLine3.geojson b/src/nearest-point-on-line/test/out/multiLine3.geojson similarity index 100% rename from packages/turf-nearest-point-on-line/test/out/multiLine3.geojson rename to src/nearest-point-on-line/test/out/multiLine3.geojson diff --git a/packages/turf-nearest-point-on-line/test/out/route1.geojson b/src/nearest-point-on-line/test/out/route1.geojson similarity index 100% rename from packages/turf-nearest-point-on-line/test/out/route1.geojson rename to src/nearest-point-on-line/test/out/route1.geojson diff --git a/packages/turf-nearest-point-on-line/test/out/route2.geojson b/src/nearest-point-on-line/test/out/route2.geojson similarity index 100% rename from packages/turf-nearest-point-on-line/test/out/route2.geojson rename to src/nearest-point-on-line/test/out/route2.geojson diff --git a/packages/turf-nearest-point-to-line/bench.js b/src/nearest-point-to-line/bench.js similarity index 100% rename from packages/turf-nearest-point-to-line/bench.js rename to src/nearest-point-to-line/bench.js diff --git a/src/nearest-point-to-line/index.d.ts b/src/nearest-point-to-line/index.d.ts new file mode 100644 index 0000000000..b881b2dfac --- /dev/null +++ b/src/nearest-point-to-line/index.d.ts @@ -0,0 +1,32 @@ +import { Feature, FeatureCollection, GeometryCollection, LineString, Point, Properties, Units } from "../helpers"; +/** + * Returns the closest {@link Point|point}, of a {@link FeatureCollection|collection} of points, + * to a {@link LineString|line}. The returned point has a `dist` property indicating its distance to the line. + * + * @name nearestPointToLine + * @param {FeatureCollection|GeometryCollection} points Point Collection + * @param {Feature|Geometry} line Line Feature + * @param {Object} [options] Optional parameters + * @param {string} [options.units='kilometers'] unit of the output distance property + * (eg: degrees, radians, miles, or kilometers) + * @param {Object} [options.properties={}] Translate Properties to Point + * @returns {Feature} the closest point + * @example + * var pt1 = turf.point([0, 0]); + * var pt2 = turf.point([0.5, 0.5]); + * var points = turf.featureCollection([pt1, pt2]); + * var line = turf.lineString([[1,1], [-1,1]]); + * + * var nearest = turf.nearestPointToLine(points, line); + * + * //addToMap + * var addToMap = [nearest, line]; + */ +declare function nearestPointToLine

(points: FeatureCollection | Feature | GeometryCollection, line: Feature | LineString, options?: { + units?: Units; + properties?: Properties; +}): Feature; +export default nearestPointToLine; diff --git a/src/nearest-point-to-line/index.js b/src/nearest-point-to-line/index.js new file mode 100644 index 0000000000..ca90afa72f --- /dev/null +++ b/src/nearest-point-to-line/index.js @@ -0,0 +1,94 @@ +import { checkIfOptionsExist } from '../helpers'; +import { getType } from '../invariant'; +import { featureEach, geomEach } from '../meta'; +import pointToLineDistance from '../point-to-line-distance'; + +/** + * Returns the closest {@link Point|point}, of a {@link FeatureCollection|collection} of points, + * to a {@link LineString|line}. The returned point has a `dist` property indicating its distance to the line. + * + * @name nearestPointToLine + * @param {FeatureCollection|GeometryCollection} points Point Collection + * @param {Feature|Geometry} line Line Feature + * @param {Object} [options] Optional parameters + * @param {string} [options.units='kilometers'] unit of the output distance property + * (eg: degrees, radians, miles, or kilometers) + * @param {Object} [options.properties={}] Translate Properties to Point + * @returns {Feature} the closest point + * @example + * var pt1 = turf.point([0, 0]); + * var pt2 = turf.point([0.5, 0.5]); + * var points = turf.featureCollection([pt1, pt2]); + * var line = turf.lineString([[1,1], [-1,1]]); + * + * var nearest = turf.nearestPointToLine(points, line); + * + * //addToMap + * var addToMap = [nearest, line]; + */ +function nearestPointToLine(points, line, options) { + options = checkIfOptionsExist(options); + const units = options.units; + const properties = options.properties || {}; + + // validation + const pts = normalize(points); + if (!pts.features.length) { throw new Error('points must contain features'); } + + if (!line) { throw new Error('line is required'); } + if (getType(line) !== 'LineString') { throw new Error('line must be a LineString'); } + + let dist = Infinity; + let pt = null; + + featureEach(pts, function (point) { + const d = pointToLineDistance(point, line, { units }); + if (d < dist) { + dist = d; + pt = point; + } + }); + /** + * Translate Properties to final Point, priorities: + * 1. options.properties + * 2. inherent Point properties + * 3. dist custom properties created by NearestPointToLine + */ + + if (pt) { + pt.properties = properties; + for (const prop in pt.properties) { + pt.properties = pt.properties[prop]; + } + pt.properties.dist = dist; + } + return pt; +} + +/** + * Convert Collection to FeatureCollection + * + * @private + * @param {FeatureCollection|GeometryCollection} points Points + * @returns {FeatureCollection} points + */ +function normalize(points) { + const features = []; + const type = points.geometry ? points.geometry.type : points.type; + switch (type) { + case 'GeometryCollection': + geomEach(points, function (geom) { + if (geom.type === 'Point') { features.push({type: 'Feature', properties: {}, geometry: geom}); } + }); + return {type: 'FeatureCollection', features}; + case 'FeatureCollection': + points.features = points.features.filter(function (feature) { + return feature.geometry.type === 'Point'; + }); + return points; + default: + throw new Error('points must be a Point Collection'); + } +} + +export default nearestPointToLine; diff --git a/src/nearest-point-to-line/test.js b/src/nearest-point-to-line/test.js new file mode 100644 index 0000000000..109ac9efe2 --- /dev/null +++ b/src/nearest-point-to-line/test.js @@ -0,0 +1,83 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const circle = require('../circle').default; +const truncate = require('../truncate').default; +const { geometryCollection, featureCollection, point, lineString, round } = require('../helpers'); +const nearestPointToLine = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-nearest-point-to-line', t => { + fixtures.forEach(fixture => { + const filename = fixture.filename; + const name = fixture.name; + const geojson = fixture.geojson; + const points = geojson.features[0]; + const line = geojson.features[1]; + const units = (geojson.properties || {}).units; + + const nearest = nearestPointToLine(points, line, {units: units}); + const distance = round(nearest.properties.dist, 6); + nearest.properties.dist = distance; + nearest.properties = Object.assign(nearest.properties, { + 'marker-color': '#F00', + 'marker-size': 'large', + 'marker-symbol': 'star' + }); + const distanceCircle = truncate(circle(nearest, distance || 1, { units: units, properties: {fill: '#F00'} })); + const results = featureCollection([points, nearest, line, distanceCircle]); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(results, load.sync(directories.out + filename), name); + }); + t.end(); +}); + + +test('turf-nearest-point-to-line -- throws', t => { + const points = featureCollection([point([0, 0]), point([0, 1])]); + const line = lineString([[1, 1], [-1, 1]]); + + // Handled by Typescript + // t.throws(() => nearestPointToLine(null, line), /points is required/, 'missing points'); + // t.throws(() => nearestPointToLine(points, null), /line is required/, 'missing line'); + // t.throws(() => nearestPointToLine(points, line, 'invalid'), /options is invalid/, 'options is invalid'); + + t.throws(() => nearestPointToLine(points, line, {units: 'invalid'}), /units is invalid/, 'invalid units'); + t.throws(() => nearestPointToLine(points, points), /line must be a LineString/, 'invalid line'); + t.throws(() => nearestPointToLine(line, line), /points must be a Point Collection/, 'invalid points'); + + t.end(); +}); + +test('turf-nearest-point-to-line -- Geometry', t => { + const points = featureCollection([point([0, 0]), point([0, 1])]); + const geomPoints = geometryCollection([point([0, 0]).geometry, point([0, 1]).geometry]); + const line = lineString([[1, 1], [-1, 1]]); + + t.assert(nearestPointToLine(points, line.geometry)); + t.assert(nearestPointToLine(geomPoints, line.geometry)); + t.end(); +}); + +test('turf-nearest-point-to-line -- Empty FeatureCollection', t => { + const points = featureCollection([]); + const line = lineString([[1, 1], [-1, 1]]); + + t.throws(() => nearestPointToLine(points, line), /points must contain features/, 'points must contain features'); + t.end(); +}); diff --git a/packages/turf-nearest-point-to-line/test/in/fiji.geojson b/src/nearest-point-to-line/test/in/fiji.geojson similarity index 100% rename from packages/turf-nearest-point-to-line/test/in/fiji.geojson rename to src/nearest-point-to-line/test/in/fiji.geojson diff --git a/packages/turf-nearest-point-to-line/test/in/on-line.geojson b/src/nearest-point-to-line/test/in/on-line.geojson similarity index 100% rename from packages/turf-nearest-point-to-line/test/in/on-line.geojson rename to src/nearest-point-to-line/test/in/on-line.geojson diff --git a/packages/turf-nearest-point-to-line/test/in/one.geojson b/src/nearest-point-to-line/test/in/one.geojson similarity index 100% rename from packages/turf-nearest-point-to-line/test/in/one.geojson rename to src/nearest-point-to-line/test/in/one.geojson diff --git a/packages/turf-nearest-point-to-line/test/in/resolute.geojson b/src/nearest-point-to-line/test/in/resolute.geojson similarity index 100% rename from packages/turf-nearest-point-to-line/test/in/resolute.geojson rename to src/nearest-point-to-line/test/in/resolute.geojson diff --git a/packages/turf-nearest-point-to-line/test/in/segment.geojson b/src/nearest-point-to-line/test/in/segment.geojson similarity index 100% rename from packages/turf-nearest-point-to-line/test/in/segment.geojson rename to src/nearest-point-to-line/test/in/segment.geojson diff --git a/packages/turf-nearest-point-to-line/test/in/two.geojson b/src/nearest-point-to-line/test/in/two.geojson similarity index 100% rename from packages/turf-nearest-point-to-line/test/in/two.geojson rename to src/nearest-point-to-line/test/in/two.geojson diff --git a/packages/turf-nearest-point-to-line/test/out/fiji.geojson b/src/nearest-point-to-line/test/out/fiji.geojson similarity index 100% rename from packages/turf-nearest-point-to-line/test/out/fiji.geojson rename to src/nearest-point-to-line/test/out/fiji.geojson diff --git a/packages/turf-nearest-point-to-line/test/out/on-line.geojson b/src/nearest-point-to-line/test/out/on-line.geojson similarity index 100% rename from packages/turf-nearest-point-to-line/test/out/on-line.geojson rename to src/nearest-point-to-line/test/out/on-line.geojson diff --git a/packages/turf-nearest-point-to-line/test/out/one.geojson b/src/nearest-point-to-line/test/out/one.geojson similarity index 100% rename from packages/turf-nearest-point-to-line/test/out/one.geojson rename to src/nearest-point-to-line/test/out/one.geojson diff --git a/packages/turf-nearest-point-to-line/test/out/resolute.geojson b/src/nearest-point-to-line/test/out/resolute.geojson similarity index 100% rename from packages/turf-nearest-point-to-line/test/out/resolute.geojson rename to src/nearest-point-to-line/test/out/resolute.geojson diff --git a/packages/turf-nearest-point-to-line/test/out/segment.geojson b/src/nearest-point-to-line/test/out/segment.geojson similarity index 100% rename from packages/turf-nearest-point-to-line/test/out/segment.geojson rename to src/nearest-point-to-line/test/out/segment.geojson diff --git a/packages/turf-nearest-point-to-line/test/out/two.geojson b/src/nearest-point-to-line/test/out/two.geojson similarity index 100% rename from packages/turf-nearest-point-to-line/test/out/two.geojson rename to src/nearest-point-to-line/test/out/two.geojson diff --git a/packages/turf-nearest-point/bench.js b/src/nearest-point/bench.js similarity index 100% rename from packages/turf-nearest-point/bench.js rename to src/nearest-point/bench.js diff --git a/src/nearest-point/index.d.ts b/src/nearest-point/index.d.ts new file mode 100644 index 0000000000..7fee560f5e --- /dev/null +++ b/src/nearest-point/index.d.ts @@ -0,0 +1,34 @@ +import { Coord, Feature, FeatureCollection, Point } from '../helpers'; +export interface NearestPoint extends Feature { + properties: { + featureIndex: number; + distanceToPoint: number; + [key: string]: any; + }; +} +/** + * Takes a reference {@link Point|point} and a FeatureCollection of Features + * with Point geometries and returns the + * point from the FeatureCollection closest to the reference. This calculation + * is geodesic. + * + * @name nearestPoint + * @param {Coord} targetPoint the reference point + * @param {FeatureCollection} points against input point set + * @returns {Feature} the closest point in the set to the reference point + * @example + * var targetPoint = turf.point([28.965797, 41.010086], {"marker-color": "#0F0"}); + * var points = turf.featureCollection([ + * turf.point([28.973865, 41.011122]), + * turf.point([28.948459, 41.024204]), + * turf.point([28.938674, 41.013324]) + * ]); + * + * var nearest = turf.nearestPoint(targetPoint, points); + * + * //addToMap + * var addToMap = [targetPoint, points, nearest]; + * nearest.properties['marker-color'] = '#F00'; + */ +declare function nearestPoint(targetPoint: Coord, points: FeatureCollection): NearestPoint; +export default nearestPoint; diff --git a/src/nearest-point/index.js b/src/nearest-point/index.js new file mode 100644 index 0000000000..d19ed089d3 --- /dev/null +++ b/src/nearest-point/index.js @@ -0,0 +1,50 @@ +import clone from '../clone'; +import distance from '../distance'; +import { featureEach } from '../meta'; + +/** + * Takes a reference {@link Point|point} and a FeatureCollection of Features + * with Point geometries and returns the + * point from the FeatureCollection closest to the reference. This calculation + * is geodesic. + * + * @name nearestPoint + * @param {Coord} targetPoint the reference point + * @param {FeatureCollection} points against input point set + * @returns {Feature} the closest point in the set to the reference point + * @example + * var targetPoint = turf.point([28.965797, 41.010086], {"marker-color": "#0F0"}); + * var points = turf.featureCollection([ + * turf.point([28.973865, 41.011122]), + * turf.point([28.948459, 41.024204]), + * turf.point([28.938674, 41.013324]) + * ]); + * + * var nearest = turf.nearestPoint(targetPoint, points); + * + * //addToMap + * var addToMap = [targetPoint, points, nearest]; + * nearest.properties['marker-color'] = '#F00'; + */ +function nearestPoint(targetPoint, points) { + // Input validation + if (!targetPoint) throw new Error('targetPoint is required'); + if (!points) throw new Error('points is required'); + + let nearest = null; + let minDist = Infinity; + let bestFeatureIndex = 0; + featureEach(points, function (pt, featureIndex) { + const distanceToPoint = distance(targetPoint, pt); + if (distanceToPoint < minDist) { + bestFeatureIndex = featureIndex; + minDist = distanceToPoint; + } + }); + nearest = clone(points.features[bestFeatureIndex]); + nearest.properties.featureIndex = bestFeatureIndex; + nearest.properties.distanceToPoint = minDist; + return nearest; +} + +export default nearestPoint; diff --git a/src/nearest-point/test.js b/src/nearest-point/test.js new file mode 100644 index 0000000000..3a7a71d2b7 --- /dev/null +++ b/src/nearest-point/test.js @@ -0,0 +1,59 @@ +const fs = require('fs'); +const test = require('tape'); +const glob = require('glob'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const {featureCollection, point} = require('../helpers'); +const nearestPoint = require('./').default; + + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-nearest-point', t => { + fixtures.forEach(fixture => { + const filename = fixture.filename; + const name = fixture.name; + const geojson = fixture.geojson; + const targetPoint = point(geojson.properties.targetPoint); + const nearestPt = nearestPoint(targetPoint, geojson); + + // Style results + nearestPt.properties['marker-color'] = '#F00'; + nearestPt.properties['marker-symbol'] = 'star'; + targetPoint.properties['marker-color'] = '#00F'; + targetPoint.properties['marker-symbol'] = 'circle'; + const results = featureCollection([...geojson.features, targetPoint, nearestPt]); + + // Save output + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(results, load.sync(directories.out + filename), name); + }); + t.end(); +}); + +test('nearest-point -- prevent input mutation', t => { + const pt1 = point([40, 50], {featureIndex: 'foo'}) + const pt2 = point([20, -10], {distanceToPoint: 'bar'}) + const pts = featureCollection([pt1, pt2]); + const nearestPt = nearestPoint([0, 0], pts) + + // Check if featureIndex properties was added to properties + t.equal(nearestPt.properties.featureIndex, 1) + + // Check if previous input points have been modified + t.deepEqual(pt1.properties, {featureIndex: 'foo'}) + t.deepEqual(pt2.properties, {distanceToPoint: 'bar'}) + t.end(); +}) \ No newline at end of file diff --git a/packages/turf-nearest-point/test/in/points.json b/src/nearest-point/test/in/points.json similarity index 100% rename from packages/turf-nearest-point/test/in/points.json rename to src/nearest-point/test/in/points.json diff --git a/packages/turf-nearest-point/test/out/points.json b/src/nearest-point/test/out/points.json similarity index 100% rename from packages/turf-nearest-point/test/out/points.json rename to src/nearest-point/test/out/points.json diff --git a/src/planepoint/bench.js b/src/planepoint/bench.js new file mode 100644 index 0000000000..1e3f539978 --- /dev/null +++ b/src/planepoint/bench.js @@ -0,0 +1,18 @@ +import Benchmark from 'benchmark'; +import { polygon } from '../helpers'; +import planepoint from './'; + +const point = [1, 1]; +const triangle = polygon([[[0, 0, 0], [2, 0, 0], [1, 2, 2], [0, 0, 0]]], {a: 0, b: 0, c: 2}); + +/** + * Benchmmark Results + * + * turf-planepoint x 14,905,445 ops/sec ±4.54% (75 runs sampled) + */ +const suite = new Benchmark.Suite('turf-planepoint'); +suite + .add('turf-planepoint', () => planepoint(point, triangle)) + .on('cycle', e => console.log(String(e.target))) + .on('complete', () => {}) + .run(); diff --git a/src/planepoint/index.d.ts b/src/planepoint/index.d.ts new file mode 100644 index 0000000000..7c4f4b57a1 --- /dev/null +++ b/src/planepoint/index.d.ts @@ -0,0 +1,9 @@ +import { Feature, Coord, Polygon } from '../helpers' + +/** + * http://turfjs.org/docs/#planepoint + */ +export default function planepoint( + point: Coord, + triangle: Feature | Polygon +): number; diff --git a/src/planepoint/index.js b/src/planepoint/index.js new file mode 100644 index 0000000000..f9256ffcb9 --- /dev/null +++ b/src/planepoint/index.js @@ -0,0 +1,67 @@ +import { getCoord, getGeom } from '../invariant'; + +/** + * Takes a triangular plane as a {@link Polygon} + * and a {@link Point} within that triangle and returns the z-value + * at that point. The Polygon should have properties `a`, `b`, and `c` + * that define the values at its three corners. Alternatively, the z-values + * of each triangle point can be provided by their respective 3rd coordinate + * if their values are not provided as properties. + * + * @name planepoint + * @param {Coord} point the Point for which a z-value will be calculated + * @param {Feature} triangle a Polygon feature with three vertices + * @returns {number} the z-value for `interpolatedPoint` + * @example + * var point = turf.point([-75.3221, 39.529]); + * // "a", "b", and "c" values represent the values of the coordinates in order. + * var triangle = turf.polygon([[ + * [-75.1221, 39.57], + * [-75.58, 39.18], + * [-75.97, 39.86], + * [-75.1221, 39.57] + * ]], { + * "a": 11, + * "b": 122, + * "c": 44 + * }); + * + * var zValue = turf.planepoint(point, triangle); + * point.properties.zValue = zValue; + * + * //addToMap + * var addToMap = [triangle, point]; + */ +function planepoint(point, triangle) { + // Normalize input + var coord = getCoord(point); + var geom = getGeom(triangle); + var coords = geom.coordinates; + var outer = coords[0]; + if (outer.length < 4) throw new Error('OuterRing of a Polygon must have 4 or more Positions.'); + var properties = triangle.properties || {}; + var a = properties.a; + var b = properties.b; + var c = properties.c; + + // Planepoint + var x = coord[0]; + var y = coord[1]; + var x1 = outer[0][0]; + var y1 = outer[0][1]; + var z1 = (a !== undefined ? a : outer[0][2]); + var x2 = outer[1][0]; + var y2 = outer[1][1]; + var z2 = (b !== undefined ? b : outer[1][2]); + var x3 = outer[2][0]; + var y3 = outer[2][1]; + var z3 = (c !== undefined ? c : outer[2][2]); + var z = (z3 * (x - x1) * (y - y2) + z1 * (x - x2) * (y - y3) + z2 * (x - x3) * (y - y1) - + z2 * (x - x1) * (y - y3) - z3 * (x - x2) * (y - y1) - z1 * (x - x3) * (y - y2)) / + ((x - x1) * (y - y2) + (x - x2) * (y - y3) + (x - x3) * (y - y1) - + (x - x1) * (y - y3) - (x - x2) * (y - y1) - (x - x3) * (y - y2)); + + return z; +} + +export default planepoint; diff --git a/src/planepoint/test.js b/src/planepoint/test.js new file mode 100644 index 0000000000..dbddb99367 --- /dev/null +++ b/src/planepoint/test.js @@ -0,0 +1,17 @@ +// http://math.stackexchange.com/questions/28043/finding-the-z-value-on-a-plane-with-x-y-values +// http://stackoverflow.com/a/13916669/461015 +import test from 'tape'; + +import { polygon } from '../helpers'; +import planepoint from '.'; + + +test('turf-planepoint', t => { + const point = [1, 1]; + const triangleProps = polygon([[[0, 0], [2, 0], [1, 2], [0, 0]]], {a: 0, b: 0, c: 2}); + const triangleZ = polygon([[[0, 0, 0], [2, 0, 0], [1, 2, 2], [0, 0, 0]]]); + + t.equal(planepoint(point, triangleProps), 1, 'properties'); + t.equal(planepoint(point, triangleZ), 1, 'z coordinates'); + t.end(); +}); diff --git a/packages/turf-planepoint/test/in/triangle.geojson b/src/planepoint/test/in/triangle.geojson similarity index 100% rename from packages/turf-planepoint/test/in/triangle.geojson rename to src/planepoint/test/in/triangle.geojson diff --git a/packages/turf-planepoint/types.ts b/src/planepoint/types.ts similarity index 100% rename from packages/turf-planepoint/types.ts rename to src/planepoint/types.ts diff --git a/src/point-grid/bench.js b/src/point-grid/bench.js new file mode 100644 index 0000000000..da8d8c95f7 --- /dev/null +++ b/src/point-grid/bench.js @@ -0,0 +1,29 @@ +const Benchmark = require('benchmark'); +const { polygon } = require('../helpers'); +const grid = require('./'); + +var bbox = [-95, 30, -85, 40]; +var mask = polygon([[[6.5, 44.6 ], [ 9.2, 44.8 ], [ 8.3, 46.4 ], [ 6.5, 44.6 ]]]); + +var highres = grid(bbox, 100, {units: 'miles'}).features.length; +var midres = grid(bbox, 10, {units: 'miles'}).features.length; +var lowres = grid(bbox, 1, {units: 'miles'}).features.length; +var masked = grid(mask, 1, {units: 'miles', mask: mask}).features.length; +var suite = new Benchmark.Suite('turf-square-grid'); + +/** + * Benchmark Results + * + * highres -- 42 cells x 274,666 ops/sec ±1.96% (77 runs sampled) + * midres -- 4200 cells x 2,725 ops/sec ±3.86% (73 runs sampled) + * lowres -- 414508 cells x 2.09 ops/sec ±21.02% (10 runs sampled) + * masked -- 7658 cells x 9,794 ops/sec ±2.08% (75 runs sampled) + */ +suite + .add('highres -- ' + highres + ' cells', () => grid(bbox, 100, {units: 'miles'})) + .add('midres -- ' + midres + ' cells', () => grid(bbox, 10, {units: 'miles'})) + .add('lowres -- ' + lowres + ' cells', () => grid(bbox, 1, {units: 'miles'})) + .add('masked -- ' + masked + ' cells', () => grid(mask, 10, {units: 'miles', mask: mask})) + .on('cycle', e => console.log(String(e.target))) + .on('complete', () => {}) + .run(); diff --git a/src/point-grid/index.js b/src/point-grid/index.js new file mode 100644 index 0000000000..6264d161f9 --- /dev/null +++ b/src/point-grid/index.js @@ -0,0 +1,79 @@ +import within from '../boolean-within'; +import distance from '../distance'; +import {point, featureCollection, checkIfOptionsExist} from '../helpers'; + +/** + * Creates a {@link Point} grid from a bounding box, {@link FeatureCollection} or {@link Feature}. + * + * @name pointGrid + * @param {Array} bbox extent in [minX, minY, maxX, maxY] order + * @param {number} cellSide the distance between points, in units + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] used in calculating cellSide, can be degrees, radians, miles, or kilometers + * @param {Feature} [options.mask] if passed a Polygon or MultiPolygon, the grid Points will be created only inside it + * @param {Object} [options.properties={}] passed to each point of the grid + * @returns {FeatureCollection} grid of points + * @example + * var extent = [-70.823364, -33.553984, -70.473175, -33.302986]; + * var cellSide = 3; + * var options = {units: 'miles'}; + * + * var grid = turf.pointGrid(extent, cellSide, options); + * + * //addToMap + * var addToMap = [grid]; + */ +function pointGrid(bbox, cellSide, options) { + options = checkIfOptionsExist(options); + // Default parameters + if (options.mask && !options.units) options.units = 'kilometers'; + + // Containers + var results = []; + + // Typescript handles the Type Validation + // if (cellSide === null || cellSide === undefined) throw new Error('cellSide is required'); + // if (!isNumber(cellSide)) throw new Error('cellSide is invalid'); + // if (!bbox) throw new Error('bbox is required'); + // if (!Array.isArray(bbox)) throw new Error('bbox must be array'); + // if (bbox.length !== 4) throw new Error('bbox must contain 4 numbers'); + // if (mask && ['Polygon', 'MultiPolygon'].indexOf(getType(mask)) === -1) throw new Error('options.mask must be a (Multi)Polygon'); + + var west = bbox[0]; + var south = bbox[1]; + var east = bbox[2]; + var north = bbox[3]; + + var xFraction = cellSide / (distance([west, south], [east, south], options)); + var cellWidth = xFraction * (east - west); + var yFraction = cellSide / (distance([west, south], [west, north], options)); + var cellHeight = yFraction * (north - south); + + var bboxWidth = (east - west); + var bboxHeight = (north - south); + var columns = Math.floor(bboxWidth / cellWidth); + var rows = Math.floor(bboxHeight / cellHeight); + + // adjust origin of the grid + var deltaX = (bboxWidth - columns * cellWidth) / 2; + var deltaY = (bboxHeight - rows * cellHeight) / 2; + + var currentX = west + deltaX; + while (currentX <= east) { + var currentY = south + deltaY; + while (currentY <= north) { + var cellPt = point([currentX, currentY], options.properties); + if (options.mask) { + if (within(cellPt, options.mask)) results.push(cellPt); + } else { + results.push(cellPt); + } + currentY += cellHeight; + } + currentX += cellWidth; + } + + return featureCollection(results); +} + +export default pointGrid; diff --git a/src/point-grid/test.js b/src/point-grid/test.js new file mode 100644 index 0000000000..20f1ab41f2 --- /dev/null +++ b/src/point-grid/test.js @@ -0,0 +1,79 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const bboxPoly = require('../bbox-polygon').default; +const truncate = require('../truncate').default; +const { point } = require('../helpers'); +const pointGrid = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + json: load.sync(directories.in + filename) + }; +}); + +test('turf-point-grid', t => { + for (const {name, json} of fixtures) { + const {bbox, cellSide} = json; + const options = json; + const result = truncate(pointGrid(bbox, cellSide, options)); + + // Add styled GeoJSON to the result + const poly = bboxPoly(bbox); + poly.properties = { + stroke: '#F00', + 'stroke-width': 6, + 'fill-opacity': 0 + }; + result.features.push(poly); + if (options.mask) { + options.mask.properties = { + "stroke": "#00F", + "stroke-width": 6, + "fill-opacity": 0 + }; + result.features.push(options.mask); + } + + if (process.env.REGEN) write.sync(directories.out + name + '.geojson', result); + t.deepEqual(result, load.sync(directories.out + name + '.geojson'), name); + } + t.end(); +}); + + +test('point-grid -- throw', t => { + const bbox = [0, 0, 1, 1]; + // Typescript handles Types + // t.throws(() => pointGrid(null, 0), /bbox is required/, 'missing bbox'); + // t.throws(() => pointGrid('foo', 0), /bbox must be array/, 'invalid bbox'); + // t.throws(() => pointGrid([0, 2], 1), /bbox must contain 4 numbers/, 'invalid bbox'); + // t.throws(() => pointGrid(bbox, null), /cellSide is required/, 'missing cellSide'); + // t.throws(() => pointGrid(bbox, 'foo'), /cellSide is invalid/, 'invalid cellSide'); + // t.throws(() => pointGrid(bbox, 1, 'foo'), /options is invalid/, 'invalid options'); + // t.throws(() => pointGrid(bbox, 1, {mask: point([0, 10])}), /options.mask must be a \(Multi\)Polygon/, 'invalid options.mask'); + t.end(); +}); + +test('point-grid -- #1177', t => { + const bbox = [0, 0, 1, 1]; + const mask = bboxPoly([0.2, 0.2, 0.8, 0.8]); + let options = {mask: mask}; + t.doesNotThrow(() => pointGrid(bbox, 1, options)); + t.equal(options.units, 'kilometers'); + + let options2 = {mask: mask, units: 'miles'}; + t.doesNotThrow(() => pointGrid(bbox, 1, options2)); + t.equal(options2.units, 'miles'); + + t.end(); +}); diff --git a/packages/turf-point-grid/test/in/big-bbox.json b/src/point-grid/test/in/big-bbox.json similarity index 100% rename from packages/turf-point-grid/test/in/big-bbox.json rename to src/point-grid/test/in/big-bbox.json diff --git a/packages/turf-point-grid/test/in/fiji-10-miles.json b/src/point-grid/test/in/fiji-10-miles.json similarity index 100% rename from packages/turf-point-grid/test/in/fiji-10-miles.json rename to src/point-grid/test/in/fiji-10-miles.json diff --git a/packages/turf-point-grid/test/in/london-20-miles.json b/src/point-grid/test/in/london-20-miles.json similarity index 100% rename from packages/turf-point-grid/test/in/london-20-miles.json rename to src/point-grid/test/in/london-20-miles.json diff --git a/packages/turf-point-grid/test/in/piedemont-mask.json b/src/point-grid/test/in/piedemont-mask.json similarity index 100% rename from packages/turf-point-grid/test/in/piedemont-mask.json rename to src/point-grid/test/in/piedemont-mask.json diff --git a/packages/turf-point-grid/test/in/properties.json b/src/point-grid/test/in/properties.json similarity index 100% rename from packages/turf-point-grid/test/in/properties.json rename to src/point-grid/test/in/properties.json diff --git a/packages/turf-point-grid/test/in/resolute.json b/src/point-grid/test/in/resolute.json similarity index 100% rename from packages/turf-point-grid/test/in/resolute.json rename to src/point-grid/test/in/resolute.json diff --git a/packages/turf-point-grid/test/out/big-bbox.geojson b/src/point-grid/test/out/big-bbox.geojson similarity index 100% rename from packages/turf-point-grid/test/out/big-bbox.geojson rename to src/point-grid/test/out/big-bbox.geojson diff --git a/packages/turf-point-grid/test/out/fiji-10-miles.geojson b/src/point-grid/test/out/fiji-10-miles.geojson similarity index 100% rename from packages/turf-point-grid/test/out/fiji-10-miles.geojson rename to src/point-grid/test/out/fiji-10-miles.geojson diff --git a/packages/turf-point-grid/test/out/london-20-miles.geojson b/src/point-grid/test/out/london-20-miles.geojson similarity index 100% rename from packages/turf-point-grid/test/out/london-20-miles.geojson rename to src/point-grid/test/out/london-20-miles.geojson diff --git a/packages/turf-point-grid/test/out/piedemont-mask.geojson b/src/point-grid/test/out/piedemont-mask.geojson similarity index 100% rename from packages/turf-point-grid/test/out/piedemont-mask.geojson rename to src/point-grid/test/out/piedemont-mask.geojson diff --git a/packages/turf-point-grid/test/out/properties.geojson b/src/point-grid/test/out/properties.geojson similarity index 100% rename from packages/turf-point-grid/test/out/properties.geojson rename to src/point-grid/test/out/properties.geojson diff --git a/packages/turf-point-grid/test/out/resolute.geojson b/src/point-grid/test/out/resolute.geojson similarity index 100% rename from packages/turf-point-grid/test/out/resolute.geojson rename to src/point-grid/test/out/resolute.geojson diff --git a/packages/turf-point-on-feature/bench.js b/src/point-on-feature/bench.js similarity index 100% rename from packages/turf-point-on-feature/bench.js rename to src/point-on-feature/bench.js diff --git a/src/point-on-feature/index.d.ts b/src/point-on-feature/index.d.ts new file mode 100644 index 0000000000..213bcf985a --- /dev/null +++ b/src/point-on-feature/index.d.ts @@ -0,0 +1,8 @@ +import { Feature, Point, AllGeoJSON } from '../helpers'; + +/** + * http://turfjs.org/docs/#pointonfeature + */ +export default function pointOnFeature( + geojson: AllGeoJSON +): Feature; diff --git a/src/point-on-feature/index.js b/src/point-on-feature/index.js new file mode 100644 index 0000000000..2a7dc9ab7b --- /dev/null +++ b/src/point-on-feature/index.js @@ -0,0 +1,143 @@ +import explode from '../explode'; +import centroid from '../center'; +import nearestPoint from '../nearest-point'; +import booleanPointInPolygon from '../boolean-point-in-polygon'; +import { featureCollection, feature, point } from '../helpers'; + +/** + * Takes a Feature or FeatureCollection and returns a {@link Point} guaranteed to be on the surface of the feature. + * + * * Given a {@link Polygon}, the point will be in the area of the polygon + * * Given a {@link LineString}, the point will be along the string + * * Given a {@link Point}, the point will the same as the input + * + * @name pointOnFeature + * @param {GeoJSON} geojson any Feature or FeatureCollection + * @returns {Feature} a point on the surface of `input` + * @example + * var polygon = turf.polygon([[ + * [116, -36], + * [131, -32], + * [146, -43], + * [155, -25], + * [133, -9], + * [111, -22], + * [116, -36] + * ]]); + * + * var pointOnPolygon = turf.pointOnFeature(polygon); + * + * //addToMap + * var addToMap = [polygon, pointOnPolygon]; + */ +function pointOnFeature(geojson) { + // normalize + var fc = normalize(geojson); + + // get centroid + var cent = centroid(fc); + + // check to see if centroid is on surface + var onSurface = false; + var i = 0; + while (!onSurface && i < fc.features.length) { + var geom = fc.features[i].geometry; + var x, y, x1, y1, x2, y2, k; + var onLine = false; + if (geom.type === 'Point') { + if (cent.geometry.coordinates[0] === geom.coordinates[0] && + cent.geometry.coordinates[1] === geom.coordinates[1]) { + onSurface = true; + } + } else if (geom.type === 'MultiPoint') { + var onMultiPoint = false; + k = 0; + while (!onMultiPoint && k < geom.coordinates.length) { + if (cent.geometry.coordinates[0] === geom.coordinates[k][0] && + cent.geometry.coordinates[1] === geom.coordinates[k][1]) { + onSurface = true; + onMultiPoint = true; + } + k++; + } + } else if (geom.type === 'LineString') { + k = 0; + while (!onLine && k < geom.coordinates.length - 1) { + x = cent.geometry.coordinates[0]; + y = cent.geometry.coordinates[1]; + x1 = geom.coordinates[k][0]; + y1 = geom.coordinates[k][1]; + x2 = geom.coordinates[k + 1][0]; + y2 = geom.coordinates[k + 1][1]; + if (pointOnSegment(x, y, x1, y1, x2, y2)) { + onLine = true; + onSurface = true; + } + k++; + } + } else if (geom.type === 'MultiLineString') { + var j = 0; + while (j < geom.coordinates.length) { + onLine = false; + k = 0; + var line = geom.coordinates[j]; + while (!onLine && k < line.length - 1) { + x = cent.geometry.coordinates[0]; + y = cent.geometry.coordinates[1]; + x1 = line[k][0]; + y1 = line[k][1]; + x2 = line[k + 1][0]; + y2 = line[k + 1][1]; + if (pointOnSegment(x, y, x1, y1, x2, y2)) { + onLine = true; + onSurface = true; + } + k++; + } + j++; + } + } else if (geom.type === 'Polygon' || geom.type === 'MultiPolygon') { + if (booleanPointInPolygon(cent, geom)) { + onSurface = true; + } + } + i++; + } + if (onSurface) { + return cent; + } else { + var vertices = featureCollection([]); + for (i = 0; i < fc.features.length; i++) { + vertices.features = vertices.features.concat(explode(fc.features[i]).features); + } + // Remove distanceToPoint properties from nearestPoint() + return point(nearestPoint(cent, vertices).geometry.coordinates); + } +} + +/** + * Normalizes any GeoJSON to a FeatureCollection + * + * @private + * @name normalize + * @param {GeoJSON} geojson Any GeoJSON + * @returns {FeatureCollection} FeatureCollection + */ +function normalize(geojson) { + if (geojson.type !== 'FeatureCollection') { + if (geojson.type !== 'Feature') { + return featureCollection([feature(geojson)]); + } + return featureCollection([geojson]); + } + return geojson; +} + +function pointOnSegment(x, y, x1, y1, x2, y2) { + var ab = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); + var ap = Math.sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1)); + var pb = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)); + return ab === ap + pb; +} + +export default pointOnFeature; diff --git a/src/point-on-feature/test.js b/src/point-on-feature/test.js new file mode 100644 index 0000000000..73d1209e2d --- /dev/null +++ b/src/point-on-feature/test.js @@ -0,0 +1,42 @@ +import fs from 'fs'; +import test from 'tape'; +import glob from 'glob'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import truncate from '../truncate'; +import { featureEach } from '../meta'; +import { featureCollection } from '../helpers'; +import pointOnFeature from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-point-on-feature', t => { + for (const {name, geojson} of fixtures) { + + const ptOnFeature = pointOnFeature(geojson); + + // Style Results + const results = featureCollection([]) + featureEach(geojson, feature => results.features.push(feature)); + ptOnFeature.properties['marker-color'] = '#F00' + ptOnFeature.properties['marker-style'] = 'star' + results.features.push(truncate(ptOnFeature)); + + // Save Tests + if (process.env.REGEN) write.sync(directories.out + name + '.json', results); + t.deepEqual(results, load.sync(directories.out + name + '.json'), name); + }; + t.end(); +}); diff --git a/packages/turf-point-on-feature/test/out/lines.json b/src/point-on-feature/test/in/lines.json similarity index 100% rename from packages/turf-point-on-feature/test/out/lines.json rename to src/point-on-feature/test/in/lines.json diff --git a/packages/turf-point-on-feature/test/out/multiline.json b/src/point-on-feature/test/in/multiline.json similarity index 100% rename from packages/turf-point-on-feature/test/out/multiline.json rename to src/point-on-feature/test/in/multiline.json diff --git a/packages/turf-point-on-feature/test/out/multipoint.json b/src/point-on-feature/test/in/multipoint.json similarity index 100% rename from packages/turf-point-on-feature/test/out/multipoint.json rename to src/point-on-feature/test/in/multipoint.json diff --git a/packages/turf-point-on-feature/test/out/multipolygon.json b/src/point-on-feature/test/in/multipolygon.json similarity index 100% rename from packages/turf-point-on-feature/test/out/multipolygon.json rename to src/point-on-feature/test/in/multipolygon.json diff --git a/packages/turf-point-on-feature/test/out/polygon-in-center.json b/src/point-on-feature/test/in/polygon-in-center.json similarity index 100% rename from packages/turf-point-on-feature/test/out/polygon-in-center.json rename to src/point-on-feature/test/in/polygon-in-center.json diff --git a/packages/turf-point-on-feature/test/out/polygons.json b/src/point-on-feature/test/in/polygons.json similarity index 100% rename from packages/turf-point-on-feature/test/out/polygons.json rename to src/point-on-feature/test/in/polygons.json diff --git a/src/point-on-feature/test/out/lines.json b/src/point-on-feature/test/out/lines.json new file mode 100644 index 0000000000..e23ba3a327 --- /dev/null +++ b/src/point-on-feature/test/out/lines.json @@ -0,0 +1,153 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 24.08203125, + -16.59408141271846 + ], + [ + 25.059814453125, + -14.519780046326073 + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 28.410644531249996, + -14.955399325942619 + ], + [ + 28.7841796875, + -15.845104902273452 + ], + [ + 27.6416015625, + -16.13026201203474 + ], + [ + 27.432861328125, + -17.518344187852218 + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 26.652832031249996, + -13.485789593908478 + ], + [ + 26.268310546875, + -14.891704754215462 + ], + [ + 25.86181640625, + -14.88108715909066 + ], + [ + 25.894775390625, + -15.421910399947057 + ], + [ + 26.323242187499996, + -15.5701278526594 + ], + [ + 26.224365234375, + -16.066928957450106 + ], + [ + 26.510009765625, + -16.583552354072005 + ], + [ + 25.927734374999996, + -16.836089974560213 + ], + [ + 25.147705078125, + -17.245744208007117 + ], + [ + 26.34521484375, + -18.271086109608863 + ], + [ + 25.33447265625, + -18.531700307384043 + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 24.466552734375, + -14.211138758545781 + ], + [ + 25.389404296875, + -13.710035342476669 + ], + [ + 25.609130859375, + -13.944729974920154 + ], + [ + 26.3671875, + -13.090179355733726 + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#F00", + "marker-style": "star" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 26.323242, + -15.570128 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#F00", + "marker-style": "star" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 26.323242, + -15.570128 + ] + } + } + ] +} diff --git a/src/point-on-feature/test/out/multiline.json b/src/point-on-feature/test/out/multiline.json new file mode 100644 index 0000000000..a692a33838 --- /dev/null +++ b/src/point-on-feature/test/out/multiline.json @@ -0,0 +1,148 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [ + 92.08740234375, + 50.708634400828224 + ], + [ + 93.0322265625, + 50.84757295365389 + ], + [ + 94.32861328125, + 50.499452103967734 + ], + [ + 95.25146484374999, + 50.0077390146369 + ], + [ + 97.470703125, + 49.908787000867136 + ], + [ + 98.4375, + 50.51342652633956 + ], + [ + 98.10791015625, + 51.467696956223385 + ], + [ + 99.5361328125, + 52.07950600379697 + ], + [ + 101.14013671875, + 51.645294049305406 + ], + [ + 102.37060546875, + 51.22064743038333 + ], + [ + 102.37060546875, + 50.764259357116465 + ], + [ + 103.18359375, + 50.30337575356313 + ], + [ + 104.56787109374999, + 50.24720490139267 + ], + [ + 105.84228515625, + 50.54136296522161 + ], + [ + 106.89697265625, + 50.2612538275847 + ] + ], + [ + [ + 97.294921875, + 53.605544099237974 + ], + [ + 99.4482421875, + 54.213861000644926 + ], + [ + 99.73388671874999, + 54.04648911335576 + ], + [ + 100.8984375, + 53.969012350740314 + ], + [ + 101.29394531249999, + 53.69670647530323 + ] + ], + [ + [ + 95.0537109375, + 47.68018294648414 + ], + [ + 96.416015625, + 47.502358951968574 + ], + [ + 97.05322265625, + 46.84516443029276 + ], + [ + 98.41552734375, + 47.76886840424207 + ], + [ + 98.89892578125, + 47.45780853075031 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#F00", + "marker-style": "star" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 98.4375, + 50.513427 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#F00", + "marker-style": "star" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 98.4375, + 50.513427 + ] + } + } + ] +} diff --git a/src/point-on-feature/test/out/multipoint.json b/src/point-on-feature/test/out/multipoint.json new file mode 100644 index 0000000000..a1f09dc770 --- /dev/null +++ b/src/point-on-feature/test/out/multipoint.json @@ -0,0 +1,62 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPoint", + "coordinates": [ + [ + 63.6328125, + 57.7041472343419 + ], + [ + 42.1875, + 52.482780222078226 + ], + [ + 71.015625, + 29.22889003019423 + ], + [ + 48.1640625, + 37.71859032558816 + ], + [ + 73.47656249999999, + 49.61070993807422 + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#F00", + "marker-style": "star" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 48.164063, + 37.71859 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#F00", + "marker-style": "star" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 48.164063, + 37.71859 + ] + } + } + ] +} diff --git a/src/point-on-feature/test/out/multipolygon.json b/src/point-on-feature/test/out/multipolygon.json new file mode 100644 index 0000000000..2434fcca43 --- /dev/null +++ b/src/point-on-feature/test/out/multipolygon.json @@ -0,0 +1,114 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 12.041015625, + 36.66841891894786 + ], + [ + 12.041015625, + 39.16414104768742 + ], + [ + 15.161132812500002, + 39.16414104768742 + ], + [ + 15.161132812500002, + 36.66841891894786 + ], + [ + 12.041015625, + 36.66841891894786 + ] + ] + ], + [ + [ + [ + 15.732421875, + 31.42866311735861 + ], + [ + 15.732421875, + 34.92197103616377 + ], + [ + 19.775390625, + 34.92197103616377 + ], + [ + 19.775390625, + 31.42866311735861 + ], + [ + 15.732421875, + 31.42866311735861 + ] + ] + ], + [ + [ + [ + 18.3251953125, + 37.68382032669382 + ], + [ + 18.3251953125, + 42.65012181368025 + ], + [ + 22.0166015625, + 42.65012181368025 + ], + [ + 22.0166015625, + 37.68382032669382 + ], + [ + 18.3251953125, + 37.68382032669382 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#F00", + "marker-style": "star" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 18.325195, + 37.68382 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#F00", + "marker-style": "star" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 18.325195, + 37.68382 + ] + } + } + ] +} diff --git a/src/point-on-feature/test/out/polygon-in-center.json b/src/point-on-feature/test/out/polygon-in-center.json new file mode 100644 index 0000000000..6a2a24120c --- /dev/null +++ b/src/point-on-feature/test/out/polygon-in-center.json @@ -0,0 +1,95 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 13.270797729492186, + 52.42042920678164 + ], + [ + 13.270797729492186, + 52.573846203920276 + ], + [ + 13.5186767578125, + 52.573846203920276 + ], + [ + 13.5186767578125, + 52.42042920678164 + ], + [ + 13.270797729492186, + 52.42042920678164 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 13.526229858398438, + 52.58177420312145 + ], + [ + 13.526229858398438, + 52.61013634893439 + ], + [ + 13.572921752929686, + 52.61013634893439 + ], + [ + 13.572921752929686, + 52.58177420312145 + ], + [ + 13.526229858398438, + 52.58177420312145 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#F00", + "marker-style": "star" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 13.42186, + 52.515283 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#F00", + "marker-style": "star" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 13.42186, + 52.515283 + ] + } + } + ] +} diff --git a/src/point-on-feature/test/out/polygons.json b/src/point-on-feature/test/out/polygons.json new file mode 100644 index 0000000000..49facd03c4 --- /dev/null +++ b/src/point-on-feature/test/out/polygons.json @@ -0,0 +1,199 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -80.4638671875, + 38.496593518947556 + ], + [ + -81.05712890625, + 38.22091976683121 + ], + [ + -80.518798828125, + 37.640334898059486 + ], + [ + -78.81591796875, + 36.730079507078415 + ], + [ + -78.167724609375, + 37.01132594307015 + ], + [ + -78.673095703125, + 37.55328764595765 + ], + [ + -78.94775390625, + 37.49229399862877 + ], + [ + -79.112548828125, + 37.68382032669382 + ], + [ + -79.51904296874999, + 37.75334401310656 + ], + [ + -79.090576171875, + 38.039438891821746 + ], + [ + -79.47509765625, + 38.1172716583054 + ], + [ + -79.969482421875, + 38.315801006824984 + ], + [ + -79.683837890625, + 38.47939467327645 + ], + [ + -79.793701171875, + 38.62545397209084 + ], + [ + -80.09033203125, + 38.71123253895224 + ], + [ + -80.33203125, + 39.104488809440475 + ], + [ + -80.4638671875, + 38.496593518947556 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -76.17919921875, + 41.00477542222949 + ], + [ + -77.091064453125, + 40.97160353279909 + ], + [ + -77.28881835937499, + 40.27952566881291 + ], + [ + -77.080078125, + 40.271143686084194 + ], + [ + -77.003173828125, + 40.136890695345905 + ], + [ + -76.7724609375, + 40.195659093364654 + ], + [ + -76.86035156249999, + 39.93501296038254 + ], + [ + -76.66259765625, + 40.0360265298117 + ], + [ + -76.37695312499999, + 39.614152077002636 + ], + [ + -75.992431640625, + 39.614152077002636 + ], + [ + -75.76171875, + 39.42770738465604 + ], + [ + -75.465087890625, + 39.40224434029275 + ], + [ + -75.377197265625, + 39.68182601089365 + ], + [ + -75.5419921875, + 40.455307212131494 + ], + [ + -76.17919921875, + 40.55554790286311 + ], + [ + -75.750732421875, + 40.697299008636755 + ], + [ + -76.1572265625, + 40.72228267283148 + ], + [ + -75.992431640625, + 40.94671366508002 + ], + [ + -76.17919921875, + 41.00477542222949 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#F00", + "marker-style": "star" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -79.090576, + 38.039439 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#F00", + "marker-style": "star" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -79.090576, + 38.039439 + ] + } + } + ] +} diff --git a/packages/turf-point-to-line-distance/bench.js b/src/point-to-line-distance/bench.js similarity index 100% rename from packages/turf-point-to-line-distance/bench.js rename to src/point-to-line-distance/bench.js diff --git a/src/point-to-line-distance/index.d.ts b/src/point-to-line-distance/index.d.ts new file mode 100644 index 0000000000..abfcb94e82 --- /dev/null +++ b/src/point-to-line-distance/index.d.ts @@ -0,0 +1,26 @@ +import { Coord, Feature, LineString, Units } from "../helpers"; +/** + * Returns the minimum distance between a {@link Point} and a {@link LineString}, being the distance from a line the + * minimum distance between the point and any segment of the `LineString`. + * + * @name pointToLineDistance + * @param {Feature|Array} pt Feature or Geometry + * @param {Feature} line GeoJSON Feature or Geometry + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units="kilometers"] can be anything supported by turf/convertLength + * (ex: degrees, radians, miles, or kilometers) + * @param {string} [options.method="geodesic"] wether to calculate the distance based on geodesic (spheroid) or + * planar (flat) method. Valid options are 'geodesic' or 'planar'. + * @returns {number} distance between point and line + * @example + * var pt = turf.point([0, 0]); + * var line = turf.lineString([[1, 1],[-1, 1]]); + * + * var distance = turf.pointToLineDistance(pt, line, {units: 'miles'}); + * //=69.11854715938406 + */ +declare function pointToLineDistance(pt: Coord, line: Feature | LineString, options?: { + units?: Units; + method?: "geodesic" | "planar"; +}): number; +export default pointToLineDistance; diff --git a/src/point-to-line-distance/index.js b/src/point-to-line-distance/index.js new file mode 100644 index 0000000000..f6e8041117 --- /dev/null +++ b/src/point-to-line-distance/index.js @@ -0,0 +1,101 @@ +// Taken from http://geomalgorithms.com/a02-_lines.html +import getDistance from '../distance'; +import { + checkIfOptionsExist, + convertLength, + feature, + lineString, + point, +} from '../helpers'; +import { featureOf } from '../invariant'; +import { segmentEach } from '../meta'; +import getPlanarDistance from '../rhumb-distance'; + +/** + * Returns the minimum distance between a {@link Point} and a {@link LineString}, being the distance from a line the + * minimum distance between the point and any segment of the `LineString`. + * + * @name pointToLineDistance + * @param {Feature|Array} pt Feature or Geometry + * @param {Feature} line GeoJSON Feature or Geometry + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] can be anything supported by turf/convertLength + * (ex: degrees, radians, miles, or kilometers) + * @param {string} [options.method='geodesic'] wether to calculate the distance based on geodesic (spheroid) or + * planar (flat) method. Valid options are 'geodesic' or 'planar'. + * @returns {number} distance between point and line + * @example + * var pt = turf.point([0, 0]); + * var line = turf.lineString([[1, 1],[-1, 1]]); + * + * var distance = turf.pointToLineDistance(pt, line, {units: 'miles'}); + * //=69.11854715938406 + */ +function pointToLineDistance(pt, line, options) { + + options = checkIfOptionsExist(options); + + // Optional parameters + if (!options.method) { options.method = 'geodesic'; } + if (!options.units) { options.units = 'kilometers'; } + + // validation + if (!pt) { throw new Error('pt is required'); } + if (Array.isArray(pt)) { + pt = point(pt); + } else if (pt.type === 'Point') { + pt = feature(pt); + } else { featureOf(pt, 'Point', 'point'); } + + if (!line) { throw new Error('line is required'); } + if (Array.isArray(line)) { + line = lineString(line); + } else if (line.type === 'LineString') { + line = feature(line); + } else { + featureOf(line, 'LineString', 'line'); + } + + let distance = Infinity; + const p = pt.geometry.coordinates; + segmentEach(line, function (segment) { + const a = segment.geometry.coordinates[0]; + const b = segment.geometry.coordinates[1]; + const d = distanceToSegment(p, a, b, options); + if (d < distance) { distance = d; } + }); + return convertLength(distance, 'degrees', options.units); +} + +/** + * Returns the distance between a point P on a segment AB. + * + * @private + * @param {Array} p external point + * @param {Array} a first segment point + * @param {Array} b second segment point + * @param {Object} [options={}] Optional parameters + * @returns {number} distance + */ +function distanceToSegment(p, a, b, options) { + const v = [b[0] - a[0], b[1] - a[1]]; + const w = [p[0] - a[0], p[1] - a[1]]; + + const c1 = dot(w, v); + if (c1 <= 0) { return calcDistance(p, a, {method: options.method, units: 'degrees'}); } + const c2 = dot(v, v); + if (c2 <= c1) { return calcDistance(p, b, {method: options.method, units: 'degrees'}); } + const b2 = c1 / c2; + const Pb = [a[0] + (b2 * v[0]), a[1] + (b2 * v[1])]; + return calcDistance(p, Pb, {method: options.method, units: 'degrees'}); +} + +function dot(u, v) { + return (u[0] * v[0] + u[1] * v[1]); +} + +function calcDistance(a, b, options) { + return options.method === 'planar' ? getPlanarDistance(a, b, options) : getDistance(a, b, options); +} + +export default pointToLineDistance; diff --git a/src/point-to-line-distance/test.js b/src/point-to-line-distance/test.js new file mode 100644 index 0000000000..c9baadf9d0 --- /dev/null +++ b/src/point-to-line-distance/test.js @@ -0,0 +1,80 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const circle = require('../circle').default; +const { point, lineString, round } = require('../helpers'); +const pointToLineDistance = require('.').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-point-to-line-distance', t => { + const results = {}; + fixtures.forEach(fixture => { + const filename = fixture.filename; + const name = fixture.name; + const geojson = fixture.geojson; + const point = geojson.features[0]; + const line = geojson.features[1]; + const properties = geojson.properties || {}; + const units = properties.units || 'kilometers'; + // main method + const options = {units: units}; + options.method = 'geodesic'; + const distance = pointToLineDistance(point, line, options); + + // Store results + results[name] = round(distance, 10); + + // debug purposes + geojson.features.push(circle(point, distance, {steps: 200, units: units})); + if (process.env.REGEN) write.sync(directories.out + filename, geojson); + }); + if (process.env.REGEN) write.sync(directories.out + 'distances.json', results); + t.deepEqual(load.sync(directories.out + 'distances.json'), results); + t.end(); +}); + +test('turf-point-to-line-distance -- throws', t => { + const pt = point([0, 0]); + const line = lineString([[1, 1], [-1, 1]]); + + t.throws(() => pointToLineDistance(null, line), /pt is required/, 'missing point'); + t.throws(() => pointToLineDistance(pt, null), /line is required/, 'missing line'); + t.throws(() => pointToLineDistance(pt, line, {units: 'invalid'}), /units is invalid/, 'invalid units'); + t.throws(() => pointToLineDistance(line, line), /Invalid input to point: must be a Point, given LineString/, 'invalid line'); + t.throws(() => pointToLineDistance(pt, pt), /Invalid input to line: must be a LineString, given Point/, 'invalid point'); + + t.end(); +}); + +test('turf-point-to-line-distance -- Geometry', t => { + const pt = point([0, 0]); + const line = lineString([[1, 1], [-1, 1]]); + + t.assert(pointToLineDistance(pt.geometry, line.geometry)); + t.end(); +}); + + +test('turf-point-to-line-distance -- Check planar and geodesic results are different', t => { + const pt = point([0, 0]); + const line = lineString([[10, 10], [-1, 1]]); + + const geoOut = pointToLineDistance(pt.geometry, line.geometry, {method: 'geodesic'}); + const planarOut = pointToLineDistance(pt.geometry, line.geometry, {method: 'planar'}); + t.notEqual(geoOut, planarOut); + t.end(); +}); diff --git a/packages/turf-point-to-line-distance/test/in/city-line1.geojson b/src/point-to-line-distance/test/in/city-line1.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/city-line1.geojson rename to src/point-to-line-distance/test/in/city-line1.geojson diff --git a/packages/turf-point-to-line-distance/test/in/city-line2.geojson b/src/point-to-line-distance/test/in/city-line2.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/city-line2.geojson rename to src/point-to-line-distance/test/in/city-line2.geojson diff --git a/packages/turf-point-to-line-distance/test/in/city-segment-inside1.geojson b/src/point-to-line-distance/test/in/city-segment-inside1.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/city-segment-inside1.geojson rename to src/point-to-line-distance/test/in/city-segment-inside1.geojson diff --git a/packages/turf-point-to-line-distance/test/in/city-segment-inside2.geojson b/src/point-to-line-distance/test/in/city-segment-inside2.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/city-segment-inside2.geojson rename to src/point-to-line-distance/test/in/city-segment-inside2.geojson diff --git a/packages/turf-point-to-line-distance/test/in/city-segment-inside3.geojson b/src/point-to-line-distance/test/in/city-segment-inside3.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/city-segment-inside3.geojson rename to src/point-to-line-distance/test/in/city-segment-inside3.geojson diff --git a/packages/turf-point-to-line-distance/test/in/city-segment-obtuse1.geojson b/src/point-to-line-distance/test/in/city-segment-obtuse1.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/city-segment-obtuse1.geojson rename to src/point-to-line-distance/test/in/city-segment-obtuse1.geojson diff --git a/packages/turf-point-to-line-distance/test/in/city-segment-obtuse2.geojson b/src/point-to-line-distance/test/in/city-segment-obtuse2.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/city-segment-obtuse2.geojson rename to src/point-to-line-distance/test/in/city-segment-obtuse2.geojson diff --git a/packages/turf-point-to-line-distance/test/in/city-segment-projected1.geojson b/src/point-to-line-distance/test/in/city-segment-projected1.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/city-segment-projected1.geojson rename to src/point-to-line-distance/test/in/city-segment-projected1.geojson diff --git a/packages/turf-point-to-line-distance/test/in/city-segment-projected2.geojson b/src/point-to-line-distance/test/in/city-segment-projected2.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/city-segment-projected2.geojson rename to src/point-to-line-distance/test/in/city-segment-projected2.geojson diff --git a/packages/turf-point-to-line-distance/test/in/issue-1156.geojson b/src/point-to-line-distance/test/in/issue-1156.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/issue-1156.geojson rename to src/point-to-line-distance/test/in/issue-1156.geojson diff --git a/packages/turf-point-to-line-distance/test/in/line-fiji.geojson b/src/point-to-line-distance/test/in/line-fiji.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/line-fiji.geojson rename to src/point-to-line-distance/test/in/line-fiji.geojson diff --git a/packages/turf-point-to-line-distance/test/in/line-resolute-bay.geojson b/src/point-to-line-distance/test/in/line-resolute-bay.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/line-resolute-bay.geojson rename to src/point-to-line-distance/test/in/line-resolute-bay.geojson diff --git a/packages/turf-point-to-line-distance/test/in/line1.geojson b/src/point-to-line-distance/test/in/line1.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/line1.geojson rename to src/point-to-line-distance/test/in/line1.geojson diff --git a/packages/turf-point-to-line-distance/test/in/line2.geojson b/src/point-to-line-distance/test/in/line2.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/line2.geojson rename to src/point-to-line-distance/test/in/line2.geojson diff --git a/packages/turf-point-to-line-distance/test/in/segment-fiji.geojson b/src/point-to-line-distance/test/in/segment-fiji.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/segment-fiji.geojson rename to src/point-to-line-distance/test/in/segment-fiji.geojson diff --git a/packages/turf-point-to-line-distance/test/in/segment1.geojson b/src/point-to-line-distance/test/in/segment1.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/segment1.geojson rename to src/point-to-line-distance/test/in/segment1.geojson diff --git a/packages/turf-point-to-line-distance/test/in/segment1a.geojson b/src/point-to-line-distance/test/in/segment1a.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/segment1a.geojson rename to src/point-to-line-distance/test/in/segment1a.geojson diff --git a/packages/turf-point-to-line-distance/test/in/segment2.geojson b/src/point-to-line-distance/test/in/segment2.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/segment2.geojson rename to src/point-to-line-distance/test/in/segment2.geojson diff --git a/packages/turf-point-to-line-distance/test/in/segment3.geojson b/src/point-to-line-distance/test/in/segment3.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/segment3.geojson rename to src/point-to-line-distance/test/in/segment3.geojson diff --git a/packages/turf-point-to-line-distance/test/in/segment4.geojson b/src/point-to-line-distance/test/in/segment4.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/in/segment4.geojson rename to src/point-to-line-distance/test/in/segment4.geojson diff --git a/packages/turf-point-to-line-distance/test/out/city-line1.geojson b/src/point-to-line-distance/test/out/city-line1.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/city-line1.geojson rename to src/point-to-line-distance/test/out/city-line1.geojson diff --git a/packages/turf-point-to-line-distance/test/out/city-line2.geojson b/src/point-to-line-distance/test/out/city-line2.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/city-line2.geojson rename to src/point-to-line-distance/test/out/city-line2.geojson diff --git a/packages/turf-point-to-line-distance/test/out/city-segment-inside1.geojson b/src/point-to-line-distance/test/out/city-segment-inside1.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/city-segment-inside1.geojson rename to src/point-to-line-distance/test/out/city-segment-inside1.geojson diff --git a/packages/turf-point-to-line-distance/test/out/city-segment-inside2.geojson b/src/point-to-line-distance/test/out/city-segment-inside2.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/city-segment-inside2.geojson rename to src/point-to-line-distance/test/out/city-segment-inside2.geojson diff --git a/packages/turf-point-to-line-distance/test/out/city-segment-inside3.geojson b/src/point-to-line-distance/test/out/city-segment-inside3.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/city-segment-inside3.geojson rename to src/point-to-line-distance/test/out/city-segment-inside3.geojson diff --git a/packages/turf-point-to-line-distance/test/out/city-segment-obtuse1.geojson b/src/point-to-line-distance/test/out/city-segment-obtuse1.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/city-segment-obtuse1.geojson rename to src/point-to-line-distance/test/out/city-segment-obtuse1.geojson diff --git a/packages/turf-point-to-line-distance/test/out/city-segment-obtuse2.geojson b/src/point-to-line-distance/test/out/city-segment-obtuse2.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/city-segment-obtuse2.geojson rename to src/point-to-line-distance/test/out/city-segment-obtuse2.geojson diff --git a/packages/turf-point-to-line-distance/test/out/city-segment-projected1.geojson b/src/point-to-line-distance/test/out/city-segment-projected1.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/city-segment-projected1.geojson rename to src/point-to-line-distance/test/out/city-segment-projected1.geojson diff --git a/packages/turf-point-to-line-distance/test/out/city-segment-projected2.geojson b/src/point-to-line-distance/test/out/city-segment-projected2.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/city-segment-projected2.geojson rename to src/point-to-line-distance/test/out/city-segment-projected2.geojson diff --git a/packages/turf-point-to-line-distance/test/out/distances.json b/src/point-to-line-distance/test/out/distances.json similarity index 100% rename from packages/turf-point-to-line-distance/test/out/distances.json rename to src/point-to-line-distance/test/out/distances.json diff --git a/packages/turf-point-to-line-distance/test/out/issue-1156.geojson b/src/point-to-line-distance/test/out/issue-1156.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/issue-1156.geojson rename to src/point-to-line-distance/test/out/issue-1156.geojson diff --git a/packages/turf-point-to-line-distance/test/out/line-fiji.geojson b/src/point-to-line-distance/test/out/line-fiji.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/line-fiji.geojson rename to src/point-to-line-distance/test/out/line-fiji.geojson diff --git a/packages/turf-point-to-line-distance/test/out/line-resolute-bay.geojson b/src/point-to-line-distance/test/out/line-resolute-bay.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/line-resolute-bay.geojson rename to src/point-to-line-distance/test/out/line-resolute-bay.geojson diff --git a/packages/turf-point-to-line-distance/test/out/line1.geojson b/src/point-to-line-distance/test/out/line1.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/line1.geojson rename to src/point-to-line-distance/test/out/line1.geojson diff --git a/packages/turf-point-to-line-distance/test/out/line2.geojson b/src/point-to-line-distance/test/out/line2.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/line2.geojson rename to src/point-to-line-distance/test/out/line2.geojson diff --git a/packages/turf-point-to-line-distance/test/out/segment-fiji.geojson b/src/point-to-line-distance/test/out/segment-fiji.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/segment-fiji.geojson rename to src/point-to-line-distance/test/out/segment-fiji.geojson diff --git a/packages/turf-point-to-line-distance/test/out/segment1.geojson b/src/point-to-line-distance/test/out/segment1.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/segment1.geojson rename to src/point-to-line-distance/test/out/segment1.geojson diff --git a/packages/turf-point-to-line-distance/test/out/segment1a.geojson b/src/point-to-line-distance/test/out/segment1a.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/segment1a.geojson rename to src/point-to-line-distance/test/out/segment1a.geojson diff --git a/packages/turf-point-to-line-distance/test/out/segment2.geojson b/src/point-to-line-distance/test/out/segment2.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/segment2.geojson rename to src/point-to-line-distance/test/out/segment2.geojson diff --git a/packages/turf-point-to-line-distance/test/out/segment3.geojson b/src/point-to-line-distance/test/out/segment3.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/segment3.geojson rename to src/point-to-line-distance/test/out/segment3.geojson diff --git a/packages/turf-point-to-line-distance/test/out/segment4.geojson b/src/point-to-line-distance/test/out/segment4.geojson similarity index 100% rename from packages/turf-point-to-line-distance/test/out/segment4.geojson rename to src/point-to-line-distance/test/out/segment4.geojson diff --git a/src/points-within-polygon/bench.js b/src/points-within-polygon/bench.js new file mode 100644 index 0000000000..22630c4a4b --- /dev/null +++ b/src/points-within-polygon/bench.js @@ -0,0 +1,22 @@ +import fs from 'fs'; +import Benchmark from 'benchmark'; +import { featureCollection, point, polygon } from '../helpers'; +import pointsWithinPolygon from './'; + +var poly1 = polygon([[[0, 0], [10, 0], [10, 10], [0, 0]]]); +var poly2 = polygon([[[10, 0], [20, 10], [20, 20], [10, 0]]]); +var polyFC = featureCollection([poly1, poly2]); +var pt1 = point([1, 1], {population: 500}); +var pt2 = point([1, 3], {population: 400}); +var pt3 = point([14, 2], {population: 600}); +var pt4 = point([13, 1], {population: 500}); +var pt5 = point([19, 7], {population: 200}); +var pt6 = point([100, 7], {population: 200}); +var ptFC = featureCollection([pt1, pt2, pt3, pt4, pt5, pt6]); + +var suite = new Benchmark.Suite('turf-points-within-polygon'); +suite + .add('turf-points-within-polygon', () => pointsWithinPolygon(ptFC, polyFC)) + .on('cycle', e => console.log(String(e.target))) + .on('complete', () => {}) + .run(); diff --git a/src/points-within-polygon/index.d.ts b/src/points-within-polygon/index.d.ts new file mode 100644 index 0000000000..26d082fe2d --- /dev/null +++ b/src/points-within-polygon/index.d.ts @@ -0,0 +1,9 @@ +import { Feature, FeatureCollection, Polygon, MultiPolygon, Point } from '../helpers' + +/** + * http://turfjs.org/docs/#pointswithinpolygon + */ +export default function pointsWithinPolygon( + points: Feature | FeatureCollection, + polygons: Feature | FeatureCollection | G +): FeatureCollection; diff --git a/src/points-within-polygon/index.js b/src/points-within-polygon/index.js new file mode 100644 index 0000000000..2bf9ce9b9a --- /dev/null +++ b/src/points-within-polygon/index.js @@ -0,0 +1,50 @@ +import pointInPolygon from '../boolean-point-in-polygon'; +import { featureCollection } from '../helpers'; +import { geomEach, featureEach } from '../meta'; + +/** + * Finds {@link Points} that fall within {@link (Multi)Polygon(s)}. + * + * @name pointsWithinPolygon + * @param {Feauture|FeatureCollection} points Points as input search + * @param {FeatureCollection|Geoemtry|Feature} polygons Points must be within these (Multi)Polygon(s) + * @returns {FeatureCollection} points that land within at least one polygon + * @example + * var points = turf.points([ + * [-46.6318, -23.5523], + * [-46.6246, -23.5325], + * [-46.6062, -23.5513], + * [-46.663, -23.554], + * [-46.643, -23.557] + * ]); + * + * var searchWithin = turf.polygon([[ + * [-46.653,-23.543], + * [-46.634,-23.5346], + * [-46.613,-23.543], + * [-46.614,-23.559], + * [-46.631,-23.567], + * [-46.653,-23.560], + * [-46.653,-23.543] + * ]]); + * + * var ptsWithin = turf.pointsWithinPolygon(points, searchWithin); + * + * //addToMap + * var addToMap = [points, searchWithin, ptsWithin] + * turf.featureEach(ptsWithin, function (currentFeature) { + * currentFeature.properties['marker-size'] = 'large'; + * currentFeature.properties['marker-color'] = '#000'; + * }); + */ +function pointsWithinPolygon(points, polygons) { + var results = []; + geomEach(polygons, function (polygon) { + featureEach(points, function (point) { + if (pointInPolygon(point, polygon)) results.push(point); + }); + }); + return featureCollection(results); +} + +export default pointsWithinPolygon; diff --git a/src/points-within-polygon/test.js b/src/points-within-polygon/test.js new file mode 100644 index 0000000000..b09e6d6da0 --- /dev/null +++ b/src/points-within-polygon/test.js @@ -0,0 +1,71 @@ +import test from 'tape'; +import { point, points } from '../helpers'; +import { polygon } from '../helpers'; +import { featureCollection } from '../helpers'; +import pointsWithinPolygon from '.'; + +test('turf-points-within-polygon', t => { + t.plan(4); + + // test with a single point + var poly = polygon([[[0, 0], [0, 100], [100, 100], [100, 0], [0, 0]]]); + var pt = point([50, 50]); + var polyFC = featureCollection([poly]); + var ptFC = featureCollection([pt]); + + var counted = pointsWithinPolygon(ptFC, polyFC); + + t.ok(counted, 'returns a featurecollection'); + t.equal(counted.features.length, 1, '1 point in 1 polygon'); + + // test with multiple points and multiple polygons + var poly1 = polygon([[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]); + var poly2 = polygon([[[10, 0], [20, 10], [20, 20], [20, 0], [10, 0]]]); + var polyFC = featureCollection([poly1, poly2]); + var pt1 = point([1, 1], {population: 500}); + var pt2 = point([1, 3], {population: 400}); + var pt3 = point([14, 2], {population: 600}); + var pt4 = point([13, 1], {population: 500}); + var pt5 = point([19, 7], {population: 200}); + var pt6 = point([100, 7], {population: 200}); + var ptFC = featureCollection([pt1, pt2, pt3, pt4, pt5, pt6]); + + var counted = pointsWithinPolygon(ptFC, polyFC); + t.ok(counted, 'returns a featurecollection'); + t.equal(counted.features.length, 5, 'multiple points in multiple polygons'); +}); + +test('turf-points-within-polygon -- support extra geometry', t => { + const pts = points([ + [-46.6318, -23.5523], + [-46.6246, -23.5325], + [-46.6062, -23.5513], + [-46.663, -23.554], + [-46.643, -23.557] + ]); + const searchWithin = polygon([[ + [-46.653,-23.543], + [-46.634,-23.5346], + [-46.613,-23.543], + [-46.614,-23.559], + [-46.631,-23.567], + [-46.653,-23.560], + [-46.653,-23.543] + ]]); + t.assert(pointsWithinPolygon(pts, searchWithin)); + t.assert(pointsWithinPolygon(pts.features[0], searchWithin)); + t.assert(pointsWithinPolygon(pts, searchWithin.geometry)); + t.end() +}); + +// test('turf-points-within-polygon -- no duplicates when multiple geometry contain a point', t => { +// const poly1 = polygon([[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]); +// const poly2 = polygon([[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]); +// const polyFC = featureCollection([poly1, poly2]); +// const pt1 = point([5, 5]); +// const ptFC = featureCollection([pt1]); + +// const counted = pointsWithinPolygon(ptFC, polyFC); +// t.equal(counted.features.length, 1, 'although point is contained by two polygons it is only counted once'); +// t.end(); +// }); diff --git a/packages/turf-polygon-smooth/bench.js b/src/polygon-smooth/bench.js similarity index 100% rename from packages/turf-polygon-smooth/bench.js rename to src/polygon-smooth/bench.js diff --git a/packages/turf-polygon-smooth/index.d.ts b/src/polygon-smooth/index.d.ts similarity index 100% rename from packages/turf-polygon-smooth/index.d.ts rename to src/polygon-smooth/index.d.ts diff --git a/src/polygon-smooth/index.js b/src/polygon-smooth/index.js new file mode 100644 index 0000000000..34d07cc0d4 --- /dev/null +++ b/src/polygon-smooth/index.js @@ -0,0 +1,108 @@ +import { geomEach, coordEach } from '../meta'; +import { polygon, multiPolygon, featureCollection } from '../helpers'; + +/** + * Smooths a {@link Polygon}. Based on [Chaikin's algorithm](http://graphics.cs.ucdavis.edu/education/CAGDNotes/Chaikins-Algorithm/Chaikins-Algorithm.html). + * Warning: may create degenerate polygons. + * + * @name polygonSmooth + * @param {FeatureCollection} inputPolys to smooth + * @param {Object} [options={}] Optional parameters + * @param {string} [options.iterations=1] THe number of times to smooth the polygon. A higher value means a smoother polygon. + * @returns {FeatureCollection} FeatureCollection containing the smoothed polygon/poylgons + * @example + * var polygon = turf.polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); + * + * var smoothed = turf.polygonSmooth(polygon) + * + * //addToMap + * var addToMap = [smoothed, polygon]; + */ +function polygonSmooth(inputPolys, options) { + var outPolys = []; + // Optional parameters + var iterations = options.iterations || 1; + if (!inputPolys) throw new Error('inputPolys is required'); + + geomEach(inputPolys, function (geom, geomIndex, properties) { + var type = geom.type === 'Polygon' ? 'Polygon' : 'MultiPolygon'; + var outCoords = type === 'Polygon' ? [] : [[]]; + + for (var i = 0; i < iterations; i++) { + var tempOutput = type === 'Polygon' ? [[]] : [[[]]]; + var poly = geom; + if (i > 0) { + poly = type === 'Polygon' ? polygon(outCoords).geometry : multiPolygon(outCoords).geometry; + } + if (type === 'Polygon') processPolygon(poly, tempOutput); + else processMultiPolygon(poly, tempOutput); + outCoords = tempOutput.slice(0); + } + if (type === 'Polygon') outPolys.push(polygon(outCoords, properties)); + else outPolys.push(multiPolygon(outCoords, properties)); + }); + return featureCollection(outPolys); +} + +/** + * @private + */ +function processPolygon(poly, tempOutput) { + var prevGeomIndex = 0; + var subtractCoordIndex = 0; + coordEach(poly, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) { + if (geometryIndex > prevGeomIndex) { + prevGeomIndex = geometryIndex; + subtractCoordIndex = coordIndex; + tempOutput.push([]); + } + var realCoordIndex = coordIndex - subtractCoordIndex; + var p1 = poly.coordinates[geometryIndex][realCoordIndex + 1]; + var p0x = currentCoord[0]; + var p0y = currentCoord[1]; + var p1x = p1[0]; + var p1y = p1[1]; + tempOutput[geometryIndex].push([0.75 * p0x + 0.25 * p1x, 0.75 * p0y + 0.25 * p1y]); + tempOutput[geometryIndex].push([0.25 * p0x + 0.75 * p1x, 0.25 * p0y + 0.75 * p1y]); + }, true); + tempOutput.forEach(function (ring) { + ring.push(ring[0]); + }); +} + +/** + * @private + */ +function processMultiPolygon(poly, tempOutput) { + var prevGeomIndex = 0; + var subtractCoordIndex = 0; + var prevMultiIndex = 0; + coordEach(poly, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) { + if (multiFeatureIndex > prevMultiIndex) { + prevMultiIndex = multiFeatureIndex; + subtractCoordIndex = coordIndex; + tempOutput.push([[]]); + } + if (geometryIndex > prevGeomIndex) { + prevGeomIndex = geometryIndex; + subtractCoordIndex = coordIndex; + tempOutput[multiFeatureIndex].push([]); + } + var realCoordIndex = coordIndex - subtractCoordIndex; + var p1 = poly.coordinates[multiFeatureIndex][geometryIndex][realCoordIndex + 1]; + var p0x = currentCoord[0]; + var p0y = currentCoord[1]; + var p1x = p1[0]; + var p1y = p1[1]; + tempOutput[multiFeatureIndex][geometryIndex].push([0.75 * p0x + 0.25 * p1x, 0.75 * p0y + 0.25 * p1y]); + tempOutput[multiFeatureIndex][geometryIndex].push([0.25 * p0x + 0.75 * p1x, 0.25 * p0y + 0.75 * p1y]); + }, true); + + tempOutput.forEach(function (poly) { + poly.forEach(function (ring) { + ring.push(ring[0]); + }); + }); +} + +export default polygonSmooth; diff --git a/src/polygon-smooth/test.js b/src/polygon-smooth/test.js new file mode 100644 index 0000000000..2443593393 --- /dev/null +++ b/src/polygon-smooth/test.js @@ -0,0 +1,37 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import glob from 'glob'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import polygonSmooth from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-polygon-smooth', t => { + fixtures.forEach(fixture => { + // Inputs + const geojson = fixture.geojson; + const options = geojson.options || {}; + const iterations = options.iterations || 3; + + // Results + const results = polygonSmooth(geojson, {iterations}); + + // Save Results + if (process.env.REGEN) write.sync(directories.out + fixture.filename, geojson); + t.deepEqual(load.sync(directories.out + fixture.filename), results); + }); + t.end(); +}); diff --git a/packages/turf-polygon-smooth/test/in/close.json b/src/polygon-smooth/test/in/close.json similarity index 100% rename from packages/turf-polygon-smooth/test/in/close.json rename to src/polygon-smooth/test/in/close.json diff --git a/packages/turf-polygon-smooth/test/in/geometry.json b/src/polygon-smooth/test/in/geometry.json similarity index 100% rename from packages/turf-polygon-smooth/test/in/geometry.json rename to src/polygon-smooth/test/in/geometry.json diff --git a/packages/turf-polygon-smooth/test/in/multipolygon.json b/src/polygon-smooth/test/in/multipolygon.json similarity index 100% rename from packages/turf-polygon-smooth/test/in/multipolygon.json rename to src/polygon-smooth/test/in/multipolygon.json diff --git a/packages/turf-polygon-smooth/test/in/multipolygonWithHole.json b/src/polygon-smooth/test/in/multipolygonWithHole.json similarity index 100% rename from packages/turf-polygon-smooth/test/in/multipolygonWithHole.json rename to src/polygon-smooth/test/in/multipolygonWithHole.json diff --git a/packages/turf-polygon-smooth/test/in/polygon.json b/src/polygon-smooth/test/in/polygon.json similarity index 100% rename from packages/turf-polygon-smooth/test/in/polygon.json rename to src/polygon-smooth/test/in/polygon.json diff --git a/packages/turf-polygon-smooth/test/in/withHole.json b/src/polygon-smooth/test/in/withHole.json similarity index 100% rename from packages/turf-polygon-smooth/test/in/withHole.json rename to src/polygon-smooth/test/in/withHole.json diff --git a/packages/turf-polygon-smooth/test/out/close.json b/src/polygon-smooth/test/out/close.json similarity index 100% rename from packages/turf-polygon-smooth/test/out/close.json rename to src/polygon-smooth/test/out/close.json diff --git a/packages/turf-polygon-smooth/test/out/geometry.json b/src/polygon-smooth/test/out/geometry.json similarity index 100% rename from packages/turf-polygon-smooth/test/out/geometry.json rename to src/polygon-smooth/test/out/geometry.json diff --git a/packages/turf-polygon-smooth/test/out/multipolygon.json b/src/polygon-smooth/test/out/multipolygon.json similarity index 100% rename from packages/turf-polygon-smooth/test/out/multipolygon.json rename to src/polygon-smooth/test/out/multipolygon.json diff --git a/packages/turf-polygon-smooth/test/out/multipolygonWithHole.json b/src/polygon-smooth/test/out/multipolygonWithHole.json similarity index 100% rename from packages/turf-polygon-smooth/test/out/multipolygonWithHole.json rename to src/polygon-smooth/test/out/multipolygonWithHole.json diff --git a/packages/turf-polygon-smooth/test/out/polygon.json b/src/polygon-smooth/test/out/polygon.json similarity index 100% rename from packages/turf-polygon-smooth/test/out/polygon.json rename to src/polygon-smooth/test/out/polygon.json diff --git a/packages/turf-polygon-smooth/test/out/withHole.json b/src/polygon-smooth/test/out/withHole.json similarity index 100% rename from packages/turf-polygon-smooth/test/out/withHole.json rename to src/polygon-smooth/test/out/withHole.json diff --git a/packages/turf-polygon-tangents/bench.js b/src/polygon-tangents/bench.js similarity index 100% rename from packages/turf-polygon-tangents/bench.js rename to src/polygon-tangents/bench.js diff --git a/src/polygon-tangents/index.d.ts b/src/polygon-tangents/index.d.ts new file mode 100644 index 0000000000..db940086c7 --- /dev/null +++ b/src/polygon-tangents/index.d.ts @@ -0,0 +1,9 @@ +import { Feature, FeatureCollection, Coord, Point, Polygon, MultiPolygon } from '../helpers' + +/** + * http://turfjs.org/docs/#polygontangents + */ +export default function ( + point: Coord, + polygon: Feature | T +): FeatureCollection; diff --git a/src/polygon-tangents/index.js b/src/polygon-tangents/index.js new file mode 100644 index 0000000000..1405e723dd --- /dev/null +++ b/src/polygon-tangents/index.js @@ -0,0 +1,87 @@ +import { getCoords, getType } from '../invariant'; +import { point, featureCollection } from '../helpers'; + +/** + * Finds the tangents of a {@link Polygon|(Multi)Polygon} from a {@link Point}. + * + * @name polygonTangents + * @param {Coord} pt to calculate the tangent points from + * @param {Feature} polygon to get tangents from + * @returns {FeatureCollection} Feature Collection containing the two tangent points + * @example + * var polygon = turf.polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); + * var point = turf.point([61, 5]); + * + * var tangents = turf.polygonTangents(point, polygon) + * + * //addToMap + * var addToMap = [tangents, point, polygon]; + */ +function polygonTangents(pt, polygon) { + var pointCoords = getCoords(pt); + var polyCoords = getCoords(polygon); + + var rtan; + var ltan; + var enext; + var eprev; + + var type = getType(polygon); + switch (type) { + case 'Polygon': + rtan = polyCoords[0][0]; + ltan = polyCoords[0][0]; + eprev = isLeft(polyCoords[0][0], polyCoords[0][polyCoords[0].length - 1], pointCoords); + var out = processPolygon(polyCoords[0], pointCoords, eprev, enext, rtan, ltan); + rtan = out[0]; + ltan = out[1]; + break; + case 'MultiPolygon': + rtan = polyCoords[0][0][0]; + ltan = polyCoords[0][0][0]; + eprev = isLeft(polyCoords[0][0][0], polyCoords[0][0][polyCoords[0][0].length - 1], pointCoords); + polyCoords.forEach(function (ring) { + var out = processPolygon(ring[0], pointCoords, eprev, enext, rtan, ltan); + rtan = out[0]; + ltan = out[1]; + }); + break; + } + return featureCollection([point(rtan), point(ltan)]); +} + +function processPolygon(polygonCoords, ptCoords, eprev, enext, rtan, ltan) { + for (var i = 0; i < polygonCoords.length; i++) { + var currentCoords = polygonCoords[i]; + var nextCoordPair = polygonCoords[i + 1]; + if (i === polygonCoords.length - 1) { + nextCoordPair = polygonCoords[0]; + } + enext = isLeft(currentCoords, nextCoordPair, ptCoords); + if (eprev <= 0 && enext > 0) { + if (!isBelow(ptCoords, currentCoords, rtan)) { + rtan = currentCoords; + } + } else if (eprev > 0 && enext <= 0) { + if (!isAbove(ptCoords, currentCoords, ltan)) { + ltan = currentCoords; + } + } + eprev = enext; + } + return [rtan, ltan]; +} + +function isAbove(point1, point2, point3) { + return isLeft(point1, point2, point3) > 0; +} + +function isBelow(point1, point2, point3) { + return isLeft(point1, point2, point3) < 0; +} + +function isLeft(point1, point2, point3) { + return (point2[0] - point1[0]) * (point3[1] - point1[1]) - (point3[0] - point1[0]) * (point2[1] - point1[1]); +} + +export default polygonTangents; diff --git a/src/polygon-tangents/test.js b/src/polygon-tangents/test.js new file mode 100644 index 0000000000..51f6e7a552 --- /dev/null +++ b/src/polygon-tangents/test.js @@ -0,0 +1,74 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import { polygon, point } from '../helpers'; +import polygonTangents from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-polygon-tangents', t => { + for (const {name, filename, geojson} of fixtures) { + const [poly, pt] = geojson.features; + const results = polygonTangents(pt, poly); + results.features = results.features.concat(geojson.features); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(load.sync(directories.out + filename), results, name); + } + t.end(); +}); + +test('turf-polygon-tangents - Geometry Objects', t => { + const pt = point([61, 5]); + const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); + t.assert(polygonTangents(pt.geometry, poly.geometry)); + t.end(); +}); + +test('turf-polygon-tangents - Prevent Input Mutation', t => { + const pt = point([61, 5]); + const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); + const beforePoly = JSON.parse(JSON.stringify(poly)); + const beforePt = JSON.parse(JSON.stringify(pt)); + polygonTangents(pt.geometry, poly.geometry); + t.deepEqual(poly, beforePoly, 'pt should not mutate'); + t.deepEqual(pt, beforePt, 'poly should not mutate'); + t.end(); +}); + +test('turf-polygon-tangents - Issue #1050', t => { + const pt = [8.725,51.57]; + const poly = polygon([[ + [8.788482103824089,51.56063487730164], + [8.788583,51.561554],[8.78839,51.562241], + [8.78705,51.563616],[8.785483,51.564445], + [8.785481,51.564446],[8.785479,51.564447], + [8.785479,51.564449],[8.785478,51.56445], + [8.785478,51.564452],[8.785479,51.564454], + [8.78548,51.564455],[8.785482,51.564457], + [8.786358,51.565053],[8.787022,51.565767], + [8.787024,51.565768],[8.787026,51.565769], + [8.787028,51.56577],[8.787031,51.565771], + [8.787033,51.565771],[8.789951649580397,51.56585502173034], + [8.789734,51.563604],[8.788482103824089,51.56063487730164] + ]]); + try { + t.assert(polygonTangents(pt, poly)); + } catch (e) { + t.skip('issue #1050 failed') + } + t.end(); +}) diff --git a/packages/turf-polygon-tangents/test/in/concave.geojson b/src/polygon-tangents/test/in/concave.geojson similarity index 100% rename from packages/turf-polygon-tangents/test/in/concave.geojson rename to src/polygon-tangents/test/in/concave.geojson diff --git a/packages/turf-polygon-tangents/test/in/high.geojson b/src/polygon-tangents/test/in/high.geojson similarity index 100% rename from packages/turf-polygon-tangents/test/in/high.geojson rename to src/polygon-tangents/test/in/high.geojson diff --git a/packages/turf-polygon-tangents/test/in/issue#1032.geojson b/src/polygon-tangents/test/in/issue#1032.geojson similarity index 100% rename from packages/turf-polygon-tangents/test/in/issue#1032.geojson rename to src/polygon-tangents/test/in/issue#1032.geojson diff --git a/packages/turf-polygon-tangents/test/in/issue#1050.geojson b/src/polygon-tangents/test/in/issue#1050.geojson similarity index 100% rename from packages/turf-polygon-tangents/test/in/issue#1050.geojson rename to src/polygon-tangents/test/in/issue#1050.geojson diff --git a/packages/turf-polygon-tangents/test/in/issue#785.geojson b/src/polygon-tangents/test/in/issue#785.geojson similarity index 100% rename from packages/turf-polygon-tangents/test/in/issue#785.geojson rename to src/polygon-tangents/test/in/issue#785.geojson diff --git a/packages/turf-polygon-tangents/test/in/multipolygon.geojson b/src/polygon-tangents/test/in/multipolygon.geojson similarity index 100% rename from packages/turf-polygon-tangents/test/in/multipolygon.geojson rename to src/polygon-tangents/test/in/multipolygon.geojson diff --git a/packages/turf-polygon-tangents/test/in/polygonWithHole.geojson b/src/polygon-tangents/test/in/polygonWithHole.geojson similarity index 100% rename from packages/turf-polygon-tangents/test/in/polygonWithHole.geojson rename to src/polygon-tangents/test/in/polygonWithHole.geojson diff --git a/packages/turf-polygon-tangents/test/in/square.geojson b/src/polygon-tangents/test/in/square.geojson similarity index 100% rename from packages/turf-polygon-tangents/test/in/square.geojson rename to src/polygon-tangents/test/in/square.geojson diff --git a/packages/turf-polygon-tangents/test/out/concave.geojson b/src/polygon-tangents/test/out/concave.geojson similarity index 100% rename from packages/turf-polygon-tangents/test/out/concave.geojson rename to src/polygon-tangents/test/out/concave.geojson diff --git a/packages/turf-polygon-tangents/test/out/high.geojson b/src/polygon-tangents/test/out/high.geojson similarity index 100% rename from packages/turf-polygon-tangents/test/out/high.geojson rename to src/polygon-tangents/test/out/high.geojson diff --git a/packages/turf-polygon-tangents/test/out/issue#1032.geojson b/src/polygon-tangents/test/out/issue#1032.geojson similarity index 100% rename from packages/turf-polygon-tangents/test/out/issue#1032.geojson rename to src/polygon-tangents/test/out/issue#1032.geojson diff --git a/packages/turf-polygon-tangents/test/out/issue#1050.geojson b/src/polygon-tangents/test/out/issue#1050.geojson similarity index 100% rename from packages/turf-polygon-tangents/test/out/issue#1050.geojson rename to src/polygon-tangents/test/out/issue#1050.geojson diff --git a/packages/turf-polygon-tangents/test/out/issue#785.geojson b/src/polygon-tangents/test/out/issue#785.geojson similarity index 97% rename from packages/turf-polygon-tangents/test/out/issue#785.geojson rename to src/polygon-tangents/test/out/issue#785.geojson index b754003506..0f3de277e4 100644 --- a/packages/turf-polygon-tangents/test/out/issue#785.geojson +++ b/src/polygon-tangents/test/out/issue#785.geojson @@ -18,8 +18,8 @@ "geometry": { "type": "Point", "coordinates": [ - 73.57579441456006, - 0.43239893065221224 + 73.57502193836378, + 0.43239356638694915 ] } }, diff --git a/packages/turf-polygon-tangents/test/out/multipolygon.geojson b/src/polygon-tangents/test/out/multipolygon.geojson similarity index 100% rename from packages/turf-polygon-tangents/test/out/multipolygon.geojson rename to src/polygon-tangents/test/out/multipolygon.geojson diff --git a/packages/turf-polygon-tangents/test/out/polygonWithHole.geojson b/src/polygon-tangents/test/out/polygonWithHole.geojson similarity index 100% rename from packages/turf-polygon-tangents/test/out/polygonWithHole.geojson rename to src/polygon-tangents/test/out/polygonWithHole.geojson diff --git a/packages/turf-polygon-tangents/test/out/square.geojson b/src/polygon-tangents/test/out/square.geojson similarity index 100% rename from packages/turf-polygon-tangents/test/out/square.geojson rename to src/polygon-tangents/test/out/square.geojson diff --git a/packages/turf-polygon-to-line/bench.js b/src/polygon-to-line/bench.js similarity index 100% rename from packages/turf-polygon-to-line/bench.js rename to src/polygon-to-line/bench.js diff --git a/src/polygon-to-line/index.d.ts b/src/polygon-to-line/index.d.ts new file mode 100644 index 0000000000..da02b25ef9 --- /dev/null +++ b/src/polygon-to-line/index.d.ts @@ -0,0 +1,37 @@ +import { Feature, FeatureCollection, LineString, MultiLineString, MultiPolygon, Polygon, Properties } from "../helpers"; +/** + * Converts a {@link Polygon} to {@link LineString|(Multi)LineString} or {@link MultiPolygon} to a + * {@link FeatureCollection} of {@link LineString|(Multi)LineString}. + * + * @name polygonToLine + * @param {Feature} poly Feature to convert + * @param {Object} [options={}] Optional parameters + * @param {Object} [options.properties={}] translates GeoJSON properties to Feature + * @returns {FeatureCollection|Feature} converted (Multi)Polygon to (Multi)LineString + * @example + * var poly = turf.polygon([[[125, -30], [145, -30], [145, -20], [125, -20], [125, -30]]]); + * + * var line = turf.polygonToLine(poly); + * + * //addToMap + * var addToMap = [line]; + */ +export default function (poly: Feature | G, options?: { + properties?: any; +}): Feature | FeatureCollection; +/** + * @private + */ +export declare function polygonToLine(poly: Feature | G, options?: { + properties?: any; +}): Feature; +/** + * @private + */ +export declare function multiPolygonToLine(multiPoly: Feature | G, options?: { + properties?: P; +}): FeatureCollection; +/** + * @private + */ +export declare function coordsToLine

(coords: number[][][], properties: P): Feature; diff --git a/src/polygon-to-line/index.js b/src/polygon-to-line/index.js new file mode 100644 index 0000000000..39eec5021e --- /dev/null +++ b/src/polygon-to-line/index.js @@ -0,0 +1,69 @@ +import { featureCollection, lineString, multiLineString, checkIfOptionsExist } from "../helpers"; +import { getCoords, getGeom } from "../invariant"; + +/** + * Converts a {@link Polygon} to {@link LineString|(Multi)LineString} or {@link MultiPolygon} to a + * {@link FeatureCollection} of {@link LineString|(Multi)LineString}. + * + * @name polygonToLine + * @param {Feature} poly Feature to convert + * @param {Object} [options={}] Optional parameters + * @param {Object} [options.properties={}] translates GeoJSON properties to Feature + * @returns {FeatureCollection|Feature} converted (Multi)Polygon to (Multi)LineString + * @example + * var poly = turf.polygon([[[125, -30], [145, -30], [145, -20], [125, -20], [125, -30]]]); + * + * var line = turf.polygonToLine(poly); + * + * //addToMap + * var addToMap = [line]; + */ +export default function (poly, options) { + options = checkIfOptionsExist(options); + const geom = getGeom(poly); + if (!options.properties && poly.type === "Feature") { options.properties = poly.properties; } + switch (geom.type) { + case "Polygon": return polygonToLine(geom, options); + case "MultiPolygon": return multiPolygonToLine(geom, options); + default: throw new Error("invalid poly"); + } +} + +/** + * @private + */ +export function polygonToLine(poly, options) { + options = checkIfOptionsExist(options); + const geom = getGeom(poly); + const type = geom.type; + const coords = geom.coordinates; + const properties = options.properties ? options.properties : poly.type === "Feature" ? poly.properties : {}; + + return coordsToLine(coords, properties); +} + +/** + * @private + */ +export function multiPolygonToLine(multiPoly, options) { + options = checkIfOptionsExist(options); + const geom = getGeom(multiPoly); + const type = geom.type; + const coords = geom.coordinates; + const properties = options.properties ? options.properties : + multiPoly.type === "Feature" ? multiPoly.properties : {}; + + const lines = []; + coords.forEach(function (coord) { + lines.push(coordsToLine(coord, properties)); + }); + return featureCollection(lines); +} + +/** + * @private + */ +export function coordsToLine(coords, properties) { + if (coords.length > 1) { return multiLineString(coords, properties); } + return lineString(coords[0], properties); +} diff --git a/src/polygon-to-line/test.js b/src/polygon-to-line/test.js new file mode 100644 index 0000000000..225e5b5e45 --- /dev/null +++ b/src/polygon-to-line/test.js @@ -0,0 +1,36 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { point } = require('../helpers'); +const { polygon } = require('../helpers'); +const polygonToLine = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-polygon-to-linestring', t => { + for (const {name, filename, geojson} of fixtures) { + const results = polygonToLine(geojson); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(load.sync(directories.out + filename), results, name); + } + // Handle Errors + t.throws(() => polygonToLine(point([10, 5])), 'throws - invalid geometry'); + t.throws(() => polygonToLine(polygon([])), 'throws - empty coordinates'); + t.end(); +}); + + diff --git a/packages/turf-polygon-to-line/test/in/geometry-polygon.geojson b/src/polygon-to-line/test/in/geometry-polygon.geojson similarity index 100% rename from packages/turf-polygon-to-line/test/in/geometry-polygon.geojson rename to src/polygon-to-line/test/in/geometry-polygon.geojson diff --git a/packages/turf-polygon-to-line/test/in/multi-polygon-outer-doughnut.geojson b/src/polygon-to-line/test/in/multi-polygon-outer-doughnut.geojson similarity index 100% rename from packages/turf-polygon-to-line/test/in/multi-polygon-outer-doughnut.geojson rename to src/polygon-to-line/test/in/multi-polygon-outer-doughnut.geojson diff --git a/packages/turf-polygon-to-line/test/in/multi-polygon-with-holes.geojson b/src/polygon-to-line/test/in/multi-polygon-with-holes.geojson similarity index 100% rename from packages/turf-polygon-to-line/test/in/multi-polygon-with-holes.geojson rename to src/polygon-to-line/test/in/multi-polygon-with-holes.geojson diff --git a/packages/turf-polygon-to-line/test/in/multi-polygon.geojson b/src/polygon-to-line/test/in/multi-polygon.geojson similarity index 100% rename from packages/turf-polygon-to-line/test/in/multi-polygon.geojson rename to src/polygon-to-line/test/in/multi-polygon.geojson diff --git a/packages/turf-polygon-to-line/test/in/polygon-with-hole.geojson b/src/polygon-to-line/test/in/polygon-with-hole.geojson similarity index 100% rename from packages/turf-polygon-to-line/test/in/polygon-with-hole.geojson rename to src/polygon-to-line/test/in/polygon-with-hole.geojson diff --git a/packages/turf-polygon-to-line/test/in/polygon.geojson b/src/polygon-to-line/test/in/polygon.geojson similarity index 100% rename from packages/turf-polygon-to-line/test/in/polygon.geojson rename to src/polygon-to-line/test/in/polygon.geojson diff --git a/packages/turf-polygon-to-line/test/out/geometry-polygon.geojson b/src/polygon-to-line/test/out/geometry-polygon.geojson similarity index 100% rename from packages/turf-polygon-to-line/test/out/geometry-polygon.geojson rename to src/polygon-to-line/test/out/geometry-polygon.geojson diff --git a/packages/turf-polygon-to-line/test/out/multi-polygon-outer-doughnut.geojson b/src/polygon-to-line/test/out/multi-polygon-outer-doughnut.geojson similarity index 100% rename from packages/turf-polygon-to-line/test/out/multi-polygon-outer-doughnut.geojson rename to src/polygon-to-line/test/out/multi-polygon-outer-doughnut.geojson diff --git a/packages/turf-polygon-to-line/test/out/multi-polygon-with-holes.geojson b/src/polygon-to-line/test/out/multi-polygon-with-holes.geojson similarity index 100% rename from packages/turf-polygon-to-line/test/out/multi-polygon-with-holes.geojson rename to src/polygon-to-line/test/out/multi-polygon-with-holes.geojson diff --git a/packages/turf-polygon-to-line/test/out/multi-polygon.geojson b/src/polygon-to-line/test/out/multi-polygon.geojson similarity index 100% rename from packages/turf-polygon-to-line/test/out/multi-polygon.geojson rename to src/polygon-to-line/test/out/multi-polygon.geojson diff --git a/packages/turf-polygon-to-line/test/out/polygon-with-hole.geojson b/src/polygon-to-line/test/out/polygon-with-hole.geojson similarity index 100% rename from packages/turf-polygon-to-line/test/out/polygon-with-hole.geojson rename to src/polygon-to-line/test/out/polygon-with-hole.geojson diff --git a/packages/turf-polygon-to-line/test/out/polygon.geojson b/src/polygon-to-line/test/out/polygon.geojson similarity index 100% rename from packages/turf-polygon-to-line/test/out/polygon.geojson rename to src/polygon-to-line/test/out/polygon.geojson diff --git a/packages/turf-polygonize/bench.js b/src/polygonize/bench.js similarity index 100% rename from packages/turf-polygonize/bench.js rename to src/polygonize/bench.js diff --git a/src/polygonize/index.d.ts b/src/polygonize/index.d.ts new file mode 100644 index 0000000000..29b405bb5a --- /dev/null +++ b/src/polygonize/index.d.ts @@ -0,0 +1,8 @@ +import { Feature, FeatureCollection, Coord, Polygon, LineString, MultiLineString } from '../helpers' + +/** + * http://turfjs.org/docs/#polygonize + */ +export default function ( + geojson: Feature | FeatureCollection | T +): FeatureCollection; diff --git a/packages/turf-polygonize/index.js b/src/polygonize/index.js similarity index 100% rename from packages/turf-polygonize/index.js rename to src/polygonize/index.js diff --git a/packages/turf-polygonize/lib/polygonize.js b/src/polygonize/lib/polygonize.js similarity index 97% rename from packages/turf-polygonize/lib/polygonize.js rename to src/polygonize/lib/polygonize.js index 62315cc949..bdc0b9f15a 100644 --- a/packages/turf-polygonize/lib/polygonize.js +++ b/src/polygonize/lib/polygonize.js @@ -1,8 +1,8 @@ -import booleanPointInPolygon from '@turf/boolean-point-in-polygon'; -import { featureCollection, lineString, multiPoint, point, polygon } from '@turf/helpers'; -import envelope from '@turf/envelope'; -import { coordReduce, flattenEach } from '@turf/meta'; -import { featureOf } from '@turf/invariant'; +import booleanPointInPolygon from '../../boolean-point-in-polygon'; +import { featureCollection, lineString, multiPoint, point, polygon } from '../../helpers'; +import envelope from '../../envelope'; +import { coordReduce, flattenEach } from '../../meta'; +import { featureOf } from '../../invariant'; /** * Returns the direction of the point q relative to the vector p1 -> p2. @@ -259,7 +259,6 @@ var EdgeRing = function EdgeRing() { this.envelope = undefined; //< Caches Envelope representation }; -var prototypeAccessors = { length: { configurable: true } }; /** * Add an edge to the ring, inserting it in the last position. @@ -285,16 +284,6 @@ EdgeRing.prototype.get = function get (i) { return this.edges[i]; }; -/** - * Getter of length property. - * - * @memberof EdgeRing - * @returns {number} - Length of the edge ring. - */ -prototypeAccessors.length.get = function () { - return this.edges.length; -}; - /** * Similar to Array.prototype.forEach for the list of Edges in the EdgeRing. * @@ -361,8 +350,8 @@ EdgeRing.prototype.isHole = function isHole () { { high = i; } return high; }, 0), - iPrev = (hiIndex === 0 ? this.length : hiIndex) - 1, - iNext = (hiIndex + 1) % this.length, + iPrev = (hiIndex === 0 ? this.edges.length : hiIndex) - 1, + iNext = (hiIndex + 1) % this.edges.length, disc = orientationIndex(this.edges[iPrev].from.coordinates, this.edges[hiIndex].from.coordinates, this.edges[iNext].from.coordinates); if (disc === 0) @@ -453,8 +442,6 @@ EdgeRing.prototype.inside = function inside (pt) { return booleanPointInPolygon(pt, this.toPolygon()); }; -Object.defineProperties( EdgeRing.prototype, prototypeAccessors ); - /** * Validates the geoJson. * diff --git a/packages/turf-polygonize/lib/polygonize/Edge.js b/src/polygonize/lib/polygonize/Edge.js similarity index 100% rename from packages/turf-polygonize/lib/polygonize/Edge.js rename to src/polygonize/lib/polygonize/Edge.js diff --git a/packages/turf-polygonize/lib/polygonize/EdgeRing.js b/src/polygonize/lib/polygonize/EdgeRing.js similarity index 100% rename from packages/turf-polygonize/lib/polygonize/EdgeRing.js rename to src/polygonize/lib/polygonize/EdgeRing.js diff --git a/packages/turf-polygonize/lib/polygonize/Graph.js b/src/polygonize/lib/polygonize/Graph.js similarity index 100% rename from packages/turf-polygonize/lib/polygonize/Graph.js rename to src/polygonize/lib/polygonize/Graph.js diff --git a/packages/turf-polygonize/lib/polygonize/Node.js b/src/polygonize/lib/polygonize/Node.js similarity index 100% rename from packages/turf-polygonize/lib/polygonize/Node.js rename to src/polygonize/lib/polygonize/Node.js diff --git a/packages/turf-polygonize/lib/polygonize/index.js b/src/polygonize/lib/polygonize/index.js similarity index 100% rename from packages/turf-polygonize/lib/polygonize/index.js rename to src/polygonize/lib/polygonize/index.js diff --git a/packages/turf-polygonize/lib/polygonize/util.js b/src/polygonize/lib/polygonize/util.js similarity index 100% rename from packages/turf-polygonize/lib/polygonize/util.js rename to src/polygonize/lib/polygonize/util.js diff --git a/packages/turf-polygonize/lib/rollup.config.js b/src/polygonize/lib/rollup.config.js similarity index 100% rename from packages/turf-polygonize/lib/rollup.config.js rename to src/polygonize/lib/rollup.config.js diff --git a/src/polygonize/test.js b/src/polygonize/test.js new file mode 100644 index 0000000000..72be91eb49 --- /dev/null +++ b/src/polygonize/test.js @@ -0,0 +1,70 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import { featureEach } from '../meta'; +import { featureCollection, lineString } from '../helpers'; +import polygonize from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-polygonize', t => { + for (const {filename, name, geojson} of fixtures) { + const polygonized = polygonize(geojson); + + const results = featureCollection([]); + featureEach(geojson, feature => results.features.push(colorize(feature))); + featureEach(polygonized, feature => results.features.push(colorize(feature, '#00F', 3))); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEquals(results, load.sync(directories.out + filename), name); + } + t.end(); +}); + +test('turf-polygonize -- Geometry Support', t => { + const line = lineString([[0, 0], [1, 1], [5, 2], [0, 0]]); + + t.assert(polygonize(line.geometry), 'line geometry'); + t.end(); +}); + +test('turf-polygonize -- throws', t => { + // const line = lineString([[0, 0], [1, 1]]); + + // t.throws(() => polygonize(line)); + t.end(); +}); + +test('turf-polygonize -- input mutation', t => { + const lines = featureCollection([ + lineString([[0, 0], [1, 1]]), + lineString([[1, 1], [-1, -1]]), + lineString([[-1, -1], [0, 0]]) + ]); + const linesBefore = JSON.parse(JSON.stringify(lines)); + polygonize(lines); + + t.deepEquals(lines, linesBefore, 'input does not mutate'); + t.end(); +}); + +function colorize(feature, color = '#F00', width = 6) { + feature.properties['fill'] = color; + feature.properties['fill-opacity'] = 0.3; + feature.properties['stroke'] = color; + feature.properties['stroke-width'] = width; + return feature; +} diff --git a/packages/turf-polygonize/test/in/complex.geojson b/src/polygonize/test/in/complex.geojson similarity index 100% rename from packages/turf-polygonize/test/in/complex.geojson rename to src/polygonize/test/in/complex.geojson diff --git a/packages/turf-polygonize/test/in/cutedge.geojson b/src/polygonize/test/in/cutedge.geojson similarity index 100% rename from packages/turf-polygonize/test/in/cutedge.geojson rename to src/polygonize/test/in/cutedge.geojson diff --git a/packages/turf-polygonize/test/in/dangle.geojson b/src/polygonize/test/in/dangle.geojson similarity index 100% rename from packages/turf-polygonize/test/in/dangle.geojson rename to src/polygonize/test/in/dangle.geojson diff --git a/packages/turf-polygonize/test/in/kinked-linestring.geojson b/src/polygonize/test/in/kinked-linestring.geojson similarity index 100% rename from packages/turf-polygonize/test/in/kinked-linestring.geojson rename to src/polygonize/test/in/kinked-linestring.geojson diff --git a/packages/turf-polygonize/test/in/linestrings.geojson b/src/polygonize/test/in/linestrings.geojson similarity index 100% rename from packages/turf-polygonize/test/in/linestrings.geojson rename to src/polygonize/test/in/linestrings.geojson diff --git a/packages/turf-polygonize/test/in/multi-linestring.geojson b/src/polygonize/test/in/multi-linestring.geojson similarity index 100% rename from packages/turf-polygonize/test/in/multi-linestring.geojson rename to src/polygonize/test/in/multi-linestring.geojson diff --git a/packages/turf-polygonize/test/in/two-polygons.geojson b/src/polygonize/test/in/two-polygons.geojson similarity index 100% rename from packages/turf-polygonize/test/in/two-polygons.geojson rename to src/polygonize/test/in/two-polygons.geojson diff --git a/packages/turf-polygonize/test/out/complex.geojson b/src/polygonize/test/out/complex.geojson similarity index 100% rename from packages/turf-polygonize/test/out/complex.geojson rename to src/polygonize/test/out/complex.geojson diff --git a/packages/turf-polygonize/test/out/cutedge.geojson b/src/polygonize/test/out/cutedge.geojson similarity index 100% rename from packages/turf-polygonize/test/out/cutedge.geojson rename to src/polygonize/test/out/cutedge.geojson diff --git a/packages/turf-polygonize/test/out/dangle.geojson b/src/polygonize/test/out/dangle.geojson similarity index 100% rename from packages/turf-polygonize/test/out/dangle.geojson rename to src/polygonize/test/out/dangle.geojson diff --git a/packages/turf-polygonize/test/out/kinked-linestring.geojson b/src/polygonize/test/out/kinked-linestring.geojson similarity index 100% rename from packages/turf-polygonize/test/out/kinked-linestring.geojson rename to src/polygonize/test/out/kinked-linestring.geojson diff --git a/packages/turf-polygonize/test/out/linestrings.geojson b/src/polygonize/test/out/linestrings.geojson similarity index 100% rename from packages/turf-polygonize/test/out/linestrings.geojson rename to src/polygonize/test/out/linestrings.geojson diff --git a/packages/turf-polygonize/test/out/multi-linestring.geojson b/src/polygonize/test/out/multi-linestring.geojson similarity index 100% rename from packages/turf-polygonize/test/out/multi-linestring.geojson rename to src/polygonize/test/out/multi-linestring.geojson diff --git a/packages/turf-polygonize/test/out/two-polygons.geojson b/src/polygonize/test/out/two-polygons.geojson similarity index 100% rename from packages/turf-polygonize/test/out/two-polygons.geojson rename to src/polygonize/test/out/two-polygons.geojson diff --git a/packages/turf-projection/bench.js b/src/projection/bench.js similarity index 100% rename from packages/turf-projection/bench.js rename to src/projection/bench.js diff --git a/src/projection/index.js b/src/projection/index.js new file mode 100644 index 0000000000..7d0d84163c --- /dev/null +++ b/src/projection/index.js @@ -0,0 +1,138 @@ +import { coordEach } from '../meta'; +import { isNumber } from '../helpers'; +import clone from '../clone'; + +/** + * Converts a WGS84 GeoJSON object into Mercator (EPSG:900913) projection + * + * @name toMercator + * @param {GeoJSON|Position} geojson WGS84 GeoJSON object + * @param {Object} [options] Optional parameters + * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) + * @returns {GeoJSON} Projected GeoJSON + * @example + * var pt = turf.point([-71,41]); + * var converted = turf.toMercator(pt); + * + * //addToMap + * var addToMap = [pt, converted]; + */ +export function toMercator(geojson, options) { + return convert(geojson, 'mercator', options); +} + +/** + * Converts a Mercator (EPSG:900913) GeoJSON object into WGS84 projection + * + * @name toWgs84 + * @param {GeoJSON|Position} geojson Mercator GeoJSON object + * @param {Object} [options] Optional parameters + * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) + * @returns {GeoJSON} Projected GeoJSON + * @example + * var pt = turf.point([-7903683.846322424, 5012341.663847514]); + * var converted = turf.toWgs84(pt); + * + * //addToMap + * var addToMap = [pt, converted]; + */ +export function toWgs84(geojson, options) { + return convert(geojson, 'wgs84', options); +} + + +/** + * Converts a GeoJSON coordinates to the defined `projection` + * + * @private + * @param {GeoJSON} geojson GeoJSON Feature or Geometry + * @param {string} projection defines the projection system to convert the coordinates to + * @param {Object} [options] Optional parameters + * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) + * @returns {GeoJSON} Converted GeoJSON + */ +function convert(geojson, projection, options) { + // Optional parameters + options = options || {}; + var mutate = options.mutate; + + // Validation + if (!geojson) throw new Error('geojson is required'); + + // Handle Position + if (Array.isArray(geojson) && isNumber(geojson[0])) geojson = (projection === 'mercator') ? convertToMercator(geojson) : convertToWgs84(geojson); + + // Handle GeoJSON + else { + // Handle possible data mutation + if (mutate !== true) geojson = clone(geojson); + + coordEach(geojson, function (coord) { + var newCoord = (projection === 'mercator') ? convertToMercator(coord) : convertToWgs84(coord); + coord[0] = newCoord[0]; + coord[1] = newCoord[1]; + }); + } + return geojson; +} + +/** + * Convert lon/lat values to 900913 x/y. + * (from https://github.com/mapbox/sphericalmercator) + * + * @private + * @param {Array} lonLat WGS84 point + * @returns {Array} Mercator [x, y] point + */ +function convertToMercator(lonLat) { + var D2R = Math.PI / 180, + // 900913 properties + A = 6378137.0, + MAXEXTENT = 20037508.342789244; + + // compensate longitudes passing the 180th meridian + // from https://github.com/proj4js/proj4js/blob/master/lib/common/adjust_lon.js + var adjusted = (Math.abs(lonLat[0]) <= 180) ? lonLat[0] : (lonLat[0] - (sign(lonLat[0]) * 360)); + var xy = [ + A * adjusted * D2R, + A * Math.log(Math.tan((Math.PI * 0.25) + (0.5 * lonLat[1] * D2R))) + ]; + + // if xy value is beyond maxextent (e.g. poles), return maxextent + if (xy[0] > MAXEXTENT) xy[0] = MAXEXTENT; + if (xy[0] < -MAXEXTENT) xy[0] = -MAXEXTENT; + if (xy[1] > MAXEXTENT) xy[1] = MAXEXTENT; + if (xy[1] < -MAXEXTENT) xy[1] = -MAXEXTENT; + + return xy; +} + +/** + * Convert 900913 x/y values to lon/lat. + * (from https://github.com/mapbox/sphericalmercator) + * + * @private + * @param {Array} xy Mercator [x, y] point + * @returns {Array} WGS84 [lon, lat] point + */ +function convertToWgs84(xy) { + // 900913 properties. + var R2D = 180 / Math.PI; + var A = 6378137.0; + + return [ + (xy[0] * R2D / A), + ((Math.PI * 0.5) - 2.0 * Math.atan(Math.exp(-xy[1] / A))) * R2D + ]; +} + +/** + * Returns the sign of the input, or zero + * + * @private + * @param {number} x input + * @returns {number} -1|0|1 output + */ +function sign(x) { + return (x < 0) ? -1 : (x > 0) ? 1 : 0; +} diff --git a/src/projection/test.js b/src/projection/test.js new file mode 100644 index 0000000000..cb8ccd1aae --- /dev/null +++ b/src/projection/test.js @@ -0,0 +1,106 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const proj4 = require('proj4'); +const write = require('write-json-file'); +const clone = require('../clone').default; +const { point } = require('../helpers'); +const truncate = require('../truncate').default; +const { coordEach } = require('../meta'); +const { toMercator, toWgs84 } = require('.'); + +const directories = { + mercator: path.join(__dirname, 'test', 'mercator') + path.sep, + wgs84: path.join(__dirname, 'test', 'wgs84') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fromWgs84 = fs.readdirSync(directories.wgs84).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: truncate(load.sync(directories.wgs84 + filename)) + }; +}); + +test('to-mercator', t => { + for (const {filename, name, geojson} of fromWgs84) { + var expected = clone(geojson); + coordEach(expected, function (coord) { + var newCoord = proj4('WGS84', 'EPSG:900913', coord); + coord[0] = newCoord[0]; + coord[1] = newCoord[1]; + }); + const results = truncate(toMercator(geojson)); + + if (process.env.REGEN) write.sync(directories.out + 'mercator-' + filename, results); + t.deepEqual(results, truncate(expected), name); + t.deepEqual(results, load.sync(directories.out + 'mercator-' + filename)); + } + t.end(); +}); + +const fromMercator = fs.readdirSync(directories.mercator).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: truncate(load.sync(directories.mercator + filename)) + }; +}); + +test('to-wgs84', t => { + for (const {filename, name, geojson} of fromMercator) { + var expected = clone(geojson); + coordEach(expected, function (coord) { + var newCoord = proj4('EPSG:900913', 'WGS84', coord); + coord[0] = newCoord[0]; + coord[1] = newCoord[1]; + }); + const results = truncate(toWgs84(geojson)); + + if (process.env.REGEN) write.sync(directories.out + 'wgs84-' + filename, results); + t.deepEqual(results, truncate(expected), name); + t.deepEqual(results, load.sync(directories.out + 'wgs84-' + filename)); + } + t.end(); +}); + + + +test('projection -- throws', t => { + t.throws(() => toMercator(null), /geojson is required/, 'throws missing geojson'); + t.throws(() => toWgs84(null), /geojson is required/, 'throws missing geojson'); + t.end(); +}); + +test('projection -- verify mutation', t => { + const pt1 = point([10, 10]); + const pt2 = point([15, 15]); + const pt1Before = clone(pt1); + const pt2Before = clone(pt2); + + toMercator(pt1); + toMercator(pt1, {mutate: false}); + t.deepEqual(pt1, pt1Before, 'mutate = undefined - input should NOT be mutated'); + t.deepEqual(pt1, pt1Before, 'mutate = false - input should NOT be mutated'); + toMercator(pt1, {mutate: true}); + t.notEqual(pt1, pt1Before, 'input should be mutated'); + + toWgs84(pt2); + toWgs84(pt2, {mutate: false}); + t.deepEqual(pt2, pt2Before, 'mutate = undefined - input should NOT be mutated'); + t.deepEqual(pt2, pt2Before, 'mutate = false - input should NOT be mutated'); + toWgs84(pt2, {mutate: true}); + t.notEqual(pt2, pt2Before, 'input should be mutated'); + + t.end(); +}); + +test('projection -- handle Position', t => { + const coord = [10, 40]; + const mercator = toMercator(coord); + const wgs84 = toWgs84(mercator); + t.deepEqual(coord, wgs84, 'coord equal same as wgs84'); + t.end(); +}); \ No newline at end of file diff --git a/packages/turf-projection/test/mercator/featureCollection.geojson b/src/projection/test/mercator/featureCollection.geojson similarity index 100% rename from packages/turf-projection/test/mercator/featureCollection.geojson rename to src/projection/test/mercator/featureCollection.geojson diff --git a/packages/turf-projection/test/mercator/fiji.geojson b/src/projection/test/mercator/fiji.geojson similarity index 100% rename from packages/turf-projection/test/mercator/fiji.geojson rename to src/projection/test/mercator/fiji.geojson diff --git a/packages/turf-projection/test/mercator/geometry.geojson b/src/projection/test/mercator/geometry.geojson similarity index 100% rename from packages/turf-projection/test/mercator/geometry.geojson rename to src/projection/test/mercator/geometry.geojson diff --git a/packages/turf-projection/test/mercator/line.geojson b/src/projection/test/mercator/line.geojson similarity index 100% rename from packages/turf-projection/test/mercator/line.geojson rename to src/projection/test/mercator/line.geojson diff --git a/packages/turf-projection/test/mercator/multiLine.geojson b/src/projection/test/mercator/multiLine.geojson similarity index 100% rename from packages/turf-projection/test/mercator/multiLine.geojson rename to src/projection/test/mercator/multiLine.geojson diff --git a/packages/turf-projection/test/mercator/multiPolygon.geojson b/src/projection/test/mercator/multiPolygon.geojson similarity index 100% rename from packages/turf-projection/test/mercator/multiPolygon.geojson rename to src/projection/test/mercator/multiPolygon.geojson diff --git a/packages/turf-projection/test/mercator/passed-180th-meridian.geojson b/src/projection/test/mercator/passed-180th-meridian.geojson similarity index 100% rename from packages/turf-projection/test/mercator/passed-180th-meridian.geojson rename to src/projection/test/mercator/passed-180th-meridian.geojson diff --git a/packages/turf-projection/test/mercator/passed-180th-meridian2.geojson b/src/projection/test/mercator/passed-180th-meridian2.geojson similarity index 100% rename from packages/turf-projection/test/mercator/passed-180th-meridian2.geojson rename to src/projection/test/mercator/passed-180th-meridian2.geojson diff --git a/packages/turf-projection/test/mercator/point.geojson b/src/projection/test/mercator/point.geojson similarity index 100% rename from packages/turf-projection/test/mercator/point.geojson rename to src/projection/test/mercator/point.geojson diff --git a/packages/turf-projection/test/mercator/polygon.geojson b/src/projection/test/mercator/polygon.geojson similarity index 100% rename from packages/turf-projection/test/mercator/polygon.geojson rename to src/projection/test/mercator/polygon.geojson diff --git a/packages/turf-projection/test/out/mercator-featureCollection.geojson b/src/projection/test/out/mercator-featureCollection.geojson similarity index 100% rename from packages/turf-projection/test/out/mercator-featureCollection.geojson rename to src/projection/test/out/mercator-featureCollection.geojson diff --git a/packages/turf-projection/test/out/mercator-fiji.geojson b/src/projection/test/out/mercator-fiji.geojson similarity index 100% rename from packages/turf-projection/test/out/mercator-fiji.geojson rename to src/projection/test/out/mercator-fiji.geojson diff --git a/packages/turf-projection/test/out/mercator-geometry.geojson b/src/projection/test/out/mercator-geometry.geojson similarity index 100% rename from packages/turf-projection/test/out/mercator-geometry.geojson rename to src/projection/test/out/mercator-geometry.geojson diff --git a/packages/turf-projection/test/out/mercator-multiLine.geojson b/src/projection/test/out/mercator-multiLine.geojson similarity index 100% rename from packages/turf-projection/test/out/mercator-multiLine.geojson rename to src/projection/test/out/mercator-multiLine.geojson diff --git a/packages/turf-projection/test/out/mercator-multiPolygon.geojson b/src/projection/test/out/mercator-multiPolygon.geojson similarity index 100% rename from packages/turf-projection/test/out/mercator-multiPolygon.geojson rename to src/projection/test/out/mercator-multiPolygon.geojson diff --git a/packages/turf-projection/test/out/mercator-passed-180th-meridian.geojson b/src/projection/test/out/mercator-passed-180th-meridian.geojson similarity index 100% rename from packages/turf-projection/test/out/mercator-passed-180th-meridian.geojson rename to src/projection/test/out/mercator-passed-180th-meridian.geojson diff --git a/packages/turf-projection/test/out/mercator-passed-180th-meridian2.geojson b/src/projection/test/out/mercator-passed-180th-meridian2.geojson similarity index 100% rename from packages/turf-projection/test/out/mercator-passed-180th-meridian2.geojson rename to src/projection/test/out/mercator-passed-180th-meridian2.geojson diff --git a/packages/turf-projection/test/out/mercator-point.geojson b/src/projection/test/out/mercator-point.geojson similarity index 100% rename from packages/turf-projection/test/out/mercator-point.geojson rename to src/projection/test/out/mercator-point.geojson diff --git a/packages/turf-projection/test/out/mercator-polygon.geojson b/src/projection/test/out/mercator-polygon.geojson similarity index 100% rename from packages/turf-projection/test/out/mercator-polygon.geojson rename to src/projection/test/out/mercator-polygon.geojson diff --git a/packages/turf-projection/test/out/wgs84-featureCollection.geojson b/src/projection/test/out/wgs84-featureCollection.geojson similarity index 100% rename from packages/turf-projection/test/out/wgs84-featureCollection.geojson rename to src/projection/test/out/wgs84-featureCollection.geojson diff --git a/packages/turf-projection/test/out/wgs84-fiji.geojson b/src/projection/test/out/wgs84-fiji.geojson similarity index 100% rename from packages/turf-projection/test/out/wgs84-fiji.geojson rename to src/projection/test/out/wgs84-fiji.geojson diff --git a/packages/turf-projection/test/out/wgs84-geometry.geojson b/src/projection/test/out/wgs84-geometry.geojson similarity index 100% rename from packages/turf-projection/test/out/wgs84-geometry.geojson rename to src/projection/test/out/wgs84-geometry.geojson diff --git a/packages/turf-projection/test/out/wgs84-line.geojson b/src/projection/test/out/wgs84-line.geojson similarity index 100% rename from packages/turf-projection/test/out/wgs84-line.geojson rename to src/projection/test/out/wgs84-line.geojson diff --git a/packages/turf-projection/test/out/wgs84-multiLine.geojson b/src/projection/test/out/wgs84-multiLine.geojson similarity index 100% rename from packages/turf-projection/test/out/wgs84-multiLine.geojson rename to src/projection/test/out/wgs84-multiLine.geojson diff --git a/packages/turf-projection/test/out/wgs84-multiPolygon.geojson b/src/projection/test/out/wgs84-multiPolygon.geojson similarity index 100% rename from packages/turf-projection/test/out/wgs84-multiPolygon.geojson rename to src/projection/test/out/wgs84-multiPolygon.geojson diff --git a/packages/turf-projection/test/out/wgs84-passed-180th-meridian.geojson b/src/projection/test/out/wgs84-passed-180th-meridian.geojson similarity index 100% rename from packages/turf-projection/test/out/wgs84-passed-180th-meridian.geojson rename to src/projection/test/out/wgs84-passed-180th-meridian.geojson diff --git a/packages/turf-projection/test/out/wgs84-passed-180th-meridian2.geojson b/src/projection/test/out/wgs84-passed-180th-meridian2.geojson similarity index 100% rename from packages/turf-projection/test/out/wgs84-passed-180th-meridian2.geojson rename to src/projection/test/out/wgs84-passed-180th-meridian2.geojson diff --git a/packages/turf-projection/test/out/wgs84-point.geojson b/src/projection/test/out/wgs84-point.geojson similarity index 100% rename from packages/turf-projection/test/out/wgs84-point.geojson rename to src/projection/test/out/wgs84-point.geojson diff --git a/packages/turf-projection/test/out/wgs84-polygon.geojson b/src/projection/test/out/wgs84-polygon.geojson similarity index 100% rename from packages/turf-projection/test/out/wgs84-polygon.geojson rename to src/projection/test/out/wgs84-polygon.geojson diff --git a/packages/turf-projection/test/wgs84/featureCollection.geojson b/src/projection/test/wgs84/featureCollection.geojson similarity index 100% rename from packages/turf-projection/test/wgs84/featureCollection.geojson rename to src/projection/test/wgs84/featureCollection.geojson diff --git a/packages/turf-projection/test/wgs84/fiji.geojson b/src/projection/test/wgs84/fiji.geojson similarity index 100% rename from packages/turf-projection/test/wgs84/fiji.geojson rename to src/projection/test/wgs84/fiji.geojson diff --git a/packages/turf-projection/test/wgs84/geometry.geojson b/src/projection/test/wgs84/geometry.geojson similarity index 100% rename from packages/turf-projection/test/wgs84/geometry.geojson rename to src/projection/test/wgs84/geometry.geojson diff --git a/packages/turf-projection/test/wgs84/multiLine.geojson b/src/projection/test/wgs84/multiLine.geojson similarity index 100% rename from packages/turf-projection/test/wgs84/multiLine.geojson rename to src/projection/test/wgs84/multiLine.geojson diff --git a/packages/turf-projection/test/wgs84/multiPolygon.geojson b/src/projection/test/wgs84/multiPolygon.geojson similarity index 100% rename from packages/turf-projection/test/wgs84/multiPolygon.geojson rename to src/projection/test/wgs84/multiPolygon.geojson diff --git a/packages/turf-projection/test/wgs84/passed-180th-meridian.geojson b/src/projection/test/wgs84/passed-180th-meridian.geojson similarity index 100% rename from packages/turf-projection/test/wgs84/passed-180th-meridian.geojson rename to src/projection/test/wgs84/passed-180th-meridian.geojson diff --git a/packages/turf-projection/test/wgs84/passed-180th-meridian2.geojson b/src/projection/test/wgs84/passed-180th-meridian2.geojson similarity index 100% rename from packages/turf-projection/test/wgs84/passed-180th-meridian2.geojson rename to src/projection/test/wgs84/passed-180th-meridian2.geojson diff --git a/packages/turf-projection/test/wgs84/point.geojson b/src/projection/test/wgs84/point.geojson similarity index 100% rename from packages/turf-projection/test/wgs84/point.geojson rename to src/projection/test/wgs84/point.geojson diff --git a/packages/turf-projection/test/wgs84/polygon.geojson b/src/projection/test/wgs84/polygon.geojson similarity index 100% rename from packages/turf-projection/test/wgs84/polygon.geojson rename to src/projection/test/wgs84/polygon.geojson diff --git a/src/quadrat-analysis/bench.js b/src/quadrat-analysis/bench.js new file mode 100644 index 0000000000..6486670b75 --- /dev/null +++ b/src/quadrat-analysis/bench.js @@ -0,0 +1,47 @@ +const glob = require('glob'); +const path = require('path'); +const load = require('load-json-file'); +const Benchmark = require('benchmark'); +const { randomPoint } = require('../random'); +const bbox = require('../bbox').default; +const nearestNeighborAnalysis = require('../nearest-neighbor-analysis').default; +const quadratAnalysis = require('.').default; + +/** + * Benchmark Results + * quadrat: 1383.768ms + * nearest: 12259.498ms + * quadrat x 0.76 ops/sec ±1.24% (6 runs sampled) + * nearest x 0.08 ops/sec ±0.97% (5 runs sampled) + */ +const suite = new Benchmark.Suite('turf-quadrat-analysis'); + + +const smallBbox = [-10, -10, 10, 10]; +const dataset = randomPoint(10000, { bbox: smallBbox }); + + +var nameQ = 'quadrat'; +var nameN = 'nearest' +console.time(nameQ); +quadratAnalysis(dataset, { + studyBbox: smallBbox, + confidenceLevel: 20 +}); +console.timeEnd(nameQ); + +console.time(nameN); +nearestNeighborAnalysis(dataset); +console.timeEnd(nameN); + +suite.add(nameQ, () => quadratAnalysis(dataset, { + studyBbox: smallBbox, + confidenceLevel: 20 +})); +suite.add(nameN, () => nearestNeighborAnalysis(dataset)); + + +suite + .on('cycle', e => console.log(String(e.target))) + .on('complete', () => { }) + .run(); diff --git a/src/quadrat-analysis/index.d.ts b/src/quadrat-analysis/index.d.ts new file mode 100644 index 0000000000..476e989afe --- /dev/null +++ b/src/quadrat-analysis/index.d.ts @@ -0,0 +1,52 @@ +import { FeatureCollection, Point } from "../helpers"; +export interface QuadratAnalysisResult { + criticalValue: number; + maxAbsoluteDifference: number; + isRandom: boolean; + observedDistribution: number[]; +} +/** + * Quadrat analysis lays a set of equal-size areas(quadrat) over the study area and counts + * the number of features in each quadrat and creates a frequency table. + * The table lists the number of quadrats containing no features, + * the number containing one feature, two features, and so on, + * all the way up to the quadrat containing the most features. + * The method then creates the frequency table for the random distribution, usually based on a Poisson distribution. + * The method uses the distribution to calculate the probability for 0 feature occuring, + * 1 feature occuring, 2 features, and so on, + * and lists these probabilities in the frequency table. + * By comparing the two frequency tables, you can see whether the features create a pattern. + * If the table for the observed distribution has more quadrats containing many features than the + * table for the random distribution dose, then the features create a clustered pattern. + * + * It is hard to judge the frequency tables are similar or different just by looking at them. + * So, we can use serval statistical tests to find out how much the frequency tables differ. + * We use Kolmogorov-Smirnov test.This method calculates cumulative probabilities for both distributions, + * and then compares the cumulative probabilities at each class level and selects the largest absolute difference D. + * Then, the test compares D to the critical value for a confidence level you specify. + * If D is greater than the critical value, the difference between the observed distribution and + * the random distribution is significant. The greater the value the bigger the difference. + * + * Traditionally, squares are used for the shape of the quadrats, in a regular grid(square-grid). + * Some researchers suggest that the quadrat size equal twice the size of mean area per feature, + * which is simply the area of the study area divided by the number of features. + * + * + * @name quadratAnalysis + * @param {FeatureCollection} pointFeatureSet point set to study + * @param {Object} [options={}] optional parameters + * @param {bbox} [options.studyBbox] bbox representing the study area + * @param {number} [options.confidenceLevel=20] a confidence level. + * The unit is percentage . 5 means 95%, value must be in {@link K_TABLE} + * @returns {Object} result {@link QuadratAnalysisResult} + * @example + * + * var bbox = [-65, 40, -63, 42]; + * var dataset = turf.randomPoint(100, { bbox: bbox }); + * var result = turf.quadratAnalysis(dataset); + * + */ +export default function quadratAnalysis(pointFeatureSet: FeatureCollection, options: { + studyBbox?: [number, number, number, number]; + confidenceLevel?: 20 | 15 | 10 | 5 | 2 | 1; +}): QuadratAnalysisResult; diff --git a/src/quadrat-analysis/index.js b/src/quadrat-analysis/index.js new file mode 100644 index 0000000000..fb36f436ac --- /dev/null +++ b/src/quadrat-analysis/index.js @@ -0,0 +1,206 @@ +import area from "../area"; +import turfBBox from "../bbox"; +import bboxPolygon from "../bbox-polygon"; +import { round } from "../helpers"; +import { getCoord } from "../invariant"; +import squareGrid from "../square-grid"; + +/** + * Quadrat analysis lays a set of equal-size areas(quadrat) over the study area and counts + * the number of features in each quadrat and creates a frequency table. + * The table lists the number of quadrats containing no features, + * the number containing one feature, two features, and so on, + * all the way up to the quadrat containing the most features. + * The method then creates the frequency table for the random distribution, usually based on a Poisson distribution. + * The method uses the distribution to calculate the probability for 0 feature occuring, + * 1 feature occuring, 2 features, and so on, + * and lists these probabilities in the frequency table. + * By comparing the two frequency tables, you can see whether the features create a pattern. + * If the table for the observed distribution has more quadrats containing many features than the + * table for the random distribution dose, then the features create a clustered pattern. + * + * It is hard to judge the frequency tables are similar or different just by looking at them. + * So, we can use serval statistical tests to find out how much the frequency tables differ. + * We use Kolmogorov-Smirnov test.This method calculates cumulative probabilities for both distributions, + * and then compares the cumulative probabilities at each class level and selects the largest absolute difference D. + * Then, the test compares D to the critical value for a confidence level you specify. + * If D is greater than the critical value, the difference between the observed distribution and + * the random distribution is significant. The greater the value the bigger the difference. + * + * Traditionally, squares are used for the shape of the quadrats, in a regular grid(square-grid). + * Some researchers suggest that the quadrat size equal twice the size of mean area per feature, + * which is simply the area of the study area divided by the number of features. + * + * + * @name quadratAnalysis + * @param {FeatureCollection} pointFeatureSet point set to study + * @param {Object} [options={}] optional parameters + * @param {bbox} [options.studyBbox] bbox representing the study area + * @param {number} [options.confidenceLevel=20] a confidence level. + * The unit is percentage . 5 means 95%, value must be in {@link K_TABLE} + * @returns {Object} result {@link QuadratAnalysisResult} + * @example + * + * var bbox = [-65, 40, -63, 42]; + * var dataset = turf.randomPoint(100, { bbox: bbox }); + * var result = turf.quadratAnalysis(dataset); + * + */ +export default function quadratAnalysis(pointFeatureSet, options) { + + options = options || {}; + const studyBbox = options.studyBbox || turfBBox(pointFeatureSet); + const confidenceLevel = options.confidenceLevel || 20; + const points = pointFeatureSet.features; + + // create square-grid + const numOfPoints = points.length; + const sizeOfArea = area(bboxPolygon(studyBbox)); + const lengthOfSide = Math.sqrt((sizeOfArea / numOfPoints) * 2); + const grid = squareGrid(studyBbox, lengthOfSide, { + units: "meters", + }); + const quadrats = grid.features; + + // count the number of features in each quadrat + const quadratIdDict = {}; + for (let i = 0; i < quadrats.length; i++) { + quadratIdDict[i] = { + box: turfBBox(quadrats[i]), + cnt: 0, + }; + } + + let sumOfPoint = 0; + for (const pt of points) { + for (const key of Object.keys(quadratIdDict)) { + const box = quadratIdDict[key].box; + if (inBBox(getCoord(pt), box)) { + quadratIdDict[key].cnt += 1; + sumOfPoint += 1; + break; + } + } + } + + // the most amount of features in quadrat + let maxCnt = 0; + for (const key of Object.keys(quadratIdDict)) { + const cnt = quadratIdDict[key].cnt; + if (cnt > maxCnt) { + maxCnt = cnt; + } + } + + const expectedDistribution = []; + const numOfQuadrat = Object.keys(quadratIdDict).length; + const lambda = sumOfPoint / numOfQuadrat; + + // get the cumulative probability of the random distribution + let cumulativeProbility = 0.0; + for (let x = 0; x < maxCnt + 1; x++) { + cumulativeProbility += Math.exp(-lambda) * Math.pow(lambda, x) / factorial(x); + expectedDistribution.push(cumulativeProbility); + } + + // get the cumulative probability of the observed distribution + const observedDistribution = []; + let cumulativeObservedQuads = 0; + for (let x = 0; x < maxCnt + 1; x++) { + for (const key of Object.keys(quadratIdDict)) { + if (quadratIdDict[key].cnt === x) { + cumulativeObservedQuads += 1; + } + } + const p = cumulativeObservedQuads / numOfQuadrat; + observedDistribution.push(p); + } + + // get the largest absolute difference between two distributions + let maxDifference = 0; + for (let x = 0; x < maxCnt + 1; x++) { + const difference = Math.abs(expectedDistribution[x] - observedDistribution[x]); + if (difference > maxDifference) { + maxDifference = difference; + } + } + + const k = K_TABLE[confidenceLevel]; + + // statistical test + const criticalValue = k / Math.sqrt(numOfQuadrat); + const result = { + criticalValue, + isRandom: true, + maxAbsoluteDifference: maxDifference, + observedDistribution, + }; + + if (maxDifference > criticalValue) { result.isRandom = false; } + + return result; +} + +/** + * the confidence level + * @type {Object} K_TABLE + * @property {number} 20 + * @property {number} 15 + * @property {number} 10 + * @property {number} 5 + * @property {number} 2 + * @property {number} 1 + */ +const K_TABLE = { + 20: 1.07275, + 15: 1.13795, + 10: 1.22385, + 5: 1.35810, + 2: 1.51743, + 1: 1.62762, +}; + +/** + * the return type of the quadratAnalysis + * @typedef {Object} QuadratAnalysisResult + * @property {number} criticalValue + * @property {number} maxAbsoluteDifference + * @property {boolean} isRandom + * @property {Array.} observedDistribution the cumulative distribution of observed features, + * the index represents the number of features in the quadrat. + */ + +/** + * inBBox from ../boolean-point-in-polygon + * + * @private + * @param {Array} pt point [x,y] + * @param {BBox} bbox BBox [west, south, east, north] + * @returns {boolean} true/false if point is inside BBox + */ +function inBBox(pt, bbox) { + return bbox[0] <= pt[0] && + bbox[1] <= pt[1] && + bbox[2] >= pt[0] && + bbox[3] >= pt[1]; +} + +/** + * https://stackoverflow.com/questions/3959211/fast-factorial-function-in-javascript + * @private + * @param {number} num Number + * @returns {number} the factorial of num + */ +function factorial(num) { + const f = []; + function inner(n) { + if (n === 0 || n === 1) { + return 1; + } + if (f[n] > 0) { + return f[n]; + } + return f[n] = inner(n - 1) * n; + } + return inner(num); +} diff --git a/src/quadrat-analysis/test.js b/src/quadrat-analysis/test.js new file mode 100644 index 0000000000..617ad096b0 --- /dev/null +++ b/src/quadrat-analysis/test.js @@ -0,0 +1,100 @@ +const test = require('tape'); +const glob = require('glob'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const bbox = require('../bbox').default; +const centroid = require('../centroid').default; +const squareGrid = require('../square-grid').default; +const bboxPolygon = require('../bbox-polygon').default; +const { randomPoint } = require('../random'); +const { featureCollection } = require('../helpers'); +const quadratAnalysis = require('./').default; + +test('turf-quadrat-analysis geojson file', t => { + const futianBboxPath = path.join(__dirname, 'test', 'in', 'futian_bbox.json'); + const futianPointPath = path.join(__dirname, 'test', 'in', 'futian_random_point.json'); + const shenzhenBboxPath = path.join(__dirname, 'test', 'in', 'shenzhen_bbox.json'); + + const futianBbox = load.sync(futianBboxPath); + const futianPoint = load.sync(futianPointPath); + const shenzhenBbox = load.sync(shenzhenBboxPath); + + const resultFutian = quadratAnalysis(futianPoint, { + studyBbox: bbox(futianBbox), + confidenceLevel: 20 + }); + + const resultShenzhen = quadratAnalysis(futianPoint, { + studyBbox: bbox(shenzhenBbox), + confidenceLevel: 20 + }); + + t.ok(resultFutian.isRandom, 'ramdom pattern ok'); + t.ok(resultFutian.maxAbsoluteDifference < resultFutian.criticalValue, 'random pattern maxAbsoluteDifference < criticalValue'); + + t.ok(!resultShenzhen.isRandom, 'cluster pattern ok'); + t.ok(resultShenzhen.maxAbsoluteDifference > resultShenzhen.criticalValue, 'cluster pattern maxAbsoluteDifference > criticalValue') + + t.end(); + +}); + +test('turf-quadrat-analysis random point', t => { + // random + const smallBbox = [-1, -1, 1, 1]; + const randomPointSet = randomPoint(400, { bbox: smallBbox }); + const result1 = quadratAnalysis(randomPointSet, { + studyBbox: smallBbox, + confidenceLevel: 20 + }); + + t.ok(result1.isRandom, 'random pattern ok'); + t.ok(result1.maxAbsoluteDifference < result1.criticalValue, 'random pattern maxAbsoluteDifference < criticalValue'); + + // cluster + const bigBbox = [-3, -3, 3, 3]; + const result2 = quadratAnalysis(randomPointSet, { + studyBbox: bigBbox, + confidenceLevel: 20 + }); + + t.ok(!result2.isRandom, 'cluster pattern ok'); + t.ok(result2.maxAbsoluteDifference > result2.criticalValue, 'cluster pattern maxAbsoluteDifference > criticalValue'); + + // uniform + const smallGrid = squareGrid(smallBbox, 0.1, { + units: 'degrees' + }) + let uniformPointSet = []; + smallGrid.features.map(function (feature) { + uniformPointSet.push(centroid(feature)); + }); + uniformPointSet = featureCollection(uniformPointSet); + const result3 = quadratAnalysis(uniformPointSet, { + studyBbox: smallBbox, + confidenceLevel: 20 + }); + + t.ok(!result3.isRandom, 'uniform pattern ok'); + t.ok(result3.maxAbsoluteDifference > result3.criticalValue, 'uniform pattern maxAbsoluteDifference > criticalValue'); + + const randomPointSetPath = path.join(__dirname, 'test', 'out', 'randomPoint.json'); + const uniformPointSetPath = path.join(__dirname, 'test', 'out', 'uniformPoint.json'); + const smallBboxPath = path.join(__dirname, 'test', 'out', 'smallBox.json'); + const bigBboxPath = path.join(__dirname, 'test', 'out', 'bigBox.json'); + const smallGridPath = path.join(__dirname, 'test', 'out', 'smallGrid.json'); + + // console.log(result1, result2, result3); + + if (process.env.REGEN) { + write.sync(randomPointSetPath, randomPointSet); + write.sync(uniformPointSetPath, uniformPointSet); + write.sync(smallBboxPath, bboxPolygon(smallBbox)); + write.sync(bigBboxPath, bboxPolygon(bigBbox)); + write.sync(smallGridPath, smallGrid); + } + + t.end(); + +}); diff --git a/packages/turf-quadrat-analysis/test/in/futian_bbox.json b/src/quadrat-analysis/test/in/futian_bbox.json similarity index 100% rename from packages/turf-quadrat-analysis/test/in/futian_bbox.json rename to src/quadrat-analysis/test/in/futian_bbox.json diff --git a/packages/turf-quadrat-analysis/test/in/futian_grid.json b/src/quadrat-analysis/test/in/futian_grid.json similarity index 100% rename from packages/turf-quadrat-analysis/test/in/futian_grid.json rename to src/quadrat-analysis/test/in/futian_grid.json diff --git a/packages/turf-quadrat-analysis/test/in/futian_random_point.json b/src/quadrat-analysis/test/in/futian_random_point.json similarity index 100% rename from packages/turf-quadrat-analysis/test/in/futian_random_point.json rename to src/quadrat-analysis/test/in/futian_random_point.json diff --git a/packages/turf-quadrat-analysis/test/in/shenzhen_bbox.json b/src/quadrat-analysis/test/in/shenzhen_bbox.json similarity index 100% rename from packages/turf-quadrat-analysis/test/in/shenzhen_bbox.json rename to src/quadrat-analysis/test/in/shenzhen_bbox.json diff --git a/packages/turf-quadrat-analysis/test/out/bigBox.json b/src/quadrat-analysis/test/out/bigBox.json similarity index 100% rename from packages/turf-quadrat-analysis/test/out/bigBox.json rename to src/quadrat-analysis/test/out/bigBox.json diff --git a/packages/turf-quadrat-analysis/test/out/randomPoint.json b/src/quadrat-analysis/test/out/randomPoint.json similarity index 100% rename from packages/turf-quadrat-analysis/test/out/randomPoint.json rename to src/quadrat-analysis/test/out/randomPoint.json diff --git a/packages/turf-quadrat-analysis/test/out/smallBox.json b/src/quadrat-analysis/test/out/smallBox.json similarity index 100% rename from packages/turf-quadrat-analysis/test/out/smallBox.json rename to src/quadrat-analysis/test/out/smallBox.json diff --git a/packages/turf-quadrat-analysis/test/out/smallGrid.json b/src/quadrat-analysis/test/out/smallGrid.json similarity index 100% rename from packages/turf-quadrat-analysis/test/out/smallGrid.json rename to src/quadrat-analysis/test/out/smallGrid.json diff --git a/packages/turf-quadrat-analysis/test/out/uniformPoint.json b/src/quadrat-analysis/test/out/uniformPoint.json similarity index 100% rename from packages/turf-quadrat-analysis/test/out/uniformPoint.json rename to src/quadrat-analysis/test/out/uniformPoint.json diff --git a/packages/turf-random/bench.js b/src/random/bench.js similarity index 100% rename from packages/turf-random/bench.js rename to src/random/bench.js diff --git a/src/random/index.d.ts b/src/random/index.d.ts new file mode 100644 index 0000000000..ce9198b0ea --- /dev/null +++ b/src/random/index.d.ts @@ -0,0 +1,72 @@ +import { BBox, FeatureCollection, LineString, Point, Polygon, Position } from "../helpers"; +/** + * Returns a random position within a {@link bounding box}. + * + * @name randomPosition + * @param {Array} [bbox=[-180, -90, 180, 90]] a bounding box inside of which positions are placed. + * @returns {Array} Position [longitude, latitude] + * @example + * var position = turf.randomPosition([-180, -90, 180, 90]) + * // => position + */ +export declare function randomPosition(bbox?: BBox | { + bbox: BBox; +}): Position; +/** + * Returns a random {@link point}. + * + * @name randomPoint + * @param {number} [count=1] how many geometries will be generated + * @param {Object} [options={}] Optional parameters + * @param {Array} [options.bbox=[-180, -90, 180, 90]] a bounding box inside of which geometries are placed. + * @returns {FeatureCollection} GeoJSON FeatureCollection of points + * @example + * var points = turf.randomPoint(25, {bbox: [-180, -90, 180, 90]}) + * // => points + */ +export declare function randomPoint(count?: number, options?: { + bbox?: BBox; +}): FeatureCollection; +/** + * Returns a random {@link polygon}. + * + * @name randomPolygon + * @param {number} [count=1] how many geometries will be generated + * @param {Object} [options={}] Optional parameters + * @param {Array} [options.bbox=[-180, -90, 180, 90]] a bounding box inside of which geometries are placed. + * @param {number} [options.num_vertices=10] is how many coordinates each LineString will contain. + * @param {number} [options.max_radial_length=10] is the maximum number of decimal degrees latitude or longitude that a + * vertex can reach out of the center of the Polygon. + * @returns {FeatureCollection} GeoJSON FeatureCollection of polygons + * @example + * var polygons = turf.randomPolygon(25, {bbox: [-180, -90, 180, 90]}) + * // => polygons + */ +export declare function randomPolygon(count?: number, options?: { + bbox?: BBox; + num_vertices?: number; + max_radial_length?: number; +}): FeatureCollection; +/** + * Returns a random {@link linestring}. + * + * @name randomLineString + * @param {number} [count=1] how many geometries will be generated + * @param {Object} [options={}] Optional parameters + * @param {Array} [options.bbox=[-180, -90, 180, 90]] a bounding box inside of which geometries are placed. + * @param {number} [options.num_vertices=10] is how many coordinates each LineString will contain. + * @param {number} [options.max_length=0.0001] is the maximum number of decimal degrees that a + * vertex can be from its predecessor + * @param {number} [options.max_rotation=Math.PI / 8] is the maximum number of radians that a + * line segment can turn from the previous segment. + * @returns {FeatureCollection} GeoJSON FeatureCollection of linestrings + * @example + * var lineStrings = turf.randomLineString(25, {bbox: [-180, -90, 180, 90]}) + * // => lineStrings + */ +export declare function randomLineString(count?: number, options?: { + bbox?: BBox; + num_vertices?: number; + max_length?: number; + max_rotation?: number; +}): FeatureCollection; diff --git a/src/random/index.js b/src/random/index.js new file mode 100644 index 0000000000..00290cdf70 --- /dev/null +++ b/src/random/index.js @@ -0,0 +1,177 @@ +import { + point, + lineString, + polygon, + featureCollection, + isObject, + isNumber +} from '../helpers'; + +/** + * Returns a random position within a {@link bounding box}. + * + * @name randomPosition + * @param {Array} [bbox=[-180, -90, 180, 90]] a bounding box inside of which positions are placed. + * @returns {Array} Position [longitude, latitude] + * @example + * var position = turf.randomPosition([-180, -90, 180, 90]) + * //=position + */ +export function randomPosition(bbox) { + if (isObject(bbox)) bbox = bbox.bbox; + if (bbox && !Array.isArray(bbox)) throw new Error('bbox is invalid'); + if (bbox) return coordInBBox(bbox); + else return [lon(), lat()]; +} + +/** + * Returns a random {@link point}. + * + * @name randomPoint + * @param {number} [count=1] how many geometries will be generated + * @param {Object} [options={}] Optional parameters + * @param {Array} [options.bbox=[-180, -90, 180, 90]] a bounding box inside of which geometries are placed. + * @returns {FeatureCollection} GeoJSON FeatureCollection of points + * @example + * var points = turf.randomPoint(25, {bbox: [-180, -90, 180, 90]}) + * //=points + */ +export function randomPoint(count, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var bbox = options.bbox; + if (count === undefined || count === null) count = 1; + + var features = []; + for (var i = 0; i < count; i++) { + features.push(point(randomPosition(bbox))); + } + return featureCollection(features); +} + +/** + * Returns a random {@link polygon}. + * + * @name randomPolygon + * @param {number} [count=1] how many geometries will be generated + * @param {Object} [options={}] Optional parameters + * @param {Array} [options.bbox=[-180, -90, 180, 90]] a bounding box inside of which geometries are placed. + * @param {number} [options.num_vertices=10] is how many coordinates each LineString will contain. + * @param {number} [options.max_radial_length=10] is the maximum number of decimal degrees latitude or longitude that a vertex can reach out of the center of the Polygon. + * @returns {FeatureCollection} GeoJSON FeatureCollection of points + * @example + * var polygons = turf.randomPolygon(25, {bbox: [-180, -90, 180, 90]}) + * //=polygons + */ +export function randomPolygon(count, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var bbox = options.bbox; + var num_vertices = options.num_vertices; + var max_radial_length = options.max_radial_length; + if (count === undefined || count === null) count = 1; + + // Validation + if (!isNumber(num_vertices)) num_vertices = 10; + if (!isNumber(max_radial_length)) max_radial_length = 10; + + var features = []; + for (var i = 0; i < count; i++) { + var vertices = [], + circle_offsets = Array.apply(null, + new Array(num_vertices + 1)).map(Math.random); + + circle_offsets.forEach(sumOffsets); + circle_offsets.forEach(scaleOffsets); + vertices[vertices.length - 1] = vertices[0]; // close the ring + + // center the polygon around something + vertices = vertices.map(vertexToCoordinate(randomPosition(bbox))); + features.push(polygon([vertices])); + } + + function sumOffsets(cur, index, arr) { + arr[index] = (index > 0) ? cur + arr[index - 1] : cur; + } + + function scaleOffsets(cur) { + cur = cur * 2 * Math.PI / circle_offsets[circle_offsets.length - 1]; + var radial_scaler = Math.random(); + vertices.push([ + radial_scaler * max_radial_length * Math.sin(cur), + radial_scaler * max_radial_length * Math.cos(cur) + ]); + } + + return featureCollection(features); +} + +/** + * Returns a random {@link linestring}. + * + * @name randomLineString + * @param {number} [count=1] how many geometries will be generated + * @param {Object} [options={}] Optional parameters + * @param {Array} [options.bbox=[-180, -90, 180, 90]] a bounding box inside of which geometries are placed. + * @param {number} [options.num_vertices=10] is how many coordinates each LineString will contain. + * @param {number} [options.max_length=0.0001] is the maximum number of decimal degrees that a vertex can be from its predecessor + * @param {number} [options.max_rotation=Math.PI / 8] is the maximum number of radians that a line segment can turn from the previous segment. + * @returns {FeatureCollection} GeoJSON FeatureCollection of points + * @example + * var lineStrings = turf.randomLineString(25, {bbox: [-180, -90, 180, 90]}) + * //=lineStrings + */ +export function randomLineString(count, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var bbox = options.bbox; + var num_vertices = options.num_vertices; + var max_length = options.max_length; + var max_rotation = options.max_rotation; + if (count === undefined || count === null) count = 1; + + // Default parameters + if (!isNumber(num_vertices) || num_vertices < 2) num_vertices = 10; + if (!isNumber(max_length)) max_length = 0.0001; + if (!isNumber(max_rotation)) max_rotation = Math.PI / 8; + + var features = []; + for (var i = 0; i < count; i++) { + var startingPoint = randomPosition(bbox); + var vertices = [startingPoint]; + for (var j = 0; j < num_vertices - 1; j++) { + var priorAngle = (j === 0) ? + Math.random() * 2 * Math.PI : + Math.tan( + (vertices[j][1] - vertices[j - 1][1]) / + (vertices[j][0] - vertices[j - 1][0]) + ); + var angle = priorAngle + (Math.random() - 0.5) * max_rotation * 2; + var distance = Math.random() * max_length; + vertices.push([ + vertices[j][0] + distance * Math.cos(angle), + vertices[j][1] + distance * Math.sin(angle) + ]); + } + features.push(lineString(vertices)); + } + + return featureCollection(features); +} + +function vertexToCoordinate(hub) { + return function (cur) { return [cur[0] + hub[0], cur[1] + hub[1]]; }; +} + +function rnd() { return Math.random() - 0.5; } +function lon() { return rnd() * 360; } +function lat() { return rnd() * 180; } + +function coordInBBox(bbox) { + return [ + (Math.random() * (bbox[2] - bbox[0])) + bbox[0], + (Math.random() * (bbox[3] - bbox[1])) + bbox[1]]; +} \ No newline at end of file diff --git a/packages/turf-random/test.js b/src/random/test.js similarity index 100% rename from packages/turf-random/test.js rename to src/random/test.js diff --git a/packages/turf-rectangle-grid/bench.js b/src/rectangle-grid/bench.js similarity index 100% rename from packages/turf-rectangle-grid/bench.js rename to src/rectangle-grid/bench.js diff --git a/src/rectangle-grid/index.d.ts b/src/rectangle-grid/index.d.ts new file mode 100644 index 0000000000..8e4ff044ed --- /dev/null +++ b/src/rectangle-grid/index.d.ts @@ -0,0 +1,11 @@ +import { BBox, Feature, FeatureCollection, MultiPolygon, Polygon, Properties, Units } from "../helpers"; + +/** + * http://turfjs.org/docs/#rectanglegrid + */ + +export default function rectangleGrid

(bbox: BBox, cellWidth: number, cellHeight: number, options?: { + units?: Units; + properties?: P; + mask?: Feature | Polygon | MultiPolygon; +}): FeatureCollection; diff --git a/src/rectangle-grid/index.js b/src/rectangle-grid/index.js new file mode 100644 index 0000000000..f1c90fa1ed --- /dev/null +++ b/src/rectangle-grid/index.js @@ -0,0 +1,78 @@ +import intersect from '../boolean-intersects'; +import distance from '../distance'; +import { polygon, featureCollection } from '../helpers'; + +/** + * Creates a grid of rectangles from a bounding box, {@link Feature} or {@link FeatureCollection}. + * + * @name rectangleGrid + * @param {Array} bbox extent in [minX, minY, maxX, maxY] order + * @param {number} cellWidth of each cell, in units + * @param {number} cellHeight of each cell, in units + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] units ("degrees", "radians", "miles", "kilometers") that the given cellWidth + * and cellHeight are expressed in. Converted at the southern border. + * @param {Feature} [options.mask] if passed a Polygon or MultiPolygon, + * the grid Points will be created only inside it + * @param {Object} [options.properties={}] passed to each point of the grid + * @returns {FeatureCollection} a grid of polygons + * @example + * var bbox = [-95, 30 ,-85, 40]; + * var cellWidth = 50; + * var cellHeight = 20; + * var options = {units: 'miles'}; + * + * var rectangleGrid = turf.rectangleGrid(bbox, cellWidth, cellHeight, options); + * + * //addToMap + * var addToMap = [rectangleGrid] + */ +function rectangleGrid(bbox, cellWidth, cellHeight, options) { + // Containers + const results = []; + const west = bbox[0]; + const south = bbox[1]; + const east = bbox[2]; + const north = bbox[3]; + + const xFraction = cellWidth / (distance([west, south], [east, south], options)); + const cellWidthDeg = xFraction * (east - west); + const yFraction = cellHeight / (distance([west, south], [west, north], options)); + const cellHeightDeg = yFraction * (north - south); + + // rows & columns + const bboxWidth = (east - west); + const bboxHeight = (north - south); + const columns = Math.floor(bboxWidth / cellWidthDeg); + const rows = Math.floor(bboxHeight / cellHeightDeg); + + // if the grid does not fill the bbox perfectly, center it. + const deltaX = (bboxWidth - columns * cellWidthDeg) / 2; + const deltaY = (bboxHeight - rows * cellHeightDeg) / 2; + + // iterate over columns & rows + let currentX = west + deltaX; + for (let column = 0; column < columns; column++) { + let currentY = south + deltaY; + for (let row = 0; row < rows; row++) { + const cellPoly = polygon([[ + [currentX, currentY], + [currentX, currentY + cellHeightDeg], + [currentX + cellWidthDeg, currentY + cellHeightDeg], + [currentX + cellWidthDeg, currentY], + [currentX, currentY], + ]], options.properties); + if (options.mask) { + if (intersect(options.mask, cellPoly)) { results.push(cellPoly); } + } else { + results.push(cellPoly); + } + + currentY += cellHeightDeg; + } + currentX += cellWidthDeg; + } + return featureCollection(results); +} + +export default rectangleGrid; diff --git a/src/rectangle-grid/test.js b/src/rectangle-grid/test.js new file mode 100644 index 0000000000..264066d535 --- /dev/null +++ b/src/rectangle-grid/test.js @@ -0,0 +1,55 @@ + +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const bboxPoly = require('../bbox-polygon').default; +const truncate = require('../truncate').default; +const rectangleGrid = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + json: load.sync(directories.in + filename) + }; +}); + +test('rectangle-grid', t => { + for (const {name, json} of fixtures) { + const {bbox, cellWidth, cellHeight, units, properties, mask} = json; + const options = { + mask, + units, + properties, + } + const result = truncate(rectangleGrid(bbox, cellWidth, cellHeight, options)); + + // Add styled GeoJSON to the result + const poly = bboxPoly(bbox); + poly.properties = { + stroke: '#F00', + 'stroke-width': 6, + 'fill-opacity': 0 + }; + result.features.push(poly); + if (options.mask) { + options.mask.properties = { + "stroke": "#00F", + "stroke-width": 6, + "fill-opacity": 0 + }; + result.features.push(options.mask); + } + + if (process.env.REGEN) write.sync(directories.out + name + '.geojson', result); + t.deepEqual(result, load.sync(directories.out + name + '.geojson'), name); + } + t.end(); +}); diff --git a/packages/turf-rectangle-grid/test/in/10x10-1degree.json b/src/rectangle-grid/test/in/10x10-1degree.json similarity index 100% rename from packages/turf-rectangle-grid/test/in/10x10-1degree.json rename to src/rectangle-grid/test/in/10x10-1degree.json diff --git a/packages/turf-rectangle-grid/test/in/australia-mask.json b/src/rectangle-grid/test/in/australia-mask.json similarity index 100% rename from packages/turf-rectangle-grid/test/in/australia-mask.json rename to src/rectangle-grid/test/in/australia-mask.json diff --git a/packages/turf-rectangle-grid/test/in/big-bbox-500x100-miles.json b/src/rectangle-grid/test/in/big-bbox-500x100-miles.json similarity index 100% rename from packages/turf-rectangle-grid/test/in/big-bbox-500x100-miles.json rename to src/rectangle-grid/test/in/big-bbox-500x100-miles.json diff --git a/packages/turf-rectangle-grid/test/in/fiji-10x5-miles.json b/src/rectangle-grid/test/in/fiji-10x5-miles.json similarity index 100% rename from packages/turf-rectangle-grid/test/in/fiji-10x5-miles.json rename to src/rectangle-grid/test/in/fiji-10x5-miles.json diff --git a/packages/turf-rectangle-grid/test/in/victoria-20x100-km.json b/src/rectangle-grid/test/in/victoria-20x100-km.json similarity index 100% rename from packages/turf-rectangle-grid/test/in/victoria-20x100-km.json rename to src/rectangle-grid/test/in/victoria-20x100-km.json diff --git a/src/rectangle-grid/test/out/10x10-1degree.geojson b/src/rectangle-grid/test/out/10x10-1degree.geojson new file mode 100644 index 0000000000..f08a862304 --- /dev/null +++ b/src/rectangle-grid/test/out/10x10-1degree.geojson @@ -0,0 +1,3146 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -5.019926, + -5 + ], + [ + -5.019926, + -4 + ], + [ + -4.015941, + -4 + ], + [ + -4.015941, + -5 + ], + [ + -5.019926, + -5 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -5.019926, + -4 + ], + [ + -5.019926, + -3 + ], + [ + -4.015941, + -3 + ], + [ + -4.015941, + -4 + ], + [ + -5.019926, + -4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -5.019926, + -3 + ], + [ + -5.019926, + -2 + ], + [ + -4.015941, + -2 + ], + [ + -4.015941, + -3 + ], + [ + -5.019926, + -3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -5.019926, + -2 + ], + [ + -5.019926, + -1 + ], + [ + -4.015941, + -1 + ], + [ + -4.015941, + -2 + ], + [ + -5.019926, + -2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -5.019926, + -1 + ], + [ + -5.019926, + 0 + ], + [ + -4.015941, + 0 + ], + [ + -4.015941, + -1 + ], + [ + -5.019926, + -1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -5.019926, + 0 + ], + [ + -5.019926, + 1 + ], + [ + -4.015941, + 1 + ], + [ + -4.015941, + 0 + ], + [ + -5.019926, + 0 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -5.019926, + 1 + ], + [ + -5.019926, + 2 + ], + [ + -4.015941, + 2 + ], + [ + -4.015941, + 1 + ], + [ + -5.019926, + 1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -5.019926, + 2 + ], + [ + -5.019926, + 3 + ], + [ + -4.015941, + 3 + ], + [ + -4.015941, + 2 + ], + [ + -5.019926, + 2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -5.019926, + 3 + ], + [ + -5.019926, + 4 + ], + [ + -4.015941, + 4 + ], + [ + -4.015941, + 3 + ], + [ + -5.019926, + 3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -5.019926, + 4 + ], + [ + -5.019926, + 5 + ], + [ + -4.015941, + 5 + ], + [ + -4.015941, + 4 + ], + [ + -5.019926, + 4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -4.015941, + -5 + ], + [ + -4.015941, + -4 + ], + [ + -3.011956, + -4 + ], + [ + -3.011956, + -5 + ], + [ + -4.015941, + -5 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -4.015941, + -4 + ], + [ + -4.015941, + -3 + ], + [ + -3.011956, + -3 + ], + [ + -3.011956, + -4 + ], + [ + -4.015941, + -4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -4.015941, + -3 + ], + [ + -4.015941, + -2 + ], + [ + -3.011956, + -2 + ], + [ + -3.011956, + -3 + ], + [ + -4.015941, + -3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -4.015941, + -2 + ], + [ + -4.015941, + -1 + ], + [ + -3.011956, + -1 + ], + [ + -3.011956, + -2 + ], + [ + -4.015941, + -2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -4.015941, + -1 + ], + [ + -4.015941, + 0 + ], + [ + -3.011956, + 0 + ], + [ + -3.011956, + -1 + ], + [ + -4.015941, + -1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -4.015941, + 0 + ], + [ + -4.015941, + 1 + ], + [ + -3.011956, + 1 + ], + [ + -3.011956, + 0 + ], + [ + -4.015941, + 0 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -4.015941, + 1 + ], + [ + -4.015941, + 2 + ], + [ + -3.011956, + 2 + ], + [ + -3.011956, + 1 + ], + [ + -4.015941, + 1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -4.015941, + 2 + ], + [ + -4.015941, + 3 + ], + [ + -3.011956, + 3 + ], + [ + -3.011956, + 2 + ], + [ + -4.015941, + 2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -4.015941, + 3 + ], + [ + -4.015941, + 4 + ], + [ + -3.011956, + 4 + ], + [ + -3.011956, + 3 + ], + [ + -4.015941, + 3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -4.015941, + 4 + ], + [ + -4.015941, + 5 + ], + [ + -3.011956, + 5 + ], + [ + -3.011956, + 4 + ], + [ + -4.015941, + 4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -3.011956, + -5 + ], + [ + -3.011956, + -4 + ], + [ + -2.00797, + -4 + ], + [ + -2.00797, + -5 + ], + [ + -3.011956, + -5 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -3.011956, + -4 + ], + [ + -3.011956, + -3 + ], + [ + -2.00797, + -3 + ], + [ + -2.00797, + -4 + ], + [ + -3.011956, + -4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -3.011956, + -3 + ], + [ + -3.011956, + -2 + ], + [ + -2.00797, + -2 + ], + [ + -2.00797, + -3 + ], + [ + -3.011956, + -3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -3.011956, + -2 + ], + [ + -3.011956, + -1 + ], + [ + -2.00797, + -1 + ], + [ + -2.00797, + -2 + ], + [ + -3.011956, + -2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -3.011956, + -1 + ], + [ + -3.011956, + 0 + ], + [ + -2.00797, + 0 + ], + [ + -2.00797, + -1 + ], + [ + -3.011956, + -1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -3.011956, + 0 + ], + [ + -3.011956, + 1 + ], + [ + -2.00797, + 1 + ], + [ + -2.00797, + 0 + ], + [ + -3.011956, + 0 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -3.011956, + 1 + ], + [ + -3.011956, + 2 + ], + [ + -2.00797, + 2 + ], + [ + -2.00797, + 1 + ], + [ + -3.011956, + 1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -3.011956, + 2 + ], + [ + -3.011956, + 3 + ], + [ + -2.00797, + 3 + ], + [ + -2.00797, + 2 + ], + [ + -3.011956, + 2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -3.011956, + 3 + ], + [ + -3.011956, + 4 + ], + [ + -2.00797, + 4 + ], + [ + -2.00797, + 3 + ], + [ + -3.011956, + 3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -3.011956, + 4 + ], + [ + -3.011956, + 5 + ], + [ + -2.00797, + 5 + ], + [ + -2.00797, + 4 + ], + [ + -3.011956, + 4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -2.00797, + -5 + ], + [ + -2.00797, + -4 + ], + [ + -1.003985, + -4 + ], + [ + -1.003985, + -5 + ], + [ + -2.00797, + -5 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -2.00797, + -4 + ], + [ + -2.00797, + -3 + ], + [ + -1.003985, + -3 + ], + [ + -1.003985, + -4 + ], + [ + -2.00797, + -4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -2.00797, + -3 + ], + [ + -2.00797, + -2 + ], + [ + -1.003985, + -2 + ], + [ + -1.003985, + -3 + ], + [ + -2.00797, + -3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -2.00797, + -2 + ], + [ + -2.00797, + -1 + ], + [ + -1.003985, + -1 + ], + [ + -1.003985, + -2 + ], + [ + -2.00797, + -2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -2.00797, + -1 + ], + [ + -2.00797, + 0 + ], + [ + -1.003985, + 0 + ], + [ + -1.003985, + -1 + ], + [ + -2.00797, + -1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -2.00797, + 0 + ], + [ + -2.00797, + 1 + ], + [ + -1.003985, + 1 + ], + [ + -1.003985, + 0 + ], + [ + -2.00797, + 0 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -2.00797, + 1 + ], + [ + -2.00797, + 2 + ], + [ + -1.003985, + 2 + ], + [ + -1.003985, + 1 + ], + [ + -2.00797, + 1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -2.00797, + 2 + ], + [ + -2.00797, + 3 + ], + [ + -1.003985, + 3 + ], + [ + -1.003985, + 2 + ], + [ + -2.00797, + 2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -2.00797, + 3 + ], + [ + -2.00797, + 4 + ], + [ + -1.003985, + 4 + ], + [ + -1.003985, + 3 + ], + [ + -2.00797, + 3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -2.00797, + 4 + ], + [ + -2.00797, + 5 + ], + [ + -1.003985, + 5 + ], + [ + -1.003985, + 4 + ], + [ + -2.00797, + 4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -1.003985, + -5 + ], + [ + -1.003985, + -4 + ], + [ + 0, + -4 + ], + [ + 0, + -5 + ], + [ + -1.003985, + -5 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -1.003985, + -4 + ], + [ + -1.003985, + -3 + ], + [ + 0, + -3 + ], + [ + 0, + -4 + ], + [ + -1.003985, + -4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -1.003985, + -3 + ], + [ + -1.003985, + -2 + ], + [ + 0, + -2 + ], + [ + 0, + -3 + ], + [ + -1.003985, + -3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -1.003985, + -2 + ], + [ + -1.003985, + -1 + ], + [ + 0, + -1 + ], + [ + 0, + -2 + ], + [ + -1.003985, + -2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -1.003985, + -1 + ], + [ + -1.003985, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + -1 + ], + [ + -1.003985, + -1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -1.003985, + 0 + ], + [ + -1.003985, + 1 + ], + [ + 0, + 1 + ], + [ + 0, + 0 + ], + [ + -1.003985, + 0 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -1.003985, + 1 + ], + [ + -1.003985, + 2 + ], + [ + 0, + 2 + ], + [ + 0, + 1 + ], + [ + -1.003985, + 1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -1.003985, + 2 + ], + [ + -1.003985, + 3 + ], + [ + 0, + 3 + ], + [ + 0, + 2 + ], + [ + -1.003985, + 2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -1.003985, + 3 + ], + [ + -1.003985, + 4 + ], + [ + 0, + 4 + ], + [ + 0, + 3 + ], + [ + -1.003985, + 3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -1.003985, + 4 + ], + [ + -1.003985, + 5 + ], + [ + 0, + 5 + ], + [ + 0, + 4 + ], + [ + -1.003985, + 4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + -5 + ], + [ + 0, + -4 + ], + [ + 1.003985, + -4 + ], + [ + 1.003985, + -5 + ], + [ + 0, + -5 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + -4 + ], + [ + 0, + -3 + ], + [ + 1.003985, + -3 + ], + [ + 1.003985, + -4 + ], + [ + 0, + -4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + -3 + ], + [ + 0, + -2 + ], + [ + 1.003985, + -2 + ], + [ + 1.003985, + -3 + ], + [ + 0, + -3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + -2 + ], + [ + 0, + -1 + ], + [ + 1.003985, + -1 + ], + [ + 1.003985, + -2 + ], + [ + 0, + -2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + -1 + ], + [ + 0, + 0 + ], + [ + 1.003985, + 0 + ], + [ + 1.003985, + -1 + ], + [ + 0, + -1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + 0 + ], + [ + 0, + 1 + ], + [ + 1.003985, + 1 + ], + [ + 1.003985, + 0 + ], + [ + 0, + 0 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + 1 + ], + [ + 0, + 2 + ], + [ + 1.003985, + 2 + ], + [ + 1.003985, + 1 + ], + [ + 0, + 1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + 2 + ], + [ + 0, + 3 + ], + [ + 1.003985, + 3 + ], + [ + 1.003985, + 2 + ], + [ + 0, + 2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + 3 + ], + [ + 0, + 4 + ], + [ + 1.003985, + 4 + ], + [ + 1.003985, + 3 + ], + [ + 0, + 3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + 4 + ], + [ + 0, + 5 + ], + [ + 1.003985, + 5 + ], + [ + 1.003985, + 4 + ], + [ + 0, + 4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 1.003985, + -5 + ], + [ + 1.003985, + -4 + ], + [ + 2.00797, + -4 + ], + [ + 2.00797, + -5 + ], + [ + 1.003985, + -5 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 1.003985, + -4 + ], + [ + 1.003985, + -3 + ], + [ + 2.00797, + -3 + ], + [ + 2.00797, + -4 + ], + [ + 1.003985, + -4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 1.003985, + -3 + ], + [ + 1.003985, + -2 + ], + [ + 2.00797, + -2 + ], + [ + 2.00797, + -3 + ], + [ + 1.003985, + -3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 1.003985, + -2 + ], + [ + 1.003985, + -1 + ], + [ + 2.00797, + -1 + ], + [ + 2.00797, + -2 + ], + [ + 1.003985, + -2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 1.003985, + -1 + ], + [ + 1.003985, + 0 + ], + [ + 2.00797, + 0 + ], + [ + 2.00797, + -1 + ], + [ + 1.003985, + -1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 1.003985, + 0 + ], + [ + 1.003985, + 1 + ], + [ + 2.00797, + 1 + ], + [ + 2.00797, + 0 + ], + [ + 1.003985, + 0 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 1.003985, + 1 + ], + [ + 1.003985, + 2 + ], + [ + 2.00797, + 2 + ], + [ + 2.00797, + 1 + ], + [ + 1.003985, + 1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 1.003985, + 2 + ], + [ + 1.003985, + 3 + ], + [ + 2.00797, + 3 + ], + [ + 2.00797, + 2 + ], + [ + 1.003985, + 2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 1.003985, + 3 + ], + [ + 1.003985, + 4 + ], + [ + 2.00797, + 4 + ], + [ + 2.00797, + 3 + ], + [ + 1.003985, + 3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 1.003985, + 4 + ], + [ + 1.003985, + 5 + ], + [ + 2.00797, + 5 + ], + [ + 2.00797, + 4 + ], + [ + 1.003985, + 4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 2.00797, + -5 + ], + [ + 2.00797, + -4 + ], + [ + 3.011956, + -4 + ], + [ + 3.011956, + -5 + ], + [ + 2.00797, + -5 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 2.00797, + -4 + ], + [ + 2.00797, + -3 + ], + [ + 3.011956, + -3 + ], + [ + 3.011956, + -4 + ], + [ + 2.00797, + -4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 2.00797, + -3 + ], + [ + 2.00797, + -2 + ], + [ + 3.011956, + -2 + ], + [ + 3.011956, + -3 + ], + [ + 2.00797, + -3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 2.00797, + -2 + ], + [ + 2.00797, + -1 + ], + [ + 3.011956, + -1 + ], + [ + 3.011956, + -2 + ], + [ + 2.00797, + -2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 2.00797, + -1 + ], + [ + 2.00797, + 0 + ], + [ + 3.011956, + 0 + ], + [ + 3.011956, + -1 + ], + [ + 2.00797, + -1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 2.00797, + 0 + ], + [ + 2.00797, + 1 + ], + [ + 3.011956, + 1 + ], + [ + 3.011956, + 0 + ], + [ + 2.00797, + 0 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 2.00797, + 1 + ], + [ + 2.00797, + 2 + ], + [ + 3.011956, + 2 + ], + [ + 3.011956, + 1 + ], + [ + 2.00797, + 1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 2.00797, + 2 + ], + [ + 2.00797, + 3 + ], + [ + 3.011956, + 3 + ], + [ + 3.011956, + 2 + ], + [ + 2.00797, + 2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 2.00797, + 3 + ], + [ + 2.00797, + 4 + ], + [ + 3.011956, + 4 + ], + [ + 3.011956, + 3 + ], + [ + 2.00797, + 3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 2.00797, + 4 + ], + [ + 2.00797, + 5 + ], + [ + 3.011956, + 5 + ], + [ + 3.011956, + 4 + ], + [ + 2.00797, + 4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 3.011956, + -5 + ], + [ + 3.011956, + -4 + ], + [ + 4.015941, + -4 + ], + [ + 4.015941, + -5 + ], + [ + 3.011956, + -5 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 3.011956, + -4 + ], + [ + 3.011956, + -3 + ], + [ + 4.015941, + -3 + ], + [ + 4.015941, + -4 + ], + [ + 3.011956, + -4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 3.011956, + -3 + ], + [ + 3.011956, + -2 + ], + [ + 4.015941, + -2 + ], + [ + 4.015941, + -3 + ], + [ + 3.011956, + -3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 3.011956, + -2 + ], + [ + 3.011956, + -1 + ], + [ + 4.015941, + -1 + ], + [ + 4.015941, + -2 + ], + [ + 3.011956, + -2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 3.011956, + -1 + ], + [ + 3.011956, + 0 + ], + [ + 4.015941, + 0 + ], + [ + 4.015941, + -1 + ], + [ + 3.011956, + -1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 3.011956, + 0 + ], + [ + 3.011956, + 1 + ], + [ + 4.015941, + 1 + ], + [ + 4.015941, + 0 + ], + [ + 3.011956, + 0 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 3.011956, + 1 + ], + [ + 3.011956, + 2 + ], + [ + 4.015941, + 2 + ], + [ + 4.015941, + 1 + ], + [ + 3.011956, + 1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 3.011956, + 2 + ], + [ + 3.011956, + 3 + ], + [ + 4.015941, + 3 + ], + [ + 4.015941, + 2 + ], + [ + 3.011956, + 2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 3.011956, + 3 + ], + [ + 3.011956, + 4 + ], + [ + 4.015941, + 4 + ], + [ + 4.015941, + 3 + ], + [ + 3.011956, + 3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 3.011956, + 4 + ], + [ + 3.011956, + 5 + ], + [ + 4.015941, + 5 + ], + [ + 4.015941, + 4 + ], + [ + 3.011956, + 4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.015941, + -5 + ], + [ + 4.015941, + -4 + ], + [ + 5.019926, + -4 + ], + [ + 5.019926, + -5 + ], + [ + 4.015941, + -5 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.015941, + -4 + ], + [ + 4.015941, + -3 + ], + [ + 5.019926, + -3 + ], + [ + 5.019926, + -4 + ], + [ + 4.015941, + -4 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.015941, + -3 + ], + [ + 4.015941, + -2 + ], + [ + 5.019926, + -2 + ], + [ + 5.019926, + -3 + ], + [ + 4.015941, + -3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.015941, + -2 + ], + [ + 4.015941, + -1 + ], + [ + 5.019926, + -1 + ], + [ + 5.019926, + -2 + ], + [ + 4.015941, + -2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.015941, + -1 + ], + [ + 4.015941, + 0 + ], + [ + 5.019926, + 0 + ], + [ + 5.019926, + -1 + ], + [ + 4.015941, + -1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.015941, + 0 + ], + [ + 4.015941, + 1 + ], + [ + 5.019926, + 1 + ], + [ + 5.019926, + 0 + ], + [ + 4.015941, + 0 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.015941, + 1 + ], + [ + 4.015941, + 2 + ], + [ + 5.019926, + 2 + ], + [ + 5.019926, + 1 + ], + [ + 4.015941, + 1 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.015941, + 2 + ], + [ + 4.015941, + 3 + ], + [ + 5.019926, + 3 + ], + [ + 5.019926, + 2 + ], + [ + 4.015941, + 2 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.015941, + 3 + ], + [ + 4.015941, + 4 + ], + [ + 5.019926, + 4 + ], + [ + 5.019926, + 3 + ], + [ + 4.015941, + 3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.015941, + 4 + ], + [ + 4.015941, + 5 + ], + [ + 5.019926, + 5 + ], + [ + 5.019926, + 4 + ], + [ + 4.015941, + 4 + ] + ] + ] + } + }, + { + "type": "Feature", + "bbox": [ + -5.1, + -5.1, + 5.1, + 5.1 + ], + "properties": { + "stroke": "#F00", + "stroke-width": 6, + "fill-opacity": 0 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -5.1, + -5.1 + ], + [ + 5.1, + -5.1 + ], + [ + 5.1, + 5.1 + ], + [ + -5.1, + 5.1 + ], + [ + -5.1, + -5.1 + ] + ] + ] + } + } + ] +} diff --git a/src/rectangle-grid/test/out/australia-mask.geojson b/src/rectangle-grid/test/out/australia-mask.geojson new file mode 100644 index 0000000000..04f30e6848 --- /dev/null +++ b/src/rectangle-grid/test/out/australia-mask.geojson @@ -0,0 +1,13123 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 114, + -20 + ], + [ + 114, + -22 + ], + [ + 115, + -22 + ], + [ + 115, + -20 + ], + [ + 114, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 114, + -22 + ], + [ + 114, + -24 + ], + [ + 115, + -24 + ], + [ + 115, + -22 + ], + [ + 114, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 114, + -24 + ], + [ + 114, + -26 + ], + [ + 115, + -26 + ], + [ + 115, + -24 + ], + [ + 114, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 114, + -26 + ], + [ + 114, + -28 + ], + [ + 115, + -28 + ], + [ + 115, + -26 + ], + [ + 114, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 114, + -28 + ], + [ + 114, + -30 + ], + [ + 115, + -30 + ], + [ + 115, + -28 + ], + [ + 114, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 114, + -30 + ], + [ + 114, + -32 + ], + [ + 115, + -32 + ], + [ + 115, + -30 + ], + [ + 114, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 114, + -32 + ], + [ + 114, + -34 + ], + [ + 115, + -34 + ], + [ + 115, + -32 + ], + [ + 114, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 115, + -20 + ], + [ + 115, + -22 + ], + [ + 116, + -22 + ], + [ + 116, + -20 + ], + [ + 115, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 115, + -22 + ], + [ + 115, + -24 + ], + [ + 116, + -24 + ], + [ + 116, + -22 + ], + [ + 115, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 115, + -24 + ], + [ + 115, + -26 + ], + [ + 116, + -26 + ], + [ + 116, + -24 + ], + [ + 115, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 115, + -26 + ], + [ + 115, + -28 + ], + [ + 116, + -28 + ], + [ + 116, + -26 + ], + [ + 115, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 115, + -28 + ], + [ + 115, + -30 + ], + [ + 116, + -30 + ], + [ + 116, + -28 + ], + [ + 115, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 115, + -30 + ], + [ + 115, + -32 + ], + [ + 116, + -32 + ], + [ + 116, + -30 + ], + [ + 115, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 115, + -32 + ], + [ + 115, + -34 + ], + [ + 116, + -34 + ], + [ + 116, + -32 + ], + [ + 115, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 115, + -34 + ], + [ + 115, + -36 + ], + [ + 116, + -36 + ], + [ + 116, + -34 + ], + [ + 115, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 116, + -20 + ], + [ + 116, + -22 + ], + [ + 117, + -22 + ], + [ + 117, + -20 + ], + [ + 116, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 116, + -22 + ], + [ + 116, + -24 + ], + [ + 117, + -24 + ], + [ + 117, + -22 + ], + [ + 116, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 116, + -24 + ], + [ + 116, + -26 + ], + [ + 117, + -26 + ], + [ + 117, + -24 + ], + [ + 116, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 116, + -26 + ], + [ + 116, + -28 + ], + [ + 117, + -28 + ], + [ + 117, + -26 + ], + [ + 116, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 116, + -28 + ], + [ + 116, + -30 + ], + [ + 117, + -30 + ], + [ + 117, + -28 + ], + [ + 116, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 116, + -30 + ], + [ + 116, + -32 + ], + [ + 117, + -32 + ], + [ + 117, + -30 + ], + [ + 116, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 116, + -32 + ], + [ + 116, + -34 + ], + [ + 117, + -34 + ], + [ + 117, + -32 + ], + [ + 116, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 116, + -34 + ], + [ + 116, + -36 + ], + [ + 117, + -36 + ], + [ + 117, + -34 + ], + [ + 116, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 117, + -20 + ], + [ + 117, + -22 + ], + [ + 118, + -22 + ], + [ + 118, + -20 + ], + [ + 117, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 117, + -22 + ], + [ + 117, + -24 + ], + [ + 118, + -24 + ], + [ + 118, + -22 + ], + [ + 117, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 117, + -24 + ], + [ + 117, + -26 + ], + [ + 118, + -26 + ], + [ + 118, + -24 + ], + [ + 117, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 117, + -26 + ], + [ + 117, + -28 + ], + [ + 118, + -28 + ], + [ + 118, + -26 + ], + [ + 117, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 117, + -28 + ], + [ + 117, + -30 + ], + [ + 118, + -30 + ], + [ + 118, + -28 + ], + [ + 117, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 117, + -30 + ], + [ + 117, + -32 + ], + [ + 118, + -32 + ], + [ + 118, + -30 + ], + [ + 117, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 117, + -32 + ], + [ + 117, + -34 + ], + [ + 118, + -34 + ], + [ + 118, + -32 + ], + [ + 117, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 117, + -34 + ], + [ + 117, + -36 + ], + [ + 118, + -36 + ], + [ + 118, + -34 + ], + [ + 117, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 118, + -20 + ], + [ + 118, + -22 + ], + [ + 119, + -22 + ], + [ + 119, + -20 + ], + [ + 118, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 118, + -22 + ], + [ + 118, + -24 + ], + [ + 119, + -24 + ], + [ + 119, + -22 + ], + [ + 118, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 118, + -24 + ], + [ + 118, + -26 + ], + [ + 119, + -26 + ], + [ + 119, + -24 + ], + [ + 118, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 118, + -26 + ], + [ + 118, + -28 + ], + [ + 119, + -28 + ], + [ + 119, + -26 + ], + [ + 118, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 118, + -28 + ], + [ + 118, + -30 + ], + [ + 119, + -30 + ], + [ + 119, + -28 + ], + [ + 118, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 118, + -30 + ], + [ + 118, + -32 + ], + [ + 119, + -32 + ], + [ + 119, + -30 + ], + [ + 118, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 118, + -32 + ], + [ + 118, + -34 + ], + [ + 119, + -34 + ], + [ + 119, + -32 + ], + [ + 118, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 118, + -34 + ], + [ + 118, + -36 + ], + [ + 119, + -36 + ], + [ + 119, + -34 + ], + [ + 118, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 119, + -18 + ], + [ + 119, + -20 + ], + [ + 120, + -20 + ], + [ + 120, + -18 + ], + [ + 119, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 119, + -20 + ], + [ + 119, + -22 + ], + [ + 120, + -22 + ], + [ + 120, + -20 + ], + [ + 119, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 119, + -22 + ], + [ + 119, + -24 + ], + [ + 120, + -24 + ], + [ + 120, + -22 + ], + [ + 119, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 119, + -24 + ], + [ + 119, + -26 + ], + [ + 120, + -26 + ], + [ + 120, + -24 + ], + [ + 119, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 119, + -26 + ], + [ + 119, + -28 + ], + [ + 120, + -28 + ], + [ + 120, + -26 + ], + [ + 119, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 119, + -28 + ], + [ + 119, + -30 + ], + [ + 120, + -30 + ], + [ + 120, + -28 + ], + [ + 119, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 119, + -30 + ], + [ + 119, + -32 + ], + [ + 120, + -32 + ], + [ + 120, + -30 + ], + [ + 119, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 119, + -32 + ], + [ + 119, + -34 + ], + [ + 120, + -34 + ], + [ + 120, + -32 + ], + [ + 119, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 119, + -34 + ], + [ + 119, + -36 + ], + [ + 120, + -36 + ], + [ + 120, + -34 + ], + [ + 119, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 120, + -18 + ], + [ + 120, + -20 + ], + [ + 121, + -20 + ], + [ + 121, + -18 + ], + [ + 120, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 120, + -20 + ], + [ + 120, + -22 + ], + [ + 121, + -22 + ], + [ + 121, + -20 + ], + [ + 120, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 120, + -22 + ], + [ + 120, + -24 + ], + [ + 121, + -24 + ], + [ + 121, + -22 + ], + [ + 120, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 120, + -24 + ], + [ + 120, + -26 + ], + [ + 121, + -26 + ], + [ + 121, + -24 + ], + [ + 120, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 120, + -26 + ], + [ + 120, + -28 + ], + [ + 121, + -28 + ], + [ + 121, + -26 + ], + [ + 120, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 120, + -28 + ], + [ + 120, + -30 + ], + [ + 121, + -30 + ], + [ + 121, + -28 + ], + [ + 120, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 120, + -30 + ], + [ + 120, + -32 + ], + [ + 121, + -32 + ], + [ + 121, + -30 + ], + [ + 120, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 120, + -32 + ], + [ + 120, + -34 + ], + [ + 121, + -34 + ], + [ + 121, + -32 + ], + [ + 120, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 120, + -34 + ], + [ + 120, + -36 + ], + [ + 121, + -36 + ], + [ + 121, + -34 + ], + [ + 120, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 121, + -18 + ], + [ + 121, + -20 + ], + [ + 122, + -20 + ], + [ + 122, + -18 + ], + [ + 121, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 121, + -20 + ], + [ + 121, + -22 + ], + [ + 122, + -22 + ], + [ + 122, + -20 + ], + [ + 121, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 121, + -22 + ], + [ + 121, + -24 + ], + [ + 122, + -24 + ], + [ + 122, + -22 + ], + [ + 121, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 121, + -24 + ], + [ + 121, + -26 + ], + [ + 122, + -26 + ], + [ + 122, + -24 + ], + [ + 121, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 121, + -26 + ], + [ + 121, + -28 + ], + [ + 122, + -28 + ], + [ + 122, + -26 + ], + [ + 121, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 121, + -28 + ], + [ + 121, + -30 + ], + [ + 122, + -30 + ], + [ + 122, + -28 + ], + [ + 121, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 121, + -30 + ], + [ + 121, + -32 + ], + [ + 122, + -32 + ], + [ + 122, + -30 + ], + [ + 121, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 121, + -32 + ], + [ + 121, + -34 + ], + [ + 122, + -34 + ], + [ + 122, + -32 + ], + [ + 121, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 121, + -34 + ], + [ + 121, + -36 + ], + [ + 122, + -36 + ], + [ + 122, + -34 + ], + [ + 121, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 122, + -16 + ], + [ + 122, + -18 + ], + [ + 123, + -18 + ], + [ + 123, + -16 + ], + [ + 122, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 122, + -18 + ], + [ + 122, + -20 + ], + [ + 123, + -20 + ], + [ + 123, + -18 + ], + [ + 122, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 122, + -20 + ], + [ + 122, + -22 + ], + [ + 123, + -22 + ], + [ + 123, + -20 + ], + [ + 122, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 122, + -22 + ], + [ + 122, + -24 + ], + [ + 123, + -24 + ], + [ + 123, + -22 + ], + [ + 122, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 122, + -24 + ], + [ + 122, + -26 + ], + [ + 123, + -26 + ], + [ + 123, + -24 + ], + [ + 122, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 122, + -26 + ], + [ + 122, + -28 + ], + [ + 123, + -28 + ], + [ + 123, + -26 + ], + [ + 122, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 122, + -28 + ], + [ + 122, + -30 + ], + [ + 123, + -30 + ], + [ + 123, + -28 + ], + [ + 122, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 122, + -30 + ], + [ + 122, + -32 + ], + [ + 123, + -32 + ], + [ + 123, + -30 + ], + [ + 122, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 122, + -32 + ], + [ + 122, + -34 + ], + [ + 123, + -34 + ], + [ + 123, + -32 + ], + [ + 122, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 122, + -34 + ], + [ + 122, + -36 + ], + [ + 123, + -36 + ], + [ + 123, + -34 + ], + [ + 122, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 123, + -16 + ], + [ + 123, + -18 + ], + [ + 124, + -18 + ], + [ + 124, + -16 + ], + [ + 123, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 123, + -18 + ], + [ + 123, + -20 + ], + [ + 124, + -20 + ], + [ + 124, + -18 + ], + [ + 123, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 123, + -20 + ], + [ + 123, + -22 + ], + [ + 124, + -22 + ], + [ + 124, + -20 + ], + [ + 123, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 123, + -22 + ], + [ + 123, + -24 + ], + [ + 124, + -24 + ], + [ + 124, + -22 + ], + [ + 123, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 123, + -24 + ], + [ + 123, + -26 + ], + [ + 124, + -26 + ], + [ + 124, + -24 + ], + [ + 123, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 123, + -26 + ], + [ + 123, + -28 + ], + [ + 124, + -28 + ], + [ + 124, + -26 + ], + [ + 123, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 123, + -28 + ], + [ + 123, + -30 + ], + [ + 124, + -30 + ], + [ + 124, + -28 + ], + [ + 123, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 123, + -30 + ], + [ + 123, + -32 + ], + [ + 124, + -32 + ], + [ + 124, + -30 + ], + [ + 123, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 123, + -32 + ], + [ + 123, + -34 + ], + [ + 124, + -34 + ], + [ + 124, + -32 + ], + [ + 123, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 123, + -34 + ], + [ + 123, + -36 + ], + [ + 124, + -36 + ], + [ + 124, + -34 + ], + [ + 123, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 124, + -14 + ], + [ + 124, + -16 + ], + [ + 125, + -16 + ], + [ + 125, + -14 + ], + [ + 124, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 124, + -16 + ], + [ + 124, + -18 + ], + [ + 125, + -18 + ], + [ + 125, + -16 + ], + [ + 124, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 124, + -18 + ], + [ + 124, + -20 + ], + [ + 125, + -20 + ], + [ + 125, + -18 + ], + [ + 124, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 124, + -20 + ], + [ + 124, + -22 + ], + [ + 125, + -22 + ], + [ + 125, + -20 + ], + [ + 124, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 124, + -22 + ], + [ + 124, + -24 + ], + [ + 125, + -24 + ], + [ + 125, + -22 + ], + [ + 124, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 124, + -24 + ], + [ + 124, + -26 + ], + [ + 125, + -26 + ], + [ + 125, + -24 + ], + [ + 124, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 124, + -26 + ], + [ + 124, + -28 + ], + [ + 125, + -28 + ], + [ + 125, + -26 + ], + [ + 124, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 124, + -28 + ], + [ + 124, + -30 + ], + [ + 125, + -30 + ], + [ + 125, + -28 + ], + [ + 124, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 124, + -30 + ], + [ + 124, + -32 + ], + [ + 125, + -32 + ], + [ + 125, + -30 + ], + [ + 124, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 124, + -32 + ], + [ + 124, + -34 + ], + [ + 125, + -34 + ], + [ + 125, + -32 + ], + [ + 124, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 125, + -14 + ], + [ + 125, + -16 + ], + [ + 126, + -16 + ], + [ + 126, + -14 + ], + [ + 125, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 125, + -16 + ], + [ + 125, + -18 + ], + [ + 126, + -18 + ], + [ + 126, + -16 + ], + [ + 125, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 125, + -18 + ], + [ + 125, + -20 + ], + [ + 126, + -20 + ], + [ + 126, + -18 + ], + [ + 125, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 125, + -20 + ], + [ + 125, + -22 + ], + [ + 126, + -22 + ], + [ + 126, + -20 + ], + [ + 125, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 125, + -22 + ], + [ + 125, + -24 + ], + [ + 126, + -24 + ], + [ + 126, + -22 + ], + [ + 125, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 125, + -24 + ], + [ + 125, + -26 + ], + [ + 126, + -26 + ], + [ + 126, + -24 + ], + [ + 125, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 125, + -26 + ], + [ + 125, + -28 + ], + [ + 126, + -28 + ], + [ + 126, + -26 + ], + [ + 125, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 125, + -28 + ], + [ + 125, + -30 + ], + [ + 126, + -30 + ], + [ + 126, + -28 + ], + [ + 125, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 125, + -30 + ], + [ + 125, + -32 + ], + [ + 126, + -32 + ], + [ + 126, + -30 + ], + [ + 125, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 125, + -32 + ], + [ + 125, + -34 + ], + [ + 126, + -34 + ], + [ + 126, + -32 + ], + [ + 125, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 126, + -14 + ], + [ + 126, + -16 + ], + [ + 127, + -16 + ], + [ + 127, + -14 + ], + [ + 126, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 126, + -16 + ], + [ + 126, + -18 + ], + [ + 127, + -18 + ], + [ + 127, + -16 + ], + [ + 126, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 126, + -18 + ], + [ + 126, + -20 + ], + [ + 127, + -20 + ], + [ + 127, + -18 + ], + [ + 126, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 126, + -20 + ], + [ + 126, + -22 + ], + [ + 127, + -22 + ], + [ + 127, + -20 + ], + [ + 126, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 126, + -22 + ], + [ + 126, + -24 + ], + [ + 127, + -24 + ], + [ + 127, + -22 + ], + [ + 126, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 126, + -24 + ], + [ + 126, + -26 + ], + [ + 127, + -26 + ], + [ + 127, + -24 + ], + [ + 126, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 126, + -26 + ], + [ + 126, + -28 + ], + [ + 127, + -28 + ], + [ + 127, + -26 + ], + [ + 126, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 126, + -28 + ], + [ + 126, + -30 + ], + [ + 127, + -30 + ], + [ + 127, + -28 + ], + [ + 126, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 126, + -30 + ], + [ + 126, + -32 + ], + [ + 127, + -32 + ], + [ + 127, + -30 + ], + [ + 126, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 126, + -32 + ], + [ + 126, + -34 + ], + [ + 127, + -34 + ], + [ + 127, + -32 + ], + [ + 126, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 127, + -14 + ], + [ + 127, + -16 + ], + [ + 128, + -16 + ], + [ + 128, + -14 + ], + [ + 127, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 127, + -16 + ], + [ + 127, + -18 + ], + [ + 128, + -18 + ], + [ + 128, + -16 + ], + [ + 127, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 127, + -18 + ], + [ + 127, + -20 + ], + [ + 128, + -20 + ], + [ + 128, + -18 + ], + [ + 127, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 127, + -20 + ], + [ + 127, + -22 + ], + [ + 128, + -22 + ], + [ + 128, + -20 + ], + [ + 127, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 127, + -22 + ], + [ + 127, + -24 + ], + [ + 128, + -24 + ], + [ + 128, + -22 + ], + [ + 127, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 127, + -24 + ], + [ + 127, + -26 + ], + [ + 128, + -26 + ], + [ + 128, + -24 + ], + [ + 127, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 127, + -26 + ], + [ + 127, + -28 + ], + [ + 128, + -28 + ], + [ + 128, + -26 + ], + [ + 127, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 127, + -28 + ], + [ + 127, + -30 + ], + [ + 128, + -30 + ], + [ + 128, + -28 + ], + [ + 127, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 127, + -30 + ], + [ + 127, + -32 + ], + [ + 128, + -32 + ], + [ + 128, + -30 + ], + [ + 127, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 127, + -32 + ], + [ + 127, + -34 + ], + [ + 128, + -34 + ], + [ + 128, + -32 + ], + [ + 127, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 128, + -14 + ], + [ + 128, + -16 + ], + [ + 129, + -16 + ], + [ + 129, + -14 + ], + [ + 128, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 128, + -16 + ], + [ + 128, + -18 + ], + [ + 129, + -18 + ], + [ + 129, + -16 + ], + [ + 128, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 128, + -18 + ], + [ + 128, + -20 + ], + [ + 129, + -20 + ], + [ + 129, + -18 + ], + [ + 128, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 128, + -20 + ], + [ + 128, + -22 + ], + [ + 129, + -22 + ], + [ + 129, + -20 + ], + [ + 128, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 128, + -22 + ], + [ + 128, + -24 + ], + [ + 129, + -24 + ], + [ + 129, + -22 + ], + [ + 128, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 128, + -24 + ], + [ + 128, + -26 + ], + [ + 129, + -26 + ], + [ + 129, + -24 + ], + [ + 128, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 128, + -26 + ], + [ + 128, + -28 + ], + [ + 129, + -28 + ], + [ + 129, + -26 + ], + [ + 128, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 128, + -28 + ], + [ + 128, + -30 + ], + [ + 129, + -30 + ], + [ + 129, + -28 + ], + [ + 128, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 128, + -30 + ], + [ + 128, + -32 + ], + [ + 129, + -32 + ], + [ + 129, + -30 + ], + [ + 128, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 129, + -12 + ], + [ + 129, + -14 + ], + [ + 130, + -14 + ], + [ + 130, + -12 + ], + [ + 129, + -12 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 129, + -14 + ], + [ + 129, + -16 + ], + [ + 130, + -16 + ], + [ + 130, + -14 + ], + [ + 129, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 129, + -16 + ], + [ + 129, + -18 + ], + [ + 130, + -18 + ], + [ + 130, + -16 + ], + [ + 129, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 129, + -18 + ], + [ + 129, + -20 + ], + [ + 130, + -20 + ], + [ + 130, + -18 + ], + [ + 129, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 129, + -20 + ], + [ + 129, + -22 + ], + [ + 130, + -22 + ], + [ + 130, + -20 + ], + [ + 129, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 129, + -22 + ], + [ + 129, + -24 + ], + [ + 130, + -24 + ], + [ + 130, + -22 + ], + [ + 129, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 129, + -24 + ], + [ + 129, + -26 + ], + [ + 130, + -26 + ], + [ + 130, + -24 + ], + [ + 129, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 129, + -26 + ], + [ + 129, + -28 + ], + [ + 130, + -28 + ], + [ + 130, + -26 + ], + [ + 129, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 129, + -28 + ], + [ + 129, + -30 + ], + [ + 130, + -30 + ], + [ + 130, + -28 + ], + [ + 129, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 129, + -30 + ], + [ + 129, + -32 + ], + [ + 130, + -32 + ], + [ + 130, + -30 + ], + [ + 129, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 130, + -10 + ], + [ + 130, + -12 + ], + [ + 131, + -12 + ], + [ + 131, + -10 + ], + [ + 130, + -10 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 130, + -12 + ], + [ + 130, + -14 + ], + [ + 131, + -14 + ], + [ + 131, + -12 + ], + [ + 130, + -12 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 130, + -14 + ], + [ + 130, + -16 + ], + [ + 131, + -16 + ], + [ + 131, + -14 + ], + [ + 130, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 130, + -16 + ], + [ + 130, + -18 + ], + [ + 131, + -18 + ], + [ + 131, + -16 + ], + [ + 130, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 130, + -18 + ], + [ + 130, + -20 + ], + [ + 131, + -20 + ], + [ + 131, + -18 + ], + [ + 130, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 130, + -20 + ], + [ + 130, + -22 + ], + [ + 131, + -22 + ], + [ + 131, + -20 + ], + [ + 130, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 130, + -22 + ], + [ + 130, + -24 + ], + [ + 131, + -24 + ], + [ + 131, + -22 + ], + [ + 130, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 130, + -24 + ], + [ + 130, + -26 + ], + [ + 131, + -26 + ], + [ + 131, + -24 + ], + [ + 130, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 130, + -26 + ], + [ + 130, + -28 + ], + [ + 131, + -28 + ], + [ + 131, + -26 + ], + [ + 130, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 130, + -28 + ], + [ + 130, + -30 + ], + [ + 131, + -30 + ], + [ + 131, + -28 + ], + [ + 130, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 130, + -30 + ], + [ + 130, + -32 + ], + [ + 131, + -32 + ], + [ + 131, + -30 + ], + [ + 130, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 131, + -10 + ], + [ + 131, + -12 + ], + [ + 132, + -12 + ], + [ + 132, + -10 + ], + [ + 131, + -10 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 131, + -12 + ], + [ + 131, + -14 + ], + [ + 132, + -14 + ], + [ + 132, + -12 + ], + [ + 131, + -12 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 131, + -14 + ], + [ + 131, + -16 + ], + [ + 132, + -16 + ], + [ + 132, + -14 + ], + [ + 131, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 131, + -16 + ], + [ + 131, + -18 + ], + [ + 132, + -18 + ], + [ + 132, + -16 + ], + [ + 131, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 131, + -18 + ], + [ + 131, + -20 + ], + [ + 132, + -20 + ], + [ + 132, + -18 + ], + [ + 131, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 131, + -20 + ], + [ + 131, + -22 + ], + [ + 132, + -22 + ], + [ + 132, + -20 + ], + [ + 131, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 131, + -22 + ], + [ + 131, + -24 + ], + [ + 132, + -24 + ], + [ + 132, + -22 + ], + [ + 131, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 131, + -24 + ], + [ + 131, + -26 + ], + [ + 132, + -26 + ], + [ + 132, + -24 + ], + [ + 131, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 131, + -26 + ], + [ + 131, + -28 + ], + [ + 132, + -28 + ], + [ + 132, + -26 + ], + [ + 131, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 131, + -28 + ], + [ + 131, + -30 + ], + [ + 132, + -30 + ], + [ + 132, + -28 + ], + [ + 131, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 131, + -30 + ], + [ + 131, + -32 + ], + [ + 132, + -32 + ], + [ + 132, + -30 + ], + [ + 131, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 132, + -10 + ], + [ + 132, + -12 + ], + [ + 133, + -12 + ], + [ + 133, + -10 + ], + [ + 132, + -10 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 132, + -12 + ], + [ + 132, + -14 + ], + [ + 133, + -14 + ], + [ + 133, + -12 + ], + [ + 132, + -12 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 132, + -14 + ], + [ + 132, + -16 + ], + [ + 133, + -16 + ], + [ + 133, + -14 + ], + [ + 132, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 132, + -16 + ], + [ + 132, + -18 + ], + [ + 133, + -18 + ], + [ + 133, + -16 + ], + [ + 132, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 132, + -18 + ], + [ + 132, + -20 + ], + [ + 133, + -20 + ], + [ + 133, + -18 + ], + [ + 132, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 132, + -20 + ], + [ + 132, + -22 + ], + [ + 133, + -22 + ], + [ + 133, + -20 + ], + [ + 132, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 132, + -22 + ], + [ + 132, + -24 + ], + [ + 133, + -24 + ], + [ + 133, + -22 + ], + [ + 132, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 132, + -24 + ], + [ + 132, + -26 + ], + [ + 133, + -26 + ], + [ + 133, + -24 + ], + [ + 132, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 132, + -26 + ], + [ + 132, + -28 + ], + [ + 133, + -28 + ], + [ + 133, + -26 + ], + [ + 132, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 132, + -28 + ], + [ + 132, + -30 + ], + [ + 133, + -30 + ], + [ + 133, + -28 + ], + [ + 132, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 132, + -30 + ], + [ + 132, + -32 + ], + [ + 133, + -32 + ], + [ + 133, + -30 + ], + [ + 132, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 132, + -32 + ], + [ + 132, + -34 + ], + [ + 133, + -34 + ], + [ + 133, + -32 + ], + [ + 132, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 133, + -10 + ], + [ + 133, + -12 + ], + [ + 134, + -12 + ], + [ + 134, + -10 + ], + [ + 133, + -10 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 133, + -12 + ], + [ + 133, + -14 + ], + [ + 134, + -14 + ], + [ + 134, + -12 + ], + [ + 133, + -12 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 133, + -14 + ], + [ + 133, + -16 + ], + [ + 134, + -16 + ], + [ + 134, + -14 + ], + [ + 133, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 133, + -16 + ], + [ + 133, + -18 + ], + [ + 134, + -18 + ], + [ + 134, + -16 + ], + [ + 133, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 133, + -18 + ], + [ + 133, + -20 + ], + [ + 134, + -20 + ], + [ + 134, + -18 + ], + [ + 133, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 133, + -20 + ], + [ + 133, + -22 + ], + [ + 134, + -22 + ], + [ + 134, + -20 + ], + [ + 133, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 133, + -22 + ], + [ + 133, + -24 + ], + [ + 134, + -24 + ], + [ + 134, + -22 + ], + [ + 133, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 133, + -24 + ], + [ + 133, + -26 + ], + [ + 134, + -26 + ], + [ + 134, + -24 + ], + [ + 133, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 133, + -26 + ], + [ + 133, + -28 + ], + [ + 134, + -28 + ], + [ + 134, + -26 + ], + [ + 133, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 133, + -28 + ], + [ + 133, + -30 + ], + [ + 134, + -30 + ], + [ + 134, + -28 + ], + [ + 133, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 133, + -30 + ], + [ + 133, + -32 + ], + [ + 134, + -32 + ], + [ + 134, + -30 + ], + [ + 133, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 133, + -32 + ], + [ + 133, + -34 + ], + [ + 134, + -34 + ], + [ + 134, + -32 + ], + [ + 133, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 134, + -10 + ], + [ + 134, + -12 + ], + [ + 135, + -12 + ], + [ + 135, + -10 + ], + [ + 134, + -10 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 134, + -12 + ], + [ + 134, + -14 + ], + [ + 135, + -14 + ], + [ + 135, + -12 + ], + [ + 134, + -12 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 134, + -14 + ], + [ + 134, + -16 + ], + [ + 135, + -16 + ], + [ + 135, + -14 + ], + [ + 134, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 134, + -16 + ], + [ + 134, + -18 + ], + [ + 135, + -18 + ], + [ + 135, + -16 + ], + [ + 134, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 134, + -18 + ], + [ + 134, + -20 + ], + [ + 135, + -20 + ], + [ + 135, + -18 + ], + [ + 134, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 134, + -20 + ], + [ + 134, + -22 + ], + [ + 135, + -22 + ], + [ + 135, + -20 + ], + [ + 134, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 134, + -22 + ], + [ + 134, + -24 + ], + [ + 135, + -24 + ], + [ + 135, + -22 + ], + [ + 134, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 134, + -24 + ], + [ + 134, + -26 + ], + [ + 135, + -26 + ], + [ + 135, + -24 + ], + [ + 134, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 134, + -26 + ], + [ + 134, + -28 + ], + [ + 135, + -28 + ], + [ + 135, + -26 + ], + [ + 134, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 134, + -28 + ], + [ + 134, + -30 + ], + [ + 135, + -30 + ], + [ + 135, + -28 + ], + [ + 134, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 134, + -30 + ], + [ + 134, + -32 + ], + [ + 135, + -32 + ], + [ + 135, + -30 + ], + [ + 134, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 134, + -32 + ], + [ + 134, + -34 + ], + [ + 135, + -34 + ], + [ + 135, + -32 + ], + [ + 134, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 134, + -34 + ], + [ + 134, + -36 + ], + [ + 135, + -36 + ], + [ + 135, + -34 + ], + [ + 134, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 135, + -10 + ], + [ + 135, + -12 + ], + [ + 136, + -12 + ], + [ + 136, + -10 + ], + [ + 135, + -10 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 135, + -12 + ], + [ + 135, + -14 + ], + [ + 136, + -14 + ], + [ + 136, + -12 + ], + [ + 135, + -12 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 135, + -14 + ], + [ + 135, + -16 + ], + [ + 136, + -16 + ], + [ + 136, + -14 + ], + [ + 135, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 135, + -16 + ], + [ + 135, + -18 + ], + [ + 136, + -18 + ], + [ + 136, + -16 + ], + [ + 135, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 135, + -18 + ], + [ + 135, + -20 + ], + [ + 136, + -20 + ], + [ + 136, + -18 + ], + [ + 135, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 135, + -20 + ], + [ + 135, + -22 + ], + [ + 136, + -22 + ], + [ + 136, + -20 + ], + [ + 135, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 135, + -22 + ], + [ + 135, + -24 + ], + [ + 136, + -24 + ], + [ + 136, + -22 + ], + [ + 135, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 135, + -24 + ], + [ + 135, + -26 + ], + [ + 136, + -26 + ], + [ + 136, + -24 + ], + [ + 135, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 135, + -26 + ], + [ + 135, + -28 + ], + [ + 136, + -28 + ], + [ + 136, + -26 + ], + [ + 135, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 135, + -28 + ], + [ + 135, + -30 + ], + [ + 136, + -30 + ], + [ + 136, + -28 + ], + [ + 135, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 135, + -30 + ], + [ + 135, + -32 + ], + [ + 136, + -32 + ], + [ + 136, + -30 + ], + [ + 135, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 135, + -32 + ], + [ + 135, + -34 + ], + [ + 136, + -34 + ], + [ + 136, + -32 + ], + [ + 135, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 135, + -34 + ], + [ + 135, + -36 + ], + [ + 136, + -36 + ], + [ + 136, + -34 + ], + [ + 135, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 136, + -10 + ], + [ + 136, + -12 + ], + [ + 137, + -12 + ], + [ + 137, + -10 + ], + [ + 136, + -10 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 136, + -12 + ], + [ + 136, + -14 + ], + [ + 137, + -14 + ], + [ + 137, + -12 + ], + [ + 136, + -12 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 136, + -14 + ], + [ + 136, + -16 + ], + [ + 137, + -16 + ], + [ + 137, + -14 + ], + [ + 136, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 136, + -16 + ], + [ + 136, + -18 + ], + [ + 137, + -18 + ], + [ + 137, + -16 + ], + [ + 136, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 136, + -18 + ], + [ + 136, + -20 + ], + [ + 137, + -20 + ], + [ + 137, + -18 + ], + [ + 136, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 136, + -20 + ], + [ + 136, + -22 + ], + [ + 137, + -22 + ], + [ + 137, + -20 + ], + [ + 136, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 136, + -22 + ], + [ + 136, + -24 + ], + [ + 137, + -24 + ], + [ + 137, + -22 + ], + [ + 136, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 136, + -24 + ], + [ + 136, + -26 + ], + [ + 137, + -26 + ], + [ + 137, + -24 + ], + [ + 136, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 136, + -26 + ], + [ + 136, + -28 + ], + [ + 137, + -28 + ], + [ + 137, + -26 + ], + [ + 136, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 136, + -28 + ], + [ + 136, + -30 + ], + [ + 137, + -30 + ], + [ + 137, + -28 + ], + [ + 136, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 136, + -30 + ], + [ + 136, + -32 + ], + [ + 137, + -32 + ], + [ + 137, + -30 + ], + [ + 136, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 136, + -32 + ], + [ + 136, + -34 + ], + [ + 137, + -34 + ], + [ + 137, + -32 + ], + [ + 136, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 136, + -34 + ], + [ + 136, + -36 + ], + [ + 137, + -36 + ], + [ + 137, + -34 + ], + [ + 136, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 137, + -10 + ], + [ + 137, + -12 + ], + [ + 138, + -12 + ], + [ + 138, + -10 + ], + [ + 137, + -10 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 137, + -12 + ], + [ + 137, + -14 + ], + [ + 138, + -14 + ], + [ + 138, + -12 + ], + [ + 137, + -12 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 137, + -14 + ], + [ + 137, + -16 + ], + [ + 138, + -16 + ], + [ + 138, + -14 + ], + [ + 137, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 137, + -16 + ], + [ + 137, + -18 + ], + [ + 138, + -18 + ], + [ + 138, + -16 + ], + [ + 137, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 137, + -18 + ], + [ + 137, + -20 + ], + [ + 138, + -20 + ], + [ + 138, + -18 + ], + [ + 137, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 137, + -20 + ], + [ + 137, + -22 + ], + [ + 138, + -22 + ], + [ + 138, + -20 + ], + [ + 137, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 137, + -22 + ], + [ + 137, + -24 + ], + [ + 138, + -24 + ], + [ + 138, + -22 + ], + [ + 137, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 137, + -24 + ], + [ + 137, + -26 + ], + [ + 138, + -26 + ], + [ + 138, + -24 + ], + [ + 137, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 137, + -26 + ], + [ + 137, + -28 + ], + [ + 138, + -28 + ], + [ + 138, + -26 + ], + [ + 137, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 137, + -28 + ], + [ + 137, + -30 + ], + [ + 138, + -30 + ], + [ + 138, + -28 + ], + [ + 137, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 137, + -30 + ], + [ + 137, + -32 + ], + [ + 138, + -32 + ], + [ + 138, + -30 + ], + [ + 137, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 137, + -32 + ], + [ + 137, + -34 + ], + [ + 138, + -34 + ], + [ + 138, + -32 + ], + [ + 137, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 137, + -34 + ], + [ + 137, + -36 + ], + [ + 138, + -36 + ], + [ + 138, + -34 + ], + [ + 137, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 138, + -16 + ], + [ + 138, + -18 + ], + [ + 139, + -18 + ], + [ + 139, + -16 + ], + [ + 138, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 138, + -18 + ], + [ + 138, + -20 + ], + [ + 139, + -20 + ], + [ + 139, + -18 + ], + [ + 138, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 138, + -20 + ], + [ + 138, + -22 + ], + [ + 139, + -22 + ], + [ + 139, + -20 + ], + [ + 138, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 138, + -22 + ], + [ + 138, + -24 + ], + [ + 139, + -24 + ], + [ + 139, + -22 + ], + [ + 138, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 138, + -24 + ], + [ + 138, + -26 + ], + [ + 139, + -26 + ], + [ + 139, + -24 + ], + [ + 138, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 138, + -26 + ], + [ + 138, + -28 + ], + [ + 139, + -28 + ], + [ + 139, + -26 + ], + [ + 138, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 138, + -28 + ], + [ + 138, + -30 + ], + [ + 139, + -30 + ], + [ + 139, + -28 + ], + [ + 138, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 138, + -30 + ], + [ + 138, + -32 + ], + [ + 139, + -32 + ], + [ + 139, + -30 + ], + [ + 138, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 138, + -32 + ], + [ + 138, + -34 + ], + [ + 139, + -34 + ], + [ + 139, + -32 + ], + [ + 138, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 138, + -34 + ], + [ + 138, + -36 + ], + [ + 139, + -36 + ], + [ + 139, + -34 + ], + [ + 138, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 139, + -16 + ], + [ + 139, + -18 + ], + [ + 140, + -18 + ], + [ + 140, + -16 + ], + [ + 139, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 139, + -18 + ], + [ + 139, + -20 + ], + [ + 140, + -20 + ], + [ + 140, + -18 + ], + [ + 139, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 139, + -20 + ], + [ + 139, + -22 + ], + [ + 140, + -22 + ], + [ + 140, + -20 + ], + [ + 139, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 139, + -22 + ], + [ + 139, + -24 + ], + [ + 140, + -24 + ], + [ + 140, + -22 + ], + [ + 139, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 139, + -24 + ], + [ + 139, + -26 + ], + [ + 140, + -26 + ], + [ + 140, + -24 + ], + [ + 139, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 139, + -26 + ], + [ + 139, + -28 + ], + [ + 140, + -28 + ], + [ + 140, + -26 + ], + [ + 139, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 139, + -28 + ], + [ + 139, + -30 + ], + [ + 140, + -30 + ], + [ + 140, + -28 + ], + [ + 139, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 139, + -30 + ], + [ + 139, + -32 + ], + [ + 140, + -32 + ], + [ + 140, + -30 + ], + [ + 139, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 139, + -32 + ], + [ + 139, + -34 + ], + [ + 140, + -34 + ], + [ + 140, + -32 + ], + [ + 139, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 139, + -34 + ], + [ + 139, + -36 + ], + [ + 140, + -36 + ], + [ + 140, + -34 + ], + [ + 139, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 139, + -36 + ], + [ + 139, + -38 + ], + [ + 140, + -38 + ], + [ + 140, + -36 + ], + [ + 139, + -36 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 140, + -14 + ], + [ + 140, + -16 + ], + [ + 141, + -16 + ], + [ + 141, + -14 + ], + [ + 140, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 140, + -16 + ], + [ + 140, + -18 + ], + [ + 141, + -18 + ], + [ + 141, + -16 + ], + [ + 140, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 140, + -18 + ], + [ + 140, + -20 + ], + [ + 141, + -20 + ], + [ + 141, + -18 + ], + [ + 140, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 140, + -20 + ], + [ + 140, + -22 + ], + [ + 141, + -22 + ], + [ + 141, + -20 + ], + [ + 140, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 140, + -22 + ], + [ + 140, + -24 + ], + [ + 141, + -24 + ], + [ + 141, + -22 + ], + [ + 140, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 140, + -24 + ], + [ + 140, + -26 + ], + [ + 141, + -26 + ], + [ + 141, + -24 + ], + [ + 140, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 140, + -26 + ], + [ + 140, + -28 + ], + [ + 141, + -28 + ], + [ + 141, + -26 + ], + [ + 140, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 140, + -28 + ], + [ + 140, + -30 + ], + [ + 141, + -30 + ], + [ + 141, + -28 + ], + [ + 140, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 140, + -30 + ], + [ + 140, + -32 + ], + [ + 141, + -32 + ], + [ + 141, + -30 + ], + [ + 140, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 140, + -32 + ], + [ + 140, + -34 + ], + [ + 141, + -34 + ], + [ + 141, + -32 + ], + [ + 140, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 140, + -34 + ], + [ + 140, + -36 + ], + [ + 141, + -36 + ], + [ + 141, + -34 + ], + [ + 140, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 140, + -36 + ], + [ + 140, + -38 + ], + [ + 141, + -38 + ], + [ + 141, + -36 + ], + [ + 140, + -36 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 141, + -10 + ], + [ + 141, + -12 + ], + [ + 142, + -12 + ], + [ + 142, + -10 + ], + [ + 141, + -10 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 141, + -12 + ], + [ + 141, + -14 + ], + [ + 142, + -14 + ], + [ + 142, + -12 + ], + [ + 141, + -12 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 141, + -14 + ], + [ + 141, + -16 + ], + [ + 142, + -16 + ], + [ + 142, + -14 + ], + [ + 141, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 141, + -16 + ], + [ + 141, + -18 + ], + [ + 142, + -18 + ], + [ + 142, + -16 + ], + [ + 141, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 141, + -18 + ], + [ + 141, + -20 + ], + [ + 142, + -20 + ], + [ + 142, + -18 + ], + [ + 141, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 141, + -20 + ], + [ + 141, + -22 + ], + [ + 142, + -22 + ], + [ + 142, + -20 + ], + [ + 141, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 141, + -22 + ], + [ + 141, + -24 + ], + [ + 142, + -24 + ], + [ + 142, + -22 + ], + [ + 141, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 141, + -24 + ], + [ + 141, + -26 + ], + [ + 142, + -26 + ], + [ + 142, + -24 + ], + [ + 141, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 141, + -26 + ], + [ + 141, + -28 + ], + [ + 142, + -28 + ], + [ + 142, + -26 + ], + [ + 141, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 141, + -28 + ], + [ + 141, + -30 + ], + [ + 142, + -30 + ], + [ + 142, + -28 + ], + [ + 141, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 141, + -30 + ], + [ + 141, + -32 + ], + [ + 142, + -32 + ], + [ + 142, + -30 + ], + [ + 141, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 141, + -32 + ], + [ + 141, + -34 + ], + [ + 142, + -34 + ], + [ + 142, + -32 + ], + [ + 141, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 141, + -34 + ], + [ + 141, + -36 + ], + [ + 142, + -36 + ], + [ + 142, + -34 + ], + [ + 141, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 141, + -36 + ], + [ + 141, + -38 + ], + [ + 142, + -38 + ], + [ + 142, + -36 + ], + [ + 141, + -36 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 141, + -38 + ], + [ + 141, + -40 + ], + [ + 142, + -40 + ], + [ + 142, + -38 + ], + [ + 141, + -38 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 142, + -10 + ], + [ + 142, + -12 + ], + [ + 143, + -12 + ], + [ + 143, + -10 + ], + [ + 142, + -10 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 142, + -12 + ], + [ + 142, + -14 + ], + [ + 143, + -14 + ], + [ + 143, + -12 + ], + [ + 142, + -12 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 142, + -14 + ], + [ + 142, + -16 + ], + [ + 143, + -16 + ], + [ + 143, + -14 + ], + [ + 142, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 142, + -16 + ], + [ + 142, + -18 + ], + [ + 143, + -18 + ], + [ + 143, + -16 + ], + [ + 142, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 142, + -18 + ], + [ + 142, + -20 + ], + [ + 143, + -20 + ], + [ + 143, + -18 + ], + [ + 142, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 142, + -20 + ], + [ + 142, + -22 + ], + [ + 143, + -22 + ], + [ + 143, + -20 + ], + [ + 142, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 142, + -22 + ], + [ + 142, + -24 + ], + [ + 143, + -24 + ], + [ + 143, + -22 + ], + [ + 142, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 142, + -24 + ], + [ + 142, + -26 + ], + [ + 143, + -26 + ], + [ + 143, + -24 + ], + [ + 142, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 142, + -26 + ], + [ + 142, + -28 + ], + [ + 143, + -28 + ], + [ + 143, + -26 + ], + [ + 142, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 142, + -28 + ], + [ + 142, + -30 + ], + [ + 143, + -30 + ], + [ + 143, + -28 + ], + [ + 142, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 142, + -30 + ], + [ + 142, + -32 + ], + [ + 143, + -32 + ], + [ + 143, + -30 + ], + [ + 142, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 142, + -32 + ], + [ + 142, + -34 + ], + [ + 143, + -34 + ], + [ + 143, + -32 + ], + [ + 142, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 142, + -34 + ], + [ + 142, + -36 + ], + [ + 143, + -36 + ], + [ + 143, + -34 + ], + [ + 142, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 142, + -36 + ], + [ + 142, + -38 + ], + [ + 143, + -38 + ], + [ + 143, + -36 + ], + [ + 142, + -36 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 142, + -38 + ], + [ + 142, + -40 + ], + [ + 143, + -40 + ], + [ + 143, + -38 + ], + [ + 142, + -38 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 143, + -10 + ], + [ + 143, + -12 + ], + [ + 144, + -12 + ], + [ + 144, + -10 + ], + [ + 143, + -10 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 143, + -12 + ], + [ + 143, + -14 + ], + [ + 144, + -14 + ], + [ + 144, + -12 + ], + [ + 143, + -12 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 143, + -14 + ], + [ + 143, + -16 + ], + [ + 144, + -16 + ], + [ + 144, + -14 + ], + [ + 143, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 143, + -16 + ], + [ + 143, + -18 + ], + [ + 144, + -18 + ], + [ + 144, + -16 + ], + [ + 143, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 143, + -18 + ], + [ + 143, + -20 + ], + [ + 144, + -20 + ], + [ + 144, + -18 + ], + [ + 143, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 143, + -20 + ], + [ + 143, + -22 + ], + [ + 144, + -22 + ], + [ + 144, + -20 + ], + [ + 143, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 143, + -22 + ], + [ + 143, + -24 + ], + [ + 144, + -24 + ], + [ + 144, + -22 + ], + [ + 143, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 143, + -24 + ], + [ + 143, + -26 + ], + [ + 144, + -26 + ], + [ + 144, + -24 + ], + [ + 143, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 143, + -26 + ], + [ + 143, + -28 + ], + [ + 144, + -28 + ], + [ + 144, + -26 + ], + [ + 143, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 143, + -28 + ], + [ + 143, + -30 + ], + [ + 144, + -30 + ], + [ + 144, + -28 + ], + [ + 143, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 143, + -30 + ], + [ + 143, + -32 + ], + [ + 144, + -32 + ], + [ + 144, + -30 + ], + [ + 143, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 143, + -32 + ], + [ + 143, + -34 + ], + [ + 144, + -34 + ], + [ + 144, + -32 + ], + [ + 143, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 143, + -34 + ], + [ + 143, + -36 + ], + [ + 144, + -36 + ], + [ + 144, + -34 + ], + [ + 143, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 143, + -36 + ], + [ + 143, + -38 + ], + [ + 144, + -38 + ], + [ + 144, + -36 + ], + [ + 143, + -36 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 143, + -38 + ], + [ + 143, + -40 + ], + [ + 144, + -40 + ], + [ + 144, + -38 + ], + [ + 143, + -38 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 144, + -12 + ], + [ + 144, + -14 + ], + [ + 145, + -14 + ], + [ + 145, + -12 + ], + [ + 144, + -12 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 144, + -14 + ], + [ + 144, + -16 + ], + [ + 145, + -16 + ], + [ + 145, + -14 + ], + [ + 144, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 144, + -16 + ], + [ + 144, + -18 + ], + [ + 145, + -18 + ], + [ + 145, + -16 + ], + [ + 144, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 144, + -18 + ], + [ + 144, + -20 + ], + [ + 145, + -20 + ], + [ + 145, + -18 + ], + [ + 144, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 144, + -20 + ], + [ + 144, + -22 + ], + [ + 145, + -22 + ], + [ + 145, + -20 + ], + [ + 144, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 144, + -22 + ], + [ + 144, + -24 + ], + [ + 145, + -24 + ], + [ + 145, + -22 + ], + [ + 144, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 144, + -24 + ], + [ + 144, + -26 + ], + [ + 145, + -26 + ], + [ + 145, + -24 + ], + [ + 144, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 144, + -26 + ], + [ + 144, + -28 + ], + [ + 145, + -28 + ], + [ + 145, + -26 + ], + [ + 144, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 144, + -28 + ], + [ + 144, + -30 + ], + [ + 145, + -30 + ], + [ + 145, + -28 + ], + [ + 144, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 144, + -30 + ], + [ + 144, + -32 + ], + [ + 145, + -32 + ], + [ + 145, + -30 + ], + [ + 144, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 144, + -32 + ], + [ + 144, + -34 + ], + [ + 145, + -34 + ], + [ + 145, + -32 + ], + [ + 144, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 144, + -34 + ], + [ + 144, + -36 + ], + [ + 145, + -36 + ], + [ + 145, + -34 + ], + [ + 144, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 144, + -36 + ], + [ + 144, + -38 + ], + [ + 145, + -38 + ], + [ + 145, + -36 + ], + [ + 144, + -36 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 144, + -38 + ], + [ + 144, + -40 + ], + [ + 145, + -40 + ], + [ + 145, + -38 + ], + [ + 144, + -38 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145, + -14 + ], + [ + 145, + -16 + ], + [ + 146, + -16 + ], + [ + 146, + -14 + ], + [ + 145, + -14 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145, + -16 + ], + [ + 145, + -18 + ], + [ + 146, + -18 + ], + [ + 146, + -16 + ], + [ + 145, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145, + -18 + ], + [ + 145, + -20 + ], + [ + 146, + -20 + ], + [ + 146, + -18 + ], + [ + 145, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145, + -20 + ], + [ + 145, + -22 + ], + [ + 146, + -22 + ], + [ + 146, + -20 + ], + [ + 145, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145, + -22 + ], + [ + 145, + -24 + ], + [ + 146, + -24 + ], + [ + 146, + -22 + ], + [ + 145, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145, + -24 + ], + [ + 145, + -26 + ], + [ + 146, + -26 + ], + [ + 146, + -24 + ], + [ + 145, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145, + -26 + ], + [ + 145, + -28 + ], + [ + 146, + -28 + ], + [ + 146, + -26 + ], + [ + 145, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145, + -28 + ], + [ + 145, + -30 + ], + [ + 146, + -30 + ], + [ + 146, + -28 + ], + [ + 145, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145, + -30 + ], + [ + 145, + -32 + ], + [ + 146, + -32 + ], + [ + 146, + -30 + ], + [ + 145, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145, + -32 + ], + [ + 145, + -34 + ], + [ + 146, + -34 + ], + [ + 146, + -32 + ], + [ + 145, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145, + -34 + ], + [ + 145, + -36 + ], + [ + 146, + -36 + ], + [ + 146, + -34 + ], + [ + 145, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145, + -36 + ], + [ + 145, + -38 + ], + [ + 146, + -38 + ], + [ + 146, + -36 + ], + [ + 145, + -36 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 145, + -38 + ], + [ + 145, + -40 + ], + [ + 146, + -40 + ], + [ + 146, + -38 + ], + [ + 145, + -38 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 146, + -16 + ], + [ + 146, + -18 + ], + [ + 147, + -18 + ], + [ + 147, + -16 + ], + [ + 146, + -16 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 146, + -18 + ], + [ + 146, + -20 + ], + [ + 147, + -20 + ], + [ + 147, + -18 + ], + [ + 146, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 146, + -20 + ], + [ + 146, + -22 + ], + [ + 147, + -22 + ], + [ + 147, + -20 + ], + [ + 146, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 146, + -22 + ], + [ + 146, + -24 + ], + [ + 147, + -24 + ], + [ + 147, + -22 + ], + [ + 146, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 146, + -24 + ], + [ + 146, + -26 + ], + [ + 147, + -26 + ], + [ + 147, + -24 + ], + [ + 146, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 146, + -26 + ], + [ + 146, + -28 + ], + [ + 147, + -28 + ], + [ + 147, + -26 + ], + [ + 146, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 146, + -28 + ], + [ + 146, + -30 + ], + [ + 147, + -30 + ], + [ + 147, + -28 + ], + [ + 146, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 146, + -30 + ], + [ + 146, + -32 + ], + [ + 147, + -32 + ], + [ + 147, + -30 + ], + [ + 146, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 146, + -32 + ], + [ + 146, + -34 + ], + [ + 147, + -34 + ], + [ + 147, + -32 + ], + [ + 146, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 146, + -34 + ], + [ + 146, + -36 + ], + [ + 147, + -36 + ], + [ + 147, + -34 + ], + [ + 146, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 146, + -36 + ], + [ + 146, + -38 + ], + [ + 147, + -38 + ], + [ + 147, + -36 + ], + [ + 146, + -36 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 146, + -38 + ], + [ + 146, + -40 + ], + [ + 147, + -40 + ], + [ + 147, + -38 + ], + [ + 146, + -38 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 147, + -18 + ], + [ + 147, + -20 + ], + [ + 148, + -20 + ], + [ + 148, + -18 + ], + [ + 147, + -18 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 147, + -20 + ], + [ + 147, + -22 + ], + [ + 148, + -22 + ], + [ + 148, + -20 + ], + [ + 147, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 147, + -22 + ], + [ + 147, + -24 + ], + [ + 148, + -24 + ], + [ + 148, + -22 + ], + [ + 147, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 147, + -24 + ], + [ + 147, + -26 + ], + [ + 148, + -26 + ], + [ + 148, + -24 + ], + [ + 147, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 147, + -26 + ], + [ + 147, + -28 + ], + [ + 148, + -28 + ], + [ + 148, + -26 + ], + [ + 147, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 147, + -28 + ], + [ + 147, + -30 + ], + [ + 148, + -30 + ], + [ + 148, + -28 + ], + [ + 147, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 147, + -30 + ], + [ + 147, + -32 + ], + [ + 148, + -32 + ], + [ + 148, + -30 + ], + [ + 147, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 147, + -32 + ], + [ + 147, + -34 + ], + [ + 148, + -34 + ], + [ + 148, + -32 + ], + [ + 147, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 147, + -34 + ], + [ + 147, + -36 + ], + [ + 148, + -36 + ], + [ + 148, + -34 + ], + [ + 147, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 147, + -36 + ], + [ + 147, + -38 + ], + [ + 148, + -38 + ], + [ + 148, + -36 + ], + [ + 147, + -36 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 147, + -38 + ], + [ + 147, + -40 + ], + [ + 148, + -40 + ], + [ + 148, + -38 + ], + [ + 147, + -38 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 148, + -20 + ], + [ + 148, + -22 + ], + [ + 149, + -22 + ], + [ + 149, + -20 + ], + [ + 148, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 148, + -22 + ], + [ + 148, + -24 + ], + [ + 149, + -24 + ], + [ + 149, + -22 + ], + [ + 148, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 148, + -24 + ], + [ + 148, + -26 + ], + [ + 149, + -26 + ], + [ + 149, + -24 + ], + [ + 148, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 148, + -26 + ], + [ + 148, + -28 + ], + [ + 149, + -28 + ], + [ + 149, + -26 + ], + [ + 148, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 148, + -28 + ], + [ + 148, + -30 + ], + [ + 149, + -30 + ], + [ + 149, + -28 + ], + [ + 148, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 148, + -30 + ], + [ + 148, + -32 + ], + [ + 149, + -32 + ], + [ + 149, + -30 + ], + [ + 148, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 148, + -32 + ], + [ + 148, + -34 + ], + [ + 149, + -34 + ], + [ + 149, + -32 + ], + [ + 148, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 148, + -34 + ], + [ + 148, + -36 + ], + [ + 149, + -36 + ], + [ + 149, + -34 + ], + [ + 148, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 148, + -36 + ], + [ + 148, + -38 + ], + [ + 149, + -38 + ], + [ + 149, + -36 + ], + [ + 148, + -36 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 148, + -38 + ], + [ + 148, + -40 + ], + [ + 149, + -40 + ], + [ + 149, + -38 + ], + [ + 148, + -38 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 149, + -20 + ], + [ + 149, + -22 + ], + [ + 150, + -22 + ], + [ + 150, + -20 + ], + [ + 149, + -20 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 149, + -22 + ], + [ + 149, + -24 + ], + [ + 150, + -24 + ], + [ + 150, + -22 + ], + [ + 149, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 149, + -24 + ], + [ + 149, + -26 + ], + [ + 150, + -26 + ], + [ + 150, + -24 + ], + [ + 149, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 149, + -26 + ], + [ + 149, + -28 + ], + [ + 150, + -28 + ], + [ + 150, + -26 + ], + [ + 149, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 149, + -28 + ], + [ + 149, + -30 + ], + [ + 150, + -30 + ], + [ + 150, + -28 + ], + [ + 149, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 149, + -30 + ], + [ + 149, + -32 + ], + [ + 150, + -32 + ], + [ + 150, + -30 + ], + [ + 149, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 149, + -32 + ], + [ + 149, + -34 + ], + [ + 150, + -34 + ], + [ + 150, + -32 + ], + [ + 149, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 149, + -34 + ], + [ + 149, + -36 + ], + [ + 150, + -36 + ], + [ + 150, + -34 + ], + [ + 149, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 149, + -36 + ], + [ + 149, + -38 + ], + [ + 150, + -38 + ], + [ + 150, + -36 + ], + [ + 149, + -36 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 149, + -38 + ], + [ + 149, + -40 + ], + [ + 150, + -40 + ], + [ + 150, + -38 + ], + [ + 149, + -38 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 150, + -22 + ], + [ + 150, + -24 + ], + [ + 151, + -24 + ], + [ + 151, + -22 + ], + [ + 150, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 150, + -24 + ], + [ + 150, + -26 + ], + [ + 151, + -26 + ], + [ + 151, + -24 + ], + [ + 150, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 150, + -26 + ], + [ + 150, + -28 + ], + [ + 151, + -28 + ], + [ + 151, + -26 + ], + [ + 150, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 150, + -28 + ], + [ + 150, + -30 + ], + [ + 151, + -30 + ], + [ + 151, + -28 + ], + [ + 150, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 150, + -30 + ], + [ + 150, + -32 + ], + [ + 151, + -32 + ], + [ + 151, + -30 + ], + [ + 150, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 150, + -32 + ], + [ + 150, + -34 + ], + [ + 151, + -34 + ], + [ + 151, + -32 + ], + [ + 150, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 150, + -34 + ], + [ + 150, + -36 + ], + [ + 151, + -36 + ], + [ + 151, + -34 + ], + [ + 150, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 150, + -36 + ], + [ + 150, + -38 + ], + [ + 151, + -38 + ], + [ + 151, + -36 + ], + [ + 150, + -36 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 151, + -22 + ], + [ + 151, + -24 + ], + [ + 152, + -24 + ], + [ + 152, + -22 + ], + [ + 151, + -22 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 151, + -24 + ], + [ + 151, + -26 + ], + [ + 152, + -26 + ], + [ + 152, + -24 + ], + [ + 151, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 151, + -26 + ], + [ + 151, + -28 + ], + [ + 152, + -28 + ], + [ + 152, + -26 + ], + [ + 151, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 151, + -28 + ], + [ + 151, + -30 + ], + [ + 152, + -30 + ], + [ + 152, + -28 + ], + [ + 151, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 151, + -30 + ], + [ + 151, + -32 + ], + [ + 152, + -32 + ], + [ + 152, + -30 + ], + [ + 151, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 151, + -32 + ], + [ + 151, + -34 + ], + [ + 152, + -34 + ], + [ + 152, + -32 + ], + [ + 151, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 151, + -34 + ], + [ + 151, + -36 + ], + [ + 152, + -36 + ], + [ + 152, + -34 + ], + [ + 151, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 151, + -36 + ], + [ + 151, + -38 + ], + [ + 152, + -38 + ], + [ + 152, + -36 + ], + [ + 151, + -36 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 152, + -24 + ], + [ + 152, + -26 + ], + [ + 153, + -26 + ], + [ + 153, + -24 + ], + [ + 152, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 152, + -26 + ], + [ + 152, + -28 + ], + [ + 153, + -28 + ], + [ + 153, + -26 + ], + [ + 152, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 152, + -28 + ], + [ + 152, + -30 + ], + [ + 153, + -30 + ], + [ + 153, + -28 + ], + [ + 152, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 152, + -30 + ], + [ + 152, + -32 + ], + [ + 153, + -32 + ], + [ + 153, + -30 + ], + [ + 152, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 152, + -32 + ], + [ + 152, + -34 + ], + [ + 153, + -34 + ], + [ + 153, + -32 + ], + [ + 152, + -32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 152, + -34 + ], + [ + 152, + -36 + ], + [ + 153, + -36 + ], + [ + 153, + -34 + ], + [ + 152, + -34 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 153, + -24 + ], + [ + 153, + -26 + ], + [ + 154, + -26 + ], + [ + 154, + -24 + ], + [ + 153, + -24 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 153, + -26 + ], + [ + 153, + -28 + ], + [ + 154, + -28 + ], + [ + 154, + -26 + ], + [ + 153, + -26 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 153, + -28 + ], + [ + 153, + -30 + ], + [ + 154, + -30 + ], + [ + 154, + -28 + ], + [ + 153, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 153, + -30 + ], + [ + 153, + -32 + ], + [ + 154, + -32 + ], + [ + 154, + -30 + ], + [ + 153, + -30 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 154, + -28 + ], + [ + 154, + -30 + ], + [ + 155, + -30 + ], + [ + 155, + -28 + ], + [ + 154, + -28 + ] + ] + ] + } + }, + { + "type": "Feature", + "bbox": [ + 110, + 0, + 160, + -50 + ], + "properties": { + "stroke": "#F00", + "stroke-width": 6, + "fill-opacity": 0 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 110, + 0 + ], + [ + 160, + 0 + ], + [ + 160, + -50 + ], + [ + 110, + -50 + ], + [ + 110, + 0 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 6, + "fill-opacity": 0 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 115.13671875, + -33.7243396617476 + ], + [ + 116.3671875, + -35.02999636902566 + ], + [ + 118.828125, + -34.59704151614416 + ], + [ + 123.74999999999999, + -33.9433599465788 + ], + [ + 126.38671874999999, + -32.249974455863295 + ], + [ + 131.484375, + -31.12819929911196 + ], + [ + 135.35156249999997, + -34.30714385628803 + ], + [ + 139.04296875, + -35.24561909420681 + ], + [ + 140.2734375, + -37.78808138412045 + ], + [ + 146.6015625, + -38.8225909761771 + ], + [ + 150.64453125, + -37.43997405227057 + ], + [ + 152.40234375, + -33.504759069226075 + ], + [ + 154.072265625, + -28.690587654250685 + ], + [ + 153.017578125, + -25.641526373065755 + ], + [ + 146.513671875, + -18.646245142670598 + ], + [ + 142.20703125, + -10.055402736564224 + ], + [ + 140.537109375, + -17.224758206624628 + ], + [ + 135.439453125, + -14.859850400601037 + ], + [ + 137.197265625, + -11.953349393643416 + ], + [ + 131.30859375, + -11.178401873711772 + ], + [ + 129.0234375, + -14.434680215297268 + ], + [ + 125.595703125, + -14.179186142354169 + ], + [ + 120.9375, + -19.559790136497398 + ], + [ + 114.873046875, + -21.125497636606266 + ], + [ + 114.169921875, + -26.11598592533351 + ], + [ + 115.13671875, + -33.7243396617476 + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-rectangle-grid/test/out/big-bbox-500x100-miles.geojson b/src/rectangle-grid/test/out/big-bbox-500x100-miles.geojson similarity index 100% rename from packages/turf-rectangle-grid/test/out/big-bbox-500x100-miles.geojson rename to src/rectangle-grid/test/out/big-bbox-500x100-miles.geojson diff --git a/packages/turf-rectangle-grid/test/out/fiji-10x5-miles.geojson b/src/rectangle-grid/test/out/fiji-10x5-miles.geojson similarity index 100% rename from packages/turf-rectangle-grid/test/out/fiji-10x5-miles.geojson rename to src/rectangle-grid/test/out/fiji-10x5-miles.geojson diff --git a/packages/turf-rectangle-grid/test/out/victoria-20x100-km.geojson b/src/rectangle-grid/test/out/victoria-20x100-km.geojson similarity index 100% rename from packages/turf-rectangle-grid/test/out/victoria-20x100-km.geojson rename to src/rectangle-grid/test/out/victoria-20x100-km.geojson diff --git a/packages/turf-rewind/bench.js b/src/rewind/bench.js similarity index 100% rename from packages/turf-rewind/bench.js rename to src/rewind/bench.js diff --git a/src/rewind/index.d.ts b/src/rewind/index.d.ts new file mode 100644 index 0000000000..aa39fd0a0a --- /dev/null +++ b/src/rewind/index.d.ts @@ -0,0 +1,12 @@ +import { AllGeoJSON } from '../helpers'; + +/** + * http://turfjs.org/docs/#rewind + */ +export default function rewind( + geojson: T, + options?: { + reversed?: boolean, + mutate?: boolean + } +): T; diff --git a/src/rewind/index.js b/src/rewind/index.js new file mode 100644 index 0000000000..d21447a73c --- /dev/null +++ b/src/rewind/index.js @@ -0,0 +1,132 @@ +import clone from '../clone'; +import booleanClockwise from '../boolean-clockwise'; +import { geomEach, featureEach } from '../meta'; +import { getCoords } from '../invariant'; +import { featureCollection, isObject } from '../helpers'; + +/** + * Rewind {@link LineString|(Multi)LineString} or {@link Polygon|(Multi)Polygon} outer ring counterclockwise and inner rings clockwise (Uses {@link http://en.wikipedia.org/wiki/Shoelace_formula|Shoelace Formula}). + * + * @name rewind + * @param {GeoJSON} geojson input GeoJSON Polygon + * @param {Object} [options={}] Optional parameters + * @param {boolean} [options.reverse=false] enable reverse winding + * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) + * @returns {GeoJSON} rewind Polygon + * @example + * var polygon = turf.polygon([[[121, -29], [138, -29], [138, -18], [121, -18], [121, -29]]]); + * + * var rewind = turf.rewind(polygon); + * + * //addToMap + * var addToMap = [rewind]; + */ +function rewind(geojson, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var reverse = options.reverse || false; + var mutate = options.mutate || false; + + // validation + if (!geojson) throw new Error(' is required'); + if (typeof reverse !== 'boolean') throw new Error(' must be a boolean'); + if (typeof mutate !== 'boolean') throw new Error(' must be a boolean'); + + // prevent input mutation + if (mutate === false) geojson = clone(geojson); + + // Support Feature Collection or Geometry Collection + var results = []; + switch (geojson.type) { + case 'GeometryCollection': + geomEach(geojson, function (geometry) { + rewindFeature(geometry, reverse); + }); + return geojson; + case 'FeatureCollection': + featureEach(geojson, function (feature) { + featureEach(rewindFeature(feature, reverse), function (result) { + results.push(result); + }); + }); + return featureCollection(results); + } + // Support Feature or Geometry Objects + return rewindFeature(geojson, reverse); +} + +/** + * Rewind + * + * @private + * @param {Geometry|Feature} geojson Geometry or Feature + * @param {Boolean} [reverse=false] enable reverse winding + * @returns {Geometry|Feature} rewind Geometry or Feature + */ +function rewindFeature(geojson, reverse) { + var type = (geojson.type === 'Feature') ? geojson.geometry.type : geojson.type; + + // Support all GeoJSON Geometry Objects + switch (type) { + case 'GeometryCollection': + geomEach(geojson, function (geometry) { + rewindFeature(geometry, reverse); + }); + return geojson; + case 'LineString': + rewindLineString(getCoords(geojson), reverse); + return geojson; + case 'Polygon': + rewindPolygon(getCoords(geojson), reverse); + return geojson; + case 'MultiLineString': + getCoords(geojson).forEach(function (lineCoords) { + rewindLineString(lineCoords, reverse); + }); + return geojson; + case 'MultiPolygon': + getCoords(geojson).forEach(function (lineCoords) { + rewindPolygon(lineCoords, reverse); + }); + return geojson; + case 'Point': + case 'MultiPoint': + return geojson; + } +} + +/** + * Rewind LineString - outer ring clockwise + * + * @private + * @param {Array>} coords GeoJSON LineString geometry coordinates + * @param {Boolean} [reverse=false] enable reverse winding + * @returns {void} mutates coordinates + */ +function rewindLineString(coords, reverse) { + if (booleanClockwise(coords) === reverse) coords.reverse(); +} + +/** + * Rewind Polygon - outer ring counterclockwise and inner rings clockwise. + * + * @private + * @param {Array>>} coords GeoJSON Polygon geometry coordinates + * @param {Boolean} [reverse=false] enable reverse winding + * @returns {void} mutates coordinates + */ +function rewindPolygon(coords, reverse) { + // outer ring + if (booleanClockwise(coords[0]) !== reverse) { + coords[0].reverse(); + } + // inner rings + for (var i = 1; i < coords.length; i++) { + if (booleanClockwise(coords[i]) === reverse) { + coords[i].reverse(); + } + } +} + +export default rewind; diff --git a/src/rewind/test.js b/src/rewind/test.js new file mode 100644 index 0000000000..09e540bfd6 --- /dev/null +++ b/src/rewind/test.js @@ -0,0 +1,58 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import { polygon, lineString, featureCollection, geometryCollection } from '../helpers'; +import rewind from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); +// fixtures = fixtures.filter(fixture => fixture.name === 'polygon-clockwise'); + +test('turf-rewind', t => { + for (const {filename, name, geojson} of fixtures) { + const {reverse} = geojson.properties || {}; + const results = rewind(geojson, reverse); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(results, load.sync(directories.out + filename), name); + } + t.end(); +}); + +test('turf-buffer - Support Geometry Objects', t => { + const line = lineString([[11, 0], [22, 4], [31, 0], [31, 11]]); + const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); + const gc = geometryCollection([poly.geometry, line.geometry]); + const fc = featureCollection([poly, line]); + + t.assert(rewind(line.geometry), 'support LineString Geometry'); + t.assert(rewind(poly.geometry), 'support Polygon Geometry'); + t.assert(rewind(fc), 'support Feature Collection'); + t.assert(rewind(gc), 'support Geometry Collection'); + t.end(); +}); + +test('turf-buffer - Prevent Input Mutation', t => { + const line = lineString([[11, 0], [22, 4], [31, 0], [31, 11]]); + const poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); + const beforePoly = JSON.parse(JSON.stringify(poly)); + const beforeLine = JSON.parse(JSON.stringify(line)); + rewind(poly); + rewind(line); + + t.deepEqual(poly, beforePoly, 'poly should not mutate'); + t.deepEqual(line, beforeLine, 'line should not mutate'); + t.end(); +}); diff --git a/packages/turf-rewind/test/in/feature-collection.geojson b/src/rewind/test/in/feature-collection.geojson similarity index 100% rename from packages/turf-rewind/test/in/feature-collection.geojson rename to src/rewind/test/in/feature-collection.geojson diff --git a/packages/turf-rewind/test/in/geometry-polygon-counter-clockwise.geojson b/src/rewind/test/in/geometry-polygon-counter-clockwise.geojson similarity index 100% rename from packages/turf-rewind/test/in/geometry-polygon-counter-clockwise.geojson rename to src/rewind/test/in/geometry-polygon-counter-clockwise.geojson diff --git a/packages/turf-rewind/test/in/line-clockwise.geojson b/src/rewind/test/in/line-clockwise.geojson similarity index 100% rename from packages/turf-rewind/test/in/line-clockwise.geojson rename to src/rewind/test/in/line-clockwise.geojson diff --git a/packages/turf-rewind/test/in/line-counter-clockwise.geojson b/src/rewind/test/in/line-counter-clockwise.geojson similarity index 100% rename from packages/turf-rewind/test/in/line-counter-clockwise.geojson rename to src/rewind/test/in/line-counter-clockwise.geojson diff --git a/packages/turf-rewind/test/in/polygon-clockwise.geojson b/src/rewind/test/in/polygon-clockwise.geojson similarity index 100% rename from packages/turf-rewind/test/in/polygon-clockwise.geojson rename to src/rewind/test/in/polygon-clockwise.geojson diff --git a/packages/turf-rewind/test/in/polygon-counter-clockwise.geojson b/src/rewind/test/in/polygon-counter-clockwise.geojson similarity index 100% rename from packages/turf-rewind/test/in/polygon-counter-clockwise.geojson rename to src/rewind/test/in/polygon-counter-clockwise.geojson diff --git a/packages/turf-rewind/test/out/feature-collection.geojson b/src/rewind/test/out/feature-collection.geojson similarity index 100% rename from packages/turf-rewind/test/out/feature-collection.geojson rename to src/rewind/test/out/feature-collection.geojson diff --git a/packages/turf-rewind/test/out/geometry-polygon-counter-clockwise.geojson b/src/rewind/test/out/geometry-polygon-counter-clockwise.geojson similarity index 100% rename from packages/turf-rewind/test/out/geometry-polygon-counter-clockwise.geojson rename to src/rewind/test/out/geometry-polygon-counter-clockwise.geojson diff --git a/packages/turf-rewind/test/out/line-clockwise.geojson b/src/rewind/test/out/line-clockwise.geojson similarity index 100% rename from packages/turf-rewind/test/out/line-clockwise.geojson rename to src/rewind/test/out/line-clockwise.geojson diff --git a/packages/turf-rewind/test/out/line-counter-clockwise.geojson b/src/rewind/test/out/line-counter-clockwise.geojson similarity index 100% rename from packages/turf-rewind/test/out/line-counter-clockwise.geojson rename to src/rewind/test/out/line-counter-clockwise.geojson diff --git a/packages/turf-rewind/test/out/polygon-clockwise.geojson b/src/rewind/test/out/polygon-clockwise.geojson similarity index 100% rename from packages/turf-rewind/test/out/polygon-clockwise.geojson rename to src/rewind/test/out/polygon-clockwise.geojson diff --git a/packages/turf-rewind/test/out/polygon-counter-clockwise.geojson b/src/rewind/test/out/polygon-counter-clockwise.geojson similarity index 100% rename from packages/turf-rewind/test/out/polygon-counter-clockwise.geojson rename to src/rewind/test/out/polygon-counter-clockwise.geojson diff --git a/src/rhumb-bearing/bench.js b/src/rhumb-bearing/bench.js new file mode 100644 index 0000000000..ba84c76d87 --- /dev/null +++ b/src/rhumb-bearing/bench.js @@ -0,0 +1,20 @@ +const { point } = require('../helpers'); +const Benchmark = require('benchmark'); +const rhumbBearing = require('./').default; + +var start = point([-75.4, 39.4]); +var end = point([-75.534, 39.123]); + +/** + * Benchmark Results + * + * initial bearing x 1,108,233 ops/sec ±3.22% (86 runs sampled) + * final bearing x 1,144,822 ops/sec ±2.01% (88 runs sampled) + */ +var suite = new Benchmark.Suite('turf-rhumb-bearing'); +suite + .add('initial bearing', () => rhumbBearing(start, end)) + .add('final bearing', () => rhumbBearing(start, end, true)) + .on('cycle', e => console.log(String(e.target))) + .on('complete', () => {}) + .run(); diff --git a/src/rhumb-bearing/index.d.ts b/src/rhumb-bearing/index.d.ts new file mode 100644 index 0000000000..2835e5eef3 --- /dev/null +++ b/src/rhumb-bearing/index.d.ts @@ -0,0 +1,26 @@ +import { Coord } from "../helpers"; +/** + * Takes two {@link Point|points} and finds the bearing angle between them along a Rhumb line + * i.e. the angle measured in degrees start the north line (0 degrees) + * + * @name rhumbBearing + * @param {Coord} start starting Point + * @param {Coord} end ending Point + * @param {Object} [options] Optional parameters + * @param {boolean} [options.final=false] calculates the final bearing if true + * @returns {number} bearing from north in decimal degrees, between -180 and 180 degrees (positive clockwise) + * @example + * var point1 = turf.point([-75.343, 39.984], {"marker-color": "#F00"}); + * var point2 = turf.point([-75.534, 39.123], {"marker-color": "#00F"}); + * + * var bearing = turf.rhumbBearing(point1, point2); + * + * //addToMap + * var addToMap = [point1, point2]; + * point1.properties.bearing = bearing; + * point2.properties.bearing = bearing; + */ +declare function rhumbBearing(start: Coord, end: Coord, options?: { + final?: boolean; +}): number; +export default rhumbBearing; diff --git a/src/rhumb-bearing/index.js b/src/rhumb-bearing/index.js new file mode 100644 index 0000000000..ffa22bdcfb --- /dev/null +++ b/src/rhumb-bearing/index.js @@ -0,0 +1,69 @@ +// https://en.wikipedia.org/wiki/Rhumb_line +import { degreesToRadians, radiansToDegrees, checkIfOptionsExist } from "../helpers"; +import { getCoord } from "../invariant"; + +/** + * Takes two {@link Point|points} and finds the bearing angle between them along a Rhumb line + * i.e. the angle measured in degrees start the north line (0 degrees) + * + * @name rhumbBearing + * @param {Coord} start starting Point + * @param {Coord} end ending Point + * @param {Object} [options] Optional parameters + * @param {boolean} [options.final=false] calculates the final bearing if true + * @returns {number} bearing from north in decimal degrees, between -180 and 180 degrees (positive clockwise) + * @example + * var point1 = turf.point([-75.343, 39.984], {"marker-color": "#F00"}); + * var point2 = turf.point([-75.534, 39.123], {"marker-color": "#00F"}); + * + * var bearing = turf.rhumbBearing(point1, point2); + * + * //addToMap + * var addToMap = [point1, point2]; + * point1.properties.bearing = bearing; + * point2.properties.bearing = bearing; + */ +function rhumbBearing(start, end, options) { + options = checkIfOptionsExist(options) + let bear360; + if (options.final) { bear360 = calculateRhumbBearing(getCoord(end), getCoord(start)); + } else { bear360 = calculateRhumbBearing(getCoord(start), getCoord(end)); } + + const bear180 = (bear360 > 180) ? - (360 - bear360) : bear360; + + return bear180; +} + +/** + * Returns the bearing from ‘this’ point to destination point along a rhumb line. + * Adapted from Geodesy: https://github.com/chrisveness/geodesy/blob/master/latlon-spherical.js + * + * @private + * @param {Array} from - origin point. + * @param {Array} to - destination point. + * @returns {number} Bearing in degrees from north. + * @example + * var p1 = new LatLon(51.127, 1.338); + * var p2 = new LatLon(50.964, 1.853); + * var d = p1.rhumbBearingTo(p2); // 116.7 m + */ +function calculateRhumbBearing(from, to) { + // φ => phi + // Δλ => deltaLambda + // Δψ => deltaPsi + // θ => theta + const phi1 = degreesToRadians(from[1]); + const phi2 = degreesToRadians(to[1]); + let deltaLambda = degreesToRadians((to[0] - from[0])); + // if deltaLambdaon over 180° take shorter rhumb line across the anti-meridian: + if (deltaLambda > Math.PI) { deltaLambda -= 2 * Math.PI; } + if (deltaLambda < -Math.PI) { deltaLambda += 2 * Math.PI; } + + const deltaPsi = Math.log(Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4)); + + const theta = Math.atan2(deltaLambda, deltaPsi); + + return (radiansToDegrees(theta) + 360) % 360; +} + +export default rhumbBearing; diff --git a/src/rhumb-bearing/test.js b/src/rhumb-bearing/test.js new file mode 100644 index 0000000000..fdf51007d6 --- /dev/null +++ b/src/rhumb-bearing/test.js @@ -0,0 +1,44 @@ +const fs = require('fs'); +const path = require('path'); +const test = require('tape'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { point } = require('../helpers'); +const rhumbBearing = require('.').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('bearing', t => { + fixtures.forEach(fixture => { + const name = fixture.name; + const filename = fixture.filename; + const geojson = fixture.geojson; + + const start = geojson.features[0]; + const end = geojson.features[1]; + + const initialBearing = rhumbBearing(start, end); + const finalBearing = rhumbBearing(start, end, {final: true}); + + const result = { + 'initialBearing': initialBearing, + 'finalBearing': finalBearing + }; + if (process.env.REGEN) write.sync(directories.out + name + '.json', result); + t.deepEqual(load.sync(directories.out + name + '.json'), result, name); + }); + + t.throws(() => { rhumbBearing(point([12, -54]), 'point'); }, 'invalid point'); + t.end(); +}); diff --git a/packages/turf-rhumb-bearing/test/in/pair1.geojson b/src/rhumb-bearing/test/in/pair1.geojson similarity index 100% rename from packages/turf-rhumb-bearing/test/in/pair1.geojson rename to src/rhumb-bearing/test/in/pair1.geojson diff --git a/packages/turf-rhumb-bearing/test/out/pair1.geojson b/src/rhumb-bearing/test/out/pair1.geojson similarity index 100% rename from packages/turf-rhumb-bearing/test/out/pair1.geojson rename to src/rhumb-bearing/test/out/pair1.geojson diff --git a/packages/turf-rhumb-bearing/test/out/pair1.json b/src/rhumb-bearing/test/out/pair1.json similarity index 100% rename from packages/turf-rhumb-bearing/test/out/pair1.json rename to src/rhumb-bearing/test/out/pair1.json diff --git a/packages/turf-rhumb-destination/bench.js b/src/rhumb-destination/bench.js similarity index 100% rename from packages/turf-rhumb-destination/bench.js rename to src/rhumb-destination/bench.js diff --git a/packages/turf-rhumb-destination/index.d.ts b/src/rhumb-destination/index.d.ts similarity index 100% rename from packages/turf-rhumb-destination/index.d.ts rename to src/rhumb-destination/index.d.ts diff --git a/src/rhumb-destination/index.js b/src/rhumb-destination/index.js new file mode 100644 index 0000000000..a03988356d --- /dev/null +++ b/src/rhumb-destination/index.js @@ -0,0 +1,86 @@ +// https://en.wikipedia.org/wiki/Rhumb_line +import { convertLength, degreesToRadians, earthRadius, point, checkIfOptionsExist } from "../helpers"; +import { getCoord } from "../invariant"; + +/** + * Returns the destination {@link Point} having travelled the given distance along a Rhumb line from the + * origin Point with the (varant) given bearing. + * + * @name rhumbDestination + * @param {Coord} origin starting point + * @param {number} distance distance from the starting point + * @param {number} bearing varant bearing angle ranging from -180 to 180 degrees from north + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers + * @param {Object} [options.properties={}] translate properties to destination point + * @returns {Feature} Destination point. + * @example + * var pt = ...point([-75.343, 39.984], {"marker-color": "F00"}); + * var distance = 50; + * var bearing = 90; + * var options = {units: 'miles'}; + * + * var destination = ...rhumbDestination(pt, distance, bearing, options); + * + * //addToMap + * var addToMap = [pt, destination] + * destination.properties['marker-color'] = '#00F'; + */ +function rhumbDestination(origin, distance, bearing, options) { + options = checkIfOptionsExist(options); + const wasNegativeDistance = distance < 0; + let distanceInMeters = convertLength(Math.abs(distance), options.units, "meters"); + if (wasNegativeDistance) distanceInMeters = -Math.abs(distanceInMeters); + const coords = getCoord(origin); + const destination = calculateRhumbDestination(coords, distanceInMeters, bearing); + + // compensate the crossing of the 180th meridian (https://macwright.org/2016/09/26/the-180th-meridian.html) + // solution from https://github.com/mapbox/mapbox-gl-js/issues/3250#issuecomment-294887678 + destination[0] += (destination[0] - coords[0] > 180) ? -360 : (coords[0] - destination[0] > 180) ? 360 : 0; + return point(destination, options.properties); +} + +/** + * Returns the destination point having travelled along a rhumb line from origin point the given + * distance on the given bearing. + * Adapted from Geodesy: http://www.movable-type.co.uk/scripts/latlong.html#rhumblines + * + * @private + * @param {Array} origin - point + * @param {number} distance - Distance travelled, in same units as earth radius (default: metres). + * @param {number} bearing - Bearing in degrees from north. + * @param {number} [radius=6371e3] - (Mean) radius of earth (defaults to radius in metres). + * @returns {Array} Destination point. + */ +function calculateRhumbDestination(origin, distance, bearing, radius) { + // φ => phi + // λ => lambda + // ψ => psi + // Δ => Delta + // δ => delta + // θ => theta + + radius = (radius === undefined) ? earthRadius : Number(radius); + + const delta = distance / radius; // angular distance in radians + const lambda1 = origin[0] * Math.PI / 180; // to radians, but without normalize to 𝜋 + const phi1 = degreesToRadians(origin[1]); + const theta = degreesToRadians(bearing); + + const DeltaPhi = delta * Math.cos(theta); + let phi2 = phi1 + DeltaPhi; + + // check for some daft bugger going past the pole, normalise latitude if so + if (Math.abs(phi2) > Math.PI / 2) { phi2 = phi2 > 0 ? Math.PI - phi2 : -Math.PI - phi2; } + + const DeltaPsi = Math.log(Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4)); + // E-W course becomes ill-conditioned with 0/0 + const q = Math.abs(DeltaPsi) > 10e-12 ? DeltaPhi / DeltaPsi : Math.cos(phi1); + + const DeltaLambda = delta * Math.sin(theta) / q; + const lambda2 = lambda1 + DeltaLambda; + + return [((lambda2 * 180 / Math.PI) + 540) % 360 - 180, phi2 * 180 / Math.PI]; // normalise to −180..+180° +} + +export default rhumbDestination; diff --git a/src/rhumb-destination/test.js b/src/rhumb-destination/test.js new file mode 100644 index 0000000000..85d931a366 --- /dev/null +++ b/src/rhumb-destination/test.js @@ -0,0 +1,65 @@ +const fs = require('fs'); +const path = require('path'); +const test = require('tape'); +const write = require('write-json-file'); +const load = require('load-json-file'); +const truncate = require('../truncate').default; +const { getCoords } = require('../invariant'); +const { featureCollection, lineString, point } = require('../helpers'); +const rhumbDestination = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-rhumb-destination', t => { + for (const {filename, name, geojson} of fixtures) { + let {bearing, dist, units} = geojson.properties || {}; + bearing = (bearing !== undefined) ? bearing : 180; + dist = (dist !== undefined) ? dist : 100; + + const destinationPoint = rhumbDestination(geojson, dist, bearing, {units: units}); + const line = truncate(lineString([getCoords(geojson), getCoords(destinationPoint)], {'stroke': '#F00', 'stroke-width': 4})); + geojson.properties['marker-color'] = '#F00'; + const result = featureCollection([line, geojson, destinationPoint]); + + if (process.env.REGEN) write.sync(directories.out + filename, result); + t.deepEqual(result, load.sync(directories.out + filename), name); + } + t.end(); +}); + +test('turf-rhumb-destintation -- throws error', t => { + const pt = point([12, -54]); + t.assert(rhumbDestination(pt, 0, 45).geometry.coordinates[0], '0 distance is valid'); + t.assert(rhumbDestination(pt, 100, 0).geometry.coordinates[0], '0 bearing is valid'); + // t.throws(() => rhumbDestination(pt, 100, 45, 'blah'), 'unknown option given to units'); + // t.throws(() => rhumbDestination(pt, null, 75), 'missing distance'); + // t.throws(() => rhumbDestination(pt, 'foo', 75), 'invalid distance - units param switched to distance'); + // t.throws(() => rhumbDestination('foo', 200, 75, {units: 'miles'}), 'invalid point'); + t.end(); +}); + +test('turf-rhumb-destintation -- add properties', t => { + const properties = {foo: 'bar'}; + const pt = point([12, -54], properties); + + t.deepEqual(rhumbDestination(pt, 0, 45, {properties}).properties, properties, 'add properties'); + t.end(); +}); + +test('turf-rhumb-destintation -- allows negative distance', t => { + const pt = point([12, -54]); + const out = rhumbDestination(pt, -100, 45); + t.deepEqual(out.geometry.coordinates, [10.90974456038191, -54.63591552764877]) + t.end(); +}); \ No newline at end of file diff --git a/packages/turf-rhumb-destination/test/in/fiji-east-west-539-lng.geojson b/src/rhumb-destination/test/in/fiji-east-west-539-lng.geojson similarity index 100% rename from packages/turf-rhumb-destination/test/in/fiji-east-west-539-lng.geojson rename to src/rhumb-destination/test/in/fiji-east-west-539-lng.geojson diff --git a/packages/turf-rhumb-destination/test/in/fiji-east-west.geojson b/src/rhumb-destination/test/in/fiji-east-west.geojson similarity index 100% rename from packages/turf-rhumb-destination/test/in/fiji-east-west.geojson rename to src/rhumb-destination/test/in/fiji-east-west.geojson diff --git a/packages/turf-rhumb-destination/test/in/fiji-west-east.geojson b/src/rhumb-destination/test/in/fiji-west-east.geojson similarity index 100% rename from packages/turf-rhumb-destination/test/in/fiji-west-east.geojson rename to src/rhumb-destination/test/in/fiji-west-east.geojson diff --git a/packages/turf-rhumb-destination/test/in/point-0.geojson b/src/rhumb-destination/test/in/point-0.geojson similarity index 100% rename from packages/turf-rhumb-destination/test/in/point-0.geojson rename to src/rhumb-destination/test/in/point-0.geojson diff --git a/packages/turf-rhumb-destination/test/in/point-180.geojson b/src/rhumb-destination/test/in/point-180.geojson similarity index 100% rename from packages/turf-rhumb-destination/test/in/point-180.geojson rename to src/rhumb-destination/test/in/point-180.geojson diff --git a/packages/turf-rhumb-destination/test/in/point-90.geojson b/src/rhumb-destination/test/in/point-90.geojson similarity index 100% rename from packages/turf-rhumb-destination/test/in/point-90.geojson rename to src/rhumb-destination/test/in/point-90.geojson diff --git a/packages/turf-rhumb-destination/test/in/point-way-far-away.geojson b/src/rhumb-destination/test/in/point-way-far-away.geojson similarity index 100% rename from packages/turf-rhumb-destination/test/in/point-way-far-away.geojson rename to src/rhumb-destination/test/in/point-way-far-away.geojson diff --git a/packages/turf-rhumb-destination/test/out/fiji-east-west-539-lng.geojson b/src/rhumb-destination/test/out/fiji-east-west-539-lng.geojson similarity index 100% rename from packages/turf-rhumb-destination/test/out/fiji-east-west-539-lng.geojson rename to src/rhumb-destination/test/out/fiji-east-west-539-lng.geojson diff --git a/packages/turf-rhumb-destination/test/out/fiji-east-west.geojson b/src/rhumb-destination/test/out/fiji-east-west.geojson similarity index 100% rename from packages/turf-rhumb-destination/test/out/fiji-east-west.geojson rename to src/rhumb-destination/test/out/fiji-east-west.geojson diff --git a/packages/turf-rhumb-destination/test/out/fiji-west-east.geojson b/src/rhumb-destination/test/out/fiji-west-east.geojson similarity index 100% rename from packages/turf-rhumb-destination/test/out/fiji-west-east.geojson rename to src/rhumb-destination/test/out/fiji-west-east.geojson diff --git a/packages/turf-rhumb-destination/test/out/point-0.geojson b/src/rhumb-destination/test/out/point-0.geojson similarity index 100% rename from packages/turf-rhumb-destination/test/out/point-0.geojson rename to src/rhumb-destination/test/out/point-0.geojson diff --git a/packages/turf-rhumb-destination/test/out/point-180.geojson b/src/rhumb-destination/test/out/point-180.geojson similarity index 100% rename from packages/turf-rhumb-destination/test/out/point-180.geojson rename to src/rhumb-destination/test/out/point-180.geojson diff --git a/packages/turf-rhumb-destination/test/out/point-90.geojson b/src/rhumb-destination/test/out/point-90.geojson similarity index 100% rename from packages/turf-rhumb-destination/test/out/point-90.geojson rename to src/rhumb-destination/test/out/point-90.geojson diff --git a/packages/turf-rhumb-destination/test/out/point-way-far-away.geojson b/src/rhumb-destination/test/out/point-way-far-away.geojson similarity index 100% rename from packages/turf-rhumb-destination/test/out/point-way-far-away.geojson rename to src/rhumb-destination/test/out/point-way-far-away.geojson diff --git a/src/rhumb-distance/bench.js b/src/rhumb-distance/bench.js new file mode 100644 index 0000000000..6cdf9c5e4e --- /dev/null +++ b/src/rhumb-distance/bench.js @@ -0,0 +1,18 @@ +const { point } = require('../helpers'); +const Benchmark = require('benchmark'); +const distance = require('./').default; + +const pt1 = point([-75.4, 39.4]); +const pt2 = point([-75.534, 39.123]); + +/** + * Benchmark Results + * + * turf-rhumb-distance x 1,721,401 ops/sec ±0.86% (89 runs sampled) + */ +const suite = new Benchmark.Suite('turf-rhumb-distance'); +suite + .add('turf-rhumb-distance', () => distance(pt1, pt2, 'miles')) + .on('cycle', e => console.log(String(e.target))) + .on('complete', () => {}) + .run(); diff --git a/packages/turf-rhumb-distance/index.d.ts b/src/rhumb-distance/index.d.ts similarity index 100% rename from packages/turf-rhumb-distance/index.d.ts rename to src/rhumb-distance/index.d.ts diff --git a/src/rhumb-distance/index.js b/src/rhumb-distance/index.js new file mode 100644 index 0000000000..e1cfeb2b3a --- /dev/null +++ b/src/rhumb-distance/index.js @@ -0,0 +1,86 @@ +// https://en.wikipedia.org/wiki/Rhumb_line +import { convertLength, earthRadius, checkIfOptionsExist } from "../helpers"; +import { getCoord } from "../invariant"; + +/** + * Calculates the distance along a rhumb line between two {@link Point|points} in degrees, radians, + * miles, or kilometers. + * + * @name rhumbDistance + * @param {Coord} from origin point + * @param {Coord} to destination point + * @param {Object} [options] Optional parameters + * @param {string} [options.units="kilometers"] can be degrees, radians, miles, or kilometers + * @returns {number} distance between the two points + * @example + * var from = turf.point([-75.343, 39.984]); + * var to = turf.point([-75.534, 39.123]); + * var options = {units: 'miles'}; + * + * var distance = turf.rhumbDistance(from, to, options); + * + * //addToMap + * var addToMap = [from, to]; + * from.properties.distance = distance; + * to.properties.distance = distance; + */ +function rhumbDistance(from, to, options) { + options = checkIfOptionsExist(options); + const origin = getCoord(from); + const destination = getCoord(to); + + // compensate the crossing of the 180th meridian (https://macwright.org/2016/09/26/the-180th-meridian.html) + // solution from https://github.com/mapbox/mapbox-gl-js/issues/3250#issuecomment-294887678 + destination[0] += (destination[0] - origin[0] > 180) ? -360 : (origin[0] - destination[0] > 180) ? 360 : 0; + const distanceInMeters = calculateRhumbDistance(origin, destination); + const distance = convertLength(distanceInMeters, "meters", options.units); + return distance; +} + +/** + * Returns the distance travelling from ‘this’ point to destination point along a rhumb line. + * Adapted from Geodesy: https://github.com/chrisveness/geodesy/blob/master/latlon-spherical.js + * + * @private + * @param {Array} origin point. + * @param {Array} destination point. + * @param {number} [radius=6371e3] - (Mean) radius of earth (defaults to radius in metres). + * @returns {number} Distance in km between this point and destination point (same units as radius). + * + * @example + * var p1 = new LatLon(51.127, 1.338); + * var p2 = new LatLon(50.964, 1.853); + * var d = p1.distanceTo(p2); // 40.31 km + */ +function calculateRhumbDistance(origin, destination, radius) { + // φ => phi + // λ => lambda + // ψ => psi + // Δ => Delta + // δ => delta + // θ => theta + + radius = (radius === undefined) ? earthRadius : Number(radius); + // see www.edwilliams.org/avform.htm#Rhumb + + const R = radius; + const phi1 = origin[1] * Math.PI / 180; + const phi2 = destination[1] * Math.PI / 180; + const DeltaPhi = phi2 - phi1; + let DeltaLambda = Math.abs(destination[0] - origin[0]) * Math.PI / 180; + // if dLon over 180° take shorter rhumb line across the anti-meridian: + if (DeltaLambda > Math.PI) { DeltaLambda -= 2 * Math.PI; } + + // on Mercator projection, longitude distances shrink by latitude; q is the 'stretch factor' + // q becomes ill-conditioned along E-W line (0/0); use empirical tolerance to avoid it + const DeltaPsi = Math.log(Math.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4)); + const q = Math.abs(DeltaPsi) > 10e-12 ? DeltaPhi / DeltaPsi : Math.cos(phi1); + + // distance is pythagoras on 'stretched' Mercator projection + const delta = Math.sqrt(DeltaPhi * DeltaPhi + q * q * DeltaLambda * DeltaLambda); // angular distance in radians + const dist = delta * R; + + return dist; +} + +export default rhumbDistance; diff --git a/src/rhumb-distance/test.js b/src/rhumb-distance/test.js new file mode 100644 index 0000000000..cc33461dc6 --- /dev/null +++ b/src/rhumb-distance/test.js @@ -0,0 +1,52 @@ +const fs = require('fs'); +const path = require('path'); +const test = require('tape'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const distance = require('../distance').default; +const { point, round } = require('../helpers'); +const rhumbDistance = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('rhumb-distance', t => { + fixtures.forEach(fixture => { + const name = fixture.name; + const geojson = fixture.geojson; + const pt1 = geojson.features[0]; + const pt2 = geojson.features[1]; + + const distances = { + miles: round(rhumbDistance(pt1, pt2, {units: 'miles'}), 6), + nauticalmiles: round(rhumbDistance(pt1, pt2, {units: 'nauticalmiles'}), 6), + kilometers: round(rhumbDistance(pt1, pt2, {units: 'kilometers'}), 6), + greatCircleDistance: round(distance(pt1, pt2, {units: 'kilometers'}), 6), + radians: round(rhumbDistance(pt1, pt2, {units: 'radians'}), 6), + degrees: round(rhumbDistance(pt1, pt2, {units: 'degrees'}), 6) + }; + + if (process.env.REGEN) write.sync(directories.out + name + '.json', distances); + t.deepEqual(distances, load.sync(directories.out + name + '.json'), name); + }); + + // Now fails due to approximation error + // TODO: to be added once earth radius is updated to 6371km + // t.ok(distances.kilometers > distances.greatCircleDistance, name + ' distance comparison'); + + t.throws(() => rhumbDistance(point([0, 0]), point([1, 1]), {units: 'foo'}), 'unknown option given to units'); + t.throws(() => rhumbDistance(null, point([1, 1])), 'null point'); + t.throws(() => rhumbDistance(point([1, 1]), 'point'), 'invalid point'); + + t.end(); +}); diff --git a/packages/turf-rhumb-distance/test/in/fiji-539-lng.geojson b/src/rhumb-distance/test/in/fiji-539-lng.geojson similarity index 100% rename from packages/turf-rhumb-distance/test/in/fiji-539-lng.geojson rename to src/rhumb-distance/test/in/fiji-539-lng.geojson diff --git a/packages/turf-rhumb-distance/test/in/points-fiji.geojson b/src/rhumb-distance/test/in/points-fiji.geojson similarity index 100% rename from packages/turf-rhumb-distance/test/in/points-fiji.geojson rename to src/rhumb-distance/test/in/points-fiji.geojson diff --git a/packages/turf-rhumb-distance/test/in/points1.geojson b/src/rhumb-distance/test/in/points1.geojson similarity index 100% rename from packages/turf-rhumb-distance/test/in/points1.geojson rename to src/rhumb-distance/test/in/points1.geojson diff --git a/packages/turf-rhumb-distance/test/in/points2.geojson b/src/rhumb-distance/test/in/points2.geojson similarity index 100% rename from packages/turf-rhumb-distance/test/in/points2.geojson rename to src/rhumb-distance/test/in/points2.geojson diff --git a/packages/turf-rhumb-distance/test/out/fiji-539-lng.json b/src/rhumb-distance/test/out/fiji-539-lng.json similarity index 87% rename from packages/turf-rhumb-distance/test/out/fiji-539-lng.json rename to src/rhumb-distance/test/out/fiji-539-lng.json index 41d2dcc440..236947ff05 100644 --- a/packages/turf-rhumb-distance/test/out/fiji-539-lng.json +++ b/src/rhumb-distance/test/out/fiji-539-lng.json @@ -4,5 +4,5 @@ "kilometers": 307.306293, "greatCircleDistance": 307.304881, "radians": 0.048235, - "degrees": 2.760443 + "degrees": 2.763668 } diff --git a/packages/turf-rhumb-distance/test/out/points-fiji.json b/src/rhumb-distance/test/out/points-fiji.json similarity index 87% rename from packages/turf-rhumb-distance/test/out/points-fiji.json rename to src/rhumb-distance/test/out/points-fiji.json index 5a57b3c56d..c773f2a6bb 100644 --- a/packages/turf-rhumb-distance/test/out/points-fiji.json +++ b/src/rhumb-distance/test/out/points-fiji.json @@ -4,5 +4,5 @@ "kilometers": 213.232075, "greatCircleDistance": 213.231201, "radians": 0.033469, - "degrees": 1.915402 + "degrees": 1.917639 } diff --git a/packages/turf-rhumb-distance/test/out/points1.json b/src/rhumb-distance/test/out/points1.json similarity index 86% rename from packages/turf-rhumb-distance/test/out/points1.json rename to src/rhumb-distance/test/out/points1.json index 8e295d9ec5..4c601ad8fc 100644 --- a/packages/turf-rhumb-distance/test/out/points1.json +++ b/src/rhumb-distance/test/out/points1.json @@ -4,5 +4,5 @@ "kilometers": 97.129239, "greatCircleDistance": 97.129221, "radians": 0.015246, - "degrees": 0.872484 + "degrees": 0.873503 } diff --git a/packages/turf-rhumb-distance/test/out/points2.json b/src/rhumb-distance/test/out/points2.json similarity index 86% rename from packages/turf-rhumb-distance/test/out/points2.json rename to src/rhumb-distance/test/out/points2.json index 28fa54f525..34a8c07768 100644 --- a/packages/turf-rhumb-distance/test/out/points2.json +++ b/src/rhumb-distance/test/out/points2.json @@ -4,5 +4,5 @@ "kilometers": 4482.044244, "greatCircleDistance": 4412.81774, "radians": 0.703506, - "degrees": 40.260896 + "degrees": 40.307937 } diff --git a/src/sample/bench.js b/src/sample/bench.js new file mode 100644 index 0000000000..eedfac09f1 --- /dev/null +++ b/src/sample/bench.js @@ -0,0 +1,25 @@ +import fs from 'fs'; +import Benchmark from 'benchmark'; +import { point, featureCollection } from '../helpers'; +import sample from './'; + +var points = featureCollection( + [point(1,2, {team: 'Red Sox'}), + point(2,1, {team: 'Yankees'}), + point(3,1, {team: 'Nationals'}), + point(2,2, {team: 'Yankees'}), + point(2,3, {team: 'Red Sox'}), + point(4,2, {team: 'Yankees'})]); + +var suite = new Benchmark.Suite('turf-sample'); +suite + .add('turf-sample',function () { + sample(points, 4); + }) + .on('cycle', function (event) { + console.log(String(event.target)); + }) + .on('complete', function () { + + }) + .run(); \ No newline at end of file diff --git a/packages/turf-sample/index.d.ts b/src/sample/index.d.ts similarity index 100% rename from packages/turf-sample/index.d.ts rename to src/sample/index.d.ts diff --git a/src/sample/index.js b/src/sample/index.js new file mode 100644 index 0000000000..f602785f3e --- /dev/null +++ b/src/sample/index.js @@ -0,0 +1,43 @@ +// http://stackoverflow.com/questions/11935175/sampling-a-random-subset-from-an-array +import { featureCollection } from '../helpers'; + +/** + * Takes a {@link FeatureCollection} and returns a FeatureCollection with given number of {@link Feature|features} at random. + * + * @name sample + * @param {FeatureCollection} featurecollection set of input features + * @param {number} num number of features to select + * @returns {FeatureCollection} a FeatureCollection with `n` features + * @example + * var points = turf.randomPoint(100, {bbox: [-80, 30, -60, 60]}); + * + * var sample = turf.sample(points, 5); + * + * //addToMap + * var addToMap = [points, sample] + * turf.featureEach(sample, function (currentFeature) { + * currentFeature.properties['marker-size'] = 'large'; + * currentFeature.properties['marker-color'] = '#000'; + * }); + */ +function sample(featurecollection, num) { + if (!featurecollection) throw new Error('featurecollection is required'); + if (num === null || num === undefined) throw new Error('num is required'); + if (typeof num !== 'number') throw new Error('num must be a number'); + + var outFC = featureCollection(getRandomSubarray(featurecollection.features, num)); + return outFC; +} + +function getRandomSubarray(arr, size) { + var shuffled = arr.slice(0), i = arr.length, min = i - size, temp, index; + while (i-- > min) { + index = Math.floor((i + 1) * Math.random()); + temp = shuffled[index]; + shuffled[index] = shuffled[i]; + shuffled[i] = temp; + } + return shuffled.slice(min); +} + +export default sample; diff --git a/src/sample/test.js b/src/sample/test.js new file mode 100644 index 0000000000..e1c94efae1 --- /dev/null +++ b/src/sample/test.js @@ -0,0 +1,20 @@ +import test from 'tape'; +import { point } from '../helpers'; +import { featureCollection } from '../helpers'; +import sample from '.'; + +test('remove', function (t) { + var points = featureCollection([ + point([1, 2], {team: 'Red Sox'}), + point([2, 1], {team: 'Yankees'}), + point([3, 1], {team: 'Nationals'}), + point([2, 2], {team: 'Yankees'}), + point([2, 3], {team: 'Red Sox'}), + point([4, 2], {team: 'Yankees'}) + ]); + + const results = sample(points, 4); + + t.equal(results.features.length, 4, 'should sample 4 features'); + t.end(); +}); diff --git a/packages/turf-sector/bench.js b/src/sector/bench.js similarity index 100% rename from packages/turf-sector/bench.js rename to src/sector/bench.js diff --git a/src/sector/index.d.ts b/src/sector/index.d.ts new file mode 100644 index 0000000000..fe41619f64 --- /dev/null +++ b/src/sector/index.d.ts @@ -0,0 +1,16 @@ +import { Feature, Polygon, Units, Coord, Properties } from '../helpers'; + +/** + * http://turfjs.org/docs/#sector + */ +export default function sector( + center: Coord, + radius: number, + bearing1: number, + bearing2: number, + options?: { + steps?: number + units?: Units + properties?: Properties + } +): Feature; diff --git a/src/sector/index.js b/src/sector/index.js new file mode 100644 index 0000000000..83cfe1c0ed --- /dev/null +++ b/src/sector/index.js @@ -0,0 +1,70 @@ +import circle from '../circle'; +import lineArc from '../line-arc'; +import { coordEach } from '../meta'; +import { polygon, checkIfOptionsExist } from '../helpers'; +import { getCoords } from '../invariant'; + +/** + * Creates a circular sector of a circle of given radius and center {@link Point}, + * between (clockwise) bearing1 and bearing2; 0 bearing is North of center point, positive clockwise. + * + * @name sector + * @param {Coord} center center point + * @param {number} radius radius of the circle + * @param {number} bearing1 angle, in decimal degrees, of the first radius of the sector + * @param {number} bearing2 angle, in decimal degrees, of the second radius of the sector + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians + * @param {number} [options.steps=64] number of steps + * @returns {Feature} sector polygon + * @example + * var center = turf.point([-75, 40]); + * var radius = 5; + * var bearing1 = 25; + * var bearing2 = 45; + * + * var sector = turf.sector(center, radius, bearing1, bearing2); + * + * //addToMap + * var addToMap = [center, sector]; + */ +function sector(center, radius, bearing1, bearing2, options) { + // Optional parameters + options = checkIfOptionsExist(options); + + // validation + if (!center) throw new Error('center is required'); + if (bearing1 === undefined || bearing1 === null) throw new Error('bearing1 is required'); + if (bearing2 === undefined || bearing2 === null) throw new Error('bearing2 is required'); + if (!radius) throw new Error('radius is required'); + if (typeof options !== 'object') throw new Error('options must be an object'); + + if (convertAngleTo360(bearing1) === convertAngleTo360(bearing2)) { + return circle(center, radius, options); + } + var coords = getCoords(center); + var arc = lineArc(center, radius, bearing1, bearing2, options); + var sliceCoords = [[coords]]; + coordEach(arc, function (currentCoords) { + sliceCoords[0].push(currentCoords); + }); + sliceCoords[0].push(coords); + + return polygon(sliceCoords, options.properties); +} + +/** + * Takes any angle in degrees + * and returns a valid angle between 0-360 degrees + * + * @private + * @param {number} alfa angle between -180-180 degrees + * @returns {number} angle between 0-360 degrees + */ +function convertAngleTo360(alfa) { + var beta = alfa % 360; + if (beta < 0) beta += 360; + return beta; +} + +export default sector; diff --git a/src/sector/test.js b/src/sector/test.js new file mode 100644 index 0000000000..753574e97b --- /dev/null +++ b/src/sector/test.js @@ -0,0 +1,44 @@ +import test from 'tape'; +import fs from 'fs'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import truncate from '../truncate'; +import { featureCollection } from '../helpers'; +import sector from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-sector', t => { + for (const {filename, name, geojson} of fixtures) { + const {radius, bearing1, bearing2} = geojson.properties; + const sectored = colorize(truncate(sector(geojson, radius, bearing1, bearing2))); + const results = featureCollection([geojson, sectored]); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEquals(results, load.sync(directories.out + filename), name); + } + t.end(); +}); + +function colorize(feature, color = '#FF0', width = 10) { + feature.properties = { + 'stroke': '#000000', + 'stroke-width': width, + 'stroke-opacity': 1, + 'fill': color, + 'fill-opacity': 0.8 + }; + return feature; +} diff --git a/packages/turf-sector/test/in/pacman.geojson b/src/sector/test/in/pacman.geojson similarity index 100% rename from packages/turf-sector/test/in/pacman.geojson rename to src/sector/test/in/pacman.geojson diff --git a/packages/turf-sector/test/in/sector-full-360.geojson b/src/sector/test/in/sector-full-360.geojson similarity index 100% rename from packages/turf-sector/test/in/sector-full-360.geojson rename to src/sector/test/in/sector-full-360.geojson diff --git a/packages/turf-sector/test/in/sector-greater-360.geojson b/src/sector/test/in/sector-greater-360.geojson similarity index 100% rename from packages/turf-sector/test/in/sector-greater-360.geojson rename to src/sector/test/in/sector-greater-360.geojson diff --git a/packages/turf-sector/test/in/sector1.geojson b/src/sector/test/in/sector1.geojson similarity index 100% rename from packages/turf-sector/test/in/sector1.geojson rename to src/sector/test/in/sector1.geojson diff --git a/packages/turf-sector/test/in/sector2.geojson b/src/sector/test/in/sector2.geojson similarity index 100% rename from packages/turf-sector/test/in/sector2.geojson rename to src/sector/test/in/sector2.geojson diff --git a/packages/turf-sector/test/in/sector3.geojson b/src/sector/test/in/sector3.geojson similarity index 100% rename from packages/turf-sector/test/in/sector3.geojson rename to src/sector/test/in/sector3.geojson diff --git a/packages/turf-sector/test/in/sector4.geojson b/src/sector/test/in/sector4.geojson similarity index 100% rename from packages/turf-sector/test/in/sector4.geojson rename to src/sector/test/in/sector4.geojson diff --git a/packages/turf-sector/test/in/sector5.geojson b/src/sector/test/in/sector5.geojson similarity index 100% rename from packages/turf-sector/test/in/sector5.geojson rename to src/sector/test/in/sector5.geojson diff --git a/packages/turf-sector/test/in/sector6.geojson b/src/sector/test/in/sector6.geojson similarity index 100% rename from packages/turf-sector/test/in/sector6.geojson rename to src/sector/test/in/sector6.geojson diff --git a/packages/turf-sector/test/out/pacman.geojson b/src/sector/test/out/pacman.geojson similarity index 100% rename from packages/turf-sector/test/out/pacman.geojson rename to src/sector/test/out/pacman.geojson diff --git a/packages/turf-sector/test/out/sector-full-360.geojson b/src/sector/test/out/sector-full-360.geojson similarity index 100% rename from packages/turf-sector/test/out/sector-full-360.geojson rename to src/sector/test/out/sector-full-360.geojson diff --git a/packages/turf-sector/test/out/sector-greater-360.geojson b/src/sector/test/out/sector-greater-360.geojson similarity index 100% rename from packages/turf-sector/test/out/sector-greater-360.geojson rename to src/sector/test/out/sector-greater-360.geojson diff --git a/packages/turf-sector/test/out/sector1.geojson b/src/sector/test/out/sector1.geojson similarity index 100% rename from packages/turf-sector/test/out/sector1.geojson rename to src/sector/test/out/sector1.geojson diff --git a/packages/turf-sector/test/out/sector2.geojson b/src/sector/test/out/sector2.geojson similarity index 100% rename from packages/turf-sector/test/out/sector2.geojson rename to src/sector/test/out/sector2.geojson diff --git a/packages/turf-sector/test/out/sector3.geojson b/src/sector/test/out/sector3.geojson similarity index 100% rename from packages/turf-sector/test/out/sector3.geojson rename to src/sector/test/out/sector3.geojson diff --git a/packages/turf-sector/test/out/sector4.geojson b/src/sector/test/out/sector4.geojson similarity index 100% rename from packages/turf-sector/test/out/sector4.geojson rename to src/sector/test/out/sector4.geojson diff --git a/packages/turf-sector/test/out/sector5.geojson b/src/sector/test/out/sector5.geojson similarity index 100% rename from packages/turf-sector/test/out/sector5.geojson rename to src/sector/test/out/sector5.geojson diff --git a/packages/turf-sector/test/out/sector6.geojson b/src/sector/test/out/sector6.geojson similarity index 100% rename from packages/turf-sector/test/out/sector6.geojson rename to src/sector/test/out/sector6.geojson diff --git a/packages/turf-shortest-path/bench.js b/src/shortest-path/bench.js similarity index 100% rename from packages/turf-shortest-path/bench.js rename to src/shortest-path/bench.js diff --git a/src/shortest-path/index.d.ts b/src/shortest-path/index.d.ts new file mode 100644 index 0000000000..6320a7d2c3 --- /dev/null +++ b/src/shortest-path/index.d.ts @@ -0,0 +1,15 @@ +import { Polygon, Feature, FeatureCollection, Coord, LineString, Units } from '../helpers' + +/** + * http://turfjs.org/docs/#shortestpath + */ +export default function shortestPath( + start: Coord, + end: Coord, + options?: { + obstacles?: Polygon | Feature | FeatureCollection, + minDistance?: number + units?: Units + resolution?: number + } +): Feature; diff --git a/src/shortest-path/index.js b/src/shortest-path/index.js new file mode 100644 index 0000000000..65741b3fcf --- /dev/null +++ b/src/shortest-path/index.js @@ -0,0 +1,193 @@ +import bbox from '../bbox'; +import booleanPointInPolygon from '../boolean-point-in-polygon'; +import distance from '../distance'; +import scale from '../transform-scale'; +import cleanCoords from '../clean-coords'; +import bboxPolygon from '../bbox-polygon'; +import { getCoord, getType, getGeom } from '../invariant'; +import { point, isNumber, lineString, isObject, featureCollection, feature } from '../helpers'; +import { Graph, astar } from './lib/javascript-astar'; + +/** + * Returns the shortest {@link LineString|path} from {@link Point|start} to {@link Point|end} without colliding with + * any {@link Feature} in {@link FeatureCollection| obstacles} + * + * @name shortestPath + * @param {Coord} start point + * @param {Coord} end point + * @param {Object} [options={}] optional parameters + * @param {Geometry|Feature|FeatureCollection} [options.obstacles] areas which path cannot travel + * @param {number} [options.minDistance] minimum distance between shortest path and obstacles + * @param {string} [options.units='kilometers'] unit in which resolution & minimum distance will be expressed in; it can be degrees, radians, miles, kilometers, ... + * @param {number} [options.resolution=100] distance between matrix points on which the path will be calculated + * @returns {Feature} shortest path between start and end + * @example + * var start = [-5, -6]; + * var end = [9, -6]; + * var options = { + * obstacles: turf.polygon([[[0, -7], [5, -7], [5, -3], [0, -3], [0, -7]]]) + * }; + * + * var path = turf.shortestPath(start, end, options); + * + * //addToMap + * var addToMap = [start, end, options.obstacles, path]; + */ +function shortestPath(start, end, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var resolution = options.resolution; + var minDistance = options.minDistance; + var obstacles = options.obstacles || featureCollection([]); + + // validation + if (!start) throw new Error('start is required'); + if (!end) throw new Error('end is required'); + if (resolution && !isNumber(resolution) || resolution <= 0) throw new Error('options.resolution must be a number, greater than 0'); + if (minDistance) throw new Error('options.minDistance is not yet implemented'); + + // Normalize Inputs + var startCoord = getCoord(start); + var endCoord = getCoord(end); + start = point(startCoord); + end = point(endCoord); + + // Handle obstacles + switch (getType(obstacles)) { + case 'FeatureCollection': + if (obstacles.features.length === 0) return lineString([startCoord, endCoord]); + break; + case 'Polygon': + obstacles = featureCollection([feature(getGeom(obstacles))]); + break; + default: + throw new Error('invalid obstacles'); + } + + // define path grid area + var collection = obstacles; + collection.features.push(start); + collection.features.push(end); + var box = bbox(scale(bboxPolygon(bbox(collection)), 1.15)); // extend 15% + if (!resolution) { + var width = distance([box[0], box[1]], [box[2], box[1]], options); + resolution = width / 100; + } + collection.features.pop(); + collection.features.pop(); + + var west = box[0]; + var south = box[1]; + var east = box[2]; + var north = box[3]; + + var xFraction = resolution / (distance([west, south], [east, south], options)); + var cellWidth = xFraction * (east - west); + var yFraction = resolution / (distance([west, south], [west, north], options)); + var cellHeight = yFraction * (north - south); + + var bboxHorizontalSide = (east - west); + var bboxVerticalSide = (north - south); + var columns = Math.floor(bboxHorizontalSide / cellWidth); + var rows = Math.floor(bboxVerticalSide / cellHeight); + // adjust origin of the grid + var deltaX = (bboxHorizontalSide - columns * cellWidth) / 2; + var deltaY = (bboxVerticalSide - rows * cellHeight) / 2; + + // loop through points only once to speed up process + // define matrix grid for A-star algorithm + var pointMatrix = []; + var matrix = []; + + var closestToStart = []; + var closestToEnd = []; + var minDistStart = Infinity; + var minDistEnd = Infinity; + var currentY = north - deltaY; + var r = 0; + while (currentY >= south) { + // var currentY = south + deltaY; + var matrixRow = []; + var pointMatrixRow = []; + var currentX = west + deltaX; + var c = 0; + while (currentX <= east) { + var pt = point([currentX, currentY]); + var isInsideObstacle = isInside(pt, obstacles); + // feed obstacles matrix + matrixRow.push(isInsideObstacle ? 0 : 1); // with javascript-astar + // matrixRow.push(isInsideObstacle ? 1 : 0); // with astar-andrea + // map point's coords + pointMatrixRow.push(currentX + '|' + currentY); + // set closest points + var distStart = distance(pt, start); + // if (distStart < minDistStart) { + if (!isInsideObstacle && distStart < minDistStart) { + minDistStart = distStart; + closestToStart = {x: c, y: r}; + } + var distEnd = distance(pt, end); + // if (distEnd < minDistEnd) { + if (!isInsideObstacle && distEnd < minDistEnd) { + minDistEnd = distEnd; + closestToEnd = {x: c, y: r}; + } + currentX += cellWidth; + c++; + } + matrix.push(matrixRow); + pointMatrix.push(pointMatrixRow); + currentY -= cellHeight; + r++; + } + + // find path on matrix grid + + // javascript-astar ---------------------- + var graph = new Graph(matrix, {diagonal: true}); + var startOnMatrix = graph.grid[closestToStart.y][closestToStart.x]; + var endOnMatrix = graph.grid[closestToEnd.y][closestToEnd.x]; + var result = astar.search(graph, startOnMatrix, endOnMatrix); + + var path = [startCoord]; + result.forEach(function (coord) { + var coords = pointMatrix[coord.x][coord.y].split('|'); + path.push([+coords[0], +coords[1]]); // make sure coords are numbers + }); + path.push(endCoord); + // --------------------------------------- + + + // astar-andrea ------------------------ + // var result = aStar(matrix, [closestToStart.x, closestToStart.y], [closestToEnd.x, closestToEnd.y], 'DiagonalFree'); + // var path = [start.geometry.coordinates]; + // result.forEach(function (coord) { + // var coords = pointMatrix[coord[1]][coord[0]].split('|'); + // path.push([+coords[0], +coords[1]]); // make sure coords are numbers + // }); + // path.push(end.geometry.coordinates); + // --------------------------------------- + + + return cleanCoords(lineString(path)); +} + +/** + * Checks if Point is inside any of the Polygons + * + * @private + * @param {Feature} pt to check + * @param {FeatureCollection} polygons features + * @returns {boolean} if inside or not + */ +function isInside(pt, polygons) { + for (var i = 0; i < polygons.features.length; i++) { + if (booleanPointInPolygon(pt, polygons.features[i])) { + return true; + } + } + return false; +} + +export default shortestPath; diff --git a/packages/turf-shortest-path/lib/javascript-astar.js b/src/shortest-path/lib/javascript-astar.js similarity index 100% rename from packages/turf-shortest-path/lib/javascript-astar.js rename to src/shortest-path/lib/javascript-astar.js diff --git a/src/shortest-path/test.js b/src/shortest-path/test.js new file mode 100644 index 0000000000..5a2d700d70 --- /dev/null +++ b/src/shortest-path/test.js @@ -0,0 +1,54 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import truncate from '../truncate'; +import { featureCollection, point } from '../helpers'; +import { getCoord } from '../invariant'; +import { featureEach } from '../meta'; +import shortestPath from './'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-shortest-path', t => { + for (const {filename, name, geojson} of fixtures) { + // First two features from Collection are Start & End Points + const start = geojson.features.shift(); + const end = geojson.features.shift(); + // Any remaining features from Collection are obstacles + const obstacles = geojson; + const options = geojson.properties; + options.obstacles = obstacles; + + const path = truncate(shortestPath(start, end, options)); + path.properties['stroke'] = '#F00'; + path.properties['stroke-width'] = 5; + + const results = featureCollection([]) + if (obstacles) { + featureEach(obstacles, obstacle => { + results.features.push(obstacle) + }) + } + results.features.push(point(getCoord(start), start.properties)); + results.features.push(point(getCoord(end), end.properties)); + results.features.push(path); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(results, load.sync(directories.out + filename), name); + } + t.end(); +}); + diff --git a/packages/turf-shortest-path/test/in/bermuda-triangle.json b/src/shortest-path/test/in/bermuda-triangle.json similarity index 100% rename from packages/turf-shortest-path/test/in/bermuda-triangle.json rename to src/shortest-path/test/in/bermuda-triangle.json diff --git a/packages/turf-shortest-path/test/in/simple.json b/src/shortest-path/test/in/simple.json similarity index 100% rename from packages/turf-shortest-path/test/in/simple.json rename to src/shortest-path/test/in/simple.json diff --git a/src/shortest-path/test/out/bermuda-triangle.json b/src/shortest-path/test/out/bermuda-triangle.json new file mode 100644 index 0000000000..fe5106c186 --- /dev/null +++ b/src/shortest-path/test/out/bermuda-triangle.json @@ -0,0 +1,190 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -80.19, + 25.774 + ], + [ + -66.118, + 18.466 + ], + [ + -64.757, + 32.321 + ], + [ + -80.19, + 25.774 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "type": "start" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -60.925, + 22.335 + ] + } + }, + { + "type": "Feature", + "properties": { + "type": "end" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -79.991, + 29.965 + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 5 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -60.925, + 22.335 + ], + [ + -61.090854, + 22.526114 + ], + [ + -62.427321, + 23.800508 + ], + [ + -62.427321, + 29.960077 + ], + [ + -64.209278, + 31.659269 + ], + [ + -64.877512, + 32.296466 + ], + [ + -65.100257, + 32.296466 + ], + [ + -65.323001, + 32.084067 + ], + [ + -65.768491, + 32.084067 + ], + [ + -65.991235, + 31.871668 + ], + [ + -66.21398, + 31.871668 + ], + [ + -66.436725, + 31.659269 + ], + [ + -66.659469, + 31.659269 + ], + [ + -66.882214, + 31.44687 + ], + [ + -67.104958, + 31.44687 + ], + [ + -67.327703, + 31.234471 + ], + [ + -67.773192, + 31.234471 + ], + [ + -67.995937, + 31.022072 + ], + [ + -68.218681, + 31.022072 + ], + [ + -68.441426, + 30.809673 + ], + [ + -68.664171, + 30.809673 + ], + [ + -68.886915, + 30.597274 + ], + [ + -69.10966, + 30.597274 + ], + [ + -69.332405, + 30.384875 + ], + [ + -69.777894, + 30.384875 + ], + [ + -70.000638, + 30.172476 + ], + [ + -70.223383, + 30.172476 + ], + [ + -70.446128, + 29.960077 + ], + [ + -80.024146, + 29.960077 + ], + [ + -79.991, + 29.965 + ] + ] + } + } + ] +} diff --git a/packages/turf-shortest-path/test/out/simple.json b/src/shortest-path/test/out/simple.json similarity index 86% rename from packages/turf-shortest-path/test/out/simple.json rename to src/shortest-path/test/out/simple.json index a9e877c7e4..c8424dda03 100644 --- a/packages/turf-shortest-path/test/out/simple.json +++ b/src/shortest-path/test/out/simple.json @@ -92,32 +92,28 @@ 40.763 ], [ - 5.677808, - 40.710248 + 5.728134, + 40.731841 ], [ - 7.71159, - 39.124937 + 7.761378, + 39.146168 ], [ - 8.510575, - 39.124937 + 8.487537, + 39.146168 ], [ - 8.801115, - 38.898464 + 8.850616, + 38.863012 ], [ - 8.87375, - 38.898464 + 9.213695, + 39.146168 ], [ - 9.164291, - 39.124937 - ], - [ - 11.924423, - 39.124937 + 11.900482, + 39.146168 ], [ 11.931, diff --git a/packages/turf-simplify/bench.js b/src/simplify/bench.js similarity index 100% rename from packages/turf-simplify/bench.js rename to src/simplify/bench.js diff --git a/src/simplify/index.d.ts b/src/simplify/index.d.ts new file mode 100644 index 0000000000..76abac424f --- /dev/null +++ b/src/simplify/index.d.ts @@ -0,0 +1,13 @@ +import { AllGeoJSON } from '../helpers' + +/** + * http://turfjs.org/docs/#simplify + */ +export default function simplify( + geojson: T, + options?: { + tolerance?: number, + highQuality?: boolean, + mutate?: boolean + } +): T; diff --git a/src/simplify/index.js b/src/simplify/index.js new file mode 100644 index 0000000000..3ab456b647 --- /dev/null +++ b/src/simplify/index.js @@ -0,0 +1,174 @@ +import cleanCoords from '../clean-coords'; +import clone from '../clone'; +import { geomEach } from '../meta'; +import { checkIfOptionsExist } from '../helpers'; +import simplifyJS from './lib/simplify'; + +/** + * Takes a {@link GeoJSON} object and returns a simplified version. Internally uses + * [simplify-js](http://mourner.github.io/simplify-js/) to perform simplification using the Ramer-Douglas-Peucker algorithm. + * + * @name simplify + * @param {GeoJSON} geojson object to be simplified + * @param {Object} [options={}] Optional parameters + * @param {number} [options.tolerance=1] simplification tolerance + * @param {boolean} [options.highQuality=false] whether or not to spend more time to create a higher-quality simplification with a different algorithm + * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) + * @returns {GeoJSON} a simplified GeoJSON + * @example + * var geojson = turf.polygon([[ + * [-70.603637, -33.399918], + * [-70.614624, -33.395332], + * [-70.639343, -33.392466], + * [-70.659942, -33.394759], + * [-70.683975, -33.404504], + * [-70.697021, -33.419406], + * [-70.701141, -33.434306], + * [-70.700454, -33.446339], + * [-70.694274, -33.458369], + * [-70.682601, -33.465816], + * [-70.668869, -33.472117], + * [-70.646209, -33.473835], + * [-70.624923, -33.472117], + * [-70.609817, -33.468107], + * [-70.595397, -33.458369], + * [-70.587158, -33.442901], + * [-70.587158, -33.426283], + * [-70.590591, -33.414248], + * [-70.594711, -33.406224], + * [-70.603637, -33.399918] + * ]]); + * var options = {tolerance: 0.01, highQuality: false}; + * var simplified = turf.simplify(geojson, options); + * + * //addToMap + * var addToMap = [geojson, simplified] + */ +function simplify(geojson, options) { + // Optional parameters + options = checkIfOptionsExist(options); + var tolerance = options.tolerance !== undefined ? options.tolerance : 1; + var highQuality = options.highQuality || false; + var mutate = options.mutate || false; + + if (!geojson) throw new Error('geojson is required'); + if (tolerance && tolerance < 0) throw new Error('invalid tolerance'); + + // Clone geojson to avoid side effects + if (mutate !== true) geojson = clone(geojson); + + geomEach(geojson, function (geom) { + simplifyGeom(geom, tolerance, highQuality); + }); + return geojson; +} + +/** + * Simplifies a feature's coordinates + * + * @private + * @param {Geometry} geometry to be simplified + * @param {number} [tolerance=1] simplification tolerance + * @param {boolean} [highQuality=false] whether or not to spend more time to create a higher-quality simplification with a different algorithm + * @returns {Geometry} output + */ +function simplifyGeom(geometry, tolerance, highQuality) { + var type = geometry.type; + + // "unsimplyfiable" geometry types + if (type === 'Point' || type === 'MultiPoint') return geometry; + + // Remove any extra coordinates + cleanCoords(geometry, {mutate: true}); + + var coordinates = geometry.coordinates; + switch (type) { + case 'LineString': + geometry['coordinates'] = simplifyLine(coordinates, tolerance, highQuality); + break; + case 'MultiLineString': + geometry['coordinates'] = coordinates.map(function (lines) { + return simplifyLine(lines, tolerance, highQuality); + }); + break; + case 'Polygon': + geometry['coordinates'] = simplifyPolygon(coordinates, tolerance, highQuality); + break; + case 'MultiPolygon': + geometry['coordinates'] = coordinates.map(function (rings) { + return simplifyPolygon(rings, tolerance, highQuality); + }); + } + return geometry; +} + + +/** + * Simplifies the coordinates of a LineString with simplify-js + * + * @private + * @param {Array} coordinates to be processed + * @param {number} tolerance simplification tolerance + * @param {boolean} highQuality whether or not to spend more time to create a higher-quality + * @returns {Array>} simplified coords + */ +function simplifyLine(coordinates, tolerance, highQuality) { + return simplifyJS(coordinates.map(function (coord) { + return {x: coord[0], y: coord[1], z: coord[2]}; + }), tolerance, highQuality).map(function (coords) { + return (coords.z) ? [coords.x, coords.y, coords.z] : [coords.x, coords.y]; + }); +} + + +/** + * Simplifies the coordinates of a Polygon with simplify-js + * + * @private + * @param {Array} coordinates to be processed + * @param {number} tolerance simplification tolerance + * @param {boolean} highQuality whether or not to spend more time to create a higher-quality + * @returns {Array>>} simplified coords + */ +function simplifyPolygon(coordinates, tolerance, highQuality) { + return coordinates.map(function (ring) { + var pts = ring.map(function (coord) { + return {x: coord[0], y: coord[1]}; + }); + if (pts.length < 4) { + throw new Error('invalid polygon'); + } + var simpleRing = simplifyJS(pts, tolerance, highQuality).map(function (coords) { + return [coords.x, coords.y]; + }); + //remove 1 percent of tolerance until enough points to make a triangle + while (!checkValidity(simpleRing)) { + tolerance -= tolerance * 0.01; + simpleRing = simplifyJS(pts, tolerance, highQuality).map(function (coords) { + return [coords.x, coords.y]; + }); + } + if ( + (simpleRing[simpleRing.length - 1][0] !== simpleRing[0][0]) || + (simpleRing[simpleRing.length - 1][1] !== simpleRing[0][1])) { + simpleRing.push(simpleRing[0]); + } + return simpleRing; + }); +} + + +/** + * Returns true if ring has at least 3 coordinates and its first coordinate is the same as its last + * + * @private + * @param {Array} ring coordinates to be checked + * @returns {boolean} true if valid + */ +function checkValidity(ring) { + if (ring.length < 3) return false; + //if the last point is the same as the first, it's not a triangle + return !(ring.length === 3 && ((ring[2][0] === ring[0][0]) && (ring[2][1] === ring[0][1]))); +} + +export default simplify; diff --git a/packages/turf-simplify/lib/simplify.js b/src/simplify/lib/simplify.js similarity index 100% rename from packages/turf-simplify/lib/simplify.js rename to src/simplify/lib/simplify.js diff --git a/src/simplify/test.js b/src/simplify/test.js new file mode 100644 index 0000000000..a3b74215fd --- /dev/null +++ b/src/simplify/test.js @@ -0,0 +1,86 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import truncate from '../truncate'; +import { polygon, multiPolygon } from '../helpers'; +import simplify from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); +// fixtures = fixtures.filter(({name}) => name.includes('#555')); + +test('simplify', t => { + for (const {filename, name, geojson} of fixtures) { + let {tolerance, highQuality} = geojson.properties || {}; + tolerance = tolerance || 0.01; + highQuality = highQuality || false; + + const simplified = truncate(simplify(geojson, { + tolerance: tolerance, + highQuality: highQuality + })); + + if (process.env.REGEN) write.sync(directories.out + filename, simplified); + t.deepEqual(simplified, load.sync(directories.out + filename), name); + } + + t.end(); +}); + + +test('simplify -- throw', t => { + const poly = polygon([[[0, 0], [2, 2], [2, 0], [0, 0]]]); + t.throws(() => simplify(null), /geojson is required/, 'missing geojson'); + t.throws(() => simplify(poly, {tolerance: -1}), /invalid tolerance/, 'negative tolerance'); + t.end(); +}); + + +test('simplify -- removes ID & BBox from properties', t => { + const properties = {foo: 'bar'}; + const id = 12345; + const bbox = [0, 0, 2, 2]; + const poly = polygon([[[0, 0], [2, 2], [2, 0], [0, 0]]], properties, {bbox, id}); + const simple = simplify(poly, {tolerance: 0.1}); + + t.equal(simple.id, id); + t.deepEqual(simple.bbox, bbox); + t.deepEqual(simple.properties, properties); + t.end(); +}); + + +test('simplify -- issue #555', t => { + // polygons from issue #555 + const poly1 = polygon([[[-75.693254, 45.431144], [-75.693335, 45.431109], [-75.693335, 45.431109], [-75.693254, 45.431144]]]); + const poly2 = polygon([[[-75.627178, 45.438106], [-75.627179, 45.438106], [-75.62718, 45.438106], [-75.627178, 45.438106]]]); + const poly3 = polygon([[[-75.684722, 45.410083], [-75.684641, 45.409989], [-75.684641, 45.409989], [-75.684722, 45.410083], [-75.684722, 45.410083]]]); + const poly4 = polygon([[[-75.885634, 45.272762], [-75.885482, 45.272641], [-75.885554, 45.272596], [-75.885534, 45.272581], [-75.885581, 45.272551], [-75.885703, 45.272647], [-75.885706, 45.272645], [-75.885709, 45.272647], [-75.885767, 45.272693], [-75.885759, 45.272698], [-75.885716, 45.272728], [-75.885716, 45.272728], [-75.885712, 45.272731], [-75.885712, 45.272731], [-75.885708, 45.272734], [-75.885684, 45.272749], [-75.885671, 45.272739], [-75.885634, 45.272762]], [[-75.885708, 45.27273], [-75.885708, 45.272729], [-75.885708, 45.272729], [-75.885708, 45.27273]]]); + const options = {tolerance: 0.000001, highQuality: true}; + + t.throws(() => simplify(poly1, options), /invalid polygon/); + t.throws(() => simplify(poly2, options), /invalid polygon/); + t.throws(() => simplify(poly3, options), /invalid polygon/); + t.throws(() => simplify(poly4, options), /invalid polygon/); + t.end(); +}); + +test('simplify -- issue #918', t => { + // simplify hangs on this input #918 + t.throws(() => simplify(multiPolygon([[[[0, 90], [0, 90], [0, 90], [0, 90], [0, 90], [0, 90], [0, 90], [0, 90], [0, 90], [0, 90], [0, 90]]]])), /invalid polygon/, 'invalid polygon'); + t.throws(() => simplify(multiPolygon([[[[0, 1], [0, 2], [0, 3], [0, 2.5], [0, 1]]]])), /invalid polygon/, 'invalid polygon'); + t.throws(() => simplify(multiPolygon([[[[0, 1], [0, 1], [1, 2], [0, 1]]]])), /invalid polygon/, 'invalid polygon'); + t.end(); +}); diff --git a/packages/turf-simplify/test/in/argentina.geojson b/src/simplify/test/in/argentina.geojson similarity index 100% rename from packages/turf-simplify/test/in/argentina.geojson rename to src/simplify/test/in/argentina.geojson diff --git a/packages/turf-simplify/test/in/featurecollection.geojson b/src/simplify/test/in/featurecollection.geojson similarity index 100% rename from packages/turf-simplify/test/in/featurecollection.geojson rename to src/simplify/test/in/featurecollection.geojson diff --git a/packages/turf-simplify/test/in/fiji-hiQ.geojson b/src/simplify/test/in/fiji-hiQ.geojson similarity index 100% rename from packages/turf-simplify/test/in/fiji-hiQ.geojson rename to src/simplify/test/in/fiji-hiQ.geojson diff --git a/packages/turf-simplify/test/in/geometrycollection.geojson b/src/simplify/test/in/geometrycollection.geojson similarity index 100% rename from packages/turf-simplify/test/in/geometrycollection.geojson rename to src/simplify/test/in/geometrycollection.geojson diff --git a/packages/turf-simplify/test/in/issue-#1144.geojson b/src/simplify/test/in/issue-#1144.geojson similarity index 100% rename from packages/turf-simplify/test/in/issue-#1144.geojson rename to src/simplify/test/in/issue-#1144.geojson diff --git a/packages/turf-simplify/test/in/linestring.geojson b/src/simplify/test/in/linestring.geojson similarity index 100% rename from packages/turf-simplify/test/in/linestring.geojson rename to src/simplify/test/in/linestring.geojson diff --git a/packages/turf-simplify/test/in/multilinestring.geojson b/src/simplify/test/in/multilinestring.geojson similarity index 100% rename from packages/turf-simplify/test/in/multilinestring.geojson rename to src/simplify/test/in/multilinestring.geojson diff --git a/packages/turf-simplify/test/in/multipoint.geojson b/src/simplify/test/in/multipoint.geojson similarity index 100% rename from packages/turf-simplify/test/in/multipoint.geojson rename to src/simplify/test/in/multipoint.geojson diff --git a/packages/turf-simplify/test/in/multipolygon.geojson b/src/simplify/test/in/multipolygon.geojson similarity index 100% rename from packages/turf-simplify/test/in/multipolygon.geojson rename to src/simplify/test/in/multipolygon.geojson diff --git a/packages/turf-simplify/test/in/point.geojson b/src/simplify/test/in/point.geojson similarity index 100% rename from packages/turf-simplify/test/in/point.geojson rename to src/simplify/test/in/point.geojson diff --git a/packages/turf-simplify/test/in/poly-issue#555-5.geojson b/src/simplify/test/in/poly-issue#555-5.geojson similarity index 100% rename from packages/turf-simplify/test/in/poly-issue#555-5.geojson rename to src/simplify/test/in/poly-issue#555-5.geojson diff --git a/packages/turf-simplify/test/in/polygon.geojson b/src/simplify/test/in/polygon.geojson similarity index 100% rename from packages/turf-simplify/test/in/polygon.geojson rename to src/simplify/test/in/polygon.geojson diff --git a/packages/turf-simplify/test/in/simple-polygon.geojson b/src/simplify/test/in/simple-polygon.geojson similarity index 100% rename from packages/turf-simplify/test/in/simple-polygon.geojson rename to src/simplify/test/in/simple-polygon.geojson diff --git a/packages/turf-simplify/test/out/argentina.geojson b/src/simplify/test/out/argentina.geojson similarity index 100% rename from packages/turf-simplify/test/out/argentina.geojson rename to src/simplify/test/out/argentina.geojson diff --git a/packages/turf-simplify/test/out/featurecollection.geojson b/src/simplify/test/out/featurecollection.geojson similarity index 100% rename from packages/turf-simplify/test/out/featurecollection.geojson rename to src/simplify/test/out/featurecollection.geojson diff --git a/packages/turf-simplify/test/out/fiji-hiQ.geojson b/src/simplify/test/out/fiji-hiQ.geojson similarity index 100% rename from packages/turf-simplify/test/out/fiji-hiQ.geojson rename to src/simplify/test/out/fiji-hiQ.geojson diff --git a/packages/turf-simplify/test/out/geometrycollection.geojson b/src/simplify/test/out/geometrycollection.geojson similarity index 100% rename from packages/turf-simplify/test/out/geometrycollection.geojson rename to src/simplify/test/out/geometrycollection.geojson diff --git a/packages/turf-simplify/test/out/issue-#1144.geojson b/src/simplify/test/out/issue-#1144.geojson similarity index 100% rename from packages/turf-simplify/test/out/issue-#1144.geojson rename to src/simplify/test/out/issue-#1144.geojson diff --git a/packages/turf-simplify/test/out/linestring.geojson b/src/simplify/test/out/linestring.geojson similarity index 100% rename from packages/turf-simplify/test/out/linestring.geojson rename to src/simplify/test/out/linestring.geojson diff --git a/packages/turf-simplify/test/out/multilinestring.geojson b/src/simplify/test/out/multilinestring.geojson similarity index 100% rename from packages/turf-simplify/test/out/multilinestring.geojson rename to src/simplify/test/out/multilinestring.geojson diff --git a/packages/turf-simplify/test/out/multipoint.geojson b/src/simplify/test/out/multipoint.geojson similarity index 100% rename from packages/turf-simplify/test/out/multipoint.geojson rename to src/simplify/test/out/multipoint.geojson diff --git a/packages/turf-simplify/test/out/multipolygon.geojson b/src/simplify/test/out/multipolygon.geojson similarity index 100% rename from packages/turf-simplify/test/out/multipolygon.geojson rename to src/simplify/test/out/multipolygon.geojson diff --git a/packages/turf-simplify/test/out/point.geojson b/src/simplify/test/out/point.geojson similarity index 100% rename from packages/turf-simplify/test/out/point.geojson rename to src/simplify/test/out/point.geojson diff --git a/packages/turf-simplify/test/out/poly-issue#555-5.geojson b/src/simplify/test/out/poly-issue#555-5.geojson similarity index 100% rename from packages/turf-simplify/test/out/poly-issue#555-5.geojson rename to src/simplify/test/out/poly-issue#555-5.geojson diff --git a/packages/turf-simplify/test/out/polygon.geojson b/src/simplify/test/out/polygon.geojson similarity index 100% rename from packages/turf-simplify/test/out/polygon.geojson rename to src/simplify/test/out/polygon.geojson diff --git a/packages/turf-simplify/test/out/simple-polygon.geojson b/src/simplify/test/out/simple-polygon.geojson similarity index 100% rename from packages/turf-simplify/test/out/simple-polygon.geojson rename to src/simplify/test/out/simple-polygon.geojson diff --git a/src/spatial-index/bench.js b/src/spatial-index/bench.js new file mode 100755 index 0000000000..0e551feb00 --- /dev/null +++ b/src/spatial-index/bench.js @@ -0,0 +1,38 @@ +const Benchmark = require('benchmark'); +const {randomPoint, randomPolygon} = require('@turf/random'); +const geojsonRbush = require('./').default; + +// Fixtures +const points = randomPoint(3); +const point = points.features[0]; +const polygons = randomPolygon(3); +const polygon = polygons.features[0]; + +// Load trees before (used to benchmark search) +const pointsTree = geojsonRbush(); +pointsTree.load(points); +const polygonsTree = geojsonRbush(); +polygonsTree.load(polygons); + +/** + * Benchmark Results + * + * rbush.points x 313,979 ops/sec ±10.60% (67 runs sampled) + * rbush.polygons x 428,333 ops/sec ±1.69% (70 runs sampled) + * search.points x 5,986,675 ops/sec ±7.95% (77 runs sampled) + * search.polygons x 6,481,248 ops/sec ±0.93% (90 runs sampled) + */ +new Benchmark.Suite('geojson-rbush') + .add('rbush.points', () => { + const tree = geojsonRbush(); + tree.load(points); + }) + .add('rbush.polygons', () => { + const tree = geojsonRbush(); + tree.load(polygons); + }) + .add('search.points', () => pointsTree.search(point)) + .add('search.polygons', () => polygonsTree.search(polygon)) + .on('cycle', e => console.log(String(e.target))) + .on('complete', () => {}) + .run(); diff --git a/src/spatial-index/index.d.ts b/src/spatial-index/index.d.ts new file mode 100755 index 0000000000..5d2da06658 --- /dev/null +++ b/src/spatial-index/index.d.ts @@ -0,0 +1,19 @@ +import { BBox, Feature, FeatureCollection, Geometry, Properties } from '@turf/helpers' + +declare class RBush { + insert(feature: Feature): RBush; + load(features: FeatureCollection | Feature[]): RBush; + remove(feature: Feature, equals?: (a: Feature, b: Feature) => boolean): RBush; + clear(): RBush; + search(geojson: Feature | FeatureCollection | BBox): FeatureCollection; + all(): FeatureCollection; + collides(geosjon: Feature | FeatureCollection | BBox): boolean; + toJSON(): any; + fromJSON(data: any): RBush; +} + +/** + * https://github.com/mourner/rbush + */ +export default function rbush(maxEntries?: number): RBush; + diff --git a/src/spatial-index/index.js b/src/spatial-index/index.js new file mode 100644 index 0000000000..ae9257d583 --- /dev/null +++ b/src/spatial-index/index.js @@ -0,0 +1,201 @@ +import rbush from './lib/rbush'; +import bbox from '../bbox'; +import { featureCollection} from '../helpers'; +import { featureEach } from '../meta'; + +/** + * GeoJSON implementation of [RBush](https://github.com/mourner/rbush#rbush) spatial index. + * + * @name rbush + * @param {number} [maxEntries=9] defines the maximum number of entries in a tree node. 9 (used by default) is a + * reasonable choice for most applications. Higher value means faster insertion and slower search, and vice versa. + * @returns {RBush} GeoJSON RBush + * @example + * var geojsonRbush = require('geojson-rbush').default; + * var tree = geojsonRbush(); + */ +export default function geojsonRbush(maxEntries) { + const tree = rbush(maxEntries); + /** + * [insert](https://github.com/mourner/rbush#data-format) + * + * @param {Feature} feature insert single GeoJSON Feature + * @returns {RBush} GeoJSON RBush + * @example + * var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]); + * tree.insert(poly) + */ + tree.insert = function (feature) { + if (feature.type !== 'Feature') throw new Error('invalid feature'); + feature.bbox = feature.bbox ? feature.bbox : bbox(feature); + return rbush.prototype.insert.call(this, feature); + }; + + /** + * [load](https://github.com/mourner/rbush#bulk-inserting-data) + * + * @param {FeatureCollection|Array} features load entire GeoJSON FeatureCollection + * @returns {RBush} GeoJSON RBush + * @example + * var polys = turf.polygons([ + * [[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]], + * [[[-93, 32], [-83, 32], [-83, 39], [-93, 39], [-93, 32]]] + * ]); + * tree.load(polys); + */ + tree.load = function (features) { + const load = []; + // Load an Array of Features + if (Array.isArray(features)) { + features.forEach(function (feature) { + if (feature.type !== 'Feature') throw new Error('invalid features'); + feature.bbox = feature.bbox ? feature.bbox : bbox(feature); + load.push(feature); + }); + } else { + // Load a FeatureCollection + featureEach(features, function (feature) { + if (feature.type !== 'Feature') throw new Error('invalid features'); + feature.bbox = feature.bbox ? feature.bbox : bbox(feature); + load.push(feature); + }); + } + return rbush.prototype.load.call(this, load); + }; + + /** + * [remove](https://github.com/mourner/rbush#removing-data) + * + * @param {Feature} feature remove single GeoJSON Feature + * @param {Function} equals Pass a custom equals function to compare by value for removal. + * @returns {RBush} GeoJSON RBush + * @example + * var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]); + * + * tree.remove(poly); + */ + tree.remove = function (feature, equals) { + if (feature.type !== 'Feature') throw new Error('invalid feature'); + feature.bbox = feature.bbox ? feature.bbox : bbox(feature); + return rbush.prototype.remove.call(this, feature, equals); + }; + + /** + * [clear](https://github.com/mourner/rbush#removing-data) + * + * @returns {RBush} GeoJSON Rbush + * @example + * tree.clear() + */ + tree.clear = function () { + return rbush.prototype.clear.call(this); + }; + + /** + * [search](https://github.com/mourner/rbush#search) + * + * @param {BBox|FeatureCollection|Feature} geojson search with GeoJSON + * @returns {FeatureCollection} all features that intersects with the given GeoJSON. + * @example + * var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]); + * + * tree.search(poly); + */ + tree.search = function (geojson) { + const features = rbush.prototype.search.call(this, this.toBBox(geojson)); + return featureCollection(features); + }; + + /** + * [collides](https://github.com/mourner/rbush#collisions) + * + * @param {BBox|FeatureCollection|Feature} geojson collides with GeoJSON + * @returns {boolean} true if there are any items intersecting the given GeoJSON, otherwise false. + * @example + * var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]); + * + * tree.collides(poly); + */ + tree.collides = function (geojson) { + return rbush.prototype.collides.call(this, this.toBBox(geojson)); + }; + + /** + * [all](https://github.com/mourner/rbush#search) + * + * @returns {FeatureCollection} all the features in RBush + * @example + * tree.all() + */ + tree.all = function () { + const features = rbush.prototype.all.call(this); + return featureCollection(features); + }; + + /** + * [toJSON](https://github.com/mourner/rbush#export-and-import) + * + * @returns {any} export data as JSON object + * @example + * var exported = tree.toJSON() + */ + tree.toJSON = function () { + return rbush.prototype.toJSON.call(this); + }; + + /** + * [fromJSON](https://github.com/mourner/rbush#export-and-import) + * + * @param {any} json import previously exported data + * @returns {RBush} GeoJSON RBush + * @example + * var exported = { + * "children": [ + * { + * "type": "Feature", + * "geometry": { + * "type": "Point", + * "coordinates": [110, 50] + * }, + * "properties": {}, + * "bbox": [110, 50, 110, 50] + * } + * ], + * "height": 1, + * "leaf": true, + * "minX": 110, + * "minY": 50, + * "maxX": 110, + * "maxY": 50 + * } + * tree.fromJSON(exported) + */ + tree.fromJSON = function (json) { + return rbush.prototype.fromJSON.call(this, json); + }; + + /** + * Converts GeoJSON to {minX, minY, maxX, maxY} schema + * + * @private + * @param {BBox|FeatureCollection|Feature} geojson feature(s) to retrieve BBox from + * @returns {Object} converted to {minX, minY, maxX, maxY} + */ + tree.toBBox = function (geojson) { + let calculatedBbox; + if (geojson.bbox) calculatedBbox = geojson.bbox; + else if (Array.isArray(geojson) && geojson.length === 4) calculatedBbox = geojson; + else if (Array.isArray(geojson) && geojson.length === 6) calculatedBbox = [geojson[0], geojson[1], geojson[3], geojson[4]]; + else if (geojson.type === 'Feature') calculatedBbox = bbox(geojson); + else if (geojson.type === 'FeatureCollection') calculatedBbox = bbox(geojson); + else throw new Error('invalid geojson'); + + return { + minX: calculatedBbox[0], + minY: calculatedBbox[1], + maxX: calculatedBbox[2], + maxY: calculatedBbox[3] + }; + }; + return tree; +} diff --git a/src/spatial-index/lib/rbush.js b/src/spatial-index/lib/rbush.js new file mode 100644 index 0000000000..daa65f04da --- /dev/null +++ b/src/spatial-index/lib/rbush.js @@ -0,0 +1,611 @@ +function quickselect(arr, k, left, right, compare) { + quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare); +} + +function quickselectStep(arr, k, left, right, compare) { + + while (right > left) { + if (right - left > 600) { + var n = right - left + 1; + var m = k - left + 1; + var z = Math.log(n); + var s = 0.5 * Math.exp(2 * z / 3); + var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1); + var newLeft = Math.max(left, Math.floor(k - m * s / n + sd)); + var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd)); + quickselectStep(arr, k, newLeft, newRight, compare); + } + + var t = arr[k]; + var i = left; + var j = right; + + swap(arr, left, k); + if (compare(arr[right], t) > 0) swap(arr, left, right); + + while (i < j) { + swap(arr, i, j); + i++; + j--; + while (compare(arr[i], t) < 0) i++; + while (compare(arr[j], t) > 0) j--; + } + + if (compare(arr[left], t) === 0) swap(arr, left, j); + else { + j++; + swap(arr, j, right); + } + + if (j <= k) left = j + 1; + if (k <= j) right = j - 1; + } +} + +function swap(arr, i, j) { + var tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; +} + +function defaultCompare(a, b) { + return a < b ? -1 : a > b ? 1 : 0; +} + +function rbush(maxEntries, format) { + if (!(this instanceof rbush)) return new rbush(maxEntries, format); + + // max entries in a node is 9 by default; min node fill is 40% for best performance + this._maxEntries = Math.max(4, maxEntries || 9); + this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4)); + + if (format) { + this._initFormat(format); + } + + this.clear(); +} + +rbush.prototype = { + + all: function () { + return this._all(this.data, []); + }, + + search: function (bbox) { + + var node = this.data, + result = [], + toBBox = this.toBBox; + + if (!intersects(bbox, node)) return result; + + var nodesToSearch = [], + i, len, child, childBBox; + + while (node) { + for (i = 0, len = node.children.length; i < len; i++) { + + child = node.children[i]; + childBBox = node.leaf ? toBBox(child) : child; + + if (intersects(bbox, childBBox)) { + if (node.leaf) result.push(child); + else if (contains(bbox, childBBox)) this._all(child, result); + else nodesToSearch.push(child); + } + } + node = nodesToSearch.pop(); + } + + return result; + }, + + collides: function (bbox) { + + var node = this.data, + toBBox = this.toBBox; + + if (!intersects(bbox, node)) return false; + + var nodesToSearch = [], + i, len, child, childBBox; + + while (node) { + for (i = 0, len = node.children.length; i < len; i++) { + + child = node.children[i]; + childBBox = node.leaf ? toBBox(child) : child; + + if (intersects(bbox, childBBox)) { + if (node.leaf || contains(bbox, childBBox)) return true; + nodesToSearch.push(child); + } + } + node = nodesToSearch.pop(); + } + + return false; + }, + + load: function (data) { + if (!(data && data.length)) return this; + + if (data.length < this._minEntries) { + for (var i = 0, len = data.length; i < len; i++) { + this.insert(data[i]); + } + return this; + } + + // recursively build the tree with the given data from scratch using OMT algorithm + var node = this._build(data.slice(), 0, data.length - 1, 0); + + if (!this.data.children.length) { + // save as is if tree is empty + this.data = node; + + } else if (this.data.height === node.height) { + // split root if trees have the same height + this._splitRoot(this.data, node); + + } else { + if (this.data.height < node.height) { + // swap trees if inserted one is bigger + var tmpNode = this.data; + this.data = node; + node = tmpNode; + } + + // insert the small tree into the large tree at appropriate level + this._insert(node, this.data.height - node.height - 1, true); + } + + return this; + }, + + insert: function (item) { + if (item) this._insert(item, this.data.height - 1); + return this; + }, + + clear: function () { + this.data = createNode([]); + return this; + }, + + remove: function (item, equalsFn) { + if (!item) return this; + + var node = this.data, + bbox = this.toBBox(item), + path = [], + indexes = [], + i, parent, index, goingUp; + + // depth-first iterative tree traversal + while (node || path.length) { + + if (!node) { // go up + node = path.pop(); + parent = path[path.length - 1]; + i = indexes.pop(); + goingUp = true; + } + + if (node.leaf) { // check current node + index = findItem(item, node.children, equalsFn); + + if (index !== -1) { + // item found, remove the item and condense tree upwards + node.children.splice(index, 1); + path.push(node); + this._condense(path); + return this; + } + } + + if (!goingUp && !node.leaf && contains(node, bbox)) { // go down + path.push(node); + indexes.push(i); + i = 0; + parent = node; + node = node.children[0]; + + } else if (parent) { // go right + i++; + node = parent.children[i]; + goingUp = false; + + } else node = null; // nothing found + } + + return this; + }, + + toBBox: function (item) { return item; }, + + compareMinX: compareNodeMinX, + compareMinY: compareNodeMinY, + + toJSON: function () { return this.data; }, + + fromJSON: function (data) { + this.data = data; + return this; + }, + + _all: function (node, result) { + var nodesToSearch = []; + while (node) { + if (node.leaf) result.push.apply(result, node.children); + else nodesToSearch.push.apply(nodesToSearch, node.children); + + node = nodesToSearch.pop(); + } + return result; + }, + + _build: function (items, left, right, height) { + + var N = right - left + 1, + M = this._maxEntries, + node; + + if (N <= M) { + // reached leaf level; return leaf + node = createNode(items.slice(left, right + 1)); + calcBBox(node, this.toBBox); + return node; + } + + if (!height) { + // target height of the bulk-loaded tree + height = Math.ceil(Math.log(N) / Math.log(M)); + + // target number of root entries to maximize storage utilization + M = Math.ceil(N / Math.pow(M, height - 1)); + } + + node = createNode([]); + node.leaf = false; + node.height = height; + + // split the items into M mostly square tiles + + var N2 = Math.ceil(N / M), + N1 = N2 * Math.ceil(Math.sqrt(M)), + i, j, right2, right3; + + multiSelect(items, left, right, N1, this.compareMinX); + + for (i = left; i <= right; i += N1) { + + right2 = Math.min(i + N1 - 1, right); + + multiSelect(items, i, right2, N2, this.compareMinY); + + for (j = i; j <= right2; j += N2) { + + right3 = Math.min(j + N2 - 1, right2); + + // pack each entry recursively + node.children.push(this._build(items, j, right3, height - 1)); + } + } + + calcBBox(node, this.toBBox); + + return node; + }, + + _chooseSubtree: function (bbox, node, level, path) { + + var i, len, child, targetNode, area, enlargement, minArea, minEnlargement; + + while (true) { + path.push(node); + + if (node.leaf || path.length - 1 === level) break; + + minArea = minEnlargement = Infinity; + + for (i = 0, len = node.children.length; i < len; i++) { + child = node.children[i]; + area = bboxArea(child); + enlargement = enlargedArea(bbox, child) - area; + + // choose entry with the least area enlargement + if (enlargement < minEnlargement) { + minEnlargement = enlargement; + minArea = area < minArea ? area : minArea; + targetNode = child; + + } else if (enlargement === minEnlargement) { + // otherwise choose one with the smallest area + if (area < minArea) { + minArea = area; + targetNode = child; + } + } + } + + node = targetNode || node.children[0]; + } + + return node; + }, + + _insert: function (item, level, isNode) { + + var toBBox = this.toBBox, + bbox = isNode ? item : toBBox(item), + insertPath = []; + + // find the best node for accommodating the item, saving all nodes along the path too + var node = this._chooseSubtree(bbox, this.data, level, insertPath); + + // put the item into the node + node.children.push(item); + extend(node, bbox); + + // split on node overflow; propagate upwards if necessary + while (level >= 0) { + if (insertPath[level].children.length > this._maxEntries) { + this._split(insertPath, level); + level--; + } else break; + } + + // adjust bboxes along the insertion path + this._adjustParentBBoxes(bbox, insertPath, level); + }, + + // split overflowed node into two + _split: function (insertPath, level) { + + var node = insertPath[level], + M = node.children.length, + m = this._minEntries; + + this._chooseSplitAxis(node, m, M); + + var splitIndex = this._chooseSplitIndex(node, m, M); + + var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex)); + newNode.height = node.height; + newNode.leaf = node.leaf; + + calcBBox(node, this.toBBox); + calcBBox(newNode, this.toBBox); + + if (level) insertPath[level - 1].children.push(newNode); + else this._splitRoot(node, newNode); + }, + + _splitRoot: function (node, newNode) { + // split root node + this.data = createNode([node, newNode]); + this.data.height = node.height + 1; + this.data.leaf = false; + calcBBox(this.data, this.toBBox); + }, + + _chooseSplitIndex: function (node, m, M) { + + var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index; + + minOverlap = minArea = Infinity; + + for (i = m; i <= M - m; i++) { + bbox1 = distBBox(node, 0, i, this.toBBox); + bbox2 = distBBox(node, i, M, this.toBBox); + + overlap = intersectionArea(bbox1, bbox2); + area = bboxArea(bbox1) + bboxArea(bbox2); + + // choose distribution with minimum overlap + if (overlap < minOverlap) { + minOverlap = overlap; + index = i; + + minArea = area < minArea ? area : minArea; + + } else if (overlap === minOverlap) { + // otherwise choose distribution with minimum area + if (area < minArea) { + minArea = area; + index = i; + } + } + } + + return index; + }, + + // sorts node children by the best axis for split + _chooseSplitAxis: function (node, m, M) { + + var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX, + compareMinY = node.leaf ? this.compareMinY : compareNodeMinY, + xMargin = this._allDistMargin(node, m, M, compareMinX), + yMargin = this._allDistMargin(node, m, M, compareMinY); + + // if total distributions margin value is minimal for x, sort by minX, + // otherwise it's already sorted by minY + if (xMargin < yMargin) node.children.sort(compareMinX); + }, + + // total margin of all possible split distributions where each node is at least m full + _allDistMargin: function (node, m, M, compare) { + + node.children.sort(compare); + + var toBBox = this.toBBox, + leftBBox = distBBox(node, 0, m, toBBox), + rightBBox = distBBox(node, M - m, M, toBBox), + margin = bboxMargin(leftBBox) + bboxMargin(rightBBox), + i, child; + + for (i = m; i < M - m; i++) { + child = node.children[i]; + extend(leftBBox, node.leaf ? toBBox(child) : child); + margin += bboxMargin(leftBBox); + } + + for (i = M - m - 1; i >= m; i--) { + child = node.children[i]; + extend(rightBBox, node.leaf ? toBBox(child) : child); + margin += bboxMargin(rightBBox); + } + + return margin; + }, + + _adjustParentBBoxes: function (bbox, path, level) { + // adjust bboxes along the given tree path + for (var i = level; i >= 0; i--) { + extend(path[i], bbox); + } + }, + + _condense: function (path) { + // go through the path, removing empty nodes and updating bboxes + for (var i = path.length - 1, siblings; i >= 0; i--) { + if (path[i].children.length === 0) { + if (i > 0) { + siblings = path[i - 1].children; + siblings.splice(siblings.indexOf(path[i]), 1); + + } else this.clear(); + + } else calcBBox(path[i], this.toBBox); + } + }, + + _initFormat: function (format) { + // data format (minX, minY, maxX, maxY accessors) + + // uses eval-type function compilation instead of just accepting a toBBox function + // because the algorithms are very sensitive to sorting functions performance, + // so they should be dead simple and without inner calls + + var compareArr = ['return a', ' - b', ';']; + + this.compareMinX = new Function('a', 'b', compareArr.join(format[0])); + this.compareMinY = new Function('a', 'b', compareArr.join(format[1])); + + this.toBBox = new Function('a', + 'return {minX: a' + format[0] + + ', minY: a' + format[1] + + ', maxX: a' + format[2] + + ', maxY: a' + format[3] + '};'); + } +}; + +function findItem(item, items, equalsFn) { + if (!equalsFn) return items.indexOf(item); + + for (var i = 0; i < items.length; i++) { + if (equalsFn(item, items[i])) return i; + } + return -1; +} + +// calculate node's bbox from bboxes of its children +function calcBBox(node, toBBox) { + distBBox(node, 0, node.children.length, toBBox, node); +} + +// min bounding rectangle of node children from k to p-1 +function distBBox(node, k, p, toBBox, destNode) { + if (!destNode) destNode = createNode(null); + destNode.minX = Infinity; + destNode.minY = Infinity; + destNode.maxX = -Infinity; + destNode.maxY = -Infinity; + + for (var i = k, child; i < p; i++) { + child = node.children[i]; + extend(destNode, node.leaf ? toBBox(child) : child); + } + + return destNode; +} + +function extend(a, b) { + a.minX = Math.min(a.minX, b.minX); + a.minY = Math.min(a.minY, b.minY); + a.maxX = Math.max(a.maxX, b.maxX); + a.maxY = Math.max(a.maxY, b.maxY); + return a; +} + +function compareNodeMinX(a, b) { return a.minX - b.minX; } +function compareNodeMinY(a, b) { return a.minY - b.minY; } + +function bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); } +function bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); } + +function enlargedArea(a, b) { + return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) * + (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY)); +} + +function intersectionArea(a, b) { + var minX = Math.max(a.minX, b.minX), + minY = Math.max(a.minY, b.minY), + maxX = Math.min(a.maxX, b.maxX), + maxY = Math.min(a.maxY, b.maxY); + + return Math.max(0, maxX - minX) * + Math.max(0, maxY - minY); +} + +function contains(a, b) { + return a.minX <= b.minX && + a.minY <= b.minY && + b.maxX <= a.maxX && + b.maxY <= a.maxY; +} + +function intersects(a, b) { + return b.minX <= a.maxX && + b.minY <= a.maxY && + b.maxX >= a.minX && + b.maxY >= a.minY; +} + +function createNode(children) { + return { + children: children, + height: 1, + leaf: true, + minX: Infinity, + minY: Infinity, + maxX: -Infinity, + maxY: -Infinity + }; +} + +// sort an array so that items come in groups of n unsorted items, with groups sorted between each other; +// combines selection algorithm with binary divide & conquer approach + +function multiSelect(arr, left, right, n, compare) { + var stack = [left, right], + mid; + + while (stack.length) { + right = stack.pop(); + left = stack.pop(); + + if (right - left <= n) continue; + + mid = left + Math.ceil((right - left) / n / 2) * n; + quickselect(arr, mid, left, right, compare); + + stack.push(left, mid, mid, right); + } +} + +export default rbush; diff --git a/src/spatial-index/test.js b/src/spatial-index/test.js new file mode 100644 index 0000000000..01497b3cb6 --- /dev/null +++ b/src/spatial-index/test.js @@ -0,0 +1,93 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import bboxPolygon from '../bbox-polygon'; +import { polygon, featureCollection, polygons } from '../helpers'; +import geojsonRbush from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('geojson-rbush', t => { + for (const fixture of fixtures) { + const name = fixture.name; + const filename = fixture.filename; + const geojson = fixture.geojson; + const tree = geojsonRbush(); + tree.load(geojson); + + // Retrive all features inside the RBush index + const all = tree.all(); + + // Search using the first item in the FeatureCollection + const search = tree.search(geojson.features[0]); + + if (process.env.REGEN) { + write.sync(directories.out + 'all.' + filename, all); + write.sync(directories.out + 'search.' + filename, search); + } + + t.deepEqual(all, load.sync(directories.out + 'all.' + filename), 'all.' + name); + t.deepEqual(search, load.sync(directories.out + 'search.' + filename), 'search.' + name); + } + t.end(); +}); + +test('geojson-rbush -- bbox', t => { + const tree = geojsonRbush(); + tree.insert(bboxPolygon([-150, -60, 150, 60])); + + t.equal(tree.collides([-140, -50, 140, 50]), true); + t.equal(tree.search([-140, -50, 140, 50]).features.length, 1); + t.equal(tree.search(bboxPolygon([-150, -60, 150, 60])).features.length, 1); + t.equal(tree.search(featureCollection([bboxPolygon([-150, -60, 150, 60])])).features.length, 1); + t.equal(tree.collides([-180, -80, -170, -60]), false); + + // Errors + t.throws(() => tree.search('foo')); + t.end(); +}); + +test('geojson-rbush -- fromJSON', t => { + const tree = geojsonRbush(); + const poly = bboxPolygon([-150, -60, 150, 60]) + tree.insert(poly); + + const newTree = geojsonRbush() + newTree.fromJSON(tree.toJSON()) + t.equal(newTree.all().features.length, 1) + newTree.remove(poly) + t.equal(newTree.all().features.length, 0) + t.end(); +}); + + + +test('geojson-rbush -- Array of Features -- Issue #5', t => { + // https://github.com/DenisCarriere/geojson-rbush/issues/5 + const tree = geojsonRbush(); + const polys = polygons([ + [[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]], + [[[-93, 32], [-83, 32], [-83, 39], [-93, 39], [-93, 32]]] + ]); + // Load Feature Collection + tree.load(polys); + t.equal(tree.all().features.length, 2); + + // Load Array of Features + tree.load(polys.features); + t.equal(tree.all().features.length, 4); + t.end(); +}); \ No newline at end of file diff --git a/src/spatial-index/test/in/linestrings.geojson b/src/spatial-index/test/in/linestrings.geojson new file mode 100755 index 0000000000..2f2a0a9e5d --- /dev/null +++ b/src/spatial-index/test/in/linestrings.geojson @@ -0,0 +1,89 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -121.9921875, + 41.77131167976407 + ], + [ + -112.1484375, + 49.15296965617042 + ], + [ + -95.2734375, + 49.15296965617042 + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -101.953125, + 34.016241889667015 + ], + [ + -88.9453125, + 40.17887331434696 + ], + [ + -78.046875, + 50.064191736659104 + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -108.6328125, + 42.032974332441405 + ], + [ + -102.65625, + 39.36827914916014 + ], + [ + -95.97656249999999, + 39.36827914916014 + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -71.71875, + 39.842286020743394 + ], + [ + -69.169921875, + 35.96022296929667 + ], + [ + -66.796875, + 31.952162238024975 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/src/spatial-index/test/in/points.geojson b/src/spatial-index/test/in/points.geojson new file mode 100755 index 0000000000..55a2882a8f --- /dev/null +++ b/src/spatial-index/test/in/points.geojson @@ -0,0 +1,38 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [ + -86.8359375, + 42.8115217450979 + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [ + -67.5, + 48.69096039092549 + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [ + -106.171875, + 46.800059446787316 + ] + } + } + ] +} \ No newline at end of file diff --git a/src/spatial-index/test/in/polygons.geojson b/src/spatial-index/test/in/polygons.geojson new file mode 100755 index 0000000000..451fd16d21 --- /dev/null +++ b/src/spatial-index/test/in/polygons.geojson @@ -0,0 +1,129 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -78, + 41 + ], + [ + -67, + 41 + ], + [ + -67, + 48 + ], + [ + -78, + 48 + ], + [ + -78, + 41 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -93, + 32 + ], + [ + -83, + 32 + ], + [ + -83, + 39 + ], + [ + -93, + 39 + ], + [ + -93, + 32 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -97.646484375, + 43.197167282501276 + ], + [ + -88.681640625, + 43.197167282501276 + ], + [ + -88.681640625, + 48.28319289548349 + ], + [ + -97.646484375, + 48.28319289548349 + ], + [ + -97.646484375, + 43.197167282501276 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -93.8671875, + 36.87962060502676 + ], + [ + -75.89355468749999, + 36.87962060502676 + ], + [ + -75.89355468749999, + 45.1510532655634 + ], + [ + -93.8671875, + 45.1510532655634 + ], + [ + -93.8671875, + 36.87962060502676 + ] + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/src/spatial-index/test/out/all.linestrings.geojson b/src/spatial-index/test/out/all.linestrings.geojson new file mode 100755 index 0000000000..4a75698a4b --- /dev/null +++ b/src/spatial-index/test/out/all.linestrings.geojson @@ -0,0 +1,113 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -121.9921875, + 41.77131167976407 + ], + [ + -112.1484375, + 49.15296965617042 + ], + [ + -95.2734375, + 49.15296965617042 + ] + ] + }, + "bbox": [ + -121.9921875, + 41.77131167976407, + -95.2734375, + 49.15296965617042 + ] + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -101.953125, + 34.016241889667015 + ], + [ + -88.9453125, + 40.17887331434696 + ], + [ + -78.046875, + 50.064191736659104 + ] + ] + }, + "bbox": [ + -101.953125, + 34.016241889667015, + -78.046875, + 50.064191736659104 + ] + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -108.6328125, + 42.032974332441405 + ], + [ + -102.65625, + 39.36827914916014 + ], + [ + -95.97656249999999, + 39.36827914916014 + ] + ] + }, + "bbox": [ + -108.6328125, + 39.36827914916014, + -95.97656249999999, + 42.032974332441405 + ] + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -71.71875, + 39.842286020743394 + ], + [ + -69.169921875, + 35.96022296929667 + ], + [ + -66.796875, + 31.952162238024975 + ] + ] + }, + "bbox": [ + -71.71875, + 31.952162238024975, + -66.796875, + 39.842286020743394 + ] + } + ] +} diff --git a/src/spatial-index/test/out/all.points.geojson b/src/spatial-index/test/out/all.points.geojson new file mode 100755 index 0000000000..24165ef6bb --- /dev/null +++ b/src/spatial-index/test/out/all.points.geojson @@ -0,0 +1,56 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [ + -86.8359375, + 42.8115217450979 + ] + }, + "bbox": [ + -86.8359375, + 42.8115217450979, + -86.8359375, + 42.8115217450979 + ] + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [ + -67.5, + 48.69096039092549 + ] + }, + "bbox": [ + -67.5, + 48.69096039092549, + -67.5, + 48.69096039092549 + ] + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [ + -106.171875, + 46.800059446787316 + ] + }, + "bbox": [ + -106.171875, + 46.800059446787316, + -106.171875, + 46.800059446787316 + ] + } + ] +} diff --git a/src/spatial-index/test/out/all.polygons.geojson b/src/spatial-index/test/out/all.polygons.geojson new file mode 100755 index 0000000000..a25063017d --- /dev/null +++ b/src/spatial-index/test/out/all.polygons.geojson @@ -0,0 +1,153 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -78, + 41 + ], + [ + -67, + 41 + ], + [ + -67, + 48 + ], + [ + -78, + 48 + ], + [ + -78, + 41 + ] + ] + ] + }, + "bbox": [ + -78, + 41, + -67, + 48 + ] + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -93, + 32 + ], + [ + -83, + 32 + ], + [ + -83, + 39 + ], + [ + -93, + 39 + ], + [ + -93, + 32 + ] + ] + ] + }, + "bbox": [ + -93, + 32, + -83, + 39 + ] + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -97.646484375, + 43.197167282501276 + ], + [ + -88.681640625, + 43.197167282501276 + ], + [ + -88.681640625, + 48.28319289548349 + ], + [ + -97.646484375, + 48.28319289548349 + ], + [ + -97.646484375, + 43.197167282501276 + ] + ] + ] + }, + "bbox": [ + -97.646484375, + 43.197167282501276, + -88.681640625, + 48.28319289548349 + ] + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -93.8671875, + 36.87962060502676 + ], + [ + -75.89355468749999, + 36.87962060502676 + ], + [ + -75.89355468749999, + 45.1510532655634 + ], + [ + -93.8671875, + 45.1510532655634 + ], + [ + -93.8671875, + 36.87962060502676 + ] + ] + ] + }, + "bbox": [ + -93.8671875, + 36.87962060502676, + -75.89355468749999, + 45.1510532655634 + ] + } + ] +} diff --git a/src/spatial-index/test/out/search.linestrings.geojson b/src/spatial-index/test/out/search.linestrings.geojson new file mode 100755 index 0000000000..619566bd0f --- /dev/null +++ b/src/spatial-index/test/out/search.linestrings.geojson @@ -0,0 +1,86 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -121.9921875, + 41.77131167976407 + ], + [ + -112.1484375, + 49.15296965617042 + ], + [ + -95.2734375, + 49.15296965617042 + ] + ] + }, + "bbox": [ + -121.9921875, + 41.77131167976407, + -95.2734375, + 49.15296965617042 + ] + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -101.953125, + 34.016241889667015 + ], + [ + -88.9453125, + 40.17887331434696 + ], + [ + -78.046875, + 50.064191736659104 + ] + ] + }, + "bbox": [ + -101.953125, + 34.016241889667015, + -78.046875, + 50.064191736659104 + ] + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -108.6328125, + 42.032974332441405 + ], + [ + -102.65625, + 39.36827914916014 + ], + [ + -95.97656249999999, + 39.36827914916014 + ] + ] + }, + "bbox": [ + -108.6328125, + 39.36827914916014, + -95.97656249999999, + 42.032974332441405 + ] + } + ] +} diff --git a/src/spatial-index/test/out/search.points.geojson b/src/spatial-index/test/out/search.points.geojson new file mode 100755 index 0000000000..2c8bcde2cb --- /dev/null +++ b/src/spatial-index/test/out/search.points.geojson @@ -0,0 +1,22 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [ + -86.8359375, + 42.8115217450979 + ] + }, + "bbox": [ + -86.8359375, + 42.8115217450979, + -86.8359375, + 42.8115217450979 + ] + } + ] +} diff --git a/src/spatial-index/test/out/search.polygons.geojson b/src/spatial-index/test/out/search.polygons.geojson new file mode 100755 index 0000000000..acffede86a --- /dev/null +++ b/src/spatial-index/test/out/search.polygons.geojson @@ -0,0 +1,79 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -78, + 41 + ], + [ + -67, + 41 + ], + [ + -67, + 48 + ], + [ + -78, + 48 + ], + [ + -78, + 41 + ] + ] + ] + }, + "bbox": [ + -78, + 41, + -67, + 48 + ] + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -93.8671875, + 36.87962060502676 + ], + [ + -75.89355468749999, + 36.87962060502676 + ], + [ + -75.89355468749999, + 45.1510532655634 + ], + [ + -93.8671875, + 45.1510532655634 + ], + [ + -93.8671875, + 36.87962060502676 + ] + ] + ] + }, + "bbox": [ + -93.8671875, + 36.87962060502676, + -75.89355468749999, + 45.1510532655634 + ] + } + ] +} diff --git a/src/spatial-index/types.ts b/src/spatial-index/types.ts new file mode 100755 index 0000000000..1ff05c8d03 --- /dev/null +++ b/src/spatial-index/types.ts @@ -0,0 +1,37 @@ +import { BBox, point, polygon, featureCollection, Polygon} from '@turf/helpers' +import rbush from './' + +// Fixtures +const bbox: BBox = [-180, -90, 180, 90] +const pt = point([0, 0]) +const points = featureCollection([pt, pt]) +const poly = polygon([[[0, 0], [1, 1], [1, 1], [0, 0]]]) +const polygons = featureCollection([poly, poly]) + +// Initialize GeoJSON RBush Tree +const tree = rbush() + +// Load Tree with a FeatureCollection +tree.load(points); +tree.load(polygons); + +// Insert by Feature +tree.insert(pt) +tree.insert(poly) + +// Find All (returns FeatureCollection) +const all = tree.all() + +// Search by Feature (returns FeatureCollection) +const search = tree.search(poly) + +// Collides by Feature (returns FeatureCollection) +const collides = tree.collides(poly) + +// Remove by Feature +tree.remove(pt) +tree.remove(poly) + +// BBox support +tree.search(bbox) +tree.collides(bbox) diff --git a/packages/turf-square-grid/bench.js b/src/square-grid/bench.js similarity index 100% rename from packages/turf-square-grid/bench.js rename to src/square-grid/bench.js diff --git a/src/square-grid/index.d.ts b/src/square-grid/index.d.ts new file mode 100644 index 0000000000..e392cff9e2 --- /dev/null +++ b/src/square-grid/index.d.ts @@ -0,0 +1,29 @@ +import { FeatureCollection, Polygon, BBox, Units, Feature, MultiPolygon, Properties } from "../helpers"; +/** + * Creates a square grid from a bounding box, {@link Feature} or {@link FeatureCollection}. + * + * @name squareGrid + * @param {Array} bbox extent in [minX, minY, maxX, maxY] order + * @param {number} cellSide of each cell, in units + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] used in calculating cellSide, can be degrees, + * radians, miles, or kilometers + * @param {Feature} [options.mask] if passed a Polygon or MultiPolygon, + * the grid Points will be created only inside it + * @param {Object} [options.properties={}] passed to each point of the grid + * @returns {FeatureCollection} grid a grid of polygons + * @example + * var bbox = [-95, 30 ,-85, 40]; + * var cellSide = 50; + * var options = {units: 'miles'}; + * + * var squareGrid = turf.squareGrid(bbox, cellSide, options); + * + * //addToMap + * var addToMap = [squareGrid] + */ +export default function squareGrid

(bbox: BBox, cellSide: number, options?: { + units?: Units; + properties?: P; + mask?: Feature | Polygon | MultiPolygon; +}): FeatureCollection; diff --git a/src/square-grid/index.js b/src/square-grid/index.js new file mode 100644 index 0000000000..c64d699020 --- /dev/null +++ b/src/square-grid/index.js @@ -0,0 +1,29 @@ +import rectangleGrid from '../rectangle-grid'; + +/** + * Creates a square grid from a bounding box, {@link Feature} or {@link FeatureCollection}. + * + * @name squareGrid + * @param {Array} bbox extent in [minX, minY, maxX, maxY] order + * @param {number} cellSide of each cell, in units + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] used in calculating cellSide, can be degrees, + * radians, miles, or kilometers + * @param {Feature} [options.mask] if passed a Polygon or MultiPolygon, + * the grid Points will be created only inside it + * @param {Object} [options.properties={}] passed to each point of the grid + * @returns {FeatureCollection} grid a grid of polygons + * @example + * var bbox = [-95, 30 ,-85, 40]; + * var cellSide = 50; + * var options = {units: 'miles'}; + * + * var squareGrid = turf.squareGrid(bbox, cellSide, options); + * + * //addToMap + * var addToMap = [squareGrid] + */ + +export default function squareGrid(bbox, cellSide, options) { + return rectangleGrid(bbox, cellSide, cellSide, options); +} \ No newline at end of file diff --git a/src/square-grid/test.js b/src/square-grid/test.js new file mode 100644 index 0000000000..6e916b6897 --- /dev/null +++ b/src/square-grid/test.js @@ -0,0 +1,66 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const bboxPoly = require('../bbox-polygon').default; +const truncate = require('../truncate').default; +const squareGrid = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + json: load.sync(directories.in + filename) + }; +}); + +test('square-grid', t => { + for (const {name, json} of fixtures) { + const {bbox, cellSide, units, properties, mask} = json; + const options = { + mask, + units, + properties, + } + const result = truncate(squareGrid(bbox, cellSide, options)); + + // Add styled GeoJSON to the result + const poly = bboxPoly(bbox); + poly.properties = { + stroke: '#F00', + 'stroke-width': 6, + 'fill-opacity': 0 + }; + result.features.push(poly); + if (options.mask) { + options.mask.properties = { + "stroke": "#00F", + "stroke-width": 6, + "fill-opacity": 0 + }; + result.features.push(options.mask); + } + + if (process.env.REGEN) write.sync(directories.out + name + '.geojson', result); + t.deepEqual(result, load.sync(directories.out + name + '.geojson'), name); + } + t.end(); +}); + + +test('square-grid -- throw', t => { + const bbox = [0, 0, 1, 1]; + // t.throws(() => squareGrid(null, 0), /bbox is required/, 'missing bbox'); + // t.throws(() => squareGrid('string', 0), /bbox must be array/, 'invalid bbox'); + // t.throws(() => squareGrid([0, 2], 0), /bbox must contain 4 numbers/, 'invalid bbox'); + // t.throws(() => squareGrid(bbox, null), /cellSide is required/, 'missing cellSide'); + // t.throws(() => squareGrid(bbox, 'string'), /cellSide is invalid/, 'invalid cellSide'); + // t.throws(() => squareGrid(bbox, 1, 'string'), /options is invalid/, 'invalid options'); + t.end(); +}); diff --git a/packages/turf-square-grid/test/in/big-bbox.json b/src/square-grid/test/in/big-bbox.json similarity index 100% rename from packages/turf-square-grid/test/in/big-bbox.json rename to src/square-grid/test/in/big-bbox.json diff --git a/packages/turf-square-grid/test/in/fiji-10-miles.json b/src/square-grid/test/in/fiji-10-miles.json similarity index 100% rename from packages/turf-square-grid/test/in/fiji-10-miles.json rename to src/square-grid/test/in/fiji-10-miles.json diff --git a/packages/turf-square-grid/test/in/issue-1215.geojson b/src/square-grid/test/in/issue-1215.geojson similarity index 100% rename from packages/turf-square-grid/test/in/issue-1215.geojson rename to src/square-grid/test/in/issue-1215.geojson diff --git a/packages/turf-square-grid/test/in/london-20-miles.json b/src/square-grid/test/in/london-20-miles.json similarity index 100% rename from packages/turf-square-grid/test/in/london-20-miles.json rename to src/square-grid/test/in/london-20-miles.json diff --git a/packages/turf-square-grid/test/in/piedemont-mask.json b/src/square-grid/test/in/piedemont-mask.json similarity index 100% rename from packages/turf-square-grid/test/in/piedemont-mask.json rename to src/square-grid/test/in/piedemont-mask.json diff --git a/packages/turf-square-grid/test/in/properties.json b/src/square-grid/test/in/properties.json similarity index 100% rename from packages/turf-square-grid/test/in/properties.json rename to src/square-grid/test/in/properties.json diff --git a/packages/turf-square-grid/test/in/resolute.json b/src/square-grid/test/in/resolute.json similarity index 100% rename from packages/turf-square-grid/test/in/resolute.json rename to src/square-grid/test/in/resolute.json diff --git a/packages/turf-square-grid/test/out/big-bbox.geojson b/src/square-grid/test/out/big-bbox.geojson similarity index 100% rename from packages/turf-square-grid/test/out/big-bbox.geojson rename to src/square-grid/test/out/big-bbox.geojson diff --git a/packages/turf-square-grid/test/out/fiji-10-miles.geojson b/src/square-grid/test/out/fiji-10-miles.geojson similarity index 100% rename from packages/turf-square-grid/test/out/fiji-10-miles.geojson rename to src/square-grid/test/out/fiji-10-miles.geojson diff --git a/packages/turf-square-grid/test/out/issue-1215.geojson b/src/square-grid/test/out/issue-1215.geojson similarity index 100% rename from packages/turf-square-grid/test/out/issue-1215.geojson rename to src/square-grid/test/out/issue-1215.geojson diff --git a/packages/turf-square-grid/test/out/london-20-miles.geojson b/src/square-grid/test/out/london-20-miles.geojson similarity index 100% rename from packages/turf-square-grid/test/out/london-20-miles.geojson rename to src/square-grid/test/out/london-20-miles.geojson diff --git a/packages/turf-square-grid/test/out/piedemont-mask.geojson b/src/square-grid/test/out/piedemont-mask.geojson similarity index 100% rename from packages/turf-square-grid/test/out/piedemont-mask.geojson rename to src/square-grid/test/out/piedemont-mask.geojson diff --git a/packages/turf-square-grid/test/out/properties.geojson b/src/square-grid/test/out/properties.geojson similarity index 100% rename from packages/turf-square-grid/test/out/properties.geojson rename to src/square-grid/test/out/properties.geojson diff --git a/packages/turf-square-grid/test/out/resolute.geojson b/src/square-grid/test/out/resolute.geojson similarity index 100% rename from packages/turf-square-grid/test/out/resolute.geojson rename to src/square-grid/test/out/resolute.geojson diff --git a/packages/turf-square/bench.js b/src/square/bench.js similarity index 100% rename from packages/turf-square/bench.js rename to src/square/bench.js diff --git a/src/square/index.d.ts b/src/square/index.d.ts new file mode 100644 index 0000000000..9887eaebef --- /dev/null +++ b/src/square/index.d.ts @@ -0,0 +1,6 @@ +import { BBox } from '../helpers' + +/** + * http://turfjs.org/docs/#square + */ +export default function (bbox: BBox): BBox; \ No newline at end of file diff --git a/src/square/index.js b/src/square/index.js new file mode 100644 index 0000000000..32164a6d6e --- /dev/null +++ b/src/square/index.js @@ -0,0 +1,44 @@ +import distance from '../distance'; + +/** + * Takes a bounding box and calculates the minimum square bounding box that + * would contain the input. + * + * @name square + * @param {BBox} bbox extent in [west, south, east, north] order + * @returns {BBox} a square surrounding `bbox` + * @example + * var bbox = [-20, -20, -15, 0]; + * var squared = turf.square(bbox); + * + * //addToMap + * var addToMap = [turf.bboxPolygon(bbox), turf.bboxPolygon(squared)] + */ +function square(bbox) { + var west = bbox[0]; + var south = bbox[1]; + var east = bbox[2]; + var north = bbox[3]; + + var horizontalDistance = distance(bbox.slice(0, 2), [east, south]); + var verticalDistance = distance(bbox.slice(0, 2), [west, north]); + if (horizontalDistance >= verticalDistance) { + var verticalMidpoint = (south + north) / 2; + return [ + west, + verticalMidpoint - ((east - west) / 2), + east, + verticalMidpoint + ((east - west) / 2) + ]; + } else { + var horizontalMidpoint = (west + east) / 2; + return [ + horizontalMidpoint - ((north - south) / 2), + south, + horizontalMidpoint + ((north - south) / 2), + north + ]; + } +} + +export default square; diff --git a/packages/turf-square/test.js b/src/square/test.js similarity index 100% rename from packages/turf-square/test.js rename to src/square/test.js diff --git a/src/standard-deviational-ellipse/bench.js b/src/standard-deviational-ellipse/bench.js new file mode 100644 index 0000000000..d6596341a2 --- /dev/null +++ b/src/standard-deviational-ellipse/bench.js @@ -0,0 +1,20 @@ +import { randomPoint } from '../random'; +import standardDeviationalEllipse from '.'; +import Benchmark from 'benchmark'; + +/** + * Benchmark Results + * + * turf-standard-deviational-ellipse - 150 points x 1,874 ops/sec ±5.89% (89 runs sampled) + * turf-standard-deviational-ellipse - 300 points x 1,092 ops/sec ±0.79% (93 runs sampled) + * turf-standard-deviational-ellipse - 600 points x 574 ops/sec ±1.14% (92 runs sampled) + */ +const suite = new Benchmark.Suite('turf-standard-deviational-ellipse'); +const properties = {bbox: [-10, -10, 10, 10]}; +suite + .add('turf-standard-deviational-ellipse - 150 points', () => standardDeviationalEllipse(randomPoint(150, properties))) + .add('turf-standard-deviational-ellipse - 300 points', () => standardDeviationalEllipse(randomPoint(300, properties))) + .add('turf-standard-deviational-ellipse - 600 points', () => standardDeviationalEllipse(randomPoint(600, properties))) + .on('cycle', e => console.log(String(e.target))) + .on('complete', () => {}) + .run(); diff --git a/src/standard-deviational-ellipse/index.d.ts b/src/standard-deviational-ellipse/index.d.ts new file mode 100644 index 0000000000..e89c221e7e --- /dev/null +++ b/src/standard-deviational-ellipse/index.d.ts @@ -0,0 +1,30 @@ +import { FeatureCollection, Feature, Position, Polygon, Properties, Point } from '../helpers'; + +/** + * http://turfjs.org/docs/#standarddeviational-ellipse + */ + +export interface SDEProps { + meanCenterCoordinates: Position, + semiMajorAxis: number, + semiMinorAxis: number, + numberOfFeatures: number, + angle: number, + percentageWithinEllipse: number +} + +export interface StandardDeviationalEllipse extends Feature { + properties: { + standardDeviationalEllipse: SDEProps, + [key: string]: any + } +} + +export default function ( + points: FeatureCollection, + options?: { + properties?: Properties, + weight?: string, + steps?: number + } +): StandardDeviationalEllipse; diff --git a/src/standard-deviational-ellipse/index.js b/src/standard-deviational-ellipse/index.js new file mode 100644 index 0000000000..b0e74479cd --- /dev/null +++ b/src/standard-deviational-ellipse/index.js @@ -0,0 +1,135 @@ +import { coordAll, featureEach } from '../meta'; +import { getCoords } from '../invariant'; +import { featureCollection, isObject, isNumber } from '../helpers'; +import centerMean from '../center-mean'; +import pointsWithinPolygon from '../points-within-polygon'; +import ellipse from '../ellipse'; + +/** + * Takes a {@link FeatureCollection} and returns a standard deviational ellipse, + * also known as a “directional distribution.” The standard deviational ellipse + * aims to show the direction and the distribution of a dataset by drawing + * an ellipse that contains about one standard deviation’s worth (~ 70%) of the + * data. + * + * This module mirrors the functionality of [Directional Distribution](http://desktop.arcgis.com/en/arcmap/10.3/tools/spatial-statistics-toolbox/directional-distribution.htm) + * in ArcGIS and the [QGIS Standard Deviational Ellipse Plugin](http://arken.nmbu.no/~havatv/gis/qgisplugins/SDEllipse/) + * + * **Bibliography** + * + * • Robert S. Yuill, “The Standard Deviational Ellipse; An Updated Tool for + * Spatial Description,” _Geografiska Annaler_ 53, no. 1 (1971): 28–39, + * doi:{@link https://doi.org/10.2307/490885|10.2307/490885}. + * + * • Paul Hanly Furfey, “A Note on Lefever’s “Standard Deviational Ellipse,” + * _American Journal of Sociology_ 33, no. 1 (1927): 94—98, + * doi:{@link https://doi.org/10.1086/214336|10.1086/214336}. + * + * + * @name standardDeviationalEllipse + * @param {FeatureCollection} points GeoJSON points + * @param {Object} [options={}] Optional parameters + * @param {string} [options.weight] the property name used to weight the center + * @param {number} [options.steps=64] number of steps for the polygon + * @param {Object} [options.properties={}] properties to pass to the resulting ellipse + * @returns {Feature} an elliptical Polygon that includes approximately 1 SD of the dataset within it. + * @example + * + * var bbox = [-74, 40.72, -73.98, 40.74]; + * var points = turf.randomPoint(400, {bbox: bbox}); + * var sdEllipse = turf.standardDeviationalEllipse(points); + * + * //addToMap + * var addToMap = [points, sdEllipse]; + * + */ +function standardDeviationalEllipse(points, options) { + // Optional params + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var steps = options.steps || 64; + var weightTerm = options.weight; + var properties = options.properties || {}; + + // Validation: + if (!isNumber(steps)) throw new Error('steps must be a number'); + if (!isObject(properties)) throw new Error('properties must be a number'); + + // Calculate mean center & number of features: + var numberOfFeatures = coordAll(points).length; + var meanCenter = centerMean(points, {weight: weightTerm}); + + // Calculate angle of rotation: + // [X, Y] = mean center of all [x, y]. + // theta = arctan( (A + B) / C ) + // A = sum((x - X)^2) - sum((y - Y)^2) + // B = sqrt(A^2 + 4(sum((x - X)(y - Y))^2)) + // C = 2(sum((x - X)(y - Y))) + + var xDeviationSquaredSum = 0; + var yDeviationSquaredSum = 0; + var xyDeviationSum = 0; + + featureEach(points, function (point) { + var weight = point.properties[weightTerm] || 1; + var deviation = getDeviations(getCoords(point), getCoords(meanCenter)); + xDeviationSquaredSum += Math.pow(deviation.x, 2) * weight; + yDeviationSquaredSum += Math.pow(deviation.y, 2) * weight; + xyDeviationSum += deviation.x * deviation.y * weight; + }); + + var bigA = xDeviationSquaredSum - yDeviationSquaredSum; + var bigB = Math.sqrt(Math.pow(bigA, 2) + 4 * Math.pow(xyDeviationSum, 2)); + var bigC = 2 * xyDeviationSum; + var theta = Math.atan((bigA + bigB) / bigC); + var thetaDeg = theta * 180 / Math.PI; + + // Calculate axes: + // sigmaX = sqrt((1 / n - 2) * sum((((x - X) * cos(theta)) - ((y - Y) * sin(theta)))^2)) + // sigmaY = sqrt((1 / n - 2) * sum((((x - X) * sin(theta)) - ((y - Y) * cos(theta)))^2)) + var sigmaXsum = 0; + var sigmaYsum = 0; + var weightsum = 0; + featureEach(points, function (point) { + var weight = point.properties[weightTerm] || 1; + var deviation = getDeviations(getCoords(point), getCoords(meanCenter)); + sigmaXsum += Math.pow((deviation.x * Math.cos(theta)) - (deviation.y * Math.sin(theta)), 2) * weight; + sigmaYsum += Math.pow((deviation.x * Math.sin(theta)) + (deviation.y * Math.cos(theta)), 2) * weight; + weightsum += weight; + }); + + var sigmaX = Math.sqrt(2 * sigmaXsum / weightsum); + var sigmaY = Math.sqrt(2 * sigmaYsum / weightsum); + + var theEllipse = ellipse(meanCenter, sigmaX, sigmaY, {units: 'degrees', angle: thetaDeg, steps: steps, properties: properties}); + var pointsWithinEllipse = pointsWithinPolygon(points, featureCollection([theEllipse])); + var standardDeviationalEllipseProperties = { + meanCenterCoordinates: getCoords(meanCenter), + semiMajorAxis: sigmaX, + semiMinorAxis: sigmaY, + numberOfFeatures: numberOfFeatures, + angle: thetaDeg, + percentageWithinEllipse: 100 * coordAll(pointsWithinEllipse).length / numberOfFeatures + }; + theEllipse.properties.standardDeviationalEllipse = standardDeviationalEllipseProperties; + + return theEllipse; +} + +/** + * Get x_i - X and y_i - Y + * + * @private + * @param {Array} coordinates Array of [x_i, y_i] + * @param {Array} center Array of [X, Y] + * @returns {Object} { x: n, y: m } + */ +function getDeviations(coordinates, center) { + return { + x: coordinates[0] - center[0], + y: coordinates[1] - center[1] + }; +} + + +export default standardDeviationalEllipse; diff --git a/src/standard-deviational-ellipse/test.js b/src/standard-deviational-ellipse/test.js new file mode 100644 index 0000000000..5b15cd5071 --- /dev/null +++ b/src/standard-deviational-ellipse/test.js @@ -0,0 +1,54 @@ +import test from 'tape'; +import fs from 'fs'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import { featureCollection } from '../helpers'; +import { featureEach } from '../meta'; +import truncate from '../truncate'; +import standardDeviationalEllipse from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('turf-standard-deviational-ellipse', t => { + for (const {name, geojson} of fixtures) { + // Define params + const options = geojson.options; + // Optional: ESRI Polygon in GeoJSON test/in to compare results + const esriEllipse = geojson.esriEllipse; + + // Colorized results + const results = featureCollection([ + colorize(standardDeviationalEllipse(geojson, options)), + ]); + if (esriEllipse) results.features.unshift(colorize(esriEllipse, '#A00', '#A00', 0.5)) + + // Save to file + if (process.env.REGEN) write.sync(directories.out + name + '.json', results); + t.deepEqual(results, load.sync(directories.out + name + '.json'), name); + }; + t.end(); +}); + +function colorize (feature, stroke = '#0A0', fill = '#FFF', opacity = 0) { + const properties = { + fill, + stroke, + 'stroke-width': 3, + 'stroke-opacity': 1, + 'fill-opacity': opacity + }; + Object.assign(feature.properties, properties) + return feature +} \ No newline at end of file diff --git a/packages/turf-standard-deviational-ellipse/test/in/mta-stations-unweighted.json b/src/standard-deviational-ellipse/test/in/mta-stations-unweighted.json similarity index 100% rename from packages/turf-standard-deviational-ellipse/test/in/mta-stations-unweighted.json rename to src/standard-deviational-ellipse/test/in/mta-stations-unweighted.json diff --git a/packages/turf-standard-deviational-ellipse/test/in/mta-stations-weighted.json b/src/standard-deviational-ellipse/test/in/mta-stations-weighted.json similarity index 100% rename from packages/turf-standard-deviational-ellipse/test/in/mta-stations-weighted.json rename to src/standard-deviational-ellipse/test/in/mta-stations-weighted.json diff --git a/packages/turf-standard-deviational-ellipse/test/out/mta-stations-unweighted.json b/src/standard-deviational-ellipse/test/out/mta-stations-unweighted.json similarity index 100% rename from packages/turf-standard-deviational-ellipse/test/out/mta-stations-unweighted.json rename to src/standard-deviational-ellipse/test/out/mta-stations-unweighted.json diff --git a/packages/turf-standard-deviational-ellipse/test/out/mta-stations-weighted.json b/src/standard-deviational-ellipse/test/out/mta-stations-weighted.json similarity index 100% rename from packages/turf-standard-deviational-ellipse/test/out/mta-stations-weighted.json rename to src/standard-deviational-ellipse/test/out/mta-stations-weighted.json diff --git a/packages/turf-tag/bench.js b/src/tag/bench.js similarity index 100% rename from packages/turf-tag/bench.js rename to src/tag/bench.js diff --git a/src/tag/index.d.ts b/src/tag/index.d.ts new file mode 100644 index 0000000000..33449536f6 --- /dev/null +++ b/src/tag/index.d.ts @@ -0,0 +1,11 @@ +import { BBox, Point, FeatureCollection, Polygon } from '../helpers' + +/** + * http://turfjs.org/docs/#tag + */ +export default function tag( + points: FeatureCollection, + polygons: FeatureCollection, + field: string, + outField: string +): FeatureCollection; diff --git a/src/tag/index.js b/src/tag/index.js new file mode 100644 index 0000000000..8af836d683 --- /dev/null +++ b/src/tag/index.js @@ -0,0 +1,55 @@ +import booleanPointInPolygon from '../boolean-point-in-polygon'; +import clone from '../clone'; +import { featureEach } from '../meta'; + +/** + * Takes a set of {@link Point|points} and a set of {@link Polygon|polygons} and performs a spatial join. + * + * @name tag + * @param {FeatureCollection} points input points + * @param {FeatureCollection} polygons input polygons + * @param {string} field property in `polygons` to add to joined {} features + * @param {string} outField property in `points` in which to store joined property from `polygons` + * @returns {FeatureCollection} points with `containingPolyId` property containing values from `polyId` + * @example + * var pt1 = turf.point([-77, 44]); + * var pt2 = turf.point([-77, 38]); + * var poly1 = turf.polygon([[ + * [-81, 41], + * [-81, 47], + * [-72, 47], + * [-72, 41], + * [-81, 41] + * ]], {pop: 3000}); + * var poly2 = turf.polygon([[ + * [-81, 35], + * [-81, 41], + * [-72, 41], + * [-72, 35], + * [-81, 35] + * ]], {pop: 1000}); + * + * var points = turf.featureCollection([pt1, pt2]); + * var polygons = turf.featureCollection([poly1, poly2]); + * + * var tagged = turf.tag(points, polygons, 'pop', 'population'); + * + * //addToMap + * var addToMap = [tagged, polygons] + */ +function tag(points, polygons, field, outField) { + // prevent mutations + points = clone(points); + polygons = clone(polygons); + featureEach(points, function (pt) { + if (!pt.properties) pt.properties = {}; + featureEach(polygons, function (poly) { + if (pt.properties[outField] === undefined) { + if (booleanPointInPolygon(pt, poly)) pt.properties[outField] = poly.properties[field]; + } + }); + }); + return points; +} + +export default tag; diff --git a/packages/turf-tag/test.js b/src/tag/test.js similarity index 100% rename from packages/turf-tag/test.js rename to src/tag/test.js diff --git a/packages/turf-tag/test/tagPoints.geojson b/src/tag/test/tagPoints.geojson similarity index 100% rename from packages/turf-tag/test/tagPoints.geojson rename to src/tag/test/tagPoints.geojson diff --git a/packages/turf-tag/test/tagPolygons.geojson b/src/tag/test/tagPolygons.geojson similarity index 100% rename from packages/turf-tag/test/tagPolygons.geojson rename to src/tag/test/tagPolygons.geojson diff --git a/src/tesselate/bench.js b/src/tesselate/bench.js new file mode 100644 index 0000000000..727f584666 --- /dev/null +++ b/src/tesselate/bench.js @@ -0,0 +1,16 @@ +import Benchmark from 'benchmark'; +import { polygon } from '../helpers'; +import tesselate from './'; + +var poly = polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); + +/** + * Benchmark Results + * + */ +const suite = new Benchmark.Suite('turf-tesselate'); +suite + .add('polygon', () => turf.tesselate(poly)) + .on('cycle', e => console.log(String(e.target))) + .on('complete', () => {}) + .run(); diff --git a/packages/turf-tesselate/index.d.ts b/src/tesselate/index.d.ts similarity index 100% rename from packages/turf-tesselate/index.d.ts rename to src/tesselate/index.d.ts diff --git a/src/tesselate/index.js b/src/tesselate/index.js new file mode 100644 index 0000000000..3ff39d3cc9 --- /dev/null +++ b/src/tesselate/index.js @@ -0,0 +1,76 @@ +import earcut from './lib/earcut'; +import { polygon } from '../helpers'; + +/** + * Tesselates a {@link Feature} into a {@link FeatureCollection} of triangles + * using [earcut](https://github.com/mapbox/earcut). + * + * @name tesselate + * @param {Feature} poly the polygon to tesselate + * @returns {FeatureCollection} a geometrycollection feature + * @example + * var poly = turf.polygon([[[11, 0], [22, 4], [31, 0], [31, 11], [21, 15], [11, 11], [11, 0]]]); + * var triangles = turf.tesselate(poly); + * + * //addToMap + * var addToMap = [poly, triangles] + */ +function tesselate(poly) { + if (!poly.geometry || (poly.geometry.type !== 'Polygon' && poly.geometry.type !== 'MultiPolygon')) { + throw new Error('input must be a Polygon or MultiPolygon'); + } + + var fc = {type: 'FeatureCollection', features: []}; + + if (poly.geometry.type === 'Polygon') { + fc.features = processPolygon(poly.geometry.coordinates); + } else { + poly.geometry.coordinates.forEach(function (coordinates) { + fc.features = fc.features.concat(processPolygon(coordinates)); + }); + } + + return fc; +} + +function processPolygon(coordinates) { + var data = flattenCoords(coordinates); + var dim = 2; + var result = earcut(data.vertices, data.holes, dim); + + var features = []; + var vertices = []; + + result.forEach(function (vert, i) { + var index = result[i]; + vertices.push([data.vertices[index * dim], data.vertices[index * dim + 1]]); + }); + + for (var i = 0; i < vertices.length; i += 3) { + var coords = vertices.slice(i, i + 3); + coords.push(vertices[i]); + features.push(polygon([coords])); + } + + return features; +} + +function flattenCoords(data) { + var dim = data[0][0].length, + result = {vertices: [], holes: [], dimensions: dim}, + holeIndex = 0; + + for (var i = 0; i < data.length; i++) { + for (var j = 0; j < data[i].length; j++) { + for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]); + } + if (i > 0) { + holeIndex += data[i - 1].length; + result.holes.push(holeIndex); + } + } + + return result; +} + +export default tesselate; diff --git a/src/tesselate/lib/earcut.js b/src/tesselate/lib/earcut.js new file mode 100644 index 0000000000..ed2fd15dea --- /dev/null +++ b/src/tesselate/lib/earcut.js @@ -0,0 +1,647 @@ +// imported from https://github.com/mapbox/earcut + +export default function earcut(data, holeIndices, dim) { + + dim = dim || 2; + + var hasHoles = holeIndices && holeIndices.length, + outerLen = hasHoles ? holeIndices[0] * dim : data.length, + outerNode = linkedList(data, 0, outerLen, dim, true), + triangles = []; + + if (!outerNode) return triangles; + + var minX, minY, maxX, maxY, x, y, invSize; + + if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); + + // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox + if (data.length > 80 * dim) { + minX = maxX = data[0]; + minY = maxY = data[1]; + + for (var i = dim; i < outerLen; i += dim) { + x = data[i]; + y = data[i + 1]; + if (x < minX) minX = x; + if (y < minY) minY = y; + if (x > maxX) maxX = x; + if (y > maxY) maxY = y; + } + + // minX, minY and invSize are later used to transform coords into integers for z-order calculation + invSize = Math.max(maxX - minX, maxY - minY); + invSize = invSize !== 0 ? 1 / invSize : 0; + } + + earcutLinked(outerNode, triangles, dim, minX, minY, invSize); + + return triangles; +} + +// create a circular doubly linked list from polygon points in the specified winding order +function linkedList(data, start, end, dim, clockwise) { + var i, last; + + if (clockwise === (signedArea(data, start, end, dim) > 0)) { + for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last); + } else { + for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last); + } + + if (last && equals(last, last.next)) { + removeNode(last); + last = last.next; + } + + return last; +} + +// eliminate colinear or duplicate points +function filterPoints(start, end) { + if (!start) return start; + if (!end) end = start; + + var p = start, + again; + do { + again = false; + + if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { + removeNode(p); + p = end = p.prev; + if (p === p.next) break; + again = true; + + } else { + p = p.next; + } + } while (again || p !== end); + + return end; +} + +// main ear slicing loop which triangulates a polygon (given as a linked list) +function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { + if (!ear) return; + + // interlink polygon nodes in z-order + if (!pass && invSize) indexCurve(ear, minX, minY, invSize); + + var stop = ear, + prev, next; + + // iterate through ears, slicing them one by one + while (ear.prev !== ear.next) { + prev = ear.prev; + next = ear.next; + + if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) { + // cut off the triangle + triangles.push(prev.i / dim); + triangles.push(ear.i / dim); + triangles.push(next.i / dim); + + removeNode(ear); + + // skipping the next vertex leads to less sliver triangles + ear = next.next; + stop = next.next; + + continue; + } + + ear = next; + + // if we looped through the whole remaining polygon and can't find any more ears + if (ear === stop) { + // try filtering points and slicing again + if (!pass) { + earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); + + // if this didn't work, try curing all small self-intersections locally + } else if (pass === 1) { + ear = cureLocalIntersections(ear, triangles, dim); + earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); + + // as a last resort, try splitting the remaining polygon into two + } else if (pass === 2) { + splitEarcut(ear, triangles, dim, minX, minY, invSize); + } + + break; + } + } +} + +// check whether a polygon node forms a valid ear with adjacent nodes +function isEar(ear) { + var a = ear.prev, + b = ear, + c = ear.next; + + if (area(a, b, c) >= 0) return false; // reflex, can't be an ear + + // now make sure we don't have other points inside the potential ear + var p = ear.next.next; + + while (p !== ear.prev) { + if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && + area(p.prev, p, p.next) >= 0) return false; + p = p.next; + } + + return true; +} + +function isEarHashed(ear, minX, minY, invSize) { + var a = ear.prev, + b = ear, + c = ear.next; + + if (area(a, b, c) >= 0) return false; // reflex, can't be an ear + + // triangle bbox; min & max are calculated like this for speed + var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x), + minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y), + maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x), + maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y); + + // z-order range for the current triangle bbox; + var minZ = zOrder(minTX, minTY, minX, minY, invSize), + maxZ = zOrder(maxTX, maxTY, minX, minY, invSize); + + var p = ear.prevZ, + n = ear.nextZ; + + // look for points inside the triangle in both directions + while (p && p.z >= minZ && n && n.z <= maxZ) { + if (p !== ear.prev && p !== ear.next && + pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && + area(p.prev, p, p.next) >= 0) return false; + p = p.prevZ; + + if (n !== ear.prev && n !== ear.next && + pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && + area(n.prev, n, n.next) >= 0) return false; + n = n.nextZ; + } + + // look for remaining points in decreasing z-order + while (p && p.z >= minZ) { + if (p !== ear.prev && p !== ear.next && + pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && + area(p.prev, p, p.next) >= 0) return false; + p = p.prevZ; + } + + // look for remaining points in increasing z-order + while (n && n.z <= maxZ) { + if (n !== ear.prev && n !== ear.next && + pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && + area(n.prev, n, n.next) >= 0) return false; + n = n.nextZ; + } + + return true; +} + +// go through all polygon nodes and cure small local self-intersections +function cureLocalIntersections(start, triangles, dim) { + var p = start; + do { + var a = p.prev, + b = p.next.next; + + if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { + + triangles.push(a.i / dim); + triangles.push(p.i / dim); + triangles.push(b.i / dim); + + // remove two nodes involved + removeNode(p); + removeNode(p.next); + + p = start = b; + } + p = p.next; + } while (p !== start); + + return p; +} + +// try splitting polygon into two and triangulate them independently +function splitEarcut(start, triangles, dim, minX, minY, invSize) { + // look for a valid diagonal that divides the polygon into two + var a = start; + do { + var b = a.next.next; + while (b !== a.prev) { + if (a.i !== b.i && isValidDiagonal(a, b)) { + // split the polygon in two by the diagonal + var c = splitPolygon(a, b); + + // filter colinear points around the cuts + a = filterPoints(a, a.next); + c = filterPoints(c, c.next); + + // run earcut on each half + earcutLinked(a, triangles, dim, minX, minY, invSize); + earcutLinked(c, triangles, dim, minX, minY, invSize); + return; + } + b = b.next; + } + a = a.next; + } while (a !== start); +} + +// link every hole into the outer loop, producing a single-ring polygon without holes +function eliminateHoles(data, holeIndices, outerNode, dim) { + var queue = [], + i, len, start, end, list; + + for (i = 0, len = holeIndices.length; i < len; i++) { + start = holeIndices[i] * dim; + end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; + list = linkedList(data, start, end, dim, false); + if (list === list.next) list.steiner = true; + queue.push(getLeftmost(list)); + } + + queue.sort(compareX); + + // process holes from left to right + for (i = 0; i < queue.length; i++) { + eliminateHole(queue[i], outerNode); + outerNode = filterPoints(outerNode, outerNode.next); + } + + return outerNode; +} + +function compareX(a, b) { + return a.x - b.x; +} + +// find a bridge between vertices that connects hole with an outer ring and and link it +function eliminateHole(hole, outerNode) { + outerNode = findHoleBridge(hole, outerNode); + if (outerNode) { + var b = splitPolygon(outerNode, hole); + filterPoints(b, b.next); + } +} + +// David Eberly's algorithm for finding a bridge between hole and outer polygon +function findHoleBridge(hole, outerNode) { + var p = outerNode, + hx = hole.x, + hy = hole.y, + qx = -Infinity, + m; + + // find a segment intersected by a ray from the hole's leftmost point to the left; + // segment's endpoint with lesser x will be potential connection point + do { + if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { + var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); + if (x <= hx && x > qx) { + qx = x; + if (x === hx) { + if (hy === p.y) return p; + if (hy === p.next.y) return p.next; + } + m = p.x < p.next.x ? p : p.next; + } + } + p = p.next; + } while (p !== outerNode); + + if (!m) return null; + + if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint + + // look for points inside the triangle of hole point, segment intersection and endpoint; + // if there are no points found, we have a valid connection; + // otherwise choose the point of the minimum angle with the ray as connection point + + var stop = m, + mx = m.x, + my = m.y, + tanMin = Infinity, + tan; + + p = m.next; + + while (p !== stop) { + if (hx >= p.x && p.x >= mx && hx !== p.x && + pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { + + tan = Math.abs(hy - p.y) / (hx - p.x); // tangential + + if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) { + m = p; + tanMin = tan; + } + } + + p = p.next; + } + + return m; +} + +// interlink polygon nodes in z-order +function indexCurve(start, minX, minY, invSize) { + var p = start; + do { + if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize); + p.prevZ = p.prev; + p.nextZ = p.next; + p = p.next; + } while (p !== start); + + p.prevZ.nextZ = null; + p.prevZ = null; + + sortLinked(p); +} + +// Simon Tatham's linked list merge sort algorithm +// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html +function sortLinked(list) { + var i, p, q, e, tail, numMerges, pSize, qSize, + inSize = 1; + + do { + p = list; + list = null; + tail = null; + numMerges = 0; + + while (p) { + numMerges++; + q = p; + pSize = 0; + for (i = 0; i < inSize; i++) { + pSize++; + q = q.nextZ; + if (!q) break; + } + qSize = inSize; + + while (pSize > 0 || (qSize > 0 && q)) { + + if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { + e = p; + p = p.nextZ; + pSize--; + } else { + e = q; + q = q.nextZ; + qSize--; + } + + if (tail) tail.nextZ = e; + else list = e; + + e.prevZ = tail; + tail = e; + } + + p = q; + } + + tail.nextZ = null; + inSize *= 2; + + } while (numMerges > 1); + + return list; +} + +// z-order of a point given coords and inverse of the longer side of data bbox +function zOrder(x, y, minX, minY, invSize) { + // coords are transformed into non-negative 15-bit integer range + x = 32767 * (x - minX) * invSize; + y = 32767 * (y - minY) * invSize; + + x = (x | (x << 8)) & 0x00FF00FF; + x = (x | (x << 4)) & 0x0F0F0F0F; + x = (x | (x << 2)) & 0x33333333; + x = (x | (x << 1)) & 0x55555555; + + y = (y | (y << 8)) & 0x00FF00FF; + y = (y | (y << 4)) & 0x0F0F0F0F; + y = (y | (y << 2)) & 0x33333333; + y = (y | (y << 1)) & 0x55555555; + + return x | (y << 1); +} + +// find the leftmost node of a polygon ring +function getLeftmost(start) { + var p = start, + leftmost = start; + do { + if (p.x < leftmost.x) leftmost = p; + p = p.next; + } while (p !== start); + + return leftmost; +} + +// check if a point lies within a convex triangle +function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { + return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && + (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && + (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0; +} + +// check if a diagonal between two polygon nodes is valid (lies in polygon interior) +function isValidDiagonal(a, b) { + return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && + locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b); +} + +// signed area of a triangle +function area(p, q, r) { + return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); +} + +// check if two points are equal +function equals(p1, p2) { + return p1.x === p2.x && p1.y === p2.y; +} + +// check if two segments intersect +function intersects(p1, q1, p2, q2) { + if ((equals(p1, q1) && equals(p2, q2)) || + (equals(p1, q2) && equals(p2, q1))) return true; + return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 && + area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0; +} + +// check if a polygon diagonal intersects any polygon segments +function intersectsPolygon(a, b) { + var p = a; + do { + if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && + intersects(p, p.next, a, b)) return true; + p = p.next; + } while (p !== a); + + return false; +} + +// check if a polygon diagonal is locally inside the polygon +function locallyInside(a, b) { + return area(a.prev, a, a.next) < 0 ? + area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : + area(a, b, a.prev) < 0 || area(a, a.next, b) < 0; +} + +// check if the middle point of a polygon diagonal is inside the polygon +function middleInside(a, b) { + var p = a, + inside = false, + px = (a.x + b.x) / 2, + py = (a.y + b.y) / 2; + do { + if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y && + (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)) + inside = !inside; + p = p.next; + } while (p !== a); + + return inside; +} + +// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; +// if one belongs to the outer ring and another to a hole, it merges it into a single ring +function splitPolygon(a, b) { + var a2 = new Node(a.i, a.x, a.y), + b2 = new Node(b.i, b.x, b.y), + an = a.next, + bp = b.prev; + + a.next = b; + b.prev = a; + + a2.next = an; + an.prev = a2; + + b2.next = a2; + a2.prev = b2; + + bp.next = b2; + b2.prev = bp; + + return b2; +} + +// create a node and optionally link it with previous one (in a circular doubly linked list) +function insertNode(i, x, y, last) { + var p = new Node(i, x, y); + + if (!last) { + p.prev = p; + p.next = p; + + } else { + p.next = last.next; + p.prev = last; + last.next.prev = p; + last.next = p; + } + return p; +} + +function removeNode(p) { + p.next.prev = p.prev; + p.prev.next = p.next; + + if (p.prevZ) p.prevZ.nextZ = p.nextZ; + if (p.nextZ) p.nextZ.prevZ = p.prevZ; +} + +function Node(i, x, y) { + // vertex index in coordinates array + this.i = i; + + // vertex coordinates + this.x = x; + this.y = y; + + // previous and next vertex nodes in a polygon ring + this.prev = null; + this.next = null; + + // z-order curve value + this.z = null; + + // previous and next nodes in z-order + this.prevZ = null; + this.nextZ = null; + + // indicates whether this is a steiner point + this.steiner = false; +} + +// return a percentage difference between the polygon area and its triangulation area; +// used to verify correctness of triangulation +earcut.deviation = function (data, holeIndices, dim, triangles) { + var hasHoles = holeIndices && holeIndices.length; + var outerLen = hasHoles ? holeIndices[0] * dim : data.length; + + var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim)); + if (hasHoles) { + for (var i = 0, len = holeIndices.length; i < len; i++) { + var start = holeIndices[i] * dim; + var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; + polygonArea -= Math.abs(signedArea(data, start, end, dim)); + } + } + + var trianglesArea = 0; + for (i = 0; i < triangles.length; i += 3) { + var a = triangles[i] * dim; + var b = triangles[i + 1] * dim; + var c = triangles[i + 2] * dim; + trianglesArea += Math.abs( + (data[a] - data[c]) * (data[b + 1] - data[a + 1]) - + (data[a] - data[b]) * (data[c + 1] - data[a + 1])); + } + + return polygonArea === 0 && trianglesArea === 0 ? 0 : + Math.abs((trianglesArea - polygonArea) / polygonArea); +}; + +function signedArea(data, start, end, dim) { + var sum = 0; + for (var i = start, j = end - dim; i < end; i += dim) { + sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); + j = i; + } + return sum; +} + +// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts +earcut.flatten = function (data) { + var dim = data[0][0].length, + result = {vertices: [], holes: [], dimensions: dim}, + holeIndex = 0; + + for (var i = 0; i < data.length; i++) { + for (var j = 0; j < data[i].length; j++) { + for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]); + } + if (i > 0) { + holeIndex += data[i - 1].length; + result.holes.push(holeIndex); + } + } + return result; +}; \ No newline at end of file diff --git a/src/tesselate/test.js b/src/tesselate/test.js new file mode 100644 index 0000000000..f06e8bb5ac --- /dev/null +++ b/src/tesselate/test.js @@ -0,0 +1,32 @@ +import test from 'tape'; +import tesselate from '.'; +import { featureCollection as featurecollection } from '../helpers'; +import { point } from '../helpers'; + +test('tesselate', function (t) { + var polygon = {type: 'Feature', id: 'USA-CA', properties: {fips: '06', name: 'California'}, geometry: {type: 'Polygon', coordinates: [[[-123.233256, 42.006186], [-122.378853, 42.011663], [-121.037003, 41.995232], [-120.001861, 41.995232], [-119.996384, 40.264519], [-120.001861, 38.999346], [-118.71478, 38.101128], [-117.498899, 37.21934], [-116.540435, 36.501861], [-115.85034, 35.970598], [-114.634459, 35.00118], [-114.634459, 34.87521], [-114.470151, 34.710902], [-114.333228, 34.448009], [-114.136058, 34.305608], [-114.256551, 34.174162], [-114.415382, 34.108438], [-114.535874, 33.933176], [-114.497536, 33.697668], [-114.524921, 33.54979], [-114.727567, 33.40739], [-114.661844, 33.034958], [-114.524921, 33.029481], [-114.470151, 32.843265], [-114.524921, 32.755634], [-114.72209, 32.717295], [-116.04751, 32.624187], [-117.126467, 32.536556], [-117.24696, 32.668003], [-117.252437, 32.876127], [-117.329114, 33.122589], [-117.471515, 33.297851], [-117.7837, 33.538836], [-118.183517, 33.763391], [-118.260194, 33.703145], [-118.413548, 33.741483], [-118.391641, 33.840068], [-118.566903, 34.042715], [-118.802411, 33.998899], [-119.218659, 34.146777], [-119.278905, 34.26727], [-119.558229, 34.415147], [-119.875891, 34.40967], [-120.138784, 34.475393], [-120.472878, 34.448009], [-120.64814, 34.579455], [-120.609801, 34.858779], [-120.670048, 34.902595], [-120.631709, 35.099764], [-120.894602, 35.247642], [-120.905556, 35.450289], [-121.004141, 35.461243], [-121.168449, 35.636505], [-121.283465, 35.674843], [-121.332757, 35.784382], [-121.716143, 36.195153], [-121.896882, 36.315645], [-121.935221, 36.638785], [-121.858544, 36.6114], [-121.787344, 36.803093], [-121.929744, 36.978355], [-122.105006, 36.956447], [-122.335038, 37.115279], [-122.417192, 37.241248], [-122.400761, 37.361741], [-122.515777, 37.520572], [-122.515777, 37.783465], [-122.329561, 37.783465], [-122.406238, 38.15042], [-122.488392, 38.112082], [-122.504823, 37.931343], [-122.701993, 37.893004], [-122.937501, 38.029928], [-122.97584, 38.265436], [-123.129194, 38.451652], [-123.331841, 38.566668], [-123.44138, 38.698114], [-123.737134, 38.95553], [-123.687842, 39.032208], [-123.824765, 39.366301], [-123.764519, 39.552517], [-123.85215, 39.831841], [-124.109566, 40.105688], [-124.361506, 40.259042], [-124.410798, 40.439781], [-124.158859, 40.877937], [-124.109566, 41.025814], [-124.158859, 41.14083], [-124.065751, 41.442061], [-124.147905, 41.715908], [-124.257444, 41.781632], [-124.213628, 42.000709], [-123.233256, 42.006186]]]}}; + + var triangles = tesselate(polygon); + + t.equal(triangles.type, 'FeatureCollection', 'Polygon returns a FeatureCollection'); + t.equal(triangles.features[0].geometry.type, 'Polygon', 'contains at least 1 triangle'); + t.equal(triangles.features[0].geometry.coordinates[0].length, 4, 'triangle is valid'); + + var multipolygon = { type: 'Feature', properties: { name: 'Michigan' }, geometry: { type: 'MultiPolygon', coordinates: [[[[-88.684434, 48.115785], [-88.675628, 48.120444], [-88.676395, 48.124876], [-88.674192, 48.127165], [-88.656915, 48.139225], [-88.614026, 48.154797], [-88.578413, 48.162370], [-88.547033, 48.174891], [-88.524753, 48.165291], [-88.501088, 48.168181], [-88.491961, 48.175466], [-88.482039, 48.179915], [-88.459735, 48.183807], [-88.447236, 48.182916], [-88.422601, 48.190975], [-88.418244, 48.180370], [-88.419875, 48.170731], [-88.427373, 48.166764], [-88.449502, 48.163312], [-88.459697, 48.158551], [-88.469573, 48.152879], [-88.485700, 48.137683], [-88.511902, 48.121699], [-88.566938, 48.093719], [-88.578053, 48.084373], [-88.578395, 48.078003], [-88.575869, 48.075166], [-88.573924, 48.068861], [-88.575048, 48.064154], [-88.579784, 48.058669], [-88.670073, 48.011446], [-88.718555, 47.995134], [-88.772357, 47.981126], [-88.791959, 47.978938], [-88.832063, 47.965213], [-88.852923, 47.965322], [-88.899184, 47.953300], [-88.918029, 47.945605], [-88.923573, 47.937976], [-88.962664, 47.923512], [-88.968903, 47.909474], [-88.968903, 47.901675], [-88.957985, 47.895436], [-88.942387, 47.895436], [-88.899698, 47.902445], [-88.898986, 47.900685], [-88.911665, 47.891344], [-88.998939, 47.867490], [-89.022736, 47.858532], [-89.044463, 47.855750], [-89.056412, 47.852598], [-89.107991, 47.835705], [-89.124134, 47.828616], [-89.157738, 47.824015], [-89.190170, 47.831603], [-89.192681, 47.833430], [-89.192207, 47.841060], [-89.201812, 47.850243], [-89.234533, 47.851718], [-89.235552, 47.853774], [-89.234535, 47.855373], [-89.228507, 47.858039], [-89.246774, 47.871016], [-89.250936, 47.870377], [-89.255202, 47.876102], [-89.247127, 47.888503], [-89.226327, 47.895438], [-89.220710, 47.900850], [-89.221332, 47.908069], [-89.214499, 47.913895], [-89.179154, 47.935030], [-89.095207, 47.967922], [-89.018303, 47.992525], [-88.994163, 48.002290], [-88.940886, 48.019590], [-88.931487, 48.021637], [-88.927529, 48.019615], [-88.915032, 48.020681], [-88.895069, 48.029059], [-88.896327, 48.031801], [-88.893701, 48.034770], [-88.835714, 48.056752], [-88.816084, 48.057006], [-88.810461, 48.055247], [-88.787556, 48.063035], [-88.772077, 48.070502], [-88.771830, 48.079457], [-88.764256, 48.085189], [-88.744458, 48.092769], [-88.728198, 48.101914], [-88.705586, 48.111013], [-88.695353, 48.110549], [-88.684434, 48.115785]]], [[[-85.566441, 45.760222], [-85.549560, 45.757266], [-85.543750, 45.751413], [-85.535620, 45.750394], [-85.525237, 45.750462], [-85.506133, 45.754715], [-85.501267, 45.754415], [-85.497656, 45.746246], [-85.503758, 45.742771], [-85.508818, 45.742358], [-85.510091, 45.742888], [-85.508522, 45.744991], [-85.509040, 45.748488], [-85.515145, 45.749451], [-85.520569, 45.744745], [-85.521911, 45.739419], [-85.520803, 45.737247], [-85.510895, 45.734414], [-85.498777, 45.726291], [-85.494154, 45.705378], [-85.494016, 45.698476], [-85.502800, 45.690998], [-85.506104, 45.681148], [-85.503767, 45.670472], [-85.500451, 45.664298], [-85.490252, 45.652122], [-85.487026, 45.621211], [-85.491347, 45.609665], [-85.509276, 45.596475], [-85.518038, 45.592912], [-85.526895, 45.591590], [-85.530273, 45.589253], [-85.534064, 45.578198], [-85.541129, 45.575045], [-85.561634, 45.572213], [-85.618049, 45.582647], [-85.622741, 45.586028], [-85.630016, 45.598166], [-85.619850, 45.624547], [-85.608653, 45.632008], [-85.604521, 45.639256], [-85.604951, 45.647599], [-85.609295, 45.658067], [-85.604881, 45.681932], [-85.600842, 45.688860], [-85.590769, 45.698051], [-85.583724, 45.700796], [-85.572309, 45.711449], [-85.565132, 45.730719], [-85.564774, 45.745462], [-85.567128, 45.750419], [-85.567781, 45.757655], [-85.566441, 45.760222]]], [[[-87.590208, 45.095264], [-87.591880, 45.094689], [-87.614897, 45.100064], [-87.621609, 45.102399], [-87.627640, 45.103328], [-87.628829, 45.104039], [-87.629571, 45.105324], [-87.631535, 45.106224], [-87.636110, 45.105918], [-87.648191, 45.106368], [-87.652512, 45.108633], [-87.657135, 45.107568], [-87.659952, 45.107512], [-87.661211, 45.108279], [-87.661296, 45.112566], [-87.667102, 45.118109], [-87.671000, 45.120069], [-87.672447, 45.121294], [-87.678209, 45.130084], [-87.678511, 45.131204], [-87.676024, 45.134089], [-87.675816, 45.135059], [-87.683902, 45.144135], [-87.688425, 45.147433], [-87.692375, 45.149505], [-87.695055, 45.150522], [-87.700618, 45.151188], [-87.703492, 45.152206], [-87.707391, 45.154679], [-87.708134, 45.156004], [-87.711322, 45.158946], [-87.717945, 45.161156], [-87.723121, 45.165141], [-87.724601, 45.167452], [-87.727768, 45.169596], [-87.730866, 45.170913], [-87.735135, 45.171538], [-87.736104, 45.172244], [-87.736509, 45.173389], [-87.735210, 45.177642], [-87.741805, 45.197051], [-87.741732, 45.198201], [-87.739492, 45.202126], [-87.736339, 45.204653], [-87.727960, 45.207956], [-87.726198, 45.209391], [-87.726175, 45.212640], [-87.727276, 45.216129], [-87.726952, 45.218949], [-87.722473, 45.223309], [-87.721354, 45.226847], [-87.721935, 45.228444], [-87.724920, 45.229977], [-87.725205, 45.231539], [-87.724156, 45.233236], [-87.718264, 45.238333], [-87.717051, 45.238743], [-87.713398, 45.238564], [-87.712184, 45.239014], [-87.711339, 45.239965], [-87.711480, 45.245224], [-87.709145, 45.254649], [-87.707779, 45.258343], [-87.709137, 45.260341], [-87.703053, 45.267041], [-87.698780, 45.269420], [-87.698456, 45.272072], [-87.699492, 45.276659], [-87.698248, 45.281512], [-87.693468, 45.287675], [-87.690364, 45.290270], [-87.687578, 45.296283], [-87.687498, 45.298055], [-87.679085, 45.305841], [-87.675328, 45.307907], [-87.667423, 45.316360], [-87.665243, 45.317115], [-87.663666, 45.318257], [-87.661500, 45.321386], [-87.662029, 45.326434], [-87.661603, 45.327608], [-87.659830, 45.329144], [-87.655775, 45.330847], [-87.648126, 45.339396], [-87.647454, 45.345232], [-87.647729, 45.350721], [-87.648476, 45.352243], [-87.650661, 45.353798], [-87.653568, 45.354204], [-87.656632, 45.358617], [-87.655807, 45.362706], [-87.656624, 45.367295], [-87.657349, 45.368752], [-87.673513, 45.376946], [-87.674403, 45.378065], [-87.674550, 45.381649], [-87.675017, 45.382454], [-87.682866, 45.384950], [-87.685934, 45.388711], [-87.690281, 45.389822], [-87.693956, 45.389893], [-87.699797, 45.387927], [-87.704337, 45.385462], [-87.706767, 45.383827], [-87.708329, 45.381218], [-87.718891, 45.377462], [-87.733409, 45.364432], [-87.737801, 45.359635], [-87.738352, 45.358243], [-87.750928, 45.355037], [-87.751626, 45.354169], [-87.751452, 45.351755], [-87.754104, 45.349442], [-87.762128, 45.348401], [-87.769172, 45.351195], [-87.771384, 45.351210], [-87.773901, 45.351226], [-87.783076, 45.349725], [-87.787967, 45.352612], [-87.790324, 45.353444], [-87.800464, 45.353608], [-87.810076, 45.351269], [-87.823028, 45.352650], [-87.823554, 45.351637], [-87.824855, 45.350713], [-87.826918, 45.350538], [-87.829775, 45.352005], [-87.832612, 45.352249], [-87.835303, 45.350980], [-87.836782, 45.346451], [-87.838141, 45.345101], [-87.848368, 45.340676], [-87.850133, 45.340435], [-87.851318, 45.341346], [-87.851475, 45.342335], [-87.849899, 45.344651], [-87.850418, 45.347492], [-87.852784, 45.349497], [-87.858617, 45.350378], [-87.860871, 45.351192], [-87.863489, 45.353020], [-87.864873, 45.354767], [-87.865274, 45.355969], [-87.865675, 45.358213], [-87.867037, 45.360137], [-87.868560, 45.360537], [-87.870243, 45.360617], [-87.871204, 45.360056], [-87.871285, 45.358614], [-87.871124, 45.357011], [-87.871685, 45.355729], [-87.873529, 45.354286], [-87.879835, 45.351490], [-87.881114, 45.351278], [-87.885170, 45.351736], [-87.886949, 45.353110], [-87.888052, 45.354697], [-87.887828, 45.358122], [-87.884855, 45.362792], [-87.876862, 45.368535], [-87.871485, 45.371546], [-87.871789, 45.373557], [-87.875692, 45.377052], [-87.875424, 45.379373], [-87.873568, 45.381357], [-87.870905, 45.383116], [-87.864677, 45.385232], [-87.859418, 45.388227], [-87.856830, 45.393106], [-87.859603, 45.396409], [-87.859773, 45.397278], [-87.859131, 45.398967], [-87.850969, 45.401925], [-87.849322, 45.403872], [-87.849668, 45.409518], [-87.850533, 45.411685], [-87.851810, 45.413103], [-87.856216, 45.416101], [-87.860432, 45.423504], [-87.860127, 45.429584], [-87.861950, 45.433072], [-87.861697, 45.434473], [-87.855298, 45.441379], [-87.847429, 45.444177], [-87.844815, 45.448411], [-87.836008, 45.450877], [-87.833042, 45.453596], [-87.832456, 45.455020], [-87.827430, 45.458076], [-87.821057, 45.459955], [-87.812976, 45.464159], [-87.812971, 45.466100], [-87.811469, 45.467991], [-87.805773, 45.473139], [-87.805873, 45.474380], [-87.807388, 45.477031], [-87.806891, 45.479092], [-87.798960, 45.485147], [-87.798362, 45.486564], [-87.797824, 45.491468], [-87.796409, 45.494679], [-87.793447, 45.498372], [-87.792769, 45.499967], [-87.793215, 45.505028], [-87.798794, 45.506287], [-87.802267, 45.514233], [-87.804203, 45.524676], [-87.804720, 45.531244], [-87.804528, 45.534373], [-87.803364, 45.537016], [-87.803390, 45.538272], [-87.807159, 45.543523], [-87.813737, 45.548616], [-87.818791, 45.552100], [-87.827215, 45.555620], [-87.832296, 45.558767], [-87.832968, 45.559461], [-87.833591, 45.562529], [-87.831689, 45.568035], [-87.829346, 45.568776], [-87.813745, 45.565175], [-87.806104, 45.562863], [-87.797536, 45.562124], [-87.792372, 45.563055], [-87.790874, 45.564096], [-87.788798, 45.565947], [-87.788326, 45.567941], [-87.787292, 45.574906], [-87.787534, 45.581376], [-87.786767, 45.582830], [-87.785647, 45.583960], [-87.781255, 45.585682], [-87.777199, 45.588499], [-87.776238, 45.597797], [-87.777671, 45.609204], [-87.780845, 45.614599], [-87.792016, 45.616756], [-87.795880, 45.618846], [-87.796179, 45.622074], [-87.796983, 45.623613], [-87.804481, 45.628933], [-87.810194, 45.638732], [-87.817277, 45.643926], [-87.821818, 45.645589], [-87.824102, 45.647138], [-87.824676, 45.653211], [-87.822693, 45.656077], [-87.822425, 45.658012], [-87.823672, 45.659817], [-87.823868, 45.661920], [-87.823164, 45.662732], [-87.803290, 45.666494], [-87.798903, 45.670140], [-87.795355, 45.671334], [-87.781623, 45.673280], [-87.781007, 45.673934], [-87.780737, 45.675458], [-87.780808, 45.680349], [-87.782226, 45.683053], [-87.787727, 45.687180], [-87.801880, 45.693862], [-87.804993, 45.695796], [-87.809075, 45.699717], [-87.809181, 45.700337], [-87.805076, 45.703556], [-87.805081, 45.704974], [-87.805867, 45.706841], [-87.810144, 45.710230], [-87.812338, 45.711303], [-87.831442, 45.714938], [-87.837343, 45.716919], [-87.855480, 45.726943], [-87.864320, 45.737139], [-87.863874, 45.742660], [-87.863050, 45.743090], [-87.864141, 45.745697], [-87.868111, 45.749477], [-87.873339, 45.750439], [-87.875813, 45.753888], [-87.879812, 45.754843], [-87.882261, 45.754779], [-87.891905, 45.754055], [-87.896032, 45.752285], [-87.898363, 45.752503], [-87.900005, 45.753497], [-87.901299, 45.756553], [-87.902707, 45.757932], [-87.904657, 45.759163], [-87.905873, 45.759364], [-87.907771, 45.759280], [-87.908933, 45.758297], [-87.921999, 45.756989], [-87.926611, 45.759590], [-87.929130, 45.760364], [-87.934585, 45.758094], [-87.944113, 45.757422], [-87.954459, 45.758414], [-87.959277, 45.757367], [-87.963452, 45.758220], [-87.964725, 45.759461], [-87.963996, 45.760794], [-87.966970, 45.764021], [-87.972451, 45.766319], [-87.976835, 45.767015], [-87.986429, 45.769596], [-87.989656, 45.772025], [-87.989829, 45.772945], [-87.985597, 45.774926], [-87.983392, 45.774696], [-87.981789, 45.775081], [-87.980870, 45.776977], [-87.982617, 45.782944], [-87.987942, 45.793075], [-87.989831, 45.794827], [-87.991447, 45.795393], [-87.995876, 45.795435], [-88.001593, 45.794091], [-88.007043, 45.792192], [-88.017588, 45.792455], [-88.023600, 45.790094], [-88.027228, 45.789190], [-88.031124, 45.789233], [-88.033568, 45.789816], [-88.039729, 45.789626], [-88.040221, 45.789236], [-88.040892, 45.786452], [-88.044697, 45.783718], [-88.048514, 45.782549], [-88.050634, 45.780972], [-88.072091, 45.780261], [-88.076375, 45.781606], [-88.078361, 45.784249], [-88.079764, 45.784950], [-88.088590, 45.784697], [-88.094047, 45.785658], [-88.099616, 45.790186], [-88.103247, 45.791361], [-88.106351, 45.797573], [-88.105518, 45.798839], [-88.105355, 45.800104], [-88.107506, 45.802668], [-88.109506, 45.803584], [-88.116024, 45.804079], [-88.129461, 45.809288], [-88.131834, 45.811312], [-88.136110, 45.819029], [-88.135067, 45.821694], [-88.133640, 45.823128], [-88.127808, 45.827173], [-88.122947, 45.829565], [-88.120723, 45.832995], [-88.114267, 45.837891], [-88.111726, 45.839196], [-88.109089, 45.839492], [-88.106622, 45.841072], [-88.098326, 45.850142], [-88.088825, 45.855860], [-88.087419, 45.857459], [-88.084985, 45.862443], [-88.082590, 45.864944], [-88.081641, 45.865087], [-88.077534, 45.863825], [-88.075146, 45.864832], [-88.073134, 45.871952], [-88.073944, 45.875593], [-88.081781, 45.880516], [-88.083965, 45.881186], [-88.095841, 45.880042], [-88.100218, 45.881205], [-88.101814, 45.883504], [-88.105447, 45.896593], [-88.105981, 45.897091], [-88.106136, 45.900811], [-88.105677, 45.904387], [-88.104576, 45.906847], [-88.101973, 45.910550], [-88.099172, 45.912362], [-88.095354, 45.913895], [-88.095409, 45.915175], [-88.096496, 45.917273], [-88.102908, 45.921869], [-88.104686, 45.922121], [-88.115346, 45.922211], [-88.118507, 45.921140], [-88.121864, 45.920750], [-88.126382, 45.921499], [-88.127594, 45.922414], [-88.127430, 45.923214], [-88.126122, 45.924639], [-88.127428, 45.926153], [-88.141001, 45.930608], [-88.145928, 45.933646], [-88.146419, 45.934194], [-88.146352, 45.935314], [-88.158704, 45.939064], [-88.163105, 45.939043], [-88.163959, 45.938340], [-88.170096, 45.939470], [-88.172628, 45.941015], [-88.175532, 45.944897], [-88.178008, 45.947111], [-88.189789, 45.952208], [-88.191991, 45.952740], [-88.196316, 45.953311], [-88.197627, 45.953082], [-88.202116, 45.949836], [-88.201852, 45.945173], [-88.209585, 45.944280], [-88.211158, 45.944531], [-88.215025, 45.946976], [-88.222167, 45.948513], [-88.223773, 45.948712], [-88.227988, 45.947688], [-88.233140, 45.947405], [-88.239672, 45.948982], [-88.242518, 45.950363], [-88.244452, 45.952142], [-88.245752, 45.954147], [-88.246579, 45.956597], [-88.245937, 45.958726], [-88.246307, 45.962983], [-88.249117, 45.963663], [-88.250133, 45.963572], [-88.250133, 45.963147], [-88.254816, 45.963538], [-88.256455, 45.962739], [-88.259343, 45.959494], [-88.268390, 45.957486], [-88.283335, 45.955091], [-88.292381, 45.951115], [-88.295264, 45.951253], [-88.296968, 45.953767], [-88.300965, 45.956168], [-88.309520, 45.959369], [-88.316894, 45.960969], [-88.320531, 45.959963], [-88.326003, 45.955300], [-88.326953, 45.955071], [-88.330296, 45.956625], [-88.327872, 45.958934], [-88.328333, 45.964054], [-88.330137, 45.965951], [-88.334628, 45.968808], [-88.380183, 45.991654], [-88.385234, 45.990239], [-88.384318, 45.988113], [-88.388847, 45.982675], [-88.395308, 45.980391], [-88.399046, 45.980278], [-88.402848, 45.981194], [-88.409864, 45.979688], [-88.411077, 45.979139], [-88.414849, 45.975483], [-88.416914, 45.975323], [-88.420356, 45.976764], [-88.423044, 45.978547], [-88.422322, 45.980170], [-88.423437, 45.981930], [-88.426125, 45.984102], [-88.434060, 45.986205], [-88.435798, 45.988125], [-88.439733, 45.990456], [-88.443078, 45.990685], [-88.448751, 45.989770], [-88.450325, 45.990181], [-88.454261, 45.993426], [-88.453868, 45.996169], [-88.454361, 45.997518], [-88.458658, 45.999391], [-88.465542, 46.000685], [-88.470855, 46.001004], [-88.474695, 45.998770], [-88.475152, 45.996598], [-88.474036, 45.994655], [-88.476002, 45.992826], [-88.478984, 45.991797], [-88.486755, 45.990949], [-88.492495, 45.992157], [-88.497417, 45.995149], [-88.498108, 45.996360], [-88.496897, 45.998281], [-88.496898, 45.999012], [-88.498765, 46.000393], [-88.500133, 46.000457], [-88.505946, 46.013385], [-88.506205, 46.017134], [-88.507188, 46.018300], [-88.509516, 46.019169], [-88.514601, 46.019926], [-88.523131, 46.019518], [-88.526673, 46.020822], [-88.532414, 46.021212], [-88.533825, 46.020915], [-88.533530, 46.019932], [-88.534876, 46.018104], [-88.539011, 46.014791], [-88.541078, 46.013763], [-88.550756, 46.012896], [-88.554987, 46.014977], [-88.565485, 46.015708], [-88.571553, 46.013811], [-88.572995, 46.011799], [-88.580670, 46.006975], [-88.589000, 46.005077], [-88.589755, 46.005602], [-88.592874, 46.011590], [-88.593302, 46.014447], [-88.593860, 46.015132], [-88.598093, 46.017623], [-88.601440, 46.017599], [-88.603965, 46.016181], [-88.607438, 46.010991], [-88.611466, 46.003332], [-88.611563, 45.998810], [-88.613063, 45.990627], [-88.614176, 45.988775], [-88.616405, 45.987700], [-88.623947, 45.988633], [-88.634055, 45.987999], [-88.634842, 45.987565], [-88.635598, 45.985119], [-88.637500, 45.984960], [-88.657760, 45.989287], [-88.661312, 45.988819], [-88.662902, 45.988730], [-88.663697, 45.989084], [-88.664802, 45.989835], [-88.664360, 45.991337], [-88.663609, 45.992397], [-88.663923, 45.993242], [-88.667464, 45.995048], [-88.671267, 45.999026], [-88.670939, 45.999957], [-88.670115, 45.999957], [-88.671458, 46.005104], [-88.674606, 46.010567], [-88.679132, 46.013538], [-88.691662, 46.015435], [-88.698716, 46.017903], [-88.704687, 46.018154], [-88.710328, 46.016303], [-88.713049, 46.012668], [-88.718397, 46.013284], [-88.721319, 46.018608], [-88.721125, 46.022013], [-88.724801, 46.024503], [-88.730675, 46.026535], [-88.739994, 46.027308], [-88.746422, 46.025798], [-88.752176, 46.023584], [-88.754033, 46.022460], [-88.756295, 46.020173], [-88.758618, 46.019542], [-88.760044, 46.019815], [-88.763767, 46.021943], [-88.765208, 46.022086], [-88.766156, 46.022149], [-88.767104, 46.021896], [-88.767610, 46.021643], [-88.768305, 46.021201], [-88.768692, 46.020571], [-88.769712, 46.018968], [-88.776187, 46.015931], [-88.779915, 46.015436], [-88.782104, 46.016558], [-88.783891, 46.020934], [-88.784007, 46.022984], [-88.783635, 46.024357], [-88.778734, 46.028875], [-88.778628, 46.031271], [-88.779221, 46.031869], [-88.784411, 46.032709], [-88.791796, 46.032057], [-88.796182, 46.033712], [-88.800670, 46.030036], [-88.796242, 46.026853], [-88.795790, 46.024864], [-88.796460, 46.023605], [-88.801761, 46.023737], [-88.811948, 46.021609], [-88.815629, 46.022320], [-88.815427, 46.022954], [-88.816489, 46.023924], [-88.820592, 46.026261], [-88.831544, 46.029620], [-88.835249, 46.030330], [-88.837991, 46.030176], [-88.840584, 46.031112], [-88.843903, 46.033050], [-88.847599, 46.037161], [-88.848464, 46.038858], [-88.850270, 46.040274], [-88.943279, 46.077943], [-88.948698, 46.080205], [-88.990807, 46.097298], [-89.091630, 46.138505], [-89.125136, 46.144531], [-89.161757, 46.151816], [-89.166887, 46.152868], [-89.194508, 46.157942], [-89.201283, 46.159426], [-89.203289, 46.160020], [-89.205657, 46.160408], [-89.218156, 46.162988], [-89.219964, 46.163319], [-89.276489, 46.174047], [-89.276883, 46.174116], [-89.495723, 46.216301], [-89.533801, 46.224119], [-89.638416, 46.243804], [-89.667617, 46.249797], [-89.764506, 46.268082], [-89.908196, 46.296037], [-89.909910, 46.296402], [-89.918798, 46.297741], [-90.120489, 46.336852], [-90.121248, 46.337217], [-90.121380, 46.338131], [-90.121084, 46.338656], [-90.119468, 46.339700], [-90.118791, 46.342253], [-90.119572, 46.344180], [-90.120198, 46.345066], [-90.120614, 46.346420], [-90.119729, 46.348504], [-90.117466, 46.349487], [-90.116741, 46.350652], [-90.116844, 46.355153], [-90.118827, 46.359241], [-90.119691, 46.359755], [-90.119757, 46.359748], [-90.120973, 46.359720], [-90.122287, 46.360139], [-90.122785, 46.361259], [-90.122757, 46.362621], [-90.122923, 46.363603], [-90.126517, 46.366889], [-90.131036, 46.369199], [-90.133871, 46.371828], [-90.134663, 46.374947], [-90.134656, 46.374979], [-90.132250, 46.381249], [-90.133966, 46.382118], [-90.135253, 46.382210], [-90.139410, 46.384999], [-90.144359, 46.390255], [-90.146816, 46.397205], [-90.148347, 46.399258], [-90.152936, 46.401293], [-90.157851, 46.409291], [-90.158972, 46.413769], [-90.158241, 46.420485], [-90.158603, 46.422656], [-90.163422, 46.434605], [-90.166526, 46.437576], [-90.166909, 46.439311], [-90.166919, 46.439851], [-90.174556, 46.439656], [-90.177860, 46.440548], [-90.179212, 46.453090], [-90.180336, 46.456746], [-90.189162, 46.459054], [-90.190749, 46.460173], [-90.193294, 46.463143], [-90.192005, 46.465611], [-90.189426, 46.467004], [-90.188633, 46.468101], [-90.188996, 46.469015], [-90.193394, 46.472487], [-90.201727, 46.476074], [-90.204009, 46.478175], [-90.211753, 46.490351], [-90.214843, 46.498181], [-90.214866, 46.499947], [-90.216594, 46.501759], [-90.220532, 46.503403], [-90.222351, 46.503380], [-90.228735, 46.501573], [-90.230324, 46.501732], [-90.231020, 46.503354], [-90.230921, 46.504656], [-90.229402, 46.507992], [-90.230363, 46.509705], [-90.231587, 46.509842], [-90.236283, 46.507121], [-90.243395, 46.505245], [-90.246043, 46.504832], [-90.248194, 46.505357], [-90.257160, 46.504716], [-90.258650, 46.503483], [-90.260504, 46.502822], [-90.263018, 46.502777], [-90.265269, 46.503829], [-90.265143, 46.505089], [-90.265143, 46.506222], [-90.266528, 46.507356], [-90.268480, 46.507167], [-90.270180, 46.507356], [-90.270684, 46.508237], [-90.270558, 46.509560], [-90.270432, 46.510756], [-90.270422, 46.511690], [-90.274721, 46.515416], [-90.271971, 46.519756], [-90.272599, 46.521127], [-90.277131, 46.524487], [-90.278356, 46.523847], [-90.278920, 46.522271], [-90.283423, 46.518868], [-90.285707, 46.518846], [-90.292854, 46.520972], [-90.294311, 46.519876], [-90.294411, 46.518848], [-90.298284, 46.517820], [-90.303546, 46.517432], [-90.306558, 46.518484], [-90.307716, 46.518392], [-90.312581, 46.517113], [-90.313839, 46.516199], [-90.313894, 46.516199], [-90.316983, 46.517319], [-90.317777, 46.521637], [-90.314434, 46.523784], [-90.311886, 46.528695], [-90.310329, 46.536852], [-90.310859, 46.539365], [-90.320428, 46.546287], [-90.324699, 46.545602], [-90.326686, 46.546150], [-90.328044, 46.548046], [-90.327548, 46.550262], [-90.331887, 46.553278], [-90.336921, 46.554076], [-90.344338, 46.552087], [-90.347514, 46.547083], [-90.349462, 46.538080], [-90.350121, 46.537337], [-90.351580, 46.537074], [-90.353534, 46.537553], [-90.355689, 46.540317], [-90.357014, 46.540591], [-90.357676, 46.540271], [-90.361600, 46.541434], [-90.369964, 46.540549], [-90.374461, 46.539212], [-90.387228, 46.533663], [-90.393320, 46.532615], [-90.395272, 46.533941], [-90.395568, 46.536317], [-90.398742, 46.542738], [-90.400041, 46.544384], [-90.400429, 46.544384], [-90.402019, 46.544384], [-90.405593, 46.547584], [-90.407775, 46.552246], [-90.414464, 46.557320], [-90.414596, 46.557320], [-90.415620, 46.563169], [-90.418136, 46.566094], [-90.348407, 46.600635], [-90.327626, 46.607744], [-90.306609, 46.602741], [-90.265294, 46.618516], [-90.237609, 46.624485], [-90.164026, 46.645515], [-90.100695, 46.655132], [-90.045420, 46.668272], [-90.028392, 46.674390], [-89.996034, 46.693225], [-89.985817, 46.703190], [-89.973803, 46.710322], [-89.957101, 46.716929], [-89.918466, 46.740324], [-89.892355, 46.763088], [-89.848652, 46.795711], [-89.831956, 46.804053], [-89.790663, 46.818469], [-89.720277, 46.830413], [-89.673375, 46.833229], [-89.660625, 46.831056], [-89.642255, 46.825340], [-89.634938, 46.819488], [-89.619329, 46.818890], [-89.569808, 46.831859], [-89.535683, 46.835878], [-89.513938, 46.841835], [-89.499080, 46.841621], [-89.491252, 46.838448], [-89.471540, 46.837359], [-89.437047, 46.839512], [-89.415154, 46.843983], [-89.372032, 46.857386], [-89.249143, 46.903326], [-89.227914, 46.912954], [-89.201511, 46.931149], [-89.168244, 46.965536], [-89.142595, 46.984859], [-89.128698, 46.992599], [-89.118339, 46.994220], [-89.113158, 46.989356], [-89.106277, 46.986480], [-89.086742, 46.985298], [-89.063103, 46.988522], [-89.039490, 46.999419], [-89.028930, 47.001140], [-89.022994, 46.995120], [-88.998417, 46.995314], [-88.987197, 46.997239], [-88.972802, 47.002096], [-88.959409, 47.008496], [-88.944045, 47.020129], [-88.924492, 47.042156], [-88.914189, 47.059246], [-88.903706, 47.086161], [-88.889140, 47.100575], [-88.855372, 47.114263], [-88.848176, 47.115065], [-88.814834, 47.141399], [-88.789813, 47.150925], [-88.778022, 47.150465], [-88.764351, 47.155762], [-88.729688, 47.185834], [-88.699660, 47.204831], [-88.672395, 47.219137], [-88.656359, 47.225624], [-88.640323, 47.226784], [-88.623579, 47.232352], [-88.609830, 47.238894], [-88.584912, 47.242361], [-88.573997, 47.245989], [-88.500780, 47.293503], [-88.477733, 47.313460], [-88.470484, 47.327653], [-88.459262, 47.339903], [-88.418673, 47.371188], [-88.389459, 47.384431], [-88.324083, 47.403542], [-88.303447, 47.412204], [-88.285195, 47.422392], [-88.239161, 47.429969], [-88.227446, 47.435093], [-88.218424, 47.441585], [-88.216977, 47.445493], [-88.217822, 47.448738], [-88.181820, 47.457657], [-88.150571, 47.460093], [-88.139651, 47.462693], [-88.085252, 47.468961], [-88.076388, 47.467752], [-88.049326, 47.469785], [-88.048226, 47.470008], [-88.048077, 47.474973], [-88.040291, 47.475999], [-87.978934, 47.479420], [-87.929269, 47.478737], [-87.902416, 47.477045], [-87.898036, 47.474872], [-87.816958, 47.471998], [-87.801184, 47.473301], [-87.756739, 47.460717], [-87.730804, 47.449112], [-87.715942, 47.439816], [-87.710471, 47.406200], [-87.712421, 47.401400], [-87.721274, 47.401032], [-87.742417, 47.405823], [-87.751380, 47.405066], [-87.759057, 47.403013], [-87.765019, 47.398652], [-87.800294, 47.392148], [-87.815371, 47.384790], [-87.827115, 47.386160], [-87.834822, 47.390478], [-87.848252, 47.394864], [-87.856700, 47.395387], [-87.882245, 47.395588], [-87.941613, 47.390073], [-87.957058, 47.387260], [-87.965063, 47.374430], [-87.965598, 47.368645], [-87.962567, 47.362543], [-87.954796, 47.356809], [-87.947397, 47.355461], [-87.938787, 47.346777], [-87.938250, 47.342299], [-87.943360, 47.335899], [-87.946352, 47.334254], [-87.958386, 47.334435], [-87.968604, 47.332582], [-87.989133, 47.322633], [-88.016478, 47.306275], [-88.054849, 47.298240], [-88.060090, 47.295796], [-88.071476, 47.286768], [-88.096851, 47.261351], [-88.108833, 47.259131], [-88.117456, 47.255174], [-88.131943, 47.239554], [-88.163059, 47.216278], [-88.194218, 47.209242], [-88.204849, 47.210498], [-88.212361, 47.209423], [-88.228987, 47.199042], [-88.236892, 47.189236], [-88.242006, 47.174767], [-88.242660, 47.158426], [-88.239470, 47.151137], [-88.236721, 47.149287], [-88.231797, 47.149609], [-88.232164, 47.145975], [-88.239895, 47.139436], [-88.247628, 47.135981], [-88.249571, 47.136231], [-88.250785, 47.140209], [-88.255303, 47.143640], [-88.262972, 47.145174], [-88.272017, 47.143511], [-88.281701, 47.138212], [-88.289040, 47.129689], [-88.289543, 47.126604], [-88.287870, 47.125374], [-88.287173, 47.120420], [-88.288347, 47.114547], [-88.297625, 47.098505], [-88.340052, 47.080494], [-88.346709, 47.079372], [-88.349952, 47.076377], [-88.353191, 47.069063], [-88.353952, 47.058047], [-88.359054, 47.039739], [-88.367624, 47.019213], [-88.373966, 47.012262], [-88.385606, 47.004522], [-88.404498, 46.983353], [-88.411145, 46.977984], [-88.443901, 46.972251], [-88.448570, 46.946769], [-88.455404, 46.923321], [-88.475859, 46.886042], [-88.477935, 46.850560], [-88.483748, 46.831727], [-88.482579, 46.826197], [-88.473342, 46.806226], [-88.462349, 46.786711], [-88.438427, 46.786714], [-88.433835, 46.793502], [-88.415225, 46.811715], [-88.381410, 46.838466], [-88.382204, 46.844477], [-88.382052, 46.845437], [-88.390135, 46.851595], [-88.404008, 46.848331], [-88.389727, 46.867100], [-88.372591, 46.872812], [-88.375855, 46.863428], [-88.369848, 46.857568], [-88.368767, 46.857313], [-88.360868, 46.856202], [-88.351940, 46.857028], [-88.310290, 46.889748], [-88.281244, 46.906632], [-88.261593, 46.915516], [-88.244437, 46.929612], [-88.167227, 46.958855], [-88.155374, 46.965069], [-88.143688, 46.966665], [-88.132876, 46.962204], [-88.150114, 46.943630], [-88.187522, 46.918999], [-88.175197, 46.904580], [-88.161913, 46.904941], [-88.126927, 46.909840], [-88.101315, 46.917207], [-88.081870, 46.920458], [-88.065192, 46.918563], [-88.032408, 46.908890], [-88.004298, 46.906982], [-87.986113, 46.905957], [-87.956000, 46.909051], [-87.900339, 46.909686], [-87.874538, 46.892578], [-87.846195, 46.883905], [-87.841228, 46.884363], [-87.827162, 46.889713], [-87.816794, 46.891154], [-87.813226, 46.888023], [-87.793194, 46.880822], [-87.782461, 46.879859], [-87.776930, 46.876726], [-87.776313, 46.872591], [-87.778752, 46.870422], [-87.776804, 46.866823], [-87.765989, 46.861316], [-87.755868, 46.860453], [-87.746646, 46.865427], [-87.741014, 46.865247], [-87.734870, 46.850120], [-87.736732, 46.847216], [-87.734325, 46.836955], [-87.731522, 46.831196], [-87.727358, 46.827656], [-87.713737, 46.825534], [-87.694590, 46.827182], [-87.685698, 46.832530], [-87.687930, 46.839159], [-87.687164, 46.841742], [-87.680668, 46.842496], [-87.674541, 46.836964], [-87.673177, 46.827593], [-87.674345, 46.824050], [-87.672015, 46.820415], [-87.662261, 46.815157], [-87.651510, 46.812411], [-87.641887, 46.813733], [-87.633300, 46.812107], [-87.628081, 46.805157], [-87.607988, 46.788408], [-87.595307, 46.782950], [-87.590767, 46.753009], [-87.582745, 46.730527], [-87.573203, 46.720471], [-87.523308, 46.688488], [-87.524444, 46.677586], [-87.503025, 46.647497], [-87.492860, 46.642561], [-87.467965, 46.635623], [-87.466537, 46.631555], [-87.467563, 46.626228], [-87.464108, 46.614811], [-87.451368, 46.605923], [-87.442612, 46.602776], [-87.411167, 46.601669], [-87.403275, 46.595215], [-87.383961, 46.593070], [-87.381649, 46.580059], [-87.392974, 46.572523], [-87.392828, 46.570852], [-87.382206, 46.553681], [-87.375613, 46.547140], [-87.390300, 46.542577], [-87.393985, 46.533183], [-87.389290, 46.524472], [-87.381349, 46.517292], [-87.366767, 46.507303], [-87.351071, 46.500749], [-87.310755, 46.492017], [-87.258732, 46.488255], [-87.202404, 46.490827], [-87.175065, 46.497548], [-87.127440, 46.494014], [-87.107559, 46.496124], [-87.098760, 46.503609], [-87.077279, 46.515339], [-87.046022, 46.519956], [-87.029892, 46.525599], [-87.017136, 46.533550], [-87.008724, 46.532723], [-86.976958, 46.526581], [-86.964534, 46.516549], [-86.962842, 46.509646], [-86.946980, 46.484567], [-86.946218, 46.479059], [-86.949526, 46.476315], [-86.947077, 46.472064], [-86.927725, 46.464566], [-86.903742, 46.466138], [-86.889094, 46.458499], [-86.883976, 46.450976], [-86.883919, 46.441514], [-86.875151, 46.437280], [-86.850111, 46.434114], [-86.837448, 46.434186], [-86.816026, 46.437892], [-86.810967, 46.449663], [-86.808817, 46.460611], [-86.803557, 46.466669], [-86.787905, 46.477729], [-86.768516, 46.479072], [-86.750157, 46.479109], [-86.735929, 46.475231], [-86.731096, 46.471760], [-86.730829, 46.468057], [-86.710573, 46.444908], [-86.703230, 46.439378], [-86.698139, 46.438624], [-86.686412, 46.454965], [-86.688816, 46.463152], [-86.686468, 46.471655], [-86.683819, 46.498079], [-86.696001, 46.503160], [-86.701929, 46.511571], [-86.709325, 46.543914], [-86.695645, 46.555026], [-86.678182, 46.561039], [-86.675764, 46.557061], [-86.670927, 46.556489], [-86.656479, 46.558453], [-86.652865, 46.560555], [-86.627380, 46.533710], [-86.629086, 46.518144], [-86.632109, 46.508865], [-86.634530, 46.504523], [-86.641088, 46.500438], [-86.645528, 46.492039], [-86.646393, 46.485776], [-86.636671, 46.478298], [-86.627441, 46.477540], [-86.620603, 46.483873], [-86.618061, 46.489452], [-86.612173, 46.493295], [-86.609393, 46.492976], [-86.606932, 46.478531], [-86.609039, 46.470239], [-86.586168, 46.463324], [-86.557731, 46.487434], [-86.524959, 46.505381], [-86.495054, 46.524874], [-86.484003, 46.535965], [-86.481956, 46.542709], [-86.469306, 46.551422], [-86.459930, 46.551928], [-86.444390, 46.548137], [-86.437167, 46.548960], [-86.390409, 46.563194], [-86.349890, 46.578035], [-86.188024, 46.654008], [-86.161681, 46.669475], [-86.138295, 46.672935], [-86.119862, 46.657256], [-86.112126, 46.655044], [-86.099843, 46.654615], [-86.074219, 46.657799], [-86.036969, 46.667627], [-85.995044, 46.673676], [-85.953670, 46.676869], [-85.924047, 46.684733], [-85.877908, 46.690914], [-85.841057, 46.688896], [-85.794923, 46.681083], [-85.750606, 46.677368], [-85.714415, 46.677156], [-85.668753, 46.680404], [-85.624573, 46.678862], [-85.587345, 46.674627], [-85.542517, 46.674263], [-85.509510, 46.675786], [-85.482096, 46.680432], [-85.369805, 46.713754], [-85.289846, 46.744644], [-85.256860, 46.753380], [-85.173042, 46.763634], [-85.063556, 46.757856], [-85.036286, 46.760435], [-85.009240, 46.769224], [-84.989497, 46.772403], [-84.964652, 46.772845], [-84.954009, 46.771362], [-84.951580, 46.769488], [-84.987539, 46.745483], [-85.007616, 46.728339], [-85.020159, 46.712463], [-85.027513, 46.697451], [-85.030078, 46.684769], [-85.028291, 46.675125], [-85.035504, 46.625021], [-85.037056, 46.600995], [-85.035476, 46.581547], [-85.031507, 46.568703], [-85.029594, 46.554419], [-85.027374, 46.553756], [-85.025491, 46.546397], [-85.027083, 46.543038], [-85.045534, 46.537694], [-85.052954, 46.532827], [-85.056133, 46.526520], [-85.054943, 46.514750], [-85.049847, 46.503963], [-85.033766, 46.487670], [-85.025598, 46.483028], [-85.015211, 46.479712], [-84.969464, 46.476290], [-84.955307, 46.480269], [-84.947269, 46.487399], [-84.937145, 46.489252], [-84.934432, 46.480315], [-84.921931, 46.469962], [-84.915184, 46.467515], [-84.893423, 46.465406], [-84.875070, 46.466781], [-84.861448, 46.469930], [-84.849767, 46.460245], [-84.843907, 46.448661], [-84.829491, 46.444071], [-84.800101, 46.446219], [-84.769151, 46.453523], [-84.723338, 46.468266], [-84.689672, 46.483923], [-84.678423, 46.487694], [-84.653880, 46.482250], [-84.631020, 46.484868], [-84.616489, 46.471870], [-84.607945, 46.456747], [-84.584167, 46.439410], [-84.573522, 46.427895], [-84.551496, 46.418522], [-84.503719, 46.439190], [-84.493401, 46.440313], [-84.479513, 46.432573], [-84.471848, 46.434289], [-84.462597, 46.440940], [-84.455527, 46.453897], [-84.455256, 46.462785], [-84.463322, 46.467435], [-84.445149, 46.489016], [-84.420274, 46.501077], [-84.394725, 46.499242], [-84.375040, 46.508669], [-84.373968, 46.509098], [-84.343599, 46.507713], [-84.337732, 46.505577], [-84.325371, 46.500021], [-84.293016, 46.492803], [-84.275814, 46.492821], [-84.265391, 46.494393], [-84.264266, 46.495055], [-84.254434, 46.500821], [-84.226131, 46.533920], [-84.193729, 46.539920], [-84.177428, 46.526920], [-84.166028, 46.526220], [-84.153027, 46.528320], [-84.146526, 46.531119], [-84.139426, 46.532219], [-84.128925, 46.530119], [-84.123325, 46.520919], [-84.117925, 46.517619], [-84.111225, 46.504119], [-84.125026, 46.470143], [-84.146172, 46.418520], [-84.138906, 46.372221], [-84.119122, 46.337014], [-84.106247, 46.321963], [-84.119629, 46.315013], [-84.115563, 46.268225], [-84.097766, 46.256512], [-84.108089, 46.241238], [-84.118175, 46.233968], [-84.125024, 46.232885], [-84.134652, 46.232140], [-84.145950, 46.224995], [-84.147150, 46.224184], [-84.149220, 46.223808], [-84.150725, 46.223808], [-84.151666, 46.224184], [-84.152042, 46.224937], [-84.152230, 46.226254], [-84.152499, 46.227875], [-84.159485, 46.233233], [-84.182732, 46.235450], [-84.219494, 46.231992], [-84.233117, 46.224037], [-84.249164, 46.206461], [-84.245233, 46.192571], [-84.247687, 46.179890], [-84.251424, 46.175888], [-84.221001, 46.163062], [-84.196669, 46.166150], [-84.177298, 46.183993], [-84.171640, 46.181731], [-84.125022, 46.180209], [-84.114941, 46.174114], [-84.113259, 46.168860], [-84.100126, 46.150770], [-84.095818, 46.147733], [-84.089309, 46.146432], [-84.060383, 46.146138], [-84.026536, 46.131648], [-84.031036, 46.123186], [-84.038696, 46.125620], [-84.051900, 46.119810], [-84.061329, 46.113482], [-84.069147, 46.103978], [-84.072398, 46.096690], [-84.071741, 46.092441], [-84.066257, 46.087438], [-84.051712, 46.079189], [-84.027861, 46.054784], [-84.006082, 46.044586], [-83.989526, 46.032823], [-83.963808, 46.027833], [-83.951410, 46.029042], [-83.943933, 46.031465], [-83.939012, 46.029226], [-83.935470, 46.020385], [-83.931175, 46.017871], [-83.908583, 46.011471], [-83.900535, 45.998918], [-83.896489, 45.989194], [-83.898594, 45.979530], [-83.901942, 45.972640], [-83.903923, 45.966210], [-83.916168, 45.955326], [-83.921257, 45.958075], [-83.952183, 45.965498], [-83.985141, 45.967133], [-83.996471, 45.961461], [-84.000033, 45.948452], [-84.017565, 45.959046], [-84.080071, 45.970822], [-84.090391, 45.967256], [-84.105370, 45.972948], [-84.107204, 45.977161], [-84.111174, 45.978675], [-84.140816, 45.975308], [-84.172250, 45.966072], [-84.178060, 45.969175], [-84.238174, 45.967595], [-84.254952, 45.956068], [-84.330021, 45.956247], [-84.353272, 45.941663], [-84.376429, 45.931962], [-84.428689, 45.958371], [-84.437633, 45.973750], [-84.443138, 45.977863], [-84.463128, 45.968925], [-84.480436, 45.977764], [-84.483062, 45.982242], [-84.482442, 45.985441], [-84.484009, 45.988250], [-84.507201, 45.991169], [-84.514123, 45.987242], [-84.514071, 45.971292], [-84.525052, 45.968578], [-84.532392, 45.969448], [-84.534422, 45.972762], [-84.534648, 45.978132], [-84.530444, 45.991385], [-84.533426, 46.005720], [-84.540995, 46.019501], [-84.544405, 46.022860], [-84.563891, 46.032459], [-84.581081, 46.031041], [-84.586592, 46.026584], [-84.609063, 46.026418], [-84.647609, 46.049704], [-84.656567, 46.052654], [-84.666710, 46.050486], [-84.675835, 46.046009], [-84.687322, 46.034880], [-84.692735, 46.027019], [-84.692700, 46.016963], [-84.686269, 45.979144], [-84.684368, 45.977499], [-84.685254, 45.973454], [-84.687712, 45.971260], [-84.703948, 45.970901], [-84.723039, 45.967279], [-84.730179, 45.961198], [-84.738849, 45.945792], [-84.739370, 45.941816], [-84.733041, 45.932837], [-84.718955, 45.927449], [-84.713614, 45.920366], [-84.713251, 45.916047], [-84.734002, 45.907026], [-84.721276, 45.873908], [-84.715481, 45.865934], [-84.701183, 45.853092], [-84.702295, 45.850464], [-84.706383, 45.848658], [-84.720836, 45.848107], [-84.722764, 45.846621], [-84.725734, 45.837045], [-84.746985, 45.835597], [-84.792763, 45.858691], [-84.831396, 45.872038], [-84.838472, 45.881512], [-84.837624, 45.889054], [-84.842243, 45.898194], [-84.852916, 45.900111], [-84.873254, 45.909815], [-84.879835, 45.915847], [-84.902913, 45.923673], [-84.917484, 45.930670], [-84.937134, 45.955949], [-84.973556, 45.986134], [-85.003597, 46.006130], [-85.013990, 46.010774], [-85.055581, 46.023148], [-85.088818, 46.028378], [-85.102899, 46.032488], [-85.130433, 46.046076], [-85.140835, 46.049601], [-85.152027, 46.050725], [-85.190630, 46.047622], [-85.197523, 46.044878], [-85.222511, 46.060689], [-85.266385, 46.065779], [-85.287693, 46.072276], [-85.316264, 46.086608], [-85.335911, 46.092595], [-85.356214, 46.092086], [-85.366622, 46.086778], [-85.381394, 46.082044], [-85.393832, 46.095465], [-85.412064, 46.101437], [-85.426916, 46.101964], [-85.441932, 46.095793], [-85.442293, 46.093941], [-85.440191, 46.092593], [-85.446990, 46.085164], [-85.480603, 46.096379], [-85.500100, 46.096940], [-85.512696, 46.094727], [-85.521570, 46.091257], [-85.540858, 46.079581], [-85.603785, 46.030363], [-85.617709, 46.008458], [-85.648581, 45.983695], [-85.654686, 45.973686], [-85.663966, 45.967013], [-85.697203, 45.960158], [-85.724246, 45.965409], [-85.743618, 45.965173], [-85.770938, 45.971349], [-85.790639, 45.977594], [-85.810442, 45.980087], [-85.817558, 45.979447], [-85.825819, 45.976292], [-85.832603, 45.967742], [-85.842404, 45.965247], [-85.861157, 45.968167], [-85.882442, 45.968620], [-85.893196, 45.967253], [-85.909100, 45.959074], [-85.922737, 45.948287], [-85.926213, 45.938093], [-85.926017, 45.932104], [-85.917238, 45.927782], [-85.910264, 45.922112], [-85.913769, 45.919439], [-85.920581, 45.920994], [-85.954063, 45.936629], [-85.998868, 45.950968], [-86.050956, 45.962205], [-86.072067, 45.965313], [-86.094753, 45.966704], [-86.123567, 45.964748], [-86.145714, 45.957372], [-86.150173, 45.954494], [-86.159415, 45.953765], [-86.196618, 45.963185], [-86.208255, 45.962978], [-86.220546, 45.958883], [-86.229060, 45.948570], [-86.233613, 45.945802], [-86.248008, 45.944849], [-86.254768, 45.948640], [-86.278007, 45.942057], [-86.315981, 45.915247], [-86.324232, 45.906080], [-86.332625, 45.851813], [-86.349134, 45.834160], [-86.355062, 45.805355], [-86.351658, 45.798132], [-86.363808, 45.790057], [-86.369918, 45.789254], [-86.395809, 45.789740], [-86.401656, 45.795412], [-86.415971, 45.793793], [-86.424828, 45.789747], [-86.428423, 45.785587], [-86.428946, 45.782524], [-86.427183, 45.779050], [-86.428294, 45.775620], [-86.431921, 45.767756], [-86.439661, 45.760669], [-86.455534, 45.756850], [-86.466039, 45.759741], [-86.479050, 45.757416], [-86.486028, 45.746608], [-86.496251, 45.749255], [-86.504216, 45.754230], [-86.514570, 45.752337], [-86.518281, 45.747688], [-86.523197, 45.736498], [-86.525166, 45.720797], [-86.533280, 45.710849], [-86.537258, 45.708361], [-86.541430, 45.708110], [-86.570627, 45.716412], [-86.580936, 45.711920], [-86.585847, 45.704922], [-86.584771, 45.682007], [-86.587528, 45.666456], [-86.593613, 45.665625], [-86.611306, 45.669733], [-86.620430, 45.667098], [-86.625132, 45.663819], [-86.627938, 45.659293], [-86.616972, 45.620581], [-86.604180, 45.606457], [-86.613803, 45.599583], [-86.616893, 45.606796], [-86.623870, 45.613262], [-86.633224, 45.618249], [-86.648439, 45.615992], [-86.666127, 45.621689], [-86.687208, 45.634253], [-86.688772, 45.639969], [-86.695275, 45.648175], [-86.708038, 45.649202], [-86.717828, 45.668106], [-86.718191, 45.677320], [-86.715781, 45.683949], [-86.705184, 45.690901], [-86.689102, 45.687862], [-86.676184, 45.691862], [-86.665677, 45.702217], [-86.665511, 45.709030], [-86.669263, 45.710860], [-86.671480, 45.720530], [-86.662762, 45.728964], [-86.647319, 45.732618], [-86.633138, 45.747654], [-86.634902, 45.763536], [-86.631018, 45.782019], [-86.617336, 45.783538], [-86.612137, 45.779356], [-86.597661, 45.775385], [-86.583391, 45.778242], [-86.576869, 45.788502], [-86.581071, 45.791802], [-86.581759, 45.794797], [-86.576858, 45.801473], [-86.571172, 45.805452], [-86.563392, 45.804469], [-86.557215, 45.808172], [-86.555547, 45.813499], [-86.559044, 45.822323], [-86.555186, 45.831696], [-86.549723, 45.836039], [-86.545602, 45.836495], [-86.538831, 45.840083], [-86.529208, 45.853043], [-86.528224, 45.856974], [-86.529573, 45.874974], [-86.532989, 45.882665], [-86.541464, 45.890234], [-86.553608, 45.896476], [-86.567719, 45.900500], [-86.583304, 45.898784], [-86.593184, 45.885110], [-86.603293, 45.876626], [-86.613536, 45.875982], [-86.625736, 45.868295], [-86.633168, 45.860068], [-86.632478, 45.843309], [-86.645998, 45.833888], [-86.721113, 45.845431], [-86.728520, 45.848759], [-86.742466, 45.864719], [-86.749638, 45.867796], [-86.758449, 45.867274], [-86.782080, 45.860195], [-86.784177, 45.854641], [-86.782259, 45.829950], [-86.777225, 45.827183], [-86.774612, 45.821696], [-86.773279, 45.811385], [-86.785722, 45.794517], [-86.805524, 45.791275], [-86.801476, 45.780027], [-86.821523, 45.770356], [-86.823743, 45.765486], [-86.820868, 45.760776], [-86.821814, 45.757164], [-86.838658, 45.741831], [-86.841818, 45.729051], [-86.838746, 45.722307], [-86.870392, 45.710087], [-86.876904, 45.711891], [-86.895342, 45.711464], [-86.904089, 45.709546], [-86.921060, 45.697868], [-86.944158, 45.695833], [-86.964275, 45.672761], [-86.966885, 45.675001], [-86.967315, 45.684923], [-86.969765, 45.691895], [-86.981349, 45.696463], [-86.984588, 45.705812], [-86.982413, 45.719873], [-86.977655, 45.728768], [-86.975224, 45.753130], [-86.981341, 45.766160], [-86.981624, 45.792221], [-86.988438, 45.810621], [-87.005080, 45.831718], [-87.018902, 45.838886], [-87.031435, 45.837238], [-87.039842, 45.834245], [-87.052043, 45.821879], [-87.057439, 45.812483], [-87.058844, 45.801510], [-87.058127, 45.779152], [-87.063975, 45.766510], [-87.064302, 45.758828], [-87.062406, 45.753296], [-87.055550, 45.751535], [-87.052908, 45.747983], [-87.057444, 45.736822], [-87.061721, 45.732821], [-87.070442, 45.718779], [-87.059533, 45.708497], [-87.095455, 45.701039], [-87.099401, 45.698614], [-87.099725, 45.695231], [-87.111638, 45.685905], [-87.129412, 45.681710], [-87.172241, 45.661788], [-87.196852, 45.636275], [-87.223647, 45.599338], [-87.234612, 45.588817], [-87.263488, 45.552032], [-87.288726, 45.501606], [-87.306122, 45.475513], [-87.319703, 45.464929], [-87.333147, 45.447208], [-87.334249, 45.442315], [-87.333240, 45.436897], [-87.329958, 45.431937], [-87.325834, 45.430040], [-87.327749, 45.425307], [-87.336152, 45.415360], [-87.350852, 45.407743], [-87.359512, 45.399829], [-87.364368, 45.388532], [-87.392500, 45.369028], [-87.399973, 45.349322], [-87.431684, 45.316383], [-87.437257, 45.305500], [-87.438908, 45.293405], [-87.465201, 45.273351], [-87.512336, 45.224252], [-87.548964, 45.191591], [-87.563417, 45.184070], [-87.585651, 45.166394], [-87.600796, 45.146842], [-87.609280, 45.132320], [-87.612019, 45.123377], [-87.610073, 45.114141], [-87.600120, 45.103011], [-87.590270, 45.096406], [-87.581969, 45.097206], [-87.590208, 45.095264]]], [[[-86.033174, 45.158420], [-86.005946, 45.155751], [-85.993194, 45.152805], [-85.989412, 45.151069], [-85.976803, 45.138363], [-85.976434, 45.120706], [-85.980433, 45.113046], [-85.984095, 45.087073], [-85.982799, 45.080787], [-85.977082, 45.072993], [-85.960590, 45.062223], [-85.959760, 45.058486], [-85.976883, 45.062660], [-85.997360, 45.055929], [-86.013073, 45.063774], [-86.019874, 45.071665], [-86.037129, 45.086576], [-86.052424, 45.095311], [-86.058653, 45.100776], [-86.060396, 45.104617], [-86.065016, 45.140266], [-86.059393, 45.152291], [-86.050473, 45.158418], [-86.044430, 45.159582], [-86.033174, 45.158420]]], [[[-86.093536, 45.007838], [-86.115699, 44.999093], [-86.133655, 44.996874], [-86.154824, 45.002394], [-86.156689, 45.010535], [-86.154557, 45.018102], [-86.141644, 45.040251], [-86.138095, 45.043038], [-86.117908, 45.048478], [-86.093166, 45.041492], [-86.079103, 45.030795], [-86.093451, 45.031660], [-86.097094, 45.030128], [-86.100315, 45.026240], [-86.101894, 45.022811], [-86.101214, 45.018101], [-86.093536, 45.007838]]], [[[-82.415937, 43.005555], [-82.422586, 43.000029], [-82.424206, 42.996938], [-82.424550, 42.993393], [-82.423086, 42.988728], [-82.420346, 42.984451], [-82.412965, 42.977041], [-82.416737, 42.966613], [-82.428603, 42.952001], [-82.447142, 42.937752], [-82.455027, 42.926866], [-82.464040, 42.901456], [-82.469912, 42.887459], [-82.470032, 42.881421], [-82.468220, 42.859107], [-82.468961, 42.852314], [-82.472681, 42.836784], [-82.478640, 42.825187], [-82.482045, 42.808629], [-82.481576, 42.805519], [-82.480394, 42.802272], [-82.471159, 42.784002], [-82.467394, 42.769298], [-82.467483, 42.761910], [-82.483604, 42.733624], [-82.483870, 42.717980], [-82.494491, 42.700823], [-82.510533, 42.665172], [-82.509935, 42.637294], [-82.518782, 42.613888], [-82.523337, 42.607486], [-82.548169, 42.591848], [-82.549717, 42.590338], [-82.554236, 42.583981], [-82.555938, 42.582425], [-82.569801, 42.573551], [-82.577380, 42.567078], [-82.579205, 42.565340], [-82.583996, 42.554041], [-82.589779, 42.550678], [-82.604686, 42.548592], [-82.607068, 42.548843], [-82.611059, 42.550419], [-82.616848, 42.554601], [-82.624907, 42.557229], [-82.633491, 42.557051], [-82.640916, 42.554973], [-82.642680, 42.554333], [-82.648776, 42.550401], [-82.661677, 42.541875], [-82.666596, 42.535084], [-82.679059, 42.522210], [-82.686417, 42.518597], [-82.685397, 42.528659], [-82.679522, 42.535520], [-82.670956, 42.537989], [-82.664335, 42.546244], [-82.680758, 42.557909], [-82.681036, 42.574695], [-82.688061, 42.588417], [-82.701152, 42.585991], [-82.711151, 42.590884], [-82.713042, 42.597904], [-82.700818, 42.606687], [-82.683482, 42.609433], [-82.681593, 42.618672], [-82.690124, 42.625033], [-82.689836, 42.627148], [-82.669103, 42.637225], [-82.645715, 42.631145], [-82.630922, 42.642110], [-82.626396, 42.647385], [-82.623043, 42.655951], [-82.623797, 42.665395], [-82.630851, 42.673341], [-82.635262, 42.675552], [-82.659781, 42.678618], [-82.674287, 42.687049], [-82.685500, 42.690036], [-82.700964, 42.689548], [-82.706135, 42.683578], [-82.726366, 42.682768], [-82.753317, 42.669732], [-82.765583, 42.655725], [-82.780817, 42.652232], [-82.792418, 42.655132], [-82.797318, 42.654032], [-82.813518, 42.640833], [-82.820118, 42.626333], [-82.819017, 42.616333], [-82.811017, 42.610933], [-82.789017, 42.603434], [-82.771844, 42.595517], [-82.769590, 42.593380], [-82.788612, 42.588501], [-82.788116, 42.582835], [-82.781514, 42.571634], [-82.782414, 42.564834], [-82.784514, 42.563634], [-82.789114, 42.568434], [-82.796715, 42.571034], [-82.821016, 42.570734], [-82.834216, 42.567849], [-82.845916, 42.560634], [-82.849316, 42.555734], [-82.851016, 42.548935], [-82.859316, 42.541935], [-82.874416, 42.523535], [-82.882316, 42.501035], [-82.883915, 42.471836], [-82.870347, 42.450888], [-82.886113, 42.408137], [-82.888413, 42.398237], [-82.894013, 42.389437], [-82.898413, 42.385437], [-82.915114, 42.378137], [-82.919114, 42.374437], [-82.928815, 42.359437], [-82.923970, 42.352068], [-82.945415, 42.347337], [-82.959416, 42.339638], [-82.988619, 42.332439], [-83.018320, 42.329739], [-83.064121, 42.317738], [-83.079721, 42.308638], [-83.096521, 42.290138], [-83.110922, 42.260638], [-83.128022, 42.238839], [-83.133923, 42.174740], [-83.121323, 42.125742], [-83.133511, 42.088143], [-83.157624, 42.085542], [-83.168759, 42.073601], [-83.188598, 42.066431], [-83.189115, 42.061853], [-83.186877, 42.061206], [-83.185526, 42.052243], [-83.188240, 42.031329], [-83.185858, 42.029451], [-83.170890, 42.022403], [-83.170890, 42.015185], [-83.193918, 41.997656], [-83.212479, 41.988720], [-83.216897, 41.988561], [-83.223354, 41.989191], [-83.228502, 41.987291], [-83.249204, 41.972402], [-83.257009, 41.959686], [-83.257292, 41.950745], [-83.253552, 41.944897], [-83.264550, 41.929086], [-83.270484, 41.939335], [-83.287130, 41.944397], [-83.295982, 41.944742], [-83.302904, 41.943073], [-83.315859, 41.935893], [-83.326024, 41.924961], [-83.333642, 41.907261], [-83.335961, 41.889721], [-83.341557, 41.879956], [-83.359467, 41.867849], [-83.366187, 41.865505], [-83.372445, 41.874477], [-83.381955, 41.870877], [-83.396220, 41.852965], [-83.409596, 41.830325], [-83.422316, 41.822278], [-83.434204, 41.818562], [-83.439612, 41.813162], [-83.441668, 41.808646], [-83.443364, 41.789118], [-83.437516, 41.769694], [-83.427308, 41.750214], [-83.424076, 41.740738], [-83.434360, 41.737058], [-83.451897, 41.734486], [-83.453832, 41.732647], [-83.497733, 41.731847], [-83.499733, 41.731647], [-83.503433, 41.731547], [-83.504334, 41.731547], [-83.585235, 41.729348], [-83.593835, 41.729148], [-83.595235, 41.729148], [-83.636636, 41.727849], [-83.639636, 41.727749], [-83.665937, 41.726949], [-83.685337, 41.726449], [-83.708937, 41.725150], [-83.763038, 41.723550], [-83.859541, 41.721250], [-83.880539, 41.720081], [-83.899764, 41.719961], [-83.998849, 41.716822], [-84.019373, 41.716668], [-84.134417, 41.712931], [-84.360546, 41.706621], [-84.396547, 41.705935], [-84.438067, 41.704903], [-84.749955, 41.698245], [-84.806082, 41.696089], [-84.806018, 41.707485], [-84.806042, 41.720544], [-84.806065, 41.732909], [-84.806074, 41.737603], [-84.806134, 41.743115], [-84.805883, 41.760216], [-84.818873, 41.760059], [-84.825196, 41.759990], [-84.932484, 41.759691], [-84.960860, 41.759438], [-84.961562, 41.759552], [-84.971551, 41.759527], [-84.972803, 41.759366], [-85.037817, 41.759801], [-85.039436, 41.759985], [-85.117267, 41.759700], [-85.123102, 41.759743], [-85.172230, 41.759618], [-85.196637, 41.759735], [-85.232835, 41.759839], [-85.272216, 41.759999], [-85.272951, 41.759911], [-85.273713, 41.759770], [-85.292099, 41.759962], [-85.298365, 41.760028], [-85.308140, 41.760097], [-85.318129, 41.759983], [-85.330623, 41.759982], [-85.350174, 41.759908], [-85.379133, 41.759875], [-85.427553, 41.759706], [-85.432471, 41.759684], [-85.515959, 41.759352], [-85.518251, 41.759513], [-85.607548, 41.759079], [-85.608312, 41.759193], [-85.622608, 41.759049], [-85.624987, 41.759093], [-85.632714, 41.759164], [-85.647683, 41.759125], [-85.650738, 41.759103], [-85.724534, 41.759085], [-85.749992, 41.759091], [-85.750469, 41.759090], [-85.775039, 41.759147], [-85.791363, 41.759051], [-85.872041, 41.759365], [-85.874997, 41.759341], [-85.888825, 41.759422], [-85.974901, 41.759849], [-85.974980, 41.759849], [-85.991302, 41.759949], [-86.041027, 41.760512], [-86.125060, 41.760576], [-86.125460, 41.760560], [-86.127844, 41.760592], [-86.217590, 41.760016], [-86.226070, 41.760016], [-86.265496, 41.760207], [-86.501773, 41.759553], [-86.519318, 41.759447], [-86.640044, 41.759671], [-86.641186, 41.759633], [-86.746521, 41.759982], [-86.748096, 41.759967], [-86.800611, 41.760251], [-86.800707, 41.760240], [-86.801578, 41.760240], [-86.804427, 41.760240], [-86.823628, 41.760240], [-86.824828, 41.760240], [-86.777227, 41.784740], [-86.717037, 41.819349], [-86.679355, 41.844793], [-86.619442, 41.893827], [-86.597899, 41.918291], [-86.582197, 41.942241], [-86.556421, 42.000042], [-86.501322, 42.084540], [-86.490122, 42.105139], [-86.485223, 42.118239], [-86.466262, 42.134406], [-86.404146, 42.196379], [-86.385179, 42.217279], [-86.356218, 42.254166], [-86.321803, 42.310743], [-86.297168, 42.358207], [-86.284448, 42.394563], [-86.284969, 42.401814], [-86.276878, 42.413317], [-86.261573, 42.443894], [-86.249710, 42.480212], [-86.240642, 42.540000], [-86.235280, 42.564958], [-86.228082, 42.583397], [-86.225613, 42.594765], [-86.229050, 42.637693], [-86.226638, 42.644922], [-86.216020, 42.664413], [-86.208654, 42.692090], [-86.206834, 42.719424], [-86.208309, 42.762789], [-86.210863, 42.783832], [-86.211815, 42.833236], [-86.210737, 42.859128], [-86.214138, 42.883555], [-86.216209, 42.919007], [-86.226305, 42.988284], [-86.232707, 43.015762], [-86.244277, 43.049681], [-86.250069, 43.057489], [-86.250517, 43.066993], [-86.254646, 43.083409], [-86.280756, 43.136015], [-86.316259, 43.195114], [-86.395750, 43.316225], [-86.407832, 43.338436], [-86.435124, 43.396702], [-86.448743, 43.432013], [-86.468747, 43.491963], [-86.479276, 43.515335], [-86.520205, 43.576718], [-86.529507, 43.593462], [-86.538497, 43.617501], [-86.540916, 43.633158], [-86.540787, 43.644593], [-86.538482, 43.658795], [-86.529179, 43.677889], [-86.510319, 43.698625], [-86.481854, 43.725135], [-86.461554, 43.746685], [-86.445123, 43.771564], [-86.437391, 43.789334], [-86.431043, 43.815975], [-86.431198, 43.840720], [-86.433915, 43.855608], [-86.445455, 43.889726], [-86.447915, 43.918089], [-86.463136, 43.970976], [-86.483331, 44.001179], [-86.501738, 44.021912], [-86.508827, 44.032755], [-86.514742, 44.047920], [-86.514702, 44.058119], [-86.508764, 44.067881], [-86.500453, 44.075607], [-86.446883, 44.105970], [-86.429871, 44.119782], [-86.421108, 44.129480], [-86.400645, 44.156848], [-86.380062, 44.189472], [-86.362847, 44.208113], [-86.351638, 44.229429], [-86.343793, 44.249608], [-86.327287, 44.263057], [-86.316025, 44.284210], [-86.300264, 44.308197], [-86.268710, 44.345324], [-86.251926, 44.400984], [-86.248083, 44.420946], [-86.248320, 44.434758], [-86.251843, 44.451632], [-86.251605, 44.465443], [-86.248914, 44.483004], [-86.243745, 44.488929], [-86.238743, 44.501682], [-86.223788, 44.549043], [-86.220697, 44.566742], [-86.225450, 44.594590], [-86.231828, 44.609107], [-86.253950, 44.648080], [-86.259029, 44.663654], [-86.256796, 44.686769], [-86.254996, 44.691935], [-86.248474, 44.699046], [-86.232482, 44.706050], [-86.172201, 44.720623], [-86.160268, 44.728189], [-86.121125, 44.727972], [-86.106182, 44.731088], [-86.089186, 44.741496], [-86.077933, 44.758234], [-86.073506, 44.769803], [-86.071746, 44.804717], [-86.065966, 44.821522], [-86.066031, 44.834852], [-86.071112, 44.865420], [-86.072468, 44.884788], [-86.070990, 44.895876], [-86.066745, 44.905685], [-86.058862, 44.911012], [-86.038332, 44.915696], [-86.031194, 44.907349], [-86.021513, 44.902774], [-86.009355, 44.899454], [-85.992535, 44.900026], [-85.980219, 44.906136], [-85.972824, 44.914781], [-85.967169, 44.929484], [-85.961603, 44.935567], [-85.952721, 44.940758], [-85.942099, 44.954317], [-85.938589, 44.964559], [-85.931600, 44.968788], [-85.915851, 44.968307], [-85.897626, 44.962014], [-85.891543, 44.957783], [-85.879934, 44.943305], [-85.869852, 44.939031], [-85.854304, 44.938147], [-85.836150, 44.940256], [-85.815451, 44.945631], [-85.807403, 44.949814], [-85.780439, 44.977932], [-85.778278, 44.983075], [-85.776207, 45.000574], [-85.771395, 45.015181], [-85.761943, 45.023454], [-85.746444, 45.051229], [-85.740836, 45.055575], [-85.712262, 45.065622], [-85.695715, 45.076461], [-85.681096, 45.092693], [-85.675671, 45.105540], [-85.674861, 45.116216], [-85.656024, 45.145788], [-85.618639, 45.186771], [-85.613174, 45.184624], [-85.611684, 45.181104], [-85.606963, 45.178477], [-85.593064, 45.178527], [-85.585986, 45.180381], [-85.564654, 45.192546], [-85.561809, 45.200524], [-85.551072, 45.210742], [-85.540497, 45.210169], [-85.526734, 45.189316], [-85.531461, 45.177247], [-85.536892, 45.173385], [-85.552179, 45.167352], [-85.561680, 45.158940], [-85.554083, 45.142568], [-85.558373, 45.133209], [-85.564612, 45.137498], [-85.564612, 45.147247], [-85.570178, 45.155145], [-85.573893, 45.155488], [-85.590434, 45.153175], [-85.599801, 45.149286], [-85.614319, 45.127562], [-85.609266, 45.113510], [-85.595029, 45.103962], [-85.597496, 45.094454], [-85.583198, 45.071304], [-85.573353, 45.068382], [-85.566066, 45.059201], [-85.566130, 45.043633], [-85.570160, 45.041278], [-85.573976, 45.043361], [-85.597181, 45.040547], [-85.599652, 45.021749], [-85.609123, 45.013103], [-85.621878, 45.004529], [-85.606588, 44.990662], [-85.604301, 44.990983], [-85.602356, 44.974272], [-85.602034, 44.926743], [-85.621403, 44.923123], [-85.625497, 44.921107], [-85.639842, 44.890255], [-85.645456, 44.883645], [-85.648932, 44.874010], [-85.652355, 44.849092], [-85.651435, 44.831624], [-85.641652, 44.810816], [-85.637000, 44.790078], [-85.640781, 44.775561], [-85.636097, 44.771329], [-85.627982, 44.767508], [-85.610776, 44.765160], [-85.599256, 44.765919], [-85.593571, 44.768783], [-85.590985, 44.783914], [-85.581717, 44.807784], [-85.545891, 44.864024], [-85.532931, 44.873190], [-85.530649, 44.889763], [-85.553509, 44.890924], [-85.559524, 44.888113], [-85.564509, 44.895246], [-85.539703, 44.916779], [-85.533553, 44.925762], [-85.520205, 44.960347], [-85.522100, 44.966727], [-85.520034, 44.973996], [-85.492600, 44.989834], [-85.475204, 44.991053], [-85.470462, 44.980745], [-85.464944, 44.961062], [-85.466650, 44.958844], [-85.472258, 44.959391], [-85.485740, 44.953626], [-85.491286, 44.927585], [-85.492490, 44.908220], [-85.488624, 44.901707], [-85.498007, 44.865451], [-85.502182, 44.855802], [-85.508617, 44.847872], [-85.519096, 44.845339], [-85.539924, 44.834166], [-85.555894, 44.818256], [-85.560231, 44.810072], [-85.560488, 44.789679], [-85.576566, 44.760208], [-85.571301, 44.755293], [-85.554326, 44.748744], [-85.538285, 44.746821], [-85.527216, 44.748235], [-85.504775, 44.768082], [-85.503935, 44.772951], [-85.505244, 44.781594], [-85.509251, 44.787334], [-85.499591, 44.803838], [-85.474796, 44.814959], [-85.462916, 44.825067], [-85.460445, 44.835667], [-85.425804, 44.881646], [-85.423003, 44.895019], [-85.406173, 44.911773], [-85.395800, 44.931018], [-85.378286, 44.998587], [-85.381654, 45.018407], [-85.380659, 45.046319], [-85.377586, 45.055713], [-85.366412, 45.069023], [-85.366908, 45.116938], [-85.372571, 45.126241], [-85.376948, 45.142881], [-85.380464, 45.180876], [-85.386726, 45.189497], [-85.388593, 45.235240], [-85.371593, 45.270834], [-85.355478, 45.282774], [-85.335016, 45.294027], [-85.323941, 45.303355], [-85.307646, 45.313140], [-85.294848, 45.316408], [-85.289568, 45.314052], [-85.273789, 45.315443], [-85.262996, 45.319507], [-85.255050, 45.325675], [-85.252193, 45.330863], [-85.235629, 45.339374], [-85.209673, 45.356937], [-85.196704, 45.360641], [-85.182471, 45.360824], [-85.143651, 45.370369], [-85.054805, 45.364091], [-85.043101, 45.361506], [-85.032813, 45.361251], [-85.022234, 45.366701], [-84.959119, 45.375973], [-84.915850, 45.393115], [-84.912537, 45.402828], [-84.912956, 45.409776], [-84.916165, 45.417639], [-84.922006, 45.421914], [-84.980953, 45.429382], [-84.990041, 45.427618], [-84.990785, 45.425264], [-84.983836, 45.420764], [-84.977116, 45.420035], [-84.978608, 45.418663], [-85.040936, 45.436701], [-85.069573, 45.459239], [-85.088386, 45.476928], [-85.109252, 45.521626], [-85.115479, 45.539406], [-85.119737, 45.569026], [-85.118637, 45.575175], [-85.111909, 45.585829], [-85.093525, 45.600121], [-85.079528, 45.617083], [-85.075686, 45.623688], [-85.074910, 45.629242], [-85.061488, 45.639505], [-85.015341, 45.651564], [-85.007026, 45.656360], [-85.001154, 45.661225], [-84.996336, 45.669685], [-84.992958, 45.679983], [-84.987847, 45.682997], [-84.975768, 45.683174], [-84.970950, 45.686334], [-84.943756, 45.710290], [-84.940526, 45.721832], [-84.942125, 45.728460], [-84.950840, 45.736893], [-84.982328, 45.751960], [-85.002914, 45.753940], [-85.048441, 45.760807], [-85.074563, 45.762182], [-85.077313, 45.765619], [-85.049129, 45.770431], [-85.030568, 45.769056], [-85.007410, 45.763168], [-84.995105, 45.759855], [-84.938312, 45.759892], [-84.924664, 45.756897], [-84.910398, 45.750010], [-84.866976, 45.752066], [-84.840981, 45.744751], [-84.806642, 45.746171], [-84.799558, 45.747130], [-84.788821, 45.752283], [-84.781373, 45.761080], [-84.779800, 45.769650], [-84.792337, 45.778497], [-84.793153, 45.780463], [-84.780313, 45.787224], [-84.772765, 45.789301], [-84.751571, 45.782733], [-84.742000, 45.784134], [-84.734065, 45.788205], [-84.726192, 45.786905], [-84.718904, 45.777599], [-84.715996, 45.766174], [-84.681967, 45.756197], [-84.679546, 45.749095], [-84.644822, 45.739990], [-84.604712, 45.721668], [-84.573631, 45.710381], [-84.555496, 45.702268], [-84.553311, 45.698566], [-84.538998, 45.690383], [-84.461680, 45.652404], [-84.442348, 45.654771], [-84.435415, 45.664106], [-84.427495, 45.669201], [-84.413642, 45.669427], [-84.400283, 45.663345], [-84.376403, 45.655565], [-84.329537, 45.664380], [-84.289685, 45.653296], [-84.270238, 45.644790], [-84.215268, 45.634767], [-84.196043, 45.621456], [-84.180514, 45.604639], [-84.157121, 45.585305], [-84.139462, 45.573714], [-84.128867, 45.562284], [-84.126532, 45.556616], [-84.126971, 45.542428], [-84.122309, 45.523788], [-84.116687, 45.513050], [-84.109238, 45.505171], [-84.095905, 45.497298], [-84.075792, 45.490537], [-84.056138, 45.489349], [-84.039958, 45.493733], [-84.036286, 45.496245], [-84.028813, 45.497225], [-84.009582, 45.495069], [-83.998350, 45.491158], [-83.978017, 45.494138], [-83.939261, 45.493189], [-83.909472, 45.485784], [-83.881813, 45.467907], [-83.858560, 45.446865], [-83.841543, 45.435287], [-83.806622, 45.419159], [-83.788777, 45.416415], [-83.773171, 45.417302], [-83.755569, 45.411034], [-83.737321, 45.410943], [-83.721815, 45.413304], [-83.697316, 45.396239], [-83.667934, 45.384675], [-83.643790, 45.371710], [-83.599273, 45.352561], [-83.570361, 45.347198], [-83.550268, 45.350832], [-83.546799, 45.352637], [-83.545729, 45.358397], [-83.538306, 45.358167], [-83.520258, 45.347239], [-83.514717, 45.346460], [-83.496704, 45.357536], [-83.488826, 45.355872], [-83.477794, 45.341891], [-83.445672, 45.310612], [-83.433040, 45.303688], [-83.425140, 45.296808], [-83.422389, 45.290775], [-83.401091, 45.279572], [-83.388274, 45.276916], [-83.385104, 45.274195], [-83.381743, 45.268983], [-83.388034, 45.254976], [-83.412569, 45.245807], [-83.412410, 45.238905], [-83.405914, 45.227157], [-83.384265, 45.203472], [-83.381647, 45.203357], [-83.368896, 45.182168], [-83.368046, 45.172478], [-83.363678, 45.166469], [-83.359895, 45.163020], [-83.348684, 45.161516], [-83.337822, 45.147120], [-83.316118, 45.141958], [-83.315924, 45.139992], [-83.319315, 45.137684], [-83.318442, 45.128930], [-83.307880, 45.099093], [-83.298275, 45.090483], [-83.290827, 45.069157], [-83.291346, 45.062597], [-83.280272, 45.045962], [-83.277037, 45.044767], [-83.271464, 45.038114], [-83.265896, 45.026844], [-83.271506, 45.023417], [-83.287974, 45.026462], [-83.302153, 45.032315], [-83.340257, 45.041545], [-83.357609, 45.050613], [-83.367470, 45.062268], [-83.399255, 45.070364], [-83.433798, 45.057616], [-83.442052, 45.051056], [-83.453363, 45.035331], [-83.454168, 45.031880], [-83.446342, 45.016655], [-83.435249, 45.011883], [-83.431254, 45.007998], [-83.435822, 45.000012], [-83.438948, 45.000011], [-83.450013, 44.990219], [-83.443718, 44.952247], [-83.438856, 44.940843], [-83.433032, 44.932890], [-83.425311, 44.926741], [-83.404596, 44.918761], [-83.398879, 44.906417], [-83.393960, 44.903056], [-83.352815, 44.886164], [-83.320503, 44.880571], [-83.312903, 44.884191], [-83.314966, 44.868380], [-83.321241, 44.852962], [-83.314429, 44.842220], [-83.300648, 44.829831], [-83.299736, 44.823359], [-83.290906, 44.807888], [-83.295718, 44.784516], [-83.288844, 44.765955], [-83.298287, 44.754907], [-83.297300, 44.746134], [-83.290665, 44.729265], [-83.284128, 44.721766], [-83.273393, 44.713901], [-83.276836, 44.689354], [-83.289442, 44.652968], [-83.307504, 44.629816], [-83.314517, 44.608725], [-83.315603, 44.595079], [-83.313649, 44.564588], [-83.308918, 44.548360], [-83.308471, 44.539902], [-83.318279, 44.514416], [-83.317610, 44.486058], [-83.326824, 44.444411], [-83.327171, 44.429234], [-83.324616, 44.415039], [-83.321553, 44.409119], [-83.321648, 44.404502], [-83.333757, 44.372486], [-83.335248, 44.357995], [-83.332533, 44.340464], [-83.336988, 44.332919], [-83.343738, 44.329763], [-83.352115, 44.332366], [-83.364312, 44.332590], [-83.373607, 44.327784], [-83.401822, 44.301831], [-83.414301, 44.294543], [-83.419236, 44.287800], [-83.425762, 44.272487], [-83.445176, 44.252823], [-83.465111, 44.245949], [-83.442731, 44.265361], [-83.445805, 44.273378], [-83.463049, 44.278838], [-83.479531, 44.280090], [-83.500392, 44.276610], [-83.508839, 44.273711], [-83.524817, 44.261558], [-83.537710, 44.248171], [-83.549096, 44.227282], [-83.552872, 44.210718], [-83.553834, 44.197956], [-83.567744, 44.155899], [-83.568915, 44.126734], [-83.567714, 44.119652], [-83.573071, 44.101298], [-83.588004, 44.086758], [-83.591361, 44.079237], [-83.590437, 44.069569], [-83.584090, 44.056748], [-83.601173, 44.054686], [-83.621078, 44.056186], [-83.650116, 44.052404], [-83.679654, 44.036365], [-83.687892, 44.020709], [-83.680108, 43.994196], [-83.743806, 43.991529], [-83.746779, 43.988807], [-83.763774, 43.985158], [-83.787863, 43.985279], [-83.829077, 43.989095], [-83.848276, 43.981594], [-83.854930, 43.977067], [-83.856128, 43.972632], [-83.869406, 43.960719], [-83.877694, 43.959235], [-83.885328, 43.946691], [-83.890145, 43.934672], [-83.890912, 43.923314], [-83.907388, 43.918062], [-83.916815, 43.899050], [-83.917875, 43.856509], [-83.926345, 43.787398], [-83.929375, 43.777091], [-83.945426, 43.759946], [-83.954792, 43.760932], [-83.956021, 43.759286], [-83.954347, 43.750647], [-83.939297, 43.715369], [-83.909479, 43.672622], [-83.897078, 43.664022], [-83.852076, 43.644922], [-83.844118, 43.652896], [-83.838160, 43.654384], [-83.814674, 43.643022], [-83.806774, 43.641221], [-83.778919, 43.630056], [-83.770693, 43.628691], [-83.769886, 43.634924], [-83.725793, 43.618691], [-83.703446, 43.597646], [-83.669795, 43.590790], [-83.666052, 43.591292], [-83.654192, 43.599290], [-83.618602, 43.628891], [-83.595579, 43.650249], [-83.563157, 43.684564], [-83.553707, 43.685432], [-83.549044, 43.693798], [-83.551470, 43.699901], [-83.540187, 43.708746], [-83.524837, 43.716948], [-83.515853, 43.718157], [-83.513461, 43.714607], [-83.506657, 43.710907], [-83.480070, 43.714636], [-83.470053, 43.723418], [-83.465080, 43.733843], [-83.459628, 43.740931], [-83.440171, 43.761694], [-83.438878, 43.767135], [-83.441591, 43.770175], [-83.446752, 43.771860], [-83.438311, 43.786846], [-83.426068, 43.799915], [-83.416378, 43.801034], [-83.411453, 43.805033], [-83.410663, 43.807730], [-83.428481, 43.817907], [-83.442917, 43.811033], [-83.471788, 43.789723], [-83.480725, 43.791786], [-83.448416, 43.861902], [-83.427794, 43.861215], [-83.425732, 43.849529], [-83.417483, 43.841967], [-83.404422, 43.841280], [-83.384487, 43.854340], [-83.358869, 43.857395], [-83.332270, 43.880522], [-83.331788, 43.893901], [-83.333532, 43.898520], [-83.340976, 43.904541], [-83.403047, 43.910709], [-83.400985, 43.916208], [-83.338067, 43.915687], [-83.318656, 43.917620], [-83.305690, 43.922489], [-83.282310, 43.938031], [-83.268980, 43.956132], [-83.261850, 43.969021], [-83.261530, 43.973525], [-83.227093, 43.981003], [-83.195688, 43.983137], [-83.180618, 43.982109], [-83.145407, 43.989441], [-83.134881, 43.993147], [-83.120659, 44.000950], [-83.107820, 44.003245], [-83.079297, 44.001079], [-83.066026, 44.003366], [-83.058741, 44.006224], [-83.046577, 44.015710], [-83.029868, 44.041175], [-83.024604, 44.045174], [-82.999283, 44.046510], [-82.990728, 44.048846], [-82.967439, 44.066138], [-82.958688, 44.065774], [-82.956658, 44.063306], [-82.947368, 44.062187], [-82.928884, 44.069389], [-82.915976, 44.070503], [-82.889831, 44.050952], [-82.875889, 44.045046], [-82.833103, 44.036851], [-82.793205, 44.023247], [-82.788298, 44.013712], [-82.783198, 44.009366], [-82.765018, 44.006845], [-82.746255, 43.996037], [-82.738992, 43.989506], [-82.728528, 43.972615], [-82.712235, 43.949610], [-82.709839, 43.948226], [-82.693505, 43.917980], [-82.678642, 43.883730], [-82.655450, 43.867883], [-82.643166, 43.852468], [-82.642899, 43.846419], [-82.647467, 43.844490], [-82.647784, 43.842684], [-82.644345, 43.837539], [-82.633641, 43.831224], [-82.617955, 43.768596], [-82.619079, 43.756088], [-82.617213, 43.746788], [-82.612224, 43.739771], [-82.604830, 43.678884], [-82.605783, 43.669489], [-82.600500, 43.602935], [-82.597911, 43.590016], [-82.593785, 43.581467], [-82.585654, 43.543969], [-82.565691, 43.502904], [-82.565505, 43.497063], [-82.553540, 43.464111], [-82.539517, 43.437539], [-82.538578, 43.431594], [-82.539930, 43.422378], [-82.535627, 43.368062], [-82.536794, 43.348510], [-82.530128, 43.333805], [-82.529416, 43.316243], [-82.532396, 43.305770], [-82.523086, 43.225361], [-82.519123, 43.212737], [-82.508881, 43.196748], [-82.501656, 43.161656], [-82.494194, 43.143736], [-82.490614, 43.118172], [-82.486042, 43.102486], [-82.471053, 43.087581], [-82.457221, 43.061285], [-82.422768, 43.007956], [-82.415937, 43.005555]]], [[[-83.436745, 44.021656], [-83.442245, 44.028530], [-83.441551, 44.038841], [-83.425743, 44.028530], [-83.436745, 44.021656]]], [[[-83.414047, 43.877026], [-83.427109, 43.877026], [-83.436729, 43.882526], [-83.432610, 43.885273], [-83.414047, 43.877026]]], [[[-87.600342, 47.407711], [-87.617531, 47.407711], [-87.629898, 47.415272], [-87.650520, 47.416649], [-87.623718, 47.426960], [-87.585907, 47.419399], [-87.600342, 47.407711]]], [[[-83.761154, 46.086082], [-83.784348, 46.090248], [-83.805168, 46.092033], [-83.821236, 46.091438], [-83.828964, 46.096790], [-83.828964, 46.102741], [-83.817070, 46.111069], [-83.803978, 46.109879], [-83.787323, 46.108093], [-83.774239, 46.097980], [-83.763527, 46.093815], [-83.758179, 46.090248], [-83.761154, 46.086082]]], [[[-83.973450, 46.065285], [-84.003006, 46.079033], [-84.012634, 46.087280], [-84.005760, 46.097591], [-83.987885, 46.103779], [-83.974136, 46.073532], [-83.973450, 46.065285]]], [[[-83.853355, 46.050987], [-83.858116, 46.055149], [-83.858116, 46.062885], [-83.858711, 46.067047], [-83.865845, 46.069427], [-83.871201, 46.075970], [-83.864059, 46.083702], [-83.852760, 46.085487], [-83.847404, 46.082516], [-83.840271, 46.071808], [-83.839081, 46.064072], [-83.846214, 46.051582], [-83.853355, 46.050987]]], [[[-83.749252, 46.034328], [-83.758774, 46.036114], [-83.763527, 46.043846], [-83.770180, 46.043228], [-83.773781, 46.051472], [-83.764122, 46.065857], [-83.749847, 46.065857], [-83.733192, 46.053364], [-83.732002, 46.048012], [-83.737358, 46.043846], [-83.743896, 46.035519], [-83.749252, 46.034328]]], [[[-84.638847, 45.955563], [-84.640915, 45.971375], [-84.639633, 45.977913], [-84.634041, 45.980309], [-84.613937, 45.973629], [-84.607750, 45.967918], [-84.608704, 45.964111], [-84.619171, 45.957447], [-84.638847, 45.955563]]], [[[-84.568253, 45.950787], [-84.582527, 45.958874], [-84.583954, 45.963634], [-84.579674, 45.968391], [-84.575386, 45.970299], [-84.563492, 45.967442], [-84.559212, 45.958401], [-84.564919, 45.951260], [-84.568253, 45.950787]]], [[[-83.561836, 45.912563], [-83.583054, 45.915920], [-83.632210, 45.932285], [-83.657661, 45.945461], [-83.687691, 45.935390], [-83.719429, 45.934078], [-83.732986, 45.937641], [-83.742775, 45.938004], [-83.766235, 45.935223], [-83.768852, 45.932068], [-83.786110, 45.933376], [-83.801041, 45.937580], [-83.803329, 45.943363], [-83.808144, 45.945694], [-83.822807, 45.943985], [-83.827568, 45.941235], [-83.835503, 45.941841], [-83.840866, 45.952724], [-83.846436, 45.953182], [-83.864861, 45.959465], [-83.881058, 45.968185], [-83.884827, 45.977165], [-83.873146, 45.993427], [-83.868233, 45.995075], [-83.845398, 46.025681], [-83.830147, 46.022324], [-83.818199, 46.002426], [-83.794052, 45.995800], [-83.776436, 46.004204], [-83.765274, 46.018364], [-83.765259, 46.024681], [-83.759369, 46.027191], [-83.746872, 46.024811], [-83.735573, 46.026596], [-83.727837, 46.034924], [-83.711777, 46.040279], [-83.692146, 46.039089], [-83.686195, 46.046227], [-83.679657, 46.057529], [-83.677872, 46.064667], [-83.682632, 46.071808], [-83.699883, 46.075375], [-83.719513, 46.081326], [-83.731407, 46.086678], [-83.723297, 46.093811], [-83.719788, 46.101032], [-83.703857, 46.103367], [-83.661163, 46.100258], [-83.634979, 46.103954], [-83.625557, 46.102211], [-83.615341, 46.095978], [-83.598610, 46.090084], [-83.581314, 46.089615], [-83.576088, 46.083511], [-83.572639, 46.074921], [-83.572571, 46.069897], [-83.565353, 46.061897], [-83.554062, 46.058884], [-83.547203, 46.047867], [-83.543365, 46.037197], [-83.540848, 46.021248], [-83.532913, 46.011330], [-83.494843, 45.999542], [-83.488350, 45.999542], [-83.480637, 45.996162], [-83.473946, 45.988560], [-83.473221, 45.984421], [-83.481766, 45.971874], [-83.488808, 45.968739], [-83.510620, 45.929325], [-83.517242, 45.923615], [-83.526344, 45.918636], [-83.561836, 45.912563]]], [[[-84.861969, 45.851276], [-84.881210, 45.860901], [-84.879150, 45.868462], [-84.861969, 45.860214], [-84.861969, 45.851276]]], [[[-84.617607, 45.844925], [-84.638428, 45.850872], [-84.650917, 45.859798], [-84.651512, 45.862770], [-84.645561, 45.874668], [-84.647346, 45.884186], [-84.644974, 45.885376], [-84.624153, 45.880020], [-84.602142, 45.852062], [-84.607491, 45.847900], [-84.617607, 45.844925]]], [[[-85.590889, 45.833141], [-85.595177, 45.835522], [-85.593811, 45.839809], [-85.581467, 45.841042], [-85.584709, 45.834095], [-85.590889, 45.833141]]], [[[-84.595001, 45.821129], [-84.609871, 45.825890], [-84.613441, 45.834217], [-84.612846, 45.836002], [-84.596786, 45.833622], [-84.589050, 45.827675], [-84.589645, 45.821724], [-84.595001, 45.821129]]], [[[-85.611832, 45.806015], [-85.617538, 45.810776], [-85.617538, 45.814106], [-85.612305, 45.816010], [-85.606598, 45.815060], [-85.603264, 45.813156], [-85.601837, 45.811253], [-85.611832, 45.806015]]], [[[-85.683296, 45.769455], [-85.690704, 45.769455], [-85.696259, 45.774391], [-85.691933, 45.777477], [-85.683296, 45.769455]]], [[[-85.377129, 45.769012], [-85.396172, 45.774723], [-85.394264, 45.778530], [-85.379036, 45.789951], [-85.379036, 45.802326], [-85.377129, 45.812794], [-85.370468, 45.818504], [-85.360954, 45.817554], [-85.353340, 45.806133], [-85.351433, 45.795662], [-85.359047, 45.776627], [-85.377129, 45.769012]]], [[[-85.462578, 45.765865], [-85.495575, 45.772739], [-85.507263, 45.778236], [-85.532013, 45.798172], [-85.529259, 45.818108], [-85.524445, 45.829792], [-85.496948, 45.822231], [-85.454330, 45.800236], [-85.450203, 45.796677], [-85.447830, 45.790134], [-85.450203, 45.776451], [-85.455559, 45.768719], [-85.462578, 45.765865]]], [[[-84.420113, 45.718815], [-84.431412, 45.724762], [-84.434387, 45.726547], [-84.442719, 45.726547], [-84.452827, 45.725952], [-84.472458, 45.731304], [-84.481384, 45.729523], [-84.500420, 45.736065], [-84.510529, 45.750340], [-84.512314, 45.755100], [-84.525406, 45.761047], [-84.558716, 45.793766], [-84.580727, 45.801498], [-84.588455, 45.807449], [-84.590240, 45.812801], [-84.589050, 45.816372], [-84.580727, 45.819939], [-84.571800, 45.819347], [-84.550385, 45.811016], [-84.525406, 45.808640], [-84.511124, 45.811611], [-84.504585, 45.811611], [-84.500420, 45.811016], [-84.490303, 45.804474], [-84.439148, 45.789604], [-84.433197, 45.787819], [-84.427841, 45.790195], [-84.423088, 45.792576], [-84.421303, 45.796146], [-84.423088, 45.805069], [-84.427246, 45.811611], [-84.418922, 45.811611], [-84.408211, 45.795551], [-84.402267, 45.787224], [-84.398697, 45.785439], [-84.390961, 45.785439], [-84.375496, 45.777706], [-84.357056, 45.772350], [-84.354080, 45.770565], [-84.354080, 45.767593], [-84.364197, 45.756290], [-84.371330, 45.746773], [-84.379662, 45.739635], [-84.390366, 45.734875], [-84.392151, 45.729523], [-84.399292, 45.722977], [-84.409996, 45.720005], [-84.420113, 45.718815]]], [[[-85.672188, 45.696632], [-85.696869, 45.697250], [-85.696259, 45.712063], [-85.695290, 45.724697], [-85.701813, 45.736130], [-85.688850, 45.747238], [-85.651863, 45.743141], [-85.649353, 45.722553], [-85.672188, 45.696632]]], [[[-85.843750, 45.690460], [-85.843750, 45.710209], [-85.835114, 45.711445], [-85.833260, 45.696632], [-85.843750, 45.690460]]], [[[-86.682877, 45.594818], [-86.691704, 45.595818], [-86.702019, 45.602692], [-86.712326, 45.610939], [-86.692390, 45.617126], [-86.677269, 45.613689], [-86.669022, 45.609566], [-86.665749, 45.606239], [-86.670982, 45.600529], [-86.682877, 45.594818]]], [[[-86.636894, 45.542053], [-86.648788, 45.543243], [-86.654144, 45.555737], [-86.661285, 45.574177], [-86.661285, 45.582504], [-86.658905, 45.586075], [-86.654739, 45.587856], [-86.644035, 45.585480], [-86.626190, 45.573582], [-86.620239, 45.562279], [-86.622025, 45.556332], [-86.630348, 45.546814], [-86.636894, 45.542053]]], [[[-86.660690, 45.520042], [-86.666641, 45.520042], [-86.669609, 45.524208], [-86.670204, 45.529560], [-86.667236, 45.531940], [-86.659500, 45.532536], [-86.656525, 45.525993], [-86.660690, 45.520042]]], [[[-86.715080, 45.497517], [-86.728142, 45.522949], [-86.723328, 45.520889], [-86.715767, 45.509201], [-86.715080, 45.497517]]], [[[-86.758385, 45.476204], [-86.782448, 45.487206], [-86.782448, 45.506451], [-86.774193, 45.511951], [-86.756325, 45.501640], [-86.758385, 45.476204]]], [[[-85.770958, 45.461353], [-85.792961, 45.481976], [-85.782646, 45.491596], [-85.770958, 45.487473], [-85.766838, 45.475788], [-85.770958, 45.461353]]], [[[-85.833519, 45.378174], [-85.873390, 45.421482], [-85.883011, 45.443478], [-85.858261, 45.440041], [-85.834892, 45.428356], [-85.825958, 45.404297], [-85.833519, 45.378174]]], [[[-83.322464, 45.186062], [-83.338272, 45.189499], [-83.334145, 45.199123], [-83.319710, 45.194313], [-83.322464, 45.186062]]], [[[-83.190582, 45.033356], [-83.229767, 45.039539], [-83.233894, 45.054665], [-83.231827, 45.058102], [-83.213959, 45.056728], [-83.201584, 45.046413], [-83.190582, 45.033356]]], [[[-85.582054, 44.859333], [-85.583755, 44.861454], [-85.581207, 44.869938], [-85.569328, 44.873333], [-85.569756, 44.863152], [-85.582054, 44.859333]]], [[[-83.829224, 43.662632], [-83.831284, 43.669506], [-83.821663, 43.677067], [-83.816162, 43.672943], [-83.816162, 43.666756], [-83.829224, 43.662632]]]] } }; + + var multiTriangles = tesselate(multipolygon); + + t.equal(multiTriangles.type, 'FeatureCollection', 'MultiPolygon returns a FeatureCollection'); + t.equal(multiTriangles.features[0].geometry.type, 'Polygon', 'contains at least 1 triangle'); + t.equal(multiTriangles.features[0].geometry.coordinates[0].length, 4, 'triangle is valid'); + + t.throws(function (err) { + tesselate(point([0, 0])); + }, /input must be a Polygon or MultiPolygon/); + + t.throws(function (err) { + tesselate(featurecollection([])); + }, /input must be a Polygon or MultiPolygon/); + + t.end(); +}); diff --git a/packages/turf-tin/bench.js b/src/tin/bench.js similarity index 100% rename from packages/turf-tin/bench.js rename to src/tin/bench.js diff --git a/packages/turf-tin/index.d.ts b/src/tin/index.d.ts similarity index 100% rename from packages/turf-tin/index.d.ts rename to src/tin/index.d.ts diff --git a/src/tin/index.js b/src/tin/index.js new file mode 100644 index 0000000000..79cedbf3f5 --- /dev/null +++ b/src/tin/index.js @@ -0,0 +1,265 @@ +// http://en.wikipedia.org/wiki/Delaunay_triangulation +// https://github.com/ironwallaby/delaunay +import { featureCollection, polygon } from "../helpers"; + +/** + * Takes a set of {@link Point|points} and creates a + * [Triangulated Irregular Network](http://en.wikipedia.org/wiki/Triangulated_irregular_network), + * or a TIN for short, returned as a collection of Polygons. These are often used + * for developing elevation contour maps or stepped heat visualizations. + * + * If an optional z-value property is provided then it is added as properties called `a`, `b`, + * and `c` representing its value at each of the points that represent the corners of the + * triangle. + * + * @name tin + * @param {FeatureCollection} points input points + * @param {String} [z] name of the property from which to pull z values + * This is optional: if not given, then there will be no extra data added to the derived triangles. + * @returns {FeatureCollection} TIN output + * @example + * // generate some random point data + * var points = turf.randomPoint(30, {bbox: [50, 30, 70, 50]}); + * + * // add a random property to each point between 0 and 9 + * for (var i = 0; i < points.features.length; i++) { + * points.features[i].properties.z = ~~(Math.random() * 9); + * } + * var tin = turf.tin(points, 'z'); + * + * //addToMap + * var addToMap = [tin, points] + * for (var i = 0; i < tin.features.length; i++) { + * var properties = tin.features[i].properties; + * properties.fill = '#' + properties.a + properties.b + properties.c; + * } + */ +export default function tin(points, z){ + // break down points + let isPointZ = false; + return featureCollection(triangulate(points.features.map(function (p) { + const point = { + x: p.geometry.coordinates[0], + y: p.geometry.coordinates[1], + }; + if (z) { + point.z = p.properties[z]; + } else if (p.geometry.coordinates.length === 3) { + isPointZ = true; + point.z = p.geometry.coordinates[2]; + } + return point; + })).map(function (triangle) { + + const a = [triangle.a.x, triangle.a.y]; + const b = [triangle.b.x, triangle.b.y]; + const c = [triangle.c.x, triangle.c.y]; + let properties = {}; + + // Add z coordinates to triangle points if user passed + // them in that way otherwise add it as a property. + if (isPointZ) { + a.push(triangle.a.z); + b.push(triangle.b.z); + c.push(triangle.c.z); + } else { + properties = { + a: triangle.a.z, + b: triangle.b.z, + c: triangle.c.z, + }; + } + + return polygon([[a, b, c, a]], properties); + + })); +} + +function Triangle(a, b, c) { + this.a = a; + this.b = b; + this.c = c; + + var A = b.x - a.x, + B = b.y - a.y, + C = c.x - a.x, + D = c.y - a.y, + E = A * (a.x + b.x) + B * (a.y + b.y), + F = C * (a.x + c.x) + D * (a.y + c.y), + G = 2 * (A * (c.y - b.y) - B * (c.x - b.x)), + dx, dy; + + // If the points of the triangle are collinear, then just find the + // extremes and use the midpoint as the center of the circumcircle. + this.x = (D * E - B * F) / G; + this.y = (A * F - C * E) / G; + dx = this.x - a.x; + dy = this.y - a.y; + this.r = dx * dx + dy * dy; +} + +function byX(a, b) { + return b.x - a.x; +} + +function dedup(edges) { + let j = edges.length; + let a; + let b; + let i; + let m; + let n; + + outer: + while (j) { + b = edges[--j]; + a = edges[--j]; + i = j; + while (i) { + n = edges[--i]; + m = edges[--i]; + if ((a === m && b === n) || (a === n && b === m)) { + edges.splice(j, 2); + edges.splice(i, 2); + j -= 2; + continue outer; + } + } + } +} + +function triangulate(vertices) { + // Bail if there aren't enough vertices to form any triangles. + if (vertices.length < 3) { + return []; + } + + // Ensure the vertex array is in order of descending X coordinate + // (which is needed to ensure a subquadratic runtime), and then find + // the bounding box around the points. + vertices.sort(byX); + + let i = vertices.length - 1; + const xmin = vertices[i].x; + const xmax = vertices[0].x; + let ymin = vertices[i].y; + let ymax = ymin; + const epsilon = 1e-12; + + let a; + let b; + let c; + let A; + let B; + let G; + + while (i--) { + if (vertices[i].y < ymin) { + ymin = vertices[i].y; + } + if (vertices[i].y > ymax) { + ymax = vertices[i].y; + } + } + + // Find a supertriangle, which is a triangle that surrounds all the + // vertices. This is used like something of a sentinel value to remove + // cases in the main algorithm, and is removed before we return any + // results. + + // Once found, put it in the "open" list. (The "open" list is for + // triangles who may still need to be considered; the "closed" list is + // for triangles which do not.) + let dx = xmax - xmin; + let dy = ymax - ymin; + const dmax = (dx > dy) ? dx : dy; + const xmid = (xmax + xmin) * 0.5; + const ymid = (ymax + ymin) * 0.5; + const open = [ + new Triangle({ + __sentinel: true, + x: xmid - 20 * dmax, + y: ymid - dmax, + }, { + __sentinel: true, + x: xmid, + y: ymid + 20 * dmax, + }, { + __sentinel: true, + x: xmid + 20 * dmax, + y: ymid - dmax, + }, + )]; + const closed = []; + const edges = []; + let j; + + // Incrementally add each vertex to the mesh. + i = vertices.length; + while (i--) { + // For each open triangle, check to see if the current point is + // inside it's circumcircle. If it is, remove the triangle and add + // it's edges to an edge list. + edges.length = 0; + j = open.length; + while (j--) { + // If this point is to the right of this triangle's circumcircle, + // then this triangle should never get checked again. Remove it + // from the open list, add it to the closed list, and skip. + dx = vertices[i].x - open[j].x; + if (dx > 0 && dx * dx > open[j].r) { + closed.push(open[j]); + open.splice(j, 1); + continue; + } + + // If not, skip this triangle. + dy = vertices[i].y - open[j].y; + if (dx * dx + dy * dy > open[j].r) { + continue; + } + + // Remove the triangle and add it's edges to the edge list. + edges.push( + open[j].a, open[j].b, + open[j].b, open[j].c, + open[j].c, open[j].a, + ); + open.splice(j, 1); + } + + // Remove any doubled edges. + dedup(edges); + + // Add a new triangle for each edge. + j = edges.length; + while (j) { + b = edges[--j]; + a = edges[--j]; + c = vertices[i]; + // Avoid adding colinear triangles (which have error-prone + // circumcircles) + A = b.x - a.x; + B = b.y - a.y; + G = 2 * (A * (c.y - b.y) - B * (c.x - b.x)); + if (Math.abs(G) > epsilon) { + open.push(new Triangle(a, b, c)); + } + } + } + + // Copy any remaining open triangles to the closed list, and then + // remove any triangles that share a vertex with the supertriangle. + Array.prototype.push.apply(closed, open); + + i = closed.length; + while (i--) { + if (closed[i].a.__sentinel || + closed[i].b.__sentinel || + closed[i].c.__sentinel) { + closed.splice(i, 1); + } + } + + return closed; +} diff --git a/packages/turf-tin/test.js b/src/tin/test.js similarity index 100% rename from packages/turf-tin/test.js rename to src/tin/test.js diff --git a/packages/turf-tin/test/Points.json b/src/tin/test/Points.json similarity index 100% rename from packages/turf-tin/test/Points.json rename to src/tin/test/Points.json diff --git a/packages/turf-tin/test/Tin-z.json b/src/tin/test/Tin-z.json similarity index 100% rename from packages/turf-tin/test/Tin-z.json rename to src/tin/test/Tin-z.json diff --git a/packages/turf-tin/test/Tin.json b/src/tin/test/Tin.json similarity index 100% rename from packages/turf-tin/test/Tin.json rename to src/tin/test/Tin.json diff --git a/packages/turf-transform-rotate/bench.js b/src/transform-rotate/bench.js similarity index 100% rename from packages/turf-transform-rotate/bench.js rename to src/transform-rotate/bench.js diff --git a/src/transform-rotate/index.d.ts b/src/transform-rotate/index.d.ts new file mode 100644 index 0000000000..cc42964c1c --- /dev/null +++ b/src/transform-rotate/index.d.ts @@ -0,0 +1,13 @@ +import { AllGeoJSON, Coord } from '../helpers'; + +/** + * http://turfjs.org/docs/#transformrotate + */ +export default function transformRotate( + geojson: T, + angle: number, + options?: { + pivot?: Coord, + mutate?: boolean + } +): T; \ No newline at end of file diff --git a/src/transform-rotate/index.js b/src/transform-rotate/index.js new file mode 100644 index 0000000000..05c504a112 --- /dev/null +++ b/src/transform-rotate/index.js @@ -0,0 +1,62 @@ +import centroid from '../centroid'; +import rhumbBearing from '../rhumb-bearing'; +import rhumbDistance from '../rhumb-distance'; +import rhumbDestination from '../rhumb-destination'; +import clone from '../clone'; +import { coordEach } from '../meta'; +import { getCoords } from '../invariant'; +import { isObject } from '../helpers'; + +/** + * Rotates any geojson Feature or Geometry of a specified angle, around its `centroid` or a given `pivot` point; + * all rotations follow the right-hand rule: https://en.wikipedia.org/wiki/Right-hand_rule + * + * @name transformRotate + * @param {GeoJSON} geojson object to be rotated + * @param {number} angle of rotation (along the vertical axis), from North in decimal degrees, negative clockwise + * @param {Object} [options={}] Optional parameters + * @param {Coord} [options.pivot='centroid'] point around which the rotation will be performed + * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) + * @returns {GeoJSON} the rotated GeoJSON feature + * @example + * var poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]); + * var options = {pivot: [0, 25]}; + * var rotatedPoly = turf.transformRotate(poly, 10, options); + * + * //addToMap + * var addToMap = [poly, rotatedPoly]; + * rotatedPoly.properties = {stroke: '#F00', 'stroke-width': 4}; + */ +function transformRotate(geojson, angle, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var pivot = options.pivot; + var mutate = options.mutate; + + // Input validation + if (!geojson) throw new Error('geojson is required'); + if (angle === undefined || angle === null || isNaN(angle)) throw new Error('angle is required'); + + // Shortcut no-rotation + if (angle === 0) return geojson; + + // Use centroid of GeoJSON if pivot is not provided + if (!pivot) pivot = centroid(geojson); + + // Clone geojson to avoid side effects + if (mutate === false || mutate === undefined) geojson = clone(geojson); + + // Rotate each coordinate + coordEach(geojson, function (pointCoords) { + var initialAngle = rhumbBearing(pivot, pointCoords); + var finalAngle = initialAngle + angle; + var distance = rhumbDistance(pivot, pointCoords); + var newCoords = getCoords(rhumbDestination(pivot, distance, finalAngle)); + pointCoords[0] = newCoords[0]; + pointCoords[1] = newCoords[1]; + }); + return geojson; +} + +export default transformRotate; diff --git a/src/transform-rotate/test.js b/src/transform-rotate/test.js new file mode 100644 index 0000000000..c54104ea4d --- /dev/null +++ b/src/transform-rotate/test.js @@ -0,0 +1,92 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import centroid from '../centroid'; +import truncate from '../truncate'; +import { getCoord } from '../invariant'; +import { point, lineString, featureCollection, geometryCollection } from '../helpers'; +import rotate from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('rotate', t => { + for (const {filename, name, geojson} of fixtures) { + const {angle, pivot} = geojson.properties || {}; + + const rotated = rotate(geojson, angle, {pivot: pivot}); + const result = featureCollection([colorize(truncate(rotated, {precision: 6, coordinates: 3})), geojson, makePivot(pivot, geojson)]); + + if (process.env.REGEN) write.sync(directories.out + filename, result); + t.deepEqual(result, load.sync(directories.out + filename), name); + } + + t.end(); +}); + +test('rotate -- throws', t => { + const line = lineString([[10, 10], [12, 15]]); + + t.throws(() => rotate(null, 100), /geojson is required/, 'missing geojson'); + t.throws(() => rotate(line, null), /angle is required/, 'missing angle'); + t.throws(() => rotate(line, 56, {pivot: 'notApoint'}), /coord must be GeoJSON Point or an Array of numbers/, 'coord must be GeoJSON Point or an Array of numbers'); + t.end(); +}); + +test('rotate -- mutated input', t => { + const line = lineString([[10, 10], [12, 15]]); + const lineBefore = JSON.parse(JSON.stringify(line)); + + rotate(line, 100); + t.deepEqual(line, lineBefore, 'input should NOT be mutated'); + + rotate(line, 100, {mutate: true}); + t.deepEqual(truncate(line, {precision: 1}), lineString([[8.6, 13.9], [13.3, 11.1]]), 'input should be mutated'); + t.end(); +}); + +test('rotate -- geometry support', t => { + const line = lineString([[10, 10], [12, 15]]); + const pt = point([10, 10]); + + t.assert(rotate(geometryCollection([line.geometry]), 100), 'geometryCollection support'); + t.assert(rotate(geometryCollection([line.geometry]).geometry, 100), 'geometryCollection support'); + t.assert(rotate(featureCollection([line]), 100), 'featureCollection support'); + t.assert(rotate(line.geometry, 100), 'geometry line support'); + t.assert(rotate(line.geometry, 100, {pivot: pt.geometry}), 'geometry pt support'); + t.assert(rotate(line.geometry, 100, {pivot: pt.geometry.coordinates}), 'pt coordinate support'); + t.end(); +}); + +// style result +function colorize(geojson) { + if (geojson.geometry.type === 'Point' || geojson.geometry.type === 'MultiPoint') { + geojson.properties['marker-color'] = '#F00'; + geojson.properties['marker-symbol'] = 'star'; + } else { + geojson.properties['stroke'] = '#F00'; + geojson.properties['stroke-width'] = 4; + } + return geojson; +} + +function makePivot(pivot, geojson) { + if (!pivot) { + const pt = centroid(geojson); + pt.properties['marker-symbol'] = 'circle'; + return pt; + } + return point(getCoord(pivot), {'marker-symbol': 'circle'}); +} diff --git a/packages/turf-transform-rotate/test/in/line.geojson b/src/transform-rotate/test/in/line.geojson similarity index 100% rename from packages/turf-transform-rotate/test/in/line.geojson rename to src/transform-rotate/test/in/line.geojson diff --git a/packages/turf-transform-rotate/test/in/multiLine.geojson b/src/transform-rotate/test/in/multiLine.geojson similarity index 100% rename from packages/turf-transform-rotate/test/in/multiLine.geojson rename to src/transform-rotate/test/in/multiLine.geojson diff --git a/packages/turf-transform-rotate/test/in/multiPoint.geojson b/src/transform-rotate/test/in/multiPoint.geojson similarity index 100% rename from packages/turf-transform-rotate/test/in/multiPoint.geojson rename to src/transform-rotate/test/in/multiPoint.geojson diff --git a/packages/turf-transform-rotate/test/in/multiPolygon.geojson b/src/transform-rotate/test/in/multiPolygon.geojson similarity index 100% rename from packages/turf-transform-rotate/test/in/multiPolygon.geojson rename to src/transform-rotate/test/in/multiPolygon.geojson diff --git a/packages/turf-transform-rotate/test/in/no-rotation.geojson b/src/transform-rotate/test/in/no-rotation.geojson similarity index 100% rename from packages/turf-transform-rotate/test/in/no-rotation.geojson rename to src/transform-rotate/test/in/no-rotation.geojson diff --git a/packages/turf-transform-rotate/test/in/point.geojson b/src/transform-rotate/test/in/point.geojson similarity index 100% rename from packages/turf-transform-rotate/test/in/point.geojson rename to src/transform-rotate/test/in/point.geojson diff --git a/packages/turf-transform-rotate/test/in/polygon-fiji.geojson b/src/transform-rotate/test/in/polygon-fiji.geojson similarity index 100% rename from packages/turf-transform-rotate/test/in/polygon-fiji.geojson rename to src/transform-rotate/test/in/polygon-fiji.geojson diff --git a/packages/turf-transform-rotate/test/in/polygon-resolute-bay.geojson b/src/transform-rotate/test/in/polygon-resolute-bay.geojson similarity index 100% rename from packages/turf-transform-rotate/test/in/polygon-resolute-bay.geojson rename to src/transform-rotate/test/in/polygon-resolute-bay.geojson diff --git a/packages/turf-transform-rotate/test/in/polygon-with-hole.geojson b/src/transform-rotate/test/in/polygon-with-hole.geojson similarity index 100% rename from packages/turf-transform-rotate/test/in/polygon-with-hole.geojson rename to src/transform-rotate/test/in/polygon-with-hole.geojson diff --git a/packages/turf-transform-rotate/test/in/polygon.geojson b/src/transform-rotate/test/in/polygon.geojson similarity index 100% rename from packages/turf-transform-rotate/test/in/polygon.geojson rename to src/transform-rotate/test/in/polygon.geojson diff --git a/packages/turf-transform-rotate/test/in/z-coord.geojson b/src/transform-rotate/test/in/z-coord.geojson similarity index 100% rename from packages/turf-transform-rotate/test/in/z-coord.geojson rename to src/transform-rotate/test/in/z-coord.geojson diff --git a/packages/turf-transform-rotate/test/out/line.geojson b/src/transform-rotate/test/out/line.geojson similarity index 100% rename from packages/turf-transform-rotate/test/out/line.geojson rename to src/transform-rotate/test/out/line.geojson diff --git a/packages/turf-transform-rotate/test/out/multiLine.geojson b/src/transform-rotate/test/out/multiLine.geojson similarity index 100% rename from packages/turf-transform-rotate/test/out/multiLine.geojson rename to src/transform-rotate/test/out/multiLine.geojson diff --git a/packages/turf-transform-rotate/test/out/multiPoint.geojson b/src/transform-rotate/test/out/multiPoint.geojson similarity index 100% rename from packages/turf-transform-rotate/test/out/multiPoint.geojson rename to src/transform-rotate/test/out/multiPoint.geojson diff --git a/src/transform-rotate/test/out/multiPolygon.geojson b/src/transform-rotate/test/out/multiPolygon.geojson new file mode 100644 index 0000000000..1be5cd2f0a --- /dev/null +++ b/src/transform-rotate/test/out/multiPolygon.geojson @@ -0,0 +1,866 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "angle": -35, + "stroke": "#F00", + "stroke-width": 4 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -80.483378, + -34.57529 + ], + [ + -80.466447, + -34.579743 + ], + [ + -80.460209, + -34.592269 + ], + [ + -80.405962, + -34.603968 + ], + [ + -80.388046, + -34.598658 + ], + [ + -80.382565, + -34.582496 + ], + [ + -80.406368, + -34.548376 + ], + [ + -80.451046, + -34.522296 + ], + [ + -80.476572, + -34.538065 + ], + [ + -80.483378, + -34.57529 + ] + ] + ], + [ + [ + [ + -78.972099, + -33.521085 + ], + [ + -78.973726, + -33.531113 + ], + [ + -78.956299, + -33.541895 + ], + [ + -78.957586, + -33.560799 + ], + [ + -78.964638, + -33.567356 + ], + [ + -78.970259, + -33.567144 + ], + [ + -78.974698, + -33.571827 + ], + [ + -78.975904, + -33.57986 + ], + [ + -78.97506, + -33.582858 + ], + [ + -78.97919, + -33.588408 + ], + [ + -78.980255, + -33.601591 + ], + [ + -78.974436, + -33.602037 + ], + [ + -78.974604, + -33.606321 + ], + [ + -78.978117, + -33.606625 + ], + [ + -78.980982, + -33.613181 + ], + [ + -78.97106, + -33.614025 + ], + [ + -78.965693, + -33.611941 + ], + [ + -78.97109, + -33.609506 + ], + [ + -78.973339, + -33.607328 + ], + [ + -78.971795, + -33.601194 + ], + [ + -78.964686, + -33.596699 + ], + [ + -78.96657, + -33.59047 + ], + [ + -78.97118, + -33.588971 + ], + [ + -78.967726, + -33.579627 + ], + [ + -78.956905, + -33.582042 + ], + [ + -78.956147, + -33.578459 + ], + [ + -78.959155, + -33.576374 + ], + [ + -78.957246, + -33.569676 + ], + [ + -78.946229, + -33.572325 + ], + [ + -78.942803, + -33.56544 + ], + [ + -78.942049, + -33.551387 + ], + [ + -78.934829, + -33.547524 + ], + [ + -78.916926, + -33.561862 + ], + [ + -78.89311, + -33.542382 + ], + [ + -78.84438, + -33.536635 + ], + [ + -78.838404, + -33.522326 + ], + [ + -78.850762, + -33.519065 + ], + [ + -78.85697, + -33.514659 + ], + [ + -78.875875, + -33.508584 + ], + [ + -78.895281, + -33.518862 + ], + [ + -78.895813, + -33.523712 + ], + [ + -78.909128, + -33.527291 + ], + [ + -78.915339, + -33.519394 + ], + [ + -78.9388, + -33.517371 + ], + [ + -78.942904, + -33.513479 + ], + [ + -78.958752, + -33.515044 + ], + [ + -78.972099, + -33.521085 + ] + ] + ], + [ + [ + [ + -78.970655, + -33.629575 + ], + [ + -78.97038, + -33.635257 + ], + [ + -78.966698, + -33.635029 + ], + [ + -78.966438, + -33.633221 + ], + [ + -78.964113, + -33.632998 + ], + [ + -78.963747, + -33.635052 + ], + [ + -78.964737, + -33.635368 + ], + [ + -78.9644, + -33.637264 + ], + [ + -78.959116, + -33.638195 + ], + [ + -78.959206, + -33.640079 + ], + [ + -78.950887, + -33.640635 + ], + [ + -78.947825, + -33.638675 + ], + [ + -78.945991, + -33.638739 + ], + [ + -78.945604, + -33.640694 + ], + [ + -78.944783, + -33.638558 + ], + [ + -78.946026, + -33.637452 + ], + [ + -78.943357, + -33.637639 + ], + [ + -78.943729, + -33.6362 + ], + [ + -78.94099, + -33.634603 + ], + [ + -78.934942, + -33.633081 + ], + [ + -78.934464, + -33.63228 + ], + [ + -78.935996, + -33.631952 + ], + [ + -78.938363, + -33.632373 + ], + [ + -78.94085, + -33.633649 + ], + [ + -78.941637, + -33.632713 + ], + [ + -78.943998, + -33.631648 + ], + [ + -78.946049, + -33.633192 + ], + [ + -78.949372, + -33.632601 + ], + [ + -78.950461, + -33.633672 + ], + [ + -78.952864, + -33.632806 + ], + [ + -78.954557, + -33.633531 + ], + [ + -78.954571, + -33.632144 + ], + [ + -78.956145, + -33.632016 + ], + [ + -78.956385, + -33.630237 + ], + [ + -78.961037, + -33.627193 + ], + [ + -78.962295, + -33.627316 + ], + [ + -78.963003, + -33.630084 + ], + [ + -78.966889, + -33.630693 + ], + [ + -78.968344, + -33.62971 + ], + [ + -78.968245, + -33.628955 + ], + [ + -78.969559, + -33.628761 + ], + [ + -78.969749, + -33.629657 + ], + [ + -78.970655, + -33.629575 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "angle": -35 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -80.83740234375, + -33.75146241858857 + ], + [ + -80.8267593383789, + -33.76316538009658 + ], + [ + -80.83036422729492, + -33.77643631739436 + ], + [ + -80.79448699951172, + -33.81181543283183 + ], + [ + -80.77629089355469, + -33.8159515518711 + ], + [ + -80.76066970825195, + -33.805254282102595 + ], + [ + -80.75637817382812, + -33.76587681391894 + ], + [ + -80.77457427978516, + -33.723197462817026 + ], + [ + -80.80615997314453, + -33.724054113439884 + ], + [ + -80.83740234375, + -33.75146241858857 + ] + ] + ], + [ + [ + [ + -78.87805938720703, + -33.60575555447342 + ], + [ + -78.88629913330078, + -33.61318971884082 + ], + [ + -78.87943267822264, + -33.63034303571294 + ], + [ + -78.89350891113281, + -33.64520648119226 + ], + [ + -78.90380859375, + -33.64720713369291 + ], + [ + -78.90827178955078, + -33.64434904445886 + ], + [ + -78.9151382446289, + -33.64606390938584 + ], + [ + -78.92166137695312, + -33.65206566761678 + ], + [ + -78.92303466796875, + -33.65492350063952 + ], + [ + -78.93024444580078, + -33.65749546922024 + ], + [ + -78.94020080566406, + -33.66778257479216 + ], + [ + -78.93573760986328, + -33.67092561169521 + ], + [ + -78.93882751464844, + -33.674354248232504 + ], + [ + -78.94191741943358, + -33.67292566628718 + ], + [ + -78.94878387451172, + -33.67692563592954 + ], + [ + -78.94123077392578, + -33.682353868548184 + ], + [ + -78.93539428710938, + -33.68321092658006 + ], + [ + -78.93814086914062, + -33.678639851675534 + ], + [ + -78.93848419189453, + -33.675782806445994 + ], + [ + -78.93299102783203, + -33.671497060610534 + ], + [ + -78.92406463623047, + -33.671211336627486 + ], + [ + -78.92131805419922, + -33.6652109137176 + ], + [ + -78.92406463623047, + -33.66178191269289 + ], + [ + -78.914794921875, + -33.65578083204094 + ], + [ + -78.90758514404297, + -33.662924928220384 + ], + [ + -78.90449523925781, + -33.660353121928814 + ], + [ + -78.90552520751953, + -33.657209698729595 + ], + [ + -78.89934539794922, + -33.652637241813174 + ], + [ + -78.89213562011719, + -33.66006736092875 + ], + [ + -78.88458251953125, + -33.65606660727672 + ], + [ + -78.87428283691406, + -33.644920669896656 + ], + [ + -78.8656997680664, + -33.64520648119226 + ], + [ + -78.86089324951172, + -33.66549665763364 + ], + [ + -78.82793426513672, + -33.66092464108171 + ], + [ + -78.78398895263672, + -33.6794969467326 + ], + [ + -78.76922607421875, + -33.670639885813706 + ], + [ + -78.7771224975586, + -33.662067667998414 + ], + [ + -78.77918243408203, + -33.655495055856136 + ], + [ + -78.79051208496094, + -33.641490860339054 + ], + [ + -78.81351470947266, + -33.64063338660099 + ], + [ + -78.81729125976561, + -33.64434904445886 + ], + [ + -78.83068084716797, + -33.640919212129155 + ], + [ + -78.83033752441406, + -33.63148646875166 + ], + [ + -78.84819030761717, + -33.618621971969276 + ], + [ + -78.848876953125, + -33.61347563543629 + ], + [ + -78.86295318603516, + -33.6071852512562 + ], + [ + -78.87805938720703, + -33.60575555447342 + ] + ] + ], + [ + [ + [ + -78.95161628723145, + -33.69528025294664 + ], + [ + -78.95530700683594, + -33.70006466462807 + ], + [ + -78.9521312713623, + -33.70163560737423 + ], + [ + -78.9506721496582, + -33.700278885784996 + ], + [ + -78.94861221313477, + -33.701207171292374 + ], + [ + -78.94972801208496, + -33.70306371221516 + ], + [ + -78.95075798034668, + -33.70284949800254 + ], + [ + -78.95178794860838, + -33.7045631967461 + ], + [ + -78.9480972290039, + -33.70784769044128 + ], + [ + -78.94947052001952, + -33.70934709145684 + ], + [ + -78.94303321838379, + -33.71377374172037 + ], + [ + -78.93917083740234, + -33.71363095011231 + ], + [ + -78.93771171569824, + -33.71455909132016 + ], + [ + -78.93874168395996, + -33.7163439500602 + ], + [ + -78.93659591674805, + -33.714987460801574 + ], + [ + -78.93685340881348, + -33.7134881582668 + ], + [ + -78.93479347229004, + -33.714916066036416 + ], + [ + -78.93410682678223, + -33.71355955421924 + ], + [ + -78.93075942993164, + -33.71355955421924 + ], + [ + -78.92475128173828, + -33.715201644740844 + ], + [ + -78.92380714416502, + -33.714773276327996 + ], + [ + -78.92483711242676, + -33.71377374172037 + ], + [ + -78.92706871032715, + -33.712988384937574 + ], + [ + -78.92998695373535, + -33.712845592023534 + ], + [ + -78.92998695373535, + -33.71170324016297 + ], + [ + -78.93118858337402, + -33.70970408784028 + ], + [ + -78.93393516540527, + -33.70998968387856 + ], + [ + -78.93625259399414, + -33.70791909108323 + ], + [ + -78.9378833770752, + -33.708276093402596 + ], + [ + -78.93925666809082, + -33.7064196651371 + ], + [ + -78.9411449432373, + -33.706205459293635 + ], + [ + -78.94020080566406, + -33.70506301910626 + ], + [ + -78.94140243530273, + -33.704206178993886 + ], + [ + -78.94037246704102, + -33.70263528325574 + ], + [ + -78.94208908081055, + -33.69792242367998 + ], + [ + -78.94320487976074, + -33.69742255977288 + ], + [ + -78.94569396972656, + -33.699350590247136 + ], + [ + -78.94929885864258, + -33.69799383257217 + ], + [ + -78.94981384277342, + -33.69649423337286 + ], + [ + -78.9492130279541, + -33.695922950602935 + ], + [ + -78.95015716552734, + -33.69513743059241 + ], + [ + -78.95092964172363, + -33.69578012931697 + ], + [ + -78.95161628723145, + -33.69528025294664 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-symbol": "circle" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -79.08634303771343, + -33.68749020845278 + ] + } + } + ] +} diff --git a/packages/turf-transform-rotate/test/out/no-rotation.geojson b/src/transform-rotate/test/out/no-rotation.geojson similarity index 98% rename from packages/turf-transform-rotate/test/out/no-rotation.geojson rename to src/transform-rotate/test/out/no-rotation.geojson index fc09aba023..a6bdf4b867 100644 --- a/packages/turf-transform-rotate/test/out/no-rotation.geojson +++ b/src/transform-rotate/test/out/no-rotation.geojson @@ -257,8 +257,8 @@ "geometry": { "type": "Point", "coordinates": [ - 127.95259259259261, - -27.255555555555556 + 127.89720000000001, + -27.307999999999993 ] } } diff --git a/packages/turf-transform-rotate/test/out/point.geojson b/src/transform-rotate/test/out/point.geojson similarity index 100% rename from packages/turf-transform-rotate/test/out/point.geojson rename to src/transform-rotate/test/out/point.geojson diff --git a/src/transform-rotate/test/out/polygon-fiji.geojson b/src/transform-rotate/test/out/polygon-fiji.geojson new file mode 100644 index 0000000000..517e9e7010 --- /dev/null +++ b/src/transform-rotate/test/out/polygon-fiji.geojson @@ -0,0 +1,218 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "angle": 90, + "stroke": "#F00", + "stroke-width": 4 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -180.492063, + -17.459212 + ], + [ + -180.370976, + -17.433132 + ], + [ + -180.299414, + -17.370105 + ], + [ + -180.365522, + -17.112142 + ], + [ + -180.673219, + -16.943559 + ], + [ + -180.799476, + -16.97502 + ], + [ + -180.750256, + -17.169571 + ], + [ + -180.492063, + -17.459212 + ] + ] + ], + [ + [ + [ + -180.22799, + -17.04385 + ], + [ + -179.792297, + -17.307707 + ], + [ + -179.732114, + -17.017918 + ], + [ + -179.777245, + -16.427649 + ], + [ + -180.245198, + -15.543629 + ], + [ + -180.56836, + -15.51301 + ], + [ + -180.809159, + -15.671427 + ], + [ + -180.809418, + -15.939503 + ], + [ + -180.694654, + -16.196919 + ], + [ + -180.651019, + -16.538667 + ], + [ + -180.601828, + -16.922566 + ], + [ + -180.22799, + -17.04385 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "angle": 90 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -179.6319580078125, + -16.762467717941593 + ], + [ + -179.659423828125, + -16.64671805097192 + ], + [ + -179.725341796875, + -16.578287608637478 + ], + [ + -179.99450683593747, + -16.641455036937753 + ], + [ + -180.1702880859375, + -16.935960102864705 + ], + [ + -180.1373291015625, + -17.056784609942543 + ], + [ + -179.93408203125, + -17.00951473208515 + ], + [ + -179.6319580078125, + -16.762467717941593 + ] + ] + ], + [ + [ + [ + -180.06591796875, + -16.509832826905836 + ], + [ + -179.79125976562497, + -16.093320185359257 + ], + [ + -180.0933837890625, + -16.0352548623504 + ], + [ + -180.7086181640625, + -16.0774858690887 + ], + [ + -181.63146972656247, + -16.525632239869275 + ], + [ + -181.6644287109375, + -16.836089974560213 + ], + [ + -181.4996337890625, + -17.06728740376787 + ], + [ + -181.219482421875, + -17.06728740376787 + ], + [ + -180.9503173828125, + -16.956978651248072 + ], + [ + -180.59326171875, + -16.914939206301646 + ], + [ + -180.1922607421875, + -16.867633616803836 + ], + [ + -180.06591796875, + -16.509832826905836 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-symbol": "circle" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -180.42572021484375, + -16.69905167218912 + ] + } + } + ] +} diff --git a/src/transform-rotate/test/out/polygon-resolute-bay.geojson b/src/transform-rotate/test/out/polygon-resolute-bay.geojson new file mode 100644 index 0000000000..9eeffa3fcc --- /dev/null +++ b/src/transform-rotate/test/out/polygon-resolute-bay.geojson @@ -0,0 +1,234 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "angle": 45, + "stroke": "#F00", + "stroke-width": 4 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -93.733309, + 75.540938 + ], + [ + -94.849869, + 75.567104 + ], + [ + -95.933141, + 75.46343 + ], + [ + -96.383707, + 75.402789 + ], + [ + -96.362684, + 75.074432 + ], + [ + -96.154, + 74.827292 + ], + [ + -95.846124, + 74.687046 + ], + [ + -95.151349, + 74.564184 + ], + [ + -94.563287, + 74.700624 + ], + [ + -94.154507, + 74.836985 + ], + [ + -93.455303, + 75.035786 + ], + [ + -93.27606, + 75.298173 + ], + [ + -93.228527, + 75.411469 + ], + [ + -93.411057, + 75.497447 + ], + [ + -93.733309, + 75.540938 + ] + ], + [ + [ + -94.274994, + 75.381808 + ], + [ + -95.14635, + 75.361361 + ], + [ + -95.717624, + 75.198903 + ], + [ + -95.491872, + 74.902463 + ], + [ + -95.058838, + 74.786731 + ], + [ + -94.122584, + 75.027407 + ], + [ + -93.993843, + 75.266376 + ], + [ + -94.274994, + 75.381808 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "angle": 45 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -95.174560546875, + 75.60953172351893 + ], + [ + -96.03149414062499, + 75.4282153667069 + ], + [ + -96.492919921875, + 75.16048677152294 + ], + [ + -96.6357421875, + 75.03617629075062 + ], + [ + -95.723876953125, + 74.80466599405533 + ], + [ + -94.910888671875, + 74.66582807452669 + ], + [ + -94.317626953125, + 74.62218784846145 + ], + [ + -93.49365234375, + 74.66292249033842 + ], + [ + -93.438720703125, + 74.86788912917916 + ], + [ + -93.515625, + 75.03901279805076 + ], + [ + -93.55957031249999, + 75.3060980061604 + ], + [ + -94.163818359375, + 75.52189820596192 + ], + [ + -94.449462890625, + 75.60953172351893 + ], + [ + -94.82299804687499, + 75.63681056594325 + ], + [ + -95.174560546875, + 75.60953172351893 + ] + ], + [ + [ + -95.108642578125, + 75.40054889588245 + ], + [ + -95.6634521484375, + 75.22926698530169 + ], + [ + -95.614013671875, + 75.01062406678055 + ], + [ + -94.647216796875, + 74.84061980605131 + ], + [ + -94.0264892578125, + 74.83774656082585 + ], + [ + -94.0155029296875, + 75.17876503868581 + ], + [ + -94.5867919921875, + 75.3700564253908 + ], + [ + -95.108642578125, + 75.40054889588245 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-symbol": "circle" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -94.78062220982143, + 75.13518489369591 + ] + } + } + ] +} diff --git a/packages/turf-transform-rotate/test/out/polygon-with-hole.geojson b/src/transform-rotate/test/out/polygon-with-hole.geojson similarity index 76% rename from packages/turf-transform-rotate/test/out/polygon-with-hole.geojson rename to src/transform-rotate/test/out/polygon-with-hole.geojson index 1e98fefd5d..a18e403b88 100644 --- a/packages/turf-transform-rotate/test/out/polygon-with-hole.geojson +++ b/src/transform-rotate/test/out/polygon-with-hole.geojson @@ -19,158 +19,158 @@ "coordinates": [ [ [ - 14.100306, - 46.364335 + 14.100752, + 46.364285 ], [ - 14.099559, - 46.365692 + 14.100005, + 46.365643 ], [ - 14.09858, - 46.365706 + 14.099026, + 46.365657 ], [ - 14.096245, - 46.368483 + 14.096691, + 46.368434 ], [ - 14.095957, - 46.370034 + 14.096403, + 46.369985 ], [ - 14.094079, - 46.370099 + 14.094524, + 46.37005 ], [ - 14.0935, - 46.368756 + 14.093946, + 46.368707 ], [ - 14.091366, - 46.369641 + 14.091812, + 46.369592 ], [ - 14.089413, - 46.369735 + 14.089859, + 46.369686 ], [ - 14.086471, - 46.367522 + 14.086916, + 46.367472 ], [ - 14.086269, - 46.366747 + 14.086714, + 46.366698 ], [ - 14.086843, - 46.365834 + 14.087289, + 46.365785 ], [ - 14.086836, - 46.364641 + 14.087281, + 46.364591 ], [ - 14.084167, - 46.361806 + 14.084612, + 46.361756 ], [ - 14.084166, - 46.360917 + 14.084612, + 46.360867 ], [ - 14.086775, - 46.360185 + 14.087221, + 46.360136 ], [ - 14.086632, - 46.354327 + 14.087077, + 46.354277 ], [ - 14.089768, - 46.351265 + 14.090214, + 46.351215 ], [ - 14.092413, - 46.352058 + 14.092859, + 46.352008 ], [ - 14.093633, - 46.353931 + 14.094079, + 46.353881 ], [ - 14.094266, - 46.356346 + 14.094712, + 46.356296 ], [ - 14.095092, - 46.358103 + 14.095538, + 46.358053 ], [ - 14.095786, - 46.359228 + 14.096232, + 46.359179 ], [ - 14.095511, - 46.360261 + 14.095956, + 46.360212 ], [ - 14.0963, - 46.361383 + 14.096746, + 46.361333 ], [ - 14.100306, - 46.364335 + 14.100752, + 46.364285 ] ], [ [ - 14.092479, - 46.365137 + 14.092924, + 46.365087 ], [ - 14.092056, - 46.365579 + 14.092501, + 46.365529 ], [ - 14.09129, - 46.365833 + 14.091735, + 46.365783 ], [ - 14.09054, - 46.365841 + 14.090986, + 46.365791 ], [ - 14.090401, - 46.365733 + 14.090847, + 46.365684 ], [ - 14.090422, - 46.36564 + 14.090868, + 46.36559 ], [ - 14.090539, - 46.365542 + 14.090984, + 46.365493 ], [ - 14.090822, - 46.365258 + 14.091267, + 46.365209 ], [ - 14.091225, - 46.365029 + 14.09167, + 46.36498 ], [ - 14.091521, - 46.364954 + 14.091966, + 46.364905 ], [ - 14.092397, - 46.365084 + 14.092843, + 46.365034 ], [ - 14.092479, - 46.365137 + 14.092924, + 46.365087 ] ] ] @@ -357,8 +357,8 @@ "geometry": { "type": "Point", "coordinates": [ - 14.092010792933012, - 46.36358244756288 + 14.092212915420532, + 46.36346899882679 ] } } diff --git a/packages/turf-transform-rotate/test/out/polygon.geojson b/src/transform-rotate/test/out/polygon.geojson similarity index 100% rename from packages/turf-transform-rotate/test/out/polygon.geojson rename to src/transform-rotate/test/out/polygon.geojson diff --git a/packages/turf-transform-rotate/test/out/z-coord.geojson b/src/transform-rotate/test/out/z-coord.geojson similarity index 81% rename from packages/turf-transform-rotate/test/out/z-coord.geojson rename to src/transform-rotate/test/out/z-coord.geojson index e332aa983e..cc9fece93c 100644 --- a/packages/turf-transform-rotate/test/out/z-coord.geojson +++ b/src/transform-rotate/test/out/z-coord.geojson @@ -13,33 +13,33 @@ "coordinates": [ [ [ - 122.881586, - -21.143814, + 123.17066, + -20.595392, 10 ], [ - 122.406714, - -26.290304, + 122.695301, + -25.749925, 10 ], [ - 126.709631, - -27.926984, + 126.980874, + -27.382228, 10 ], [ - 129.423115, - -25.440498, + 129.68694, + -24.888351, 10 ], [ - 127.991388, - -21.321849, + 128.263897, + -20.766401, 10 ], [ - 122.881586, - -21.143814, + 123.17066, + -20.595392, 10 ] ] @@ -97,8 +97,8 @@ "geometry": { "type": "Point", "coordinates": [ - 125.3759765625, - -23.878970838788252 + 126.158203125, + -23.87759746657351 ] } } diff --git a/packages/turf-transform-scale/bench.js b/src/transform-scale/bench.js similarity index 100% rename from packages/turf-transform-scale/bench.js rename to src/transform-scale/bench.js diff --git a/src/transform-scale/index.d.ts b/src/transform-scale/index.d.ts new file mode 100644 index 0000000000..e36d4142a6 --- /dev/null +++ b/src/transform-scale/index.d.ts @@ -0,0 +1,13 @@ +import { Corners, Coord, AllGeoJSON } from '../helpers' + +/** + * http://turfjs.org/docs/#transformscale + */ +export default function transformScale( + geojson: T, + factor: number, + options?: { + origin?: Corners | Coord, + mutate?: boolean + } +): T; diff --git a/src/transform-scale/index.js b/src/transform-scale/index.js new file mode 100644 index 0000000000..2e0e9ac0fb --- /dev/null +++ b/src/transform-scale/index.js @@ -0,0 +1,142 @@ +import clone from '../clone'; +import center from '../center'; +import centroid from '../centroid'; +import turfBBox from '../bbox'; +import rhumbBearing from '../rhumb-bearing'; +import rhumbDistance from '../rhumb-distance'; +import rhumbDestination from '../rhumb-destination'; +import { coordEach, featureEach } from '../meta'; +import { point, isObject } from '../helpers'; +import { getCoord, getCoords, getType} from '../invariant'; + +/** + * Scale a GeoJSON from a given point by a factor of scaling (ex: factor=2 would make the GeoJSON 200% larger). + * If a FeatureCollection is provided, the origin point will be calculated based on each individual Feature. + * + * @name transformScale + * @param {GeoJSON} geojson GeoJSON to be scaled + * @param {number} factor of scaling, positive or negative values greater than 0 + * @param {Object} [options={}] Optional parameters + * @param {string|Coord} [options.origin='centroid'] Point from which the scaling will occur (string options: sw/se/nw/ne/center/centroid) + * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) + * @returns {GeoJSON} scaled GeoJSON + * @example + * var poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]); + * var scaledPoly = turf.transformScale(poly, 3); + * + * //addToMap + * var addToMap = [poly, scaledPoly]; + * scaledPoly.properties = {stroke: '#F00', 'stroke-width': 4}; + */ +function transformScale(geojson, factor, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var origin = options.origin; + var mutate = options.mutate; + + // Input validation + if (!geojson) throw new Error('geojson required'); + if (typeof factor !== 'number' || factor === 0) throw new Error('invalid factor'); + var originIsPoint = Array.isArray(origin) || typeof origin === 'object'; + + // Clone geojson to avoid side effects + if (mutate !== true) geojson = clone(geojson); + + // Scale each Feature separately + if (geojson.type === 'FeatureCollection' && !originIsPoint) { + featureEach(geojson, function (feature, index) { + geojson.features[index] = scale(feature, factor, origin); + }); + return geojson; + } + // Scale Feature/Geometry + return scale(geojson, factor, origin); +} + +/** + * Scale Feature/Geometry + * + * @private + * @param {Feature|Geometry} feature GeoJSON Feature/Geometry + * @param {number} factor of scaling, positive or negative values greater than 0 + * @param {string|Coord} [origin="centroid"] Point from which the scaling will occur (string options: sw/se/nw/ne/center/centroid) + * @returns {Feature|Geometry} scaled GeoJSON Feature/Geometry + */ +function scale(feature, factor, origin) { + // Default params + var isPoint = getType(feature) === 'Point'; + origin = defineOrigin(feature, origin); + + // Shortcut no-scaling + if (factor === 1 || isPoint) return feature; + + // Scale each coordinate + coordEach(feature, function (coord) { + var originalDistance = rhumbDistance(origin, coord); + var bearing = rhumbBearing(origin, coord); + var newDistance = originalDistance * factor; + var newCoord = getCoords(rhumbDestination(origin, newDistance, bearing)); + coord[0] = newCoord[0]; + coord[1] = newCoord[1]; + if (coord.length === 3) coord[2] *= factor; + }); + + return feature; +} + +/** + * Define Origin + * + * @private + * @param {GeoJSON} geojson GeoJSON + * @param {string|Coord} origin sw/se/nw/ne/center/centroid + * @returns {Feature} Point origin + */ +function defineOrigin(geojson, origin) { + // Default params + if (origin === undefined || origin === null) origin = 'centroid'; + + // Input Coord + if (Array.isArray(origin) || typeof origin === 'object') return getCoord(origin); + + // Define BBox + var bbox = (geojson.bbox) ? geojson.bbox : turfBBox(geojson); + var west = bbox[0]; + var south = bbox[1]; + var east = bbox[2]; + var north = bbox[3]; + + switch (origin) { + case 'sw': + case 'southwest': + case 'westsouth': + case 'bottomleft': + return point([west, south]); + case 'se': + case 'southeast': + case 'eastsouth': + case 'bottomright': + return point([east, south]); + case 'nw': + case 'northwest': + case 'westnorth': + case 'topleft': + return point([west, north]); + case 'ne': + case 'northeast': + case 'eastnorth': + case 'topright': + return point([east, north]); + case 'center': + return center(geojson); + case undefined: + case null: + case 'centroid': + return centroid(geojson); + default: + throw new Error('invalid origin'); + } +} + +export default transformScale; diff --git a/src/transform-scale/test.js b/src/transform-scale/test.js new file mode 100644 index 0000000000..e8ca420e13 --- /dev/null +++ b/src/transform-scale/test.js @@ -0,0 +1,211 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import center from '../center'; +import hexGrid from '../hex-grid'; +import truncate from '../truncate'; +import turfBBox from '../bbox'; +import bboxPolygon from '../bbox-polygon'; +import centroid from '../centroid'; +import { featureEach } from '../meta'; +import { getCoord } from '../invariant'; +import { point, lineString, geometryCollection, featureCollection } from '../helpers'; +import scale from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('scale', t => { + for (const {filename, name, geojson} of fixtures) { + let {factor, origin, mutate} = geojson.properties || {}; + factor = factor || 2; + + const scaled = scale(geojson, factor, { + origin: origin, + mutate: mutate + }); + const result = featureCollection([]); + featureEach(colorize(truncate(scaled, {precision: 6, coordinates: 3})), feature => result.features.push(feature)); + featureEach(geojson, feature => result.features.push(feature)); + featureEach(geojson, feature => result.features.push(markedOrigin(feature, origin))); + + if (process.env.REGEN) write.sync(directories.out + filename, result); + t.deepEqual(result, load.sync(directories.out + filename), name); + } + + t.end(); +}); + +test('scale -- throws', t => { + const line = lineString([[10, 10], [12, 15]]); + + t.throws(() => scale(null, 1.5), /geojson required/); + t.throws(() => scale(line, null), /invalid factor/); + t.throws(() => scale(line, 0), /invalid factor/); + t.throws(() => scale(line, 1.5, {origin: 'foobar'}), /invalid origin/); + t.throws(() => scale(line, 1.5, {origin: 2}), /invalid origin/); + + t.end(); +}); + +test('scale -- additional params', t => { + const line = lineString([[10, 10], [12, 15]]); + const bbox = [-180, -90, 180, 90]; + + t.assert(scale(line, 1.5, {origin: 'sw'})); + t.assert(scale(line, 1.5, {origin: 'se'})); + t.assert(scale(line, 1.5, {origin: 'nw'})); + t.assert(scale(line, 1.5, {origin: 'ne'})); + t.assert(scale(line, 1.5, {origin: 'center'})); + t.assert(scale(line, 1.5, {origin: 'centroid'})); + t.assert(scale(line, 1.5, {origin: null})); + line.bbox = bbox; + t.assert(scale(line, 1.5)); + t.end(); +}); + +test('scale -- bbox provided', t => { + const line = lineString([[10, 10], [12, 15]]); + line.bbox = [-180, -90, 180, 90]; + + t.assert(scale(line, 1.5)); + t.end(); +}); + +test('scale -- mutated input', t => { + const line = lineString([[10, 10], [12, 15]]); + const lineBefore = JSON.parse(JSON.stringify(line)); + + scale(line, 1.5); + t.deepEqual(line, lineBefore, 'mutate = undefined - input should NOT be mutated'); + scale(line, 1.5, {origin: 'centroid', mutate: false}); + t.deepEqual(line, lineBefore, 'mutate = false - input should NOT be mutated'); + scale(line, 1.5, {orgin: 'centroid', muate: 'nonBoolean'}); + t.deepEqual(line, lineBefore, 'non-boolean mutate - input should NOT be mutated'); + + scale(line, 1.5, {origin: 'centroid', mutate: true}); + t.deepEqual(truncate(line, {precision: 1}), lineString([[9.5, 8.8], [12.5, 16.2]]), 'mutate = true - input should be mutated'); + t.end(); +}); + +test('scale -- mutated FeatureCollection', t => { + const line = featureCollection([ + lineString([[10, 10], [12, 15]]), + lineString([[15, 15], [22, 35]]), + lineString([[30, 30], [42, 45]]) + ]); + const lineBefore = JSON.parse(JSON.stringify(line)); + scale(line, 1.5); + t.deepEqual(line, lineBefore, 'mutate = undefined - input should NOT be mutated'); + scale(line, 1.5, {origin: 'centroid', mutate: false}); + t.deepEqual(line, lineBefore, 'mutate = false - input should NOT be mutated'); + scale(line, 1.5, {origin: 'centroid', mutate: 'nonBoolean'}); + t.deepEqual(line, lineBefore, 'non-boolean mutate - input should NOT be mutated'); + t.end(); +}); + +test('scale -- Issue #895', t => { + const bbox = [-122.930, 45.385, -122.294, 45.772]; + const grid = hexGrid(bbox, 2, {units: 'miles'}); + featureEach(grid, (feature, index) => { + const factor = (index % 2 === 0) ? 0.4 : 0.6; + scale(feature, factor, {origin: 'centroid', mutate: true}); + }); + // Add styled GeoJSON to the result + const poly = bboxPolygon(bbox); + poly.properties = { + stroke: '#F00', + 'stroke-width': 6, + 'fill-opacity': 0 + }; + grid.features.push(poly); + const output = directories.out + 'issue-#895.geojson'; + if (process.env.REGEN) write.sync(output, grid); + t.deepEqual(grid, load.sync(output)); + t.end(); +}); + +test('scale -- geometry support', t => { + const pt = point([10, 10]); + const line = lineString([[10, 10], [12, 15]]); + + t.assert(scale(geometryCollection([line.geometry]), 1.5), 'geometryCollection support'); + t.assert(scale(geometryCollection([line.geometry]).geometry, 1.5), 'geometryCollection support'); + t.assert(scale(featureCollection([line]), 1.50), 'featureCollection support'); + t.assert(scale(line.geometry, 1.5), 'geometry line support'); + t.assert(scale(pt.geometry, 1.5), 'geometry point support'); + t.assert(scale(pt, 1.5), 'geometry point support'); + t.assert(scale(pt, 1.5, { origin: pt }), 'feature point support'); + t.assert(scale(pt, 1.5, { origin: pt.geometry }), 'geometry point support'); + t.assert(scale(pt, 1.5, { origin: pt.geometry.coordinates }), 'coordinate point support'); + + t.end(); +}); + +// style result +function colorize(geojson) { + featureEach(geojson, (feature, index) => { + if (feature.geometry.type === 'Point' || feature.geometry.type === 'MultiPoint') { + feature.properties['marker-color'] = '#F00'; + feature.properties['marker-symbol'] = 'star'; + } else { + feature.properties['stroke'] = '#F00'; + feature.properties['stroke-width'] = 4; + } + if (geojson.type === 'Feature') return feature; + geojson.features[index] = feature; + }); + return geojson; +} + +// define origin, as defined in transform-scale, and style it +function markedOrigin(geojson, origin, properties = {'marker-color': '#00F', 'marker-symbol': 'circle'}) { + // Input Geometry|Feature|Array + if (Array.isArray(origin) || typeof origin === 'object') return point(getCoord(origin), properties); + + // Define BBox + const [west, south, east, north] = (geojson.bbox) ? geojson.bbox : turfBBox(geojson); + + switch (origin) { + case 'sw': + case 'southwest': + case 'westsouth': + case 'bottomleft': + return point([west, south], properties); + case 'se': + case 'southeast': + case 'eastsouth': + case 'bottomright': + return point([east, south], properties); + case 'nw': + case 'northwest': + case 'westnorth': + case 'topleft': + return point([west, north], properties); + case 'ne': + case 'northeast': + case 'eastnorth': + case 'topright': + return point([east, north], properties); + case 'center': + var cr = center(geojson); + cr.properties = properties; + return cr; + default: + var cid = centroid(geojson); + cid.properties = properties; + return cid; + } +} diff --git a/packages/turf-transform-scale/test/in/feature-collection-polygon.geojson b/src/transform-scale/test/in/feature-collection-polygon.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/feature-collection-polygon.geojson rename to src/transform-scale/test/in/feature-collection-polygon.geojson diff --git a/packages/turf-transform-scale/test/in/issue-#1059.geojson b/src/transform-scale/test/in/issue-#1059.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/issue-#1059.geojson rename to src/transform-scale/test/in/issue-#1059.geojson diff --git a/packages/turf-transform-scale/test/in/line.geojson b/src/transform-scale/test/in/line.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/line.geojson rename to src/transform-scale/test/in/line.geojson diff --git a/packages/turf-transform-scale/test/in/multiLine.geojson b/src/transform-scale/test/in/multiLine.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/multiLine.geojson rename to src/transform-scale/test/in/multiLine.geojson diff --git a/packages/turf-transform-scale/test/in/multiPoint.geojson b/src/transform-scale/test/in/multiPoint.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/multiPoint.geojson rename to src/transform-scale/test/in/multiPoint.geojson diff --git a/packages/turf-transform-scale/test/in/multiPolygon.geojson b/src/transform-scale/test/in/multiPolygon.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/multiPolygon.geojson rename to src/transform-scale/test/in/multiPolygon.geojson diff --git a/packages/turf-transform-scale/test/in/no-scale.geojson b/src/transform-scale/test/in/no-scale.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/no-scale.geojson rename to src/transform-scale/test/in/no-scale.geojson diff --git a/packages/turf-transform-scale/test/in/origin-inside-bbox.geojson b/src/transform-scale/test/in/origin-inside-bbox.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/origin-inside-bbox.geojson rename to src/transform-scale/test/in/origin-inside-bbox.geojson diff --git a/packages/turf-transform-scale/test/in/origin-inside-feature.geojson b/src/transform-scale/test/in/origin-inside-feature.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/origin-inside-feature.geojson rename to src/transform-scale/test/in/origin-inside-feature.geojson diff --git a/packages/turf-transform-scale/test/in/origin-outside-bbox.geojson b/src/transform-scale/test/in/origin-outside-bbox.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/origin-outside-bbox.geojson rename to src/transform-scale/test/in/origin-outside-bbox.geojson diff --git a/packages/turf-transform-scale/test/in/point.geojson b/src/transform-scale/test/in/point.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/point.geojson rename to src/transform-scale/test/in/point.geojson diff --git a/packages/turf-transform-scale/test/in/poly-double.geojson b/src/transform-scale/test/in/poly-double.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/poly-double.geojson rename to src/transform-scale/test/in/poly-double.geojson diff --git a/packages/turf-transform-scale/test/in/poly-half.geojson b/src/transform-scale/test/in/poly-half.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/poly-half.geojson rename to src/transform-scale/test/in/poly-half.geojson diff --git a/packages/turf-transform-scale/test/in/polygon-fiji.geojson b/src/transform-scale/test/in/polygon-fiji.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/polygon-fiji.geojson rename to src/transform-scale/test/in/polygon-fiji.geojson diff --git a/packages/turf-transform-scale/test/in/polygon-resolute-bay.geojson b/src/transform-scale/test/in/polygon-resolute-bay.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/polygon-resolute-bay.geojson rename to src/transform-scale/test/in/polygon-resolute-bay.geojson diff --git a/packages/turf-transform-scale/test/in/polygon-with-hole.geojson b/src/transform-scale/test/in/polygon-with-hole.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/polygon-with-hole.geojson rename to src/transform-scale/test/in/polygon-with-hole.geojson diff --git a/packages/turf-transform-scale/test/in/polygon.geojson b/src/transform-scale/test/in/polygon.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/polygon.geojson rename to src/transform-scale/test/in/polygon.geojson diff --git a/packages/turf-transform-scale/test/in/z-scaling.geojson b/src/transform-scale/test/in/z-scaling.geojson similarity index 100% rename from packages/turf-transform-scale/test/in/z-scaling.geojson rename to src/transform-scale/test/in/z-scaling.geojson diff --git a/src/transform-scale/test/out/feature-collection-polygon.geojson b/src/transform-scale/test/out/feature-collection-polygon.geojson new file mode 100644 index 0000000000..4e9a155423 --- /dev/null +++ b/src/transform-scale/test/out/feature-collection-polygon.geojson @@ -0,0 +1,909 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "fill": "#0F0", + "factor": 0.8, + "origin": "center", + "stroke": "#F00", + "stroke-width": 4 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -80.878897, + -33.732123 + ], + [ + -80.857617, + -33.755529 + ], + [ + -80.864832, + -33.782071 + ], + [ + -80.793075, + -33.852829 + ], + [ + -80.756673, + -33.861102 + ], + [ + -80.725427, + -33.839707 + ], + [ + -80.71686, + -33.760952 + ], + [ + -80.753262, + -33.675593 + ], + [ + -80.816416, + -33.677307 + ], + [ + -80.878897, + -33.732123 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "fill": "#00F", + "factor": 0.8, + "origin": "center", + "stroke": "#F00", + "stroke-width": 4 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -78.844645, + -33.532541 + ], + [ + -78.861115, + -33.54741 + ], + [ + -78.847381, + -33.581716 + ], + [ + -78.875523, + -33.611443 + ], + [ + -78.896118, + -33.615445 + ], + [ + -78.905043, + -33.609728 + ], + [ + -78.918773, + -33.613158 + ], + [ + -78.931817, + -33.625162 + ], + [ + -78.934564, + -33.630877 + ], + [ + -78.948982, + -33.636021 + ], + [ + -78.968896, + -33.656595 + ], + [ + -78.959971, + -33.662881 + ], + [ + -78.966151, + -33.669739 + ], + [ + -78.972331, + -33.666882 + ], + [ + -78.986065, + -33.674882 + ], + [ + -78.970961, + -33.685738 + ], + [ + -78.959288, + -33.687452 + ], + [ + -78.964779, + -33.67831 + ], + [ + -78.965465, + -33.672596 + ], + [ + -78.954478, + -33.664024 + ], + [ + -78.936626, + -33.663453 + ], + [ + -78.931132, + -33.651452 + ], + [ + -78.936625, + -33.644594 + ], + [ + -78.918087, + -33.632592 + ], + [ + -78.903669, + -33.64688 + ], + [ + -78.89749, + -33.641737 + ], + [ + -78.89955, + -33.63545 + ], + [ + -78.887192, + -33.626305 + ], + [ + -78.872773, + -33.641165 + ], + [ + -78.85767, + -33.633163 + ], + [ + -78.837078, + -33.610872 + ], + [ + -78.819915, + -33.611443 + ], + [ + -78.810292, + -33.652024 + ], + [ + -78.744384, + -33.64288 + ], + [ + -78.656475, + -33.680024 + ], + [ + -78.626964, + -33.66231 + ], + [ + -78.642769, + -33.645166 + ], + [ + -78.646899, + -33.63202 + ], + [ + -78.669575, + -33.604012 + ], + [ + -78.715571, + -33.602297 + ], + [ + -78.723118, + -33.609728 + ], + [ + -78.749895, + -33.602869 + ], + [ + -78.749218, + -33.584003 + ], + [ + -78.784923, + -33.558274 + ], + [ + -78.786299, + -33.547982 + ], + [ + -78.814445, + -33.535401 + ], + [ + -78.844645, + -33.532541 + ] + ] + ], + [ + [ + [ + -78.991738, + -33.711591 + ], + [ + -78.999123, + -33.72116 + ], + [ + -78.992771, + -33.724301 + ], + [ + -78.989852, + -33.721588 + ], + [ + -78.985732, + -33.723445 + ], + [ + -78.987965, + -33.727158 + ], + [ + -78.990025, + -33.726729 + ], + [ + -78.992086, + -33.730157 + ], + [ + -78.984705, + -33.736726 + ], + [ + -78.987452, + -33.739724 + ], + [ + -78.974577, + -33.748578 + ], + [ + -78.966851, + -33.748292 + ], + [ + -78.963932, + -33.750148 + ], + [ + -78.965993, + -33.753718 + ], + [ + -78.9617, + -33.751005 + ], + [ + -78.962215, + -33.748007 + ], + [ + -78.958095, + -33.750862 + ], + [ + -78.956721, + -33.748149 + ], + [ + -78.950024, + -33.748149 + ], + [ + -78.938006, + -33.751434 + ], + [ + -78.936117, + -33.750577 + ], + [ + -78.938177, + -33.748578 + ], + [ + -78.942641, + -33.747007 + ], + [ + -78.948479, + -33.746721 + ], + [ + -78.948479, + -33.744437 + ], + [ + -78.950882, + -33.740438 + ], + [ + -78.956376, + -33.74101 + ], + [ + -78.961011, + -33.736868 + ], + [ + -78.964274, + -33.737582 + ], + [ + -78.96702, + -33.73387 + ], + [ + -78.970797, + -33.733441 + ], + [ + -78.968908, + -33.731156 + ], + [ + -78.971312, + -33.729443 + ], + [ + -78.969251, + -33.726301 + ], + [ + -78.972683, + -33.716875 + ], + [ + -78.974914, + -33.715875 + ], + [ + -78.979894, + -33.719731 + ], + [ + -78.987104, + -33.717018 + ], + [ + -78.988133, + -33.714019 + ], + [ + -78.986931, + -33.712876 + ], + [ + -78.988819, + -33.711305 + ], + [ + -78.990365, + -33.712591 + ], + [ + -78.991738, + -33.711591 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "fill": "#0F0", + "factor": 0.8, + "origin": "center" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -80.83740234375, + -33.75146241858857 + ], + [ + -80.8267593383789, + -33.76316538009658 + ], + [ + -80.83036422729492, + -33.77643631739436 + ], + [ + -80.79448699951172, + -33.81181543283183 + ], + [ + -80.77629089355469, + -33.8159515518711 + ], + [ + -80.76066970825195, + -33.805254282102595 + ], + [ + -80.75637817382812, + -33.76587681391894 + ], + [ + -80.77457427978516, + -33.723197462817026 + ], + [ + -80.80615997314453, + -33.724054113439884 + ], + [ + -80.83740234375, + -33.75146241858857 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "fill": "#00F", + "factor": 0.8, + "origin": "center" + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -78.87805938720703, + -33.60575555447342 + ], + [ + -78.88629913330078, + -33.61318971884082 + ], + [ + -78.87943267822264, + -33.63034303571294 + ], + [ + -78.89350891113281, + -33.64520648119226 + ], + [ + -78.90380859375, + -33.64720713369291 + ], + [ + -78.90827178955078, + -33.64434904445886 + ], + [ + -78.9151382446289, + -33.64606390938584 + ], + [ + -78.92166137695312, + -33.65206566761678 + ], + [ + -78.92303466796875, + -33.65492350063952 + ], + [ + -78.93024444580078, + -33.65749546922024 + ], + [ + -78.94020080566406, + -33.66778257479216 + ], + [ + -78.93573760986328, + -33.67092561169521 + ], + [ + -78.93882751464844, + -33.674354248232504 + ], + [ + -78.94191741943358, + -33.67292566628718 + ], + [ + -78.94878387451172, + -33.67692563592954 + ], + [ + -78.94123077392578, + -33.682353868548184 + ], + [ + -78.93539428710938, + -33.68321092658006 + ], + [ + -78.93814086914062, + -33.678639851675534 + ], + [ + -78.93848419189453, + -33.675782806445994 + ], + [ + -78.93299102783203, + -33.671497060610534 + ], + [ + -78.92406463623047, + -33.671211336627486 + ], + [ + -78.92131805419922, + -33.6652109137176 + ], + [ + -78.92406463623047, + -33.66178191269289 + ], + [ + -78.914794921875, + -33.65578083204094 + ], + [ + -78.90758514404297, + -33.662924928220384 + ], + [ + -78.90449523925781, + -33.660353121928814 + ], + [ + -78.90552520751953, + -33.657209698729595 + ], + [ + -78.89934539794922, + -33.652637241813174 + ], + [ + -78.89213562011719, + -33.66006736092875 + ], + [ + -78.88458251953125, + -33.65606660727672 + ], + [ + -78.87428283691406, + -33.644920669896656 + ], + [ + -78.8656997680664, + -33.64520648119226 + ], + [ + -78.86089324951172, + -33.66549665763364 + ], + [ + -78.82793426513672, + -33.66092464108171 + ], + [ + -78.78398895263672, + -33.6794969467326 + ], + [ + -78.76922607421875, + -33.670639885813706 + ], + [ + -78.7771224975586, + -33.662067667998414 + ], + [ + -78.77918243408203, + -33.655495055856136 + ], + [ + -78.79051208496094, + -33.641490860339054 + ], + [ + -78.81351470947266, + -33.64063338660099 + ], + [ + -78.81729125976561, + -33.64434904445886 + ], + [ + -78.83068084716797, + -33.640919212129155 + ], + [ + -78.83033752441406, + -33.63148646875166 + ], + [ + -78.84819030761717, + -33.618621971969276 + ], + [ + -78.848876953125, + -33.61347563543629 + ], + [ + -78.86295318603516, + -33.6071852512562 + ], + [ + -78.87805938720703, + -33.60575555447342 + ] + ] + ], + [ + [ + [ + -78.95161628723145, + -33.69528025294664 + ], + [ + -78.95530700683594, + -33.70006466462807 + ], + [ + -78.9521312713623, + -33.70163560737423 + ], + [ + -78.9506721496582, + -33.700278885784996 + ], + [ + -78.94861221313477, + -33.701207171292374 + ], + [ + -78.94972801208496, + -33.70306371221516 + ], + [ + -78.95075798034668, + -33.70284949800254 + ], + [ + -78.95178794860838, + -33.7045631967461 + ], + [ + -78.9480972290039, + -33.70784769044128 + ], + [ + -78.94947052001952, + -33.70934709145684 + ], + [ + -78.94303321838379, + -33.71377374172037 + ], + [ + -78.93917083740234, + -33.71363095011231 + ], + [ + -78.93771171569824, + -33.71455909132016 + ], + [ + -78.93874168395996, + -33.7163439500602 + ], + [ + -78.93659591674805, + -33.714987460801574 + ], + [ + -78.93685340881348, + -33.7134881582668 + ], + [ + -78.93479347229004, + -33.714916066036416 + ], + [ + -78.93410682678223, + -33.71355955421924 + ], + [ + -78.93075942993164, + -33.71355955421924 + ], + [ + -78.92475128173828, + -33.715201644740844 + ], + [ + -78.92380714416502, + -33.714773276327996 + ], + [ + -78.92483711242676, + -33.71377374172037 + ], + [ + -78.92706871032715, + -33.712988384937574 + ], + [ + -78.92998695373535, + -33.712845592023534 + ], + [ + -78.92998695373535, + -33.71170324016297 + ], + [ + -78.93118858337402, + -33.70970408784028 + ], + [ + -78.93393516540527, + -33.70998968387856 + ], + [ + -78.93625259399414, + -33.70791909108323 + ], + [ + -78.9378833770752, + -33.708276093402596 + ], + [ + -78.93925666809082, + -33.7064196651371 + ], + [ + -78.9411449432373, + -33.706205459293635 + ], + [ + -78.94020080566406, + -33.70506301910626 + ], + [ + -78.94140243530273, + -33.704206178993886 + ], + [ + -78.94037246704102, + -33.70263528325574 + ], + [ + -78.94208908081055, + -33.69792242367998 + ], + [ + -78.94320487976074, + -33.69742255977288 + ], + [ + -78.94569396972656, + -33.699350590247136 + ], + [ + -78.94929885864258, + -33.69799383257217 + ], + [ + -78.94981384277342, + -33.69649423337286 + ], + [ + -78.9492130279541, + -33.695922950602935 + ], + [ + -78.95015716552734, + -33.69513743059241 + ], + [ + -78.95092964172363, + -33.69578012931697 + ], + [ + -78.95161628723145, + -33.69528025294664 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#00F", + "marker-symbol": "circle" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -80.7958984375, + -33.770801530340094 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#00F", + "marker-symbol": "circle" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -78.91150214455344, + -33.67896973235066 + ] + } + } + ] +} diff --git a/packages/turf-transform-scale/test/out/issue-#1059.geojson b/src/transform-scale/test/out/issue-#1059.geojson similarity index 82% rename from packages/turf-transform-scale/test/out/issue-#1059.geojson rename to src/transform-scale/test/out/issue-#1059.geojson index 51fa61aef4..8bcd5a2620 100644 --- a/packages/turf-transform-scale/test/out/issue-#1059.geojson +++ b/src/transform-scale/test/out/issue-#1059.geojson @@ -14,24 +14,24 @@ "coordinates": [ [ [ - -48.954516, - 18.808618 + -53.292048, + 15.043169 ], [ - 76.156383, - 18.808618 + 69.112361, + 15.043169 ], [ - 116.055141, - 85.882395 + -132.621875, + 89.647844 ], [ - -75.553688, - 85.882395 + 148.442187, + 89.647844 ], [ - -48.954516, - 18.808618 + -53.292048, + 15.043169 ] ] ] @@ -80,8 +80,8 @@ "geometry": { "type": "Point", "coordinates": [ - 1.08984375, - 48.93221294549635 + 7.91015625, + 52.697662294134986 ] } } diff --git a/src/transform-scale/test/out/issue-#895.geojson b/src/transform-scale/test/out/issue-#895.geojson new file mode 100644 index 0000000000..585f16893c --- /dev/null +++ b/src/transform-scale/test/out/issue-#895.geojson @@ -0,0 +1,2347 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.84359383762614, + 45.42809052672104 + ], + [ + -122.85186614854638, + 45.43811782493964 + ], + [ + -122.86840636065244, + 45.43811782493964 + ], + [ + -122.87667867157268, + 45.42809052672104 + ], + [ + -122.86840856465221, + 45.41806322850245 + ], + [ + -122.85186394454661, + 45.41806322850245 + ], + [ + -122.84359383762614, + 45.42809052672104 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.83532262913945, + 45.47822701781403 + ], + [ + -122.84773054633155, + 45.49326796514193 + ], + [ + -122.87254196286727, + 45.49326796514193 + ], + [ + -122.88494988005937, + 45.47822701781403 + ], + [ + -122.87254417072825, + 45.463186070486124 + ], + [ + -122.84772833847057, + 45.463186070486124 + ], + [ + -122.83532262913945, + 45.47822701781403 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.84359383762614, + 45.52836350890701 + ], + [ + -122.85186615241241, + 45.53839080712561 + ], + [ + -122.86840635678641, + 45.53839080712561 + ], + [ + -122.87667867157268, + 45.52836350890701 + ], + [ + -122.86840856851524, + 45.51833621068842 + ], + [ + -122.85186394068364, + 45.51833621068842 + ], + [ + -122.84359383762614, + 45.52836350890701 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.83532262913945, + 45.5785 + ], + [ + -122.84773055020491, + 45.59354094732789 + ], + [ + -122.8725419589939, + 45.59354094732789 + ], + [ + -122.88494988005937, + 45.5785 + ], + [ + -122.87254417459769, + 45.5634590526721 + ], + [ + -122.84772833460113, + 45.5634590526721 + ], + [ + -122.83532262913945, + 45.5785 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.84359383762614, + 45.62863649109298 + ], + [ + -122.8518661562922, + 45.638663789311586 + ], + [ + -122.86840635290662, + 45.638663789311586 + ], + [ + -122.87667867157268, + 45.62863649109298 + ], + [ + -122.86840857239201, + 45.61860919287439 + ], + [ + -122.85186393680681, + 45.61860919287439 + ], + [ + -122.84359383762614, + 45.62863649109298 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.83532262913945, + 45.678772982185976 + ], + [ + -122.8477305540921, + 45.693813929513865 + ], + [ + -122.87254195510673, + 45.693813929513865 + ], + [ + -122.88494988005937, + 45.678772982185976 + ], + [ + -122.87254417848095, + 45.66373203485807 + ], + [ + -122.84772833071787, + 45.66373203485807 + ], + [ + -122.83532262913945, + 45.678772982185976 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.84359383762614, + 45.728909473278954 + ], + [ + -122.85186616018592, + 45.73893677149755 + ], + [ + -122.8684063490129, + 45.73893677149755 + ], + [ + -122.87667867157268, + 45.728909473278954 + ], + [ + -122.86840857628272, + 45.71888217506035 + ], + [ + -122.8518639329161, + 45.71888217506035 + ], + [ + -122.84359383762614, + 45.728909473278954 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.77328856548962, + 45.45315877226753 + ], + [ + -122.78569648171549, + 45.46819971959543 + ], + [ + -122.81050790018361, + 45.46819971959543 + ], + [ + -122.82291581640948, + 45.45315877226753 + ], + [ + -122.81051010611316, + 45.43811782493964 + ], + [ + -122.785694275786, + 45.43811782493964 + ], + [ + -122.77328856548962, + 45.45315877226753 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.78155977397626, + 45.50329526336053 + ], + [ + -122.78983208779476, + 45.513322561579116 + ], + [ + -122.80637229410439, + 45.513322561579116 + ], + [ + -122.8146446079229, + 45.50329526336053 + ], + [ + -122.80637450389833, + 45.49326796514193 + ], + [ + -122.78982987800077, + 45.49326796514193 + ], + [ + -122.78155977397626, + 45.50329526336053 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.77328856548962, + 45.553431754453506 + ], + [ + -122.78569648558539, + 45.5684727017814 + ], + [ + -122.81050789631371, + 45.5684727017814 + ], + [ + -122.82291581640948, + 45.553431754453506 + ], + [ + -122.81051010997913, + 45.53839080712561 + ], + [ + -122.78569427191997, + 45.53839080712561 + ], + [ + -122.77328856548962, + 45.553431754453506 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.78155977397626, + 45.60356824554649 + ], + [ + -122.78983209167109, + 45.613595543765086 + ], + [ + -122.80637229022801, + 45.613595543765086 + ], + [ + -122.8146446079229, + 45.60356824554649 + ], + [ + -122.8063745077717, + 45.59354094732789 + ], + [ + -122.78982987412746, + 45.59354094732789 + ], + [ + -122.78155977397626, + 45.60356824554649 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.77328856548962, + 45.653704736639476 + ], + [ + -122.78569648946916, + 45.66874568396738 + ], + [ + -122.81050789243, + 45.66874568396738 + ], + [ + -122.82291581640948, + 45.653704736639476 + ], + [ + -122.81051011385898, + 45.638663789311586 + ], + [ + -122.78569426804017, + 45.638663789311586 + ], + [ + -122.77328856548962, + 45.653704736639476 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.78155977397626, + 45.70384122773246 + ], + [ + -122.78983209556134, + 45.71386852595106 + ], + [ + -122.80637228633776, + 45.71386852595106 + ], + [ + -122.8146446079229, + 45.70384122773246 + ], + [ + -122.80637451165887, + 45.693813929513865 + ], + [ + -122.78982987024023, + 45.693813929513865 + ], + [ + -122.78155977397626, + 45.70384122773246 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.71125450183973, + 45.42809052672104 + ], + [ + -122.72366241710034, + 45.44313147404894 + ], + [ + -122.74847383749909, + 45.44313147404894 + ], + [ + -122.76088175275964, + 45.42809052672104 + ], + [ + -122.74847604149892, + 45.413049579393146 + ], + [ + -122.72366021310046, + 45.413049579393146 + ], + [ + -122.71125450183973, + 45.42809052672104 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.71952571032642, + 45.47822701781403 + ], + [ + -122.72779802317797, + 45.48825431603263 + ], + [ + -122.74433823142147, + 45.48825431603263 + ], + [ + -122.75261054427301, + 45.47822701781403 + ], + [ + -122.74434043928227, + 45.46819971959543 + ], + [ + -122.72779581531711, + 45.46819971959543 + ], + [ + -122.71952571032642, + 45.47822701781403 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.71125450183973, + 45.52836350890701 + ], + [ + -122.72366242096678, + 45.54340445623491 + ], + [ + -122.7484738336326, + 45.54340445623491 + ], + [ + -122.76088175275964, + 45.52836350890701 + ], + [ + -122.74847604536154, + 45.513322561579116 + ], + [ + -122.72366020923789, + 45.513322561579116 + ], + [ + -122.71125450183973, + 45.52836350890701 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.71952571032642, + 45.5785 + ], + [ + -122.72779802705082, + 45.588527298218594 + ], + [ + -122.74433822754855, + 45.588527298218594 + ], + [ + -122.75261054427301, + 45.5785 + ], + [ + -122.74434044315217, + 45.5684727017814 + ], + [ + -122.72779581144721, + 45.5684727017814 + ], + [ + -122.71952571032642, + 45.5785 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.71125450183973, + 45.62863649109298 + ], + [ + -122.72366242484702, + 45.64367743842088 + ], + [ + -122.74847382975236, + 45.64367743842088 + ], + [ + -122.76088175275964, + 45.62863649109298 + ], + [ + -122.74847604923787, + 45.613595543765086 + ], + [ + -122.72366020536151, + 45.613595543765086 + ], + [ + -122.71125450183973, + 45.62863649109298 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.71952571032642, + 45.678772982185976 + ], + [ + -122.7277980309376, + 45.68880028040457 + ], + [ + -122.74433822366177, + 45.68880028040457 + ], + [ + -122.75261054427301, + 45.678772982185976 + ], + [ + -122.74434044703594, + 45.66874568396738 + ], + [ + -122.72779580756344, + 45.66874568396738 + ], + [ + -122.71952571032642, + 45.678772982185976 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.71125450183973, + 45.728909473278954 + ], + [ + -122.72366242874125, + 45.74395042060685 + ], + [ + -122.74847382585818, + 45.74395042060685 + ], + [ + -122.76088175275964, + 45.728909473278954 + ], + [ + -122.74847605312812, + 45.71386852595106 + ], + [ + -122.72366020147132, + 45.71386852595106 + ], + [ + -122.71125450183973, + 45.728909473278954 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.65749164667659, + 45.45315877226753 + ], + [ + -122.66576395856202, + 45.463186070486124 + ], + [ + -122.68230416873769, + 45.463186070486124 + ], + [ + -122.69057648062318, + 45.45315877226753 + ], + [ + -122.68230637466712, + 45.44313147404894 + ], + [ + -122.66576175263265, + 45.44313147404894 + ], + [ + -122.65749164667659, + 45.45315877226753 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.6492204381899, + 45.50329526336053 + ], + [ + -122.66162835634907, + 45.51833621068842 + ], + [ + -122.6864397709507, + 45.51833621068842 + ], + [ + -122.69884768910981, + 45.50329526336053 + ], + [ + -122.68644198074475, + 45.48825431603263 + ], + [ + -122.66162614655502, + 45.48825431603263 + ], + [ + -122.6492204381899, + 45.50329526336053 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.65749164667659, + 45.553431754453506 + ], + [ + -122.66576396243147, + 45.5634590526721 + ], + [ + -122.68230416486824, + 45.5634590526721 + ], + [ + -122.69057648062318, + 45.553431754453506 + ], + [ + -122.68230637853355, + 45.54340445623491 + ], + [ + -122.66576174876616, + 45.54340445623491 + ], + [ + -122.65749164667659, + 45.553431754453506 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.6492204381899, + 45.60356824554649 + ], + [ + -122.66162836022585, + 45.61860919287439 + ], + [ + -122.68643976707392, + 45.61860919287439 + ], + [ + -122.69884768910981, + 45.60356824554649 + ], + [ + -122.68644198461766, + 45.588527298218594 + ], + [ + -122.66162614268211, + 45.588527298218594 + ], + [ + -122.6492204381899, + 45.60356824554649 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.65749164667659, + 45.653704736639476 + ], + [ + -122.66576396631478, + 45.66373203485807 + ], + [ + -122.68230416098498, + 45.66373203485807 + ], + [ + -122.69057648062318, + 45.653704736639476 + ], + [ + -122.68230638241386, + 45.64367743842088 + ], + [ + -122.66576174488591, + 45.64367743842088 + ], + [ + -122.65749164667659, + 45.653704736639476 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.6492204381899, + 45.70384122773246 + ], + [ + -122.66162836411655, + 45.71888217506035 + ], + [ + -122.68643976318316, + 45.71888217506035 + ], + [ + -122.69884768910981, + 45.70384122773246 + ], + [ + -122.68644198850438, + 45.68880028040457 + ], + [ + -122.66162613879533, + 45.68880028040457 + ], + [ + -122.6492204381899, + 45.70384122773246 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.5954575830267, + 45.42809052672104 + ], + [ + -122.60372989394699, + 45.43811782493964 + ], + [ + -122.620270106053, + 45.43811782493964 + ], + [ + -122.62854241697329, + 45.42809052672104 + ], + [ + -122.62027231005277, + 45.41806322850245 + ], + [ + -122.60372768994722, + 45.41806322850245 + ], + [ + -122.5954575830267, + 45.42809052672104 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.58718637454007, + 45.47822701781403 + ], + [ + -122.59959429173216, + 45.49326796514193 + ], + [ + -122.62440570826783, + 45.49326796514193 + ], + [ + -122.63681362545992, + 45.47822701781403 + ], + [ + -122.6244079161288, + 45.463186070486124 + ], + [ + -122.59959208387119, + 45.463186070486124 + ], + [ + -122.58718637454007, + 45.47822701781403 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.5954575830267, + 45.52836350890701 + ], + [ + -122.60372989781297, + 45.53839080712561 + ], + [ + -122.62027010218702, + 45.53839080712561 + ], + [ + -122.62854241697329, + 45.52836350890701 + ], + [ + -122.62027231391579, + 45.51833621068842 + ], + [ + -122.6037276860842, + 45.51833621068842 + ], + [ + -122.5954575830267, + 45.52836350890701 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.58718637454007, + 45.5785 + ], + [ + -122.59959429560547, + 45.59354094732789 + ], + [ + -122.62440570439452, + 45.59354094732789 + ], + [ + -122.63681362545992, + 45.5785 + ], + [ + -122.62440791999825, + 45.5634590526721 + ], + [ + -122.59959208000174, + 45.5634590526721 + ], + [ + -122.58718637454007, + 45.5785 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.5954575830267, + 45.62863649109298 + ], + [ + -122.60372990169276, + 45.638663789311586 + ], + [ + -122.62027009830723, + 45.638663789311586 + ], + [ + -122.62854241697329, + 45.62863649109298 + ], + [ + -122.62027231779257, + 45.61860919287439 + ], + [ + -122.60372768220736, + 45.61860919287439 + ], + [ + -122.5954575830267, + 45.62863649109298 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.58718637454007, + 45.678772982185976 + ], + [ + -122.59959429949265, + 45.693813929513865 + ], + [ + -122.62440570050728, + 45.693813929513865 + ], + [ + -122.63681362545992, + 45.678772982185976 + ], + [ + -122.6244079238815, + 45.66373203485807 + ], + [ + -122.59959207611848, + 45.66373203485807 + ], + [ + -122.58718637454007, + 45.678772982185976 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.5954575830267, + 45.728909473278954 + ], + [ + -122.60372990558653, + 45.73893677149755 + ], + [ + -122.62027009441351, + 45.73893677149755 + ], + [ + -122.62854241697329, + 45.728909473278954 + ], + [ + -122.62027232168327, + 45.71888217506035 + ], + [ + -122.60372767831666, + 45.71888217506035 + ], + [ + -122.5954575830267, + 45.728909473278954 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.52515231089023, + 45.45315877226753 + ], + [ + -122.5375602271161, + 45.46819971959543 + ], + [ + -122.56237164558422, + 45.46819971959543 + ], + [ + -122.57477956181009, + 45.45315877226753 + ], + [ + -122.56237385151371, + 45.43811782493964 + ], + [ + -122.53755802118656, + 45.43811782493964 + ], + [ + -122.52515231089023, + 45.45315877226753 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.53342351937687, + 45.50329526336053 + ], + [ + -122.54169583319538, + 45.513322561579116 + ], + [ + -122.55823603950495, + 45.513322561579116 + ], + [ + -122.56650835332346, + 45.50329526336053 + ], + [ + -122.55823824929894, + 45.49326796514193 + ], + [ + -122.54169362340139, + 45.49326796514193 + ], + [ + -122.53342351937687, + 45.50329526336053 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.52515231089023, + 45.553431754453506 + ], + [ + -122.537560230986, + 45.5684727017814 + ], + [ + -122.56237164171432, + 45.5684727017814 + ], + [ + -122.57477956181009, + 45.553431754453506 + ], + [ + -122.56237385537975, + 45.53839080712561 + ], + [ + -122.53755801732058, + 45.53839080712561 + ], + [ + -122.52515231089023, + 45.553431754453506 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.53342351937687, + 45.60356824554649 + ], + [ + -122.54169583707164, + 45.613595543765086 + ], + [ + -122.55823603562862, + 45.613595543765086 + ], + [ + -122.56650835332346, + 45.60356824554649 + ], + [ + -122.55823825317225, + 45.59354094732789 + ], + [ + -122.54169361952802, + 45.59354094732789 + ], + [ + -122.53342351937687, + 45.60356824554649 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.52515231089023, + 45.653704736639476 + ], + [ + -122.53756023486972, + 45.66874568396738 + ], + [ + -122.56237163783055, + 45.66874568396738 + ], + [ + -122.57477956181009, + 45.653704736639476 + ], + [ + -122.56237385925954, + 45.638663789311586 + ], + [ + -122.53755801344073, + 45.638663789311586 + ], + [ + -122.52515231089023, + 45.653704736639476 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.53342351937687, + 45.70384122773246 + ], + [ + -122.54169584096195, + 45.71386852595106 + ], + [ + -122.55823603173837, + 45.71386852595106 + ], + [ + -122.56650835332346, + 45.70384122773246 + ], + [ + -122.55823825705949, + 45.693813929513865 + ], + [ + -122.54169361564084, + 45.693813929513865 + ], + [ + -122.53342351937687, + 45.70384122773246 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.46311824724035, + 45.42809052672104 + ], + [ + -122.4755261625009, + 45.44313147404894 + ], + [ + -122.50033758289965, + 45.44313147404894 + ], + [ + -122.51274549816026, + 45.42809052672104 + ], + [ + -122.50033978689953, + 45.413049579393146 + ], + [ + -122.47552395850101, + 45.413049579393146 + ], + [ + -122.46311824724035, + 45.42809052672104 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.47138945572698, + 45.47822701781403 + ], + [ + -122.47966176857852, + 45.48825431603263 + ], + [ + -122.49620197682202, + 45.48825431603263 + ], + [ + -122.50447428967357, + 45.47822701781403 + ], + [ + -122.49620418468288, + 45.46819971959543 + ], + [ + -122.47965956071772, + 45.46819971959543 + ], + [ + -122.47138945572698, + 45.47822701781403 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.46311824724035, + 45.52836350890701 + ], + [ + -122.47552616636739, + 45.54340445623491 + ], + [ + -122.50033757903321, + 45.54340445623491 + ], + [ + -122.51274549816026, + 45.52836350890701 + ], + [ + -122.5003397907621, + 45.513322561579116 + ], + [ + -122.47552395463845, + 45.513322561579116 + ], + [ + -122.46311824724035, + 45.52836350890701 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.47138945572698, + 45.5785 + ], + [ + -122.47966177245144, + 45.588527298218594 + ], + [ + -122.49620197294911, + 45.588527298218594 + ], + [ + -122.50447428967357, + 45.5785 + ], + [ + -122.49620418855278, + 45.5684727017814 + ], + [ + -122.47965955684782, + 45.5684727017814 + ], + [ + -122.47138945572698, + 45.5785 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.46311824724035, + 45.62863649109298 + ], + [ + -122.47552617024763, + 45.64367743842088 + ], + [ + -122.50033757515291, + 45.64367743842088 + ], + [ + -122.51274549816026, + 45.62863649109298 + ], + [ + -122.50033979463842, + 45.613595543765086 + ], + [ + -122.47552395076212, + 45.613595543765086 + ], + [ + -122.46311824724035, + 45.62863649109298 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.47138945572698, + 45.678772982185976 + ], + [ + -122.47966177633816, + 45.68880028040457 + ], + [ + -122.49620196906238, + 45.68880028040457 + ], + [ + -122.50447428967357, + 45.678772982185976 + ], + [ + -122.4962041924365, + 45.66874568396738 + ], + [ + -122.47965955296411, + 45.66874568396738 + ], + [ + -122.47138945572698, + 45.678772982185976 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.46311824724035, + 45.728909473278954 + ], + [ + -122.4755261741418, + 45.74395042060685 + ], + [ + -122.50033757125874, + 45.74395042060685 + ], + [ + -122.51274549816026, + 45.728909473278954 + ], + [ + -122.50033979852867, + 45.71386852595106 + ], + [ + -122.47552394687187, + 45.71386852595106 + ], + [ + -122.46311824724035, + 45.728909473278954 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.40935539207715, + 45.45315877226753 + ], + [ + -122.41762770396258, + 45.463186070486124 + ], + [ + -122.43416791413824, + 45.463186070486124 + ], + [ + -122.44244022602373, + 45.45315877226753 + ], + [ + -122.43417012006768, + 45.44313147404894 + ], + [ + -122.4176254980332, + 45.44313147404894 + ], + [ + -122.40935539207715, + 45.45315877226753 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.40108418359046, + 45.50329526336053 + ], + [ + -122.41349210174963, + 45.51833621068842 + ], + [ + -122.43830351635125, + 45.51833621068842 + ], + [ + -122.45071143451037, + 45.50329526336053 + ], + [ + -122.43830572614536, + 45.48825431603263 + ], + [ + -122.41348989195552, + 45.48825431603263 + ], + [ + -122.40108418359046, + 45.50329526336053 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.40935539207715, + 45.553431754453506 + ], + [ + -122.41762770783203, + 45.5634590526721 + ], + [ + -122.4341679102688, + 45.5634590526721 + ], + [ + -122.44244022602373, + 45.553431754453506 + ], + [ + -122.43417012393411, + 45.54340445623491 + ], + [ + -122.41762549416671, + 45.54340445623491 + ], + [ + -122.40935539207715, + 45.553431754453506 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.40108418359046, + 45.60356824554649 + ], + [ + -122.4134921056264, + 45.61860919287439 + ], + [ + -122.43830351247448, + 45.61860919287439 + ], + [ + -122.45071143451037, + 45.60356824554649 + ], + [ + -122.43830573001821, + 45.588527298218594 + ], + [ + -122.41348988808267, + 45.588527298218594 + ], + [ + -122.40108418359046, + 45.60356824554649 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.40935539207715, + 45.653704736639476 + ], + [ + -122.41762771171534, + 45.66373203485807 + ], + [ + -122.43416790638548, + 45.66373203485807 + ], + [ + -122.44244022602373, + 45.653704736639476 + ], + [ + -122.43417012781441, + 45.64367743842088 + ], + [ + -122.41762549028647, + 45.64367743842088 + ], + [ + -122.40935539207715, + 45.653704736639476 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.40108418359046, + 45.70384122773246 + ], + [ + -122.41349210951711, + 45.71888217506035 + ], + [ + -122.43830350858377, + 45.71888217506035 + ], + [ + -122.45071143451037, + 45.70384122773246 + ], + [ + -122.43830573390494, + 45.68880028040457 + ], + [ + -122.41348988419588, + 45.68880028040457 + ], + [ + -122.40108418359046, + 45.70384122773246 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.34732132842726, + 45.42809052672104 + ], + [ + -122.3555936393476, + 45.43811782493964 + ], + [ + -122.37213385145355, + 45.43811782493964 + ], + [ + -122.3804061623739, + 45.42809052672104 + ], + [ + -122.37213605545332, + 45.41806322850245 + ], + [ + -122.35559143534783, + 45.41806322850245 + ], + [ + -122.34732132842726, + 45.42809052672104 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.33905011994062, + 45.47822701781403 + ], + [ + -122.35145803713272, + 45.49326796514193 + ], + [ + -122.37626945366844, + 45.49326796514193 + ], + [ + -122.38867737086053, + 45.47822701781403 + ], + [ + -122.37627166152936, + 45.463186070486124 + ], + [ + -122.3514558292718, + 45.463186070486124 + ], + [ + -122.33905011994062, + 45.47822701781403 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.34732132842726, + 45.52836350890701 + ], + [ + -122.35559364321352, + 45.53839080712561 + ], + [ + -122.37213384758763, + 45.53839080712561 + ], + [ + -122.3804061623739, + 45.52836350890701 + ], + [ + -122.3721360593164, + 45.51833621068842 + ], + [ + -122.35559143148475, + 45.51833621068842 + ], + [ + -122.34732132842726, + 45.52836350890701 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.33905011994062, + 45.5785 + ], + [ + -122.35145804100608, + 45.59354094732789 + ], + [ + -122.37626944979507, + 45.59354094732789 + ], + [ + -122.38867737086053, + 45.5785 + ], + [ + -122.3762716653988, + 45.5634590526721 + ], + [ + -122.35145582540235, + 45.5634590526721 + ], + [ + -122.33905011994062, + 45.5785 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.34732132842726, + 45.62863649109298 + ], + [ + -122.35559364709337, + 45.638663789311586 + ], + [ + -122.37213384370779, + 45.638663789311586 + ], + [ + -122.3804061623739, + 45.62863649109298 + ], + [ + -122.37213606319318, + 45.61860919287439 + ], + [ + -122.35559142760798, + 45.61860919287439 + ], + [ + -122.34732132842726, + 45.62863649109298 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.33905011994062, + 45.678772982185976 + ], + [ + -122.35145804489332, + 45.693813929513865 + ], + [ + -122.37626944590784, + 45.693813929513865 + ], + [ + -122.38867737086053, + 45.678772982185976 + ], + [ + -122.37627166928212, + 45.66373203485807 + ], + [ + -122.35145582151904, + 45.66373203485807 + ], + [ + -122.33905011994062, + 45.678772982185976 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.34732132842726, + 45.728909473278954 + ], + [ + -122.35559365098709, + 45.73893677149755 + ], + [ + -122.37213383981407, + 45.73893677149755 + ], + [ + -122.3804061623739, + 45.728909473278954 + ], + [ + -122.37213606708389, + 45.71888217506035 + ], + [ + -122.35559142371727, + 45.71888217506035 + ], + [ + -122.34732132842726, + 45.728909473278954 + ] + ] + ] + } + }, + { + "type": "Feature", + "bbox": [ + -122.93, + 45.385, + -122.294, + 45.772 + ], + "properties": { + "stroke": "#F00", + "stroke-width": 6, + "fill-opacity": 0 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -122.93, + 45.385 + ], + [ + -122.294, + 45.385 + ], + [ + -122.294, + 45.772 + ], + [ + -122.93, + 45.772 + ], + [ + -122.93, + 45.385 + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-transform-scale/test/out/line.geojson b/src/transform-scale/test/out/line.geojson similarity index 100% rename from packages/turf-transform-scale/test/out/line.geojson rename to src/transform-scale/test/out/line.geojson diff --git a/packages/turf-transform-scale/test/out/multiLine.geojson b/src/transform-scale/test/out/multiLine.geojson similarity index 100% rename from packages/turf-transform-scale/test/out/multiLine.geojson rename to src/transform-scale/test/out/multiLine.geojson diff --git a/packages/turf-transform-scale/test/out/multiPoint.geojson b/src/transform-scale/test/out/multiPoint.geojson similarity index 100% rename from packages/turf-transform-scale/test/out/multiPoint.geojson rename to src/transform-scale/test/out/multiPoint.geojson diff --git a/packages/turf-transform-scale/test/out/multiPolygon.geojson b/src/transform-scale/test/out/multiPolygon.geojson similarity index 100% rename from packages/turf-transform-scale/test/out/multiPolygon.geojson rename to src/transform-scale/test/out/multiPolygon.geojson diff --git a/packages/turf-transform-scale/test/out/no-scale.geojson b/src/transform-scale/test/out/no-scale.geojson similarity index 100% rename from packages/turf-transform-scale/test/out/no-scale.geojson rename to src/transform-scale/test/out/no-scale.geojson diff --git a/packages/turf-transform-scale/test/out/origin-inside-bbox.geojson b/src/transform-scale/test/out/origin-inside-bbox.geojson similarity index 100% rename from packages/turf-transform-scale/test/out/origin-inside-bbox.geojson rename to src/transform-scale/test/out/origin-inside-bbox.geojson diff --git a/packages/turf-transform-scale/test/out/origin-inside-feature.geojson b/src/transform-scale/test/out/origin-inside-feature.geojson similarity index 100% rename from packages/turf-transform-scale/test/out/origin-inside-feature.geojson rename to src/transform-scale/test/out/origin-inside-feature.geojson diff --git a/packages/turf-transform-scale/test/out/origin-outside-bbox.geojson b/src/transform-scale/test/out/origin-outside-bbox.geojson similarity index 100% rename from packages/turf-transform-scale/test/out/origin-outside-bbox.geojson rename to src/transform-scale/test/out/origin-outside-bbox.geojson diff --git a/packages/turf-transform-scale/test/out/point.geojson b/src/transform-scale/test/out/point.geojson similarity index 100% rename from packages/turf-transform-scale/test/out/point.geojson rename to src/transform-scale/test/out/point.geojson diff --git a/packages/turf-transform-scale/test/out/poly-double.geojson b/src/transform-scale/test/out/poly-double.geojson similarity index 100% rename from packages/turf-transform-scale/test/out/poly-double.geojson rename to src/transform-scale/test/out/poly-double.geojson diff --git a/packages/turf-transform-scale/test/out/poly-half.geojson b/src/transform-scale/test/out/poly-half.geojson similarity index 100% rename from packages/turf-transform-scale/test/out/poly-half.geojson rename to src/transform-scale/test/out/poly-half.geojson diff --git a/src/transform-scale/test/out/polygon-fiji.geojson b/src/transform-scale/test/out/polygon-fiji.geojson new file mode 100644 index 0000000000..817d07f201 --- /dev/null +++ b/src/transform-scale/test/out/polygon-fiji.geojson @@ -0,0 +1,216 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 4 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -178.837931, + -16.825884 + ], + [ + -178.893337, + -16.594384 + ], + [ + -179.025403, + -16.457524 + ], + [ + -179.563423, + -16.583858 + ], + [ + -179.914534, + -17.172869 + ], + [ + -179.848385, + -17.414518 + ], + [ + -179.441628, + -17.319978 + ], + [ + -178.837931, + -16.825884 + ] + ] + ], + [ + [ + [ + -179.706468, + -16.320614 + ], + [ + -179.158732, + -15.487589 + ], + [ + -179.762152, + -15.371458 + ], + [ + -180.990633, + -15.45592 + ], + [ + -182.836137, + -16.352213 + ], + [ + -182.904034, + -16.973128 + ], + [ + -182.575668, + -17.435523 + ], + [ + -182.014812, + -17.435523 + ], + [ + -181.475635, + -17.214906 + ], + [ + -180.760995, + -17.130827 + ], + [ + -179.958593, + -17.036216 + ], + [ + -179.706468, + -16.320614 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -179.6319580078125, + -16.762467717941593 + ], + [ + -179.659423828125, + -16.64671805097192 + ], + [ + -179.725341796875, + -16.578287608637478 + ], + [ + -179.99450683593747, + -16.641455036937753 + ], + [ + -180.1702880859375, + -16.935960102864705 + ], + [ + -180.1373291015625, + -17.056784609942543 + ], + [ + -179.93408203125, + -17.00951473208515 + ], + [ + -179.6319580078125, + -16.762467717941593 + ] + ] + ], + [ + [ + [ + -180.06591796875, + -16.509832826905836 + ], + [ + -179.79125976562497, + -16.093320185359257 + ], + [ + -180.0933837890625, + -16.0352548623504 + ], + [ + -180.7086181640625, + -16.0774858690887 + ], + [ + -181.63146972656247, + -16.525632239869275 + ], + [ + -181.6644287109375, + -16.836089974560213 + ], + [ + -181.4996337890625, + -17.06728740376787 + ], + [ + -181.219482421875, + -17.06728740376787 + ], + [ + -180.9503173828125, + -16.956978651248072 + ], + [ + -180.59326171875, + -16.914939206301646 + ], + [ + -180.1922607421875, + -16.867633616803836 + ], + [ + -180.06591796875, + -16.509832826905836 + ] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#00F", + "marker-symbol": "circle" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -180.42572021484375, + -16.69905167218912 + ] + } + } + ] +} diff --git a/src/transform-scale/test/out/polygon-resolute-bay.geojson b/src/transform-scale/test/out/polygon-resolute-bay.geojson new file mode 100644 index 0000000000..efdb2839cc --- /dev/null +++ b/src/transform-scale/test/out/polygon-resolute-bay.geojson @@ -0,0 +1,235 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "factor": 2.5, + "stroke": "#F00", + "stroke-width": 4 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -95.789976, + 76.321052 + ], + [ + -97.95473, + 75.867761 + ], + [ + -99.066725, + 75.19844 + ], + [ + -99.396055, + 74.887663 + ], + [ + -97.101854, + 74.308888 + ], + [ + -95.09917, + 73.961793 + ], + [ + -93.650646, + 73.852692 + ], + [ + -91.633938, + 73.954529 + ], + [ + -91.468654, + 74.466945 + ], + [ + -91.632949, + 74.894755 + ], + [ + -91.701695, + 75.562468 + ], + [ + -93.207694, + 76.101968 + ], + [ + -93.932121, + 76.321052 + ], + [ + -94.88936, + 76.389249 + ], + [ + -95.789976, + 76.321052 + ] + ], + [ + [ + -95.611777, + 75.798595 + ], + [ + -96.998061, + 75.37039 + ], + [ + -96.8515, + 74.823783 + ], + [ + -94.451781, + 74.398772 + ], + [ + -92.921949, + 74.391589 + ], + [ + -92.86369, + 75.244135 + ], + [ + -94.290262, + 75.722364 + ], + [ + -95.611777, + 75.798595 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "factor": 2.5 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -95.174560546875, + 75.60953172351893 + ], + [ + -96.03149414062499, + 75.4282153667069 + ], + [ + -96.492919921875, + 75.16048677152294 + ], + [ + -96.6357421875, + 75.03617629075062 + ], + [ + -95.723876953125, + 74.80466599405533 + ], + [ + -94.910888671875, + 74.66582807452669 + ], + [ + -94.317626953125, + 74.62218784846145 + ], + [ + -93.49365234375, + 74.66292249033842 + ], + [ + -93.438720703125, + 74.86788912917916 + ], + [ + -93.515625, + 75.03901279805076 + ], + [ + -93.55957031249999, + 75.3060980061604 + ], + [ + -94.163818359375, + 75.52189820596192 + ], + [ + -94.449462890625, + 75.60953172351893 + ], + [ + -94.82299804687499, + 75.63681056594325 + ], + [ + -95.174560546875, + 75.60953172351893 + ] + ], + [ + [ + -95.108642578125, + 75.40054889588245 + ], + [ + -95.6634521484375, + 75.22926698530169 + ], + [ + -95.614013671875, + 75.01062406678055 + ], + [ + -94.647216796875, + 74.84061980605131 + ], + [ + -94.0264892578125, + 74.83774656082585 + ], + [ + -94.0155029296875, + 75.17876503868581 + ], + [ + -94.5867919921875, + 75.3700564253908 + ], + [ + -95.108642578125, + 75.40054889588245 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#00F", + "marker-symbol": "circle" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -94.78062220982143, + 75.13518489369591 + ] + } + } + ] +} diff --git a/packages/turf-transform-scale/test/out/polygon-with-hole.geojson b/src/transform-scale/test/out/polygon-with-hole.geojson similarity index 100% rename from packages/turf-transform-scale/test/out/polygon-with-hole.geojson rename to src/transform-scale/test/out/polygon-with-hole.geojson diff --git a/src/transform-scale/test/out/polygon.geojson b/src/transform-scale/test/out/polygon.geojson new file mode 100644 index 0000000000..13b24c6eeb --- /dev/null +++ b/src/transform-scale/test/out/polygon.geojson @@ -0,0 +1,79 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "factor": 0.1, + "stroke": "#F00", + "stroke-width": 4 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 1.799105, + 29.9 + ], + [ + 2.150671, + 29.9 + ], + [ + 2.049534, + 30.2 + ], + [ + 1.799105, + 29.9 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "factor": 0.1 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + 29 + ], + [ + 3.5, + 29 + ], + [ + 2.5, + 32 + ], + [ + 0, + 29 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#00F", + "marker-symbol": "circle" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 2, + 30 + ] + } + } + ] +} diff --git a/packages/turf-transform-scale/test/out/z-scaling.geojson b/src/transform-scale/test/out/z-scaling.geojson similarity index 81% rename from packages/turf-transform-scale/test/out/z-scaling.geojson rename to src/transform-scale/test/out/z-scaling.geojson index 8f64808144..f198f7f7fc 100644 --- a/packages/turf-transform-scale/test/out/z-scaling.geojson +++ b/src/transform-scale/test/out/z-scaling.geojson @@ -13,33 +13,33 @@ "coordinates": [ [ [ - 116.380061, - -23.894765, + 115.36303, + -23.89655, 23 ], [ - 125.685905, - -32.181535, + 124.629212, + -32.18332, 25.3 ], [ - 135.271208, - -27.750547, + 134.23767, + -27.752333, 27.6 ], [ - 134.197527, - -19.707477, + 133.195438, + -19.709263, 29.9 ], [ - 124.379669, - -15.844736, + 123.388452, + -15.846522, 32.2 ], [ - 116.380061, - -23.894765, + 115.36303, + -23.89655, 23 ] ] @@ -98,8 +98,8 @@ "geometry": { "type": "Point", "coordinates": [ - 125.3759765625, - -23.878970838788252 + 126.158203125, + -23.87759746657351 ] } } diff --git a/packages/turf-transform-translate/bench.js b/src/transform-translate/bench.js similarity index 100% rename from packages/turf-transform-translate/bench.js rename to src/transform-translate/bench.js diff --git a/src/transform-translate/index.d.ts b/src/transform-translate/index.d.ts new file mode 100644 index 0000000000..79c93852a6 --- /dev/null +++ b/src/transform-translate/index.d.ts @@ -0,0 +1,15 @@ +import { AllGeoJSON, Units } from '../helpers' + +/** + * http://turfjs.org/docs/#transform-translate + */ +export default function transformTranslate( + geojson: T, + distance: number, + direction: number, + options?: { + units?: Units, + zTranslation?: number, + mutate?: boolean + } +): T; \ No newline at end of file diff --git a/src/transform-translate/index.js b/src/transform-translate/index.js new file mode 100644 index 0000000000..1d7d470199 --- /dev/null +++ b/src/transform-translate/index.js @@ -0,0 +1,66 @@ +import { coordEach } from '../meta'; +import { isObject } from '../helpers'; +import { getCoords } from '../invariant'; +import clone from '../clone'; +import rhumbDestination from '../rhumb-destination'; + +/** + * Moves any geojson Feature or Geometry of a specified distance along a Rhumb Line + * on the provided direction angle. + * + * @name transformTranslate + * @param {GeoJSON} geojson object to be translated + * @param {number} distance length of the motion; negative values determine motion in opposite direction + * @param {number} direction of the motion; angle from North in decimal degrees, positive clockwise + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] in which `distance` will be express; miles, kilometers, degrees, or radians + * @param {number} [options.zTranslation=0] length of the vertical motion, same unit of distance + * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) + * @returns {GeoJSON} the translated GeoJSON object + * @example + * var poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]); + * var translatedPoly = turf.transformTranslate(poly, 100, 35); + * + * //addToMap + * var addToMap = [poly, translatedPoly]; + * translatedPoly.properties = {stroke: '#F00', 'stroke-width': 4}; + */ +function transformTranslate(geojson, distance, direction, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var units = options.units; + var zTranslation = options.zTranslation; + var mutate = options.mutate; + + // Input validation + if (!geojson) throw new Error('geojson is required'); + if (distance === undefined || distance === null || isNaN(distance)) throw new Error('distance is required'); + if (zTranslation && typeof zTranslation !== 'number' && isNaN(zTranslation)) throw new Error('zTranslation is not a number'); + + // Shortcut no-motion + zTranslation = (zTranslation !== undefined) ? zTranslation : 0; + if (distance === 0 && zTranslation === 0) return geojson; + + if (direction === undefined || direction === null || isNaN(direction)) throw new Error('direction is required'); + + // Invert with negative distances + if (distance < 0) { + distance = -distance; + direction = direction + 180; + } + + // Clone geojson to avoid side effects + if (mutate === false || mutate === undefined) geojson = clone(geojson); + + // Translate each coordinate + coordEach(geojson, function (pointCoords) { + var newCoords = getCoords(rhumbDestination(pointCoords, distance, direction, {units: units})); + pointCoords[0] = newCoords[0]; + pointCoords[1] = newCoords[1]; + if (zTranslation && pointCoords.length === 3) pointCoords[2] += zTranslation; + }); + return geojson; +} + +export default transformTranslate; diff --git a/src/transform-translate/test.js b/src/transform-translate/test.js new file mode 100644 index 0000000000..a287b7d6c3 --- /dev/null +++ b/src/transform-translate/test.js @@ -0,0 +1,82 @@ +import fs from 'fs'; +import test from 'tape'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import truncate from '../truncate'; +import { point, lineString, geometryCollection, featureCollection } from '../helpers'; +import translate from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('translate', t => { + for (const {filename, name, geojson} of fixtures) { + let {distance, direction, units, zTranslation} = geojson.properties || {}; + + const translated = translate(geojson, distance, direction, {units, zTranslation}); + const result = featureCollection([colorize(truncate(translated, {precision: 6, coordiantes: 3})), geojson]); + + if (process.env.REGEN) write.sync(directories.out + filename, result); + t.deepEqual(result, load.sync(directories.out + filename), name); + } + + t.end(); +}); + +test('translate -- throws', t => { + const pt = point([-70.823364, -33.553984]); + + t.throws(() => translate(null, 100, -29), 'missing geojson'); + t.throws(() => translate(pt, null, 98), 'missing distance'); + t.throws(() => translate(pt, 23, null), 'missing direction'); + t.throws(() => translate(pt, 56, 57, {units: 'foo'}), 'invalid units'); + t.throws(() => translate(pt, 56, 57, {zTranslation: 'foo'}), 'invalid zTranslation'); + + t.end(); +}); + +test('rotate -- mutated input', t => { + const line = lineString([[10, 10], [12, 15]]); + const lineBefore = JSON.parse(JSON.stringify(line)); + + translate(line, 100, 50); + t.deepEqual(line, lineBefore, 'input should NOT be mutated'); + + translate(line, 100, 50, {units: 'kilometers', mutate: true}); + t.deepEqual(truncate(line, {precision: 1}), lineString([[10.7, 10.6], [12.7, 15.6]]), 'input should be mutated'); + t.end(); +}); + +test('rotate -- geometry support', t => { + const line = lineString([[10, 10], [12, 15]]); + t.assert(translate(geometryCollection([line.geometry]), 100, 50), 'geometryCollection support'); + t.assert(translate(geometryCollection([line.geometry]).geometry, 100, 50), 'geometryCollection support'); + t.assert(translate(featureCollection([line]), 100, 50), 'featureCollection support'); + t.assert(translate(line.geometry, 100, 50), 'geometry line support'); + t.assert(translate(line.geometry, 100, 50), 'geometry pt support'); + t.assert(translate(line, 0, 100), 'shortcut no-motion'); + t.end(); +}); + +// style result +function colorize(geojson) { + if (geojson.geometry.type === 'Point' || geojson.geometry.type === 'MultiPoint') { + geojson.properties['marker-color'] = '#F00'; + geojson.properties['marker-symbol'] = 'star'; + } else { + geojson.properties['stroke'] = '#F00'; + geojson.properties['stroke-width'] = 4; + } + return geojson; +} diff --git a/packages/turf-transform-translate/test/in/line.geojson b/src/transform-translate/test/in/line.geojson similarity index 100% rename from packages/turf-transform-translate/test/in/line.geojson rename to src/transform-translate/test/in/line.geojson diff --git a/packages/turf-transform-translate/test/in/multiLine.geojson b/src/transform-translate/test/in/multiLine.geojson similarity index 100% rename from packages/turf-transform-translate/test/in/multiLine.geojson rename to src/transform-translate/test/in/multiLine.geojson diff --git a/packages/turf-transform-translate/test/in/multiPoint.geojson b/src/transform-translate/test/in/multiPoint.geojson similarity index 100% rename from packages/turf-transform-translate/test/in/multiPoint.geojson rename to src/transform-translate/test/in/multiPoint.geojson diff --git a/packages/turf-transform-translate/test/in/multiPolygon.geojson b/src/transform-translate/test/in/multiPolygon.geojson similarity index 100% rename from packages/turf-transform-translate/test/in/multiPolygon.geojson rename to src/transform-translate/test/in/multiPolygon.geojson diff --git a/packages/turf-transform-translate/test/in/no-motion.geojson b/src/transform-translate/test/in/no-motion.geojson similarity index 100% rename from packages/turf-transform-translate/test/in/no-motion.geojson rename to src/transform-translate/test/in/no-motion.geojson diff --git a/packages/turf-transform-translate/test/in/point.geojson b/src/transform-translate/test/in/point.geojson similarity index 100% rename from packages/turf-transform-translate/test/in/point.geojson rename to src/transform-translate/test/in/point.geojson diff --git a/packages/turf-transform-translate/test/in/polygon-fiji.geojson b/src/transform-translate/test/in/polygon-fiji.geojson similarity index 100% rename from packages/turf-transform-translate/test/in/polygon-fiji.geojson rename to src/transform-translate/test/in/polygon-fiji.geojson diff --git a/packages/turf-transform-translate/test/in/polygon-resolute-bay.geojson b/src/transform-translate/test/in/polygon-resolute-bay.geojson similarity index 100% rename from packages/turf-transform-translate/test/in/polygon-resolute-bay.geojson rename to src/transform-translate/test/in/polygon-resolute-bay.geojson diff --git a/packages/turf-transform-translate/test/in/polygon-with-hole.geojson b/src/transform-translate/test/in/polygon-with-hole.geojson similarity index 100% rename from packages/turf-transform-translate/test/in/polygon-with-hole.geojson rename to src/transform-translate/test/in/polygon-with-hole.geojson diff --git a/packages/turf-transform-translate/test/in/polygon.geojson b/src/transform-translate/test/in/polygon.geojson similarity index 100% rename from packages/turf-transform-translate/test/in/polygon.geojson rename to src/transform-translate/test/in/polygon.geojson diff --git a/packages/turf-transform-translate/test/in/z-translation.geojson b/src/transform-translate/test/in/z-translation.geojson similarity index 100% rename from packages/turf-transform-translate/test/in/z-translation.geojson rename to src/transform-translate/test/in/z-translation.geojson diff --git a/packages/turf-transform-translate/test/out/line.geojson b/src/transform-translate/test/out/line.geojson similarity index 100% rename from packages/turf-transform-translate/test/out/line.geojson rename to src/transform-translate/test/out/line.geojson diff --git a/packages/turf-transform-translate/test/out/multiLine.geojson b/src/transform-translate/test/out/multiLine.geojson similarity index 100% rename from packages/turf-transform-translate/test/out/multiLine.geojson rename to src/transform-translate/test/out/multiLine.geojson diff --git a/packages/turf-transform-translate/test/out/multiPoint.geojson b/src/transform-translate/test/out/multiPoint.geojson similarity index 100% rename from packages/turf-transform-translate/test/out/multiPoint.geojson rename to src/transform-translate/test/out/multiPoint.geojson diff --git a/packages/turf-transform-translate/test/out/multiPolygon.geojson b/src/transform-translate/test/out/multiPolygon.geojson similarity index 100% rename from packages/turf-transform-translate/test/out/multiPolygon.geojson rename to src/transform-translate/test/out/multiPolygon.geojson diff --git a/packages/turf-transform-translate/test/out/no-motion.geojson b/src/transform-translate/test/out/no-motion.geojson similarity index 100% rename from packages/turf-transform-translate/test/out/no-motion.geojson rename to src/transform-translate/test/out/no-motion.geojson diff --git a/packages/turf-transform-translate/test/out/point.geojson b/src/transform-translate/test/out/point.geojson similarity index 100% rename from packages/turf-transform-translate/test/out/point.geojson rename to src/transform-translate/test/out/point.geojson diff --git a/packages/turf-transform-translate/test/out/polygon-fiji.geojson b/src/transform-translate/test/out/polygon-fiji.geojson similarity index 100% rename from packages/turf-transform-translate/test/out/polygon-fiji.geojson rename to src/transform-translate/test/out/polygon-fiji.geojson diff --git a/packages/turf-transform-translate/test/out/polygon-resolute-bay.geojson b/src/transform-translate/test/out/polygon-resolute-bay.geojson similarity index 100% rename from packages/turf-transform-translate/test/out/polygon-resolute-bay.geojson rename to src/transform-translate/test/out/polygon-resolute-bay.geojson diff --git a/packages/turf-transform-translate/test/out/polygon-with-hole.geojson b/src/transform-translate/test/out/polygon-with-hole.geojson similarity index 100% rename from packages/turf-transform-translate/test/out/polygon-with-hole.geojson rename to src/transform-translate/test/out/polygon-with-hole.geojson diff --git a/packages/turf-transform-translate/test/out/polygon.geojson b/src/transform-translate/test/out/polygon.geojson similarity index 100% rename from packages/turf-transform-translate/test/out/polygon.geojson rename to src/transform-translate/test/out/polygon.geojson diff --git a/packages/turf-transform-translate/test/out/z-translation.geojson b/src/transform-translate/test/out/z-translation.geojson similarity index 100% rename from packages/turf-transform-translate/test/out/z-translation.geojson rename to src/transform-translate/test/out/z-translation.geojson diff --git a/packages/turf-triangle-grid/bench.js b/src/triangle-grid/bench.js similarity index 100% rename from packages/turf-triangle-grid/bench.js rename to src/triangle-grid/bench.js diff --git a/src/triangle-grid/index.js b/src/triangle-grid/index.js new file mode 100644 index 0000000000..e2885b116f --- /dev/null +++ b/src/triangle-grid/index.js @@ -0,0 +1,131 @@ +import distance from '../distance'; +import intersect from '../intersect'; +import {getType} from '../invariant'; +import {polygon, featureCollection, isObject, isNumber} from '../helpers'; + +/** + * Takes a bounding box and a cell depth and returns a set of triangular {@link Polygon|polygons} in a grid. + * + * @name triangleGrid + * @param {Array} bbox extent in [minX, minY, maxX, maxY] order + * @param {number} cellSide dimension of each cell + * @param {Object} [options={}] Optional parameters + * @param {string} [options.units='kilometers'] used in calculating cellSide, can be degrees, radians, miles, or kilometers + * @param {Feature} [options.mask] if passed a Polygon or MultiPolygon, the grid Points will be created only inside it + * @param {Object} [options.properties={}] passed to each point of the grid + * @returns {FeatureCollection} grid of polygons + * @example + * var bbox = [-95, 30 ,-85, 40]; + * var cellSide = 50; + * var options = {units: 'miles'}; + * + * var triangleGrid = turf.triangleGrid(bbox, cellSide, options); + * + * //addToMap + * var addToMap = [triangleGrid]; + */ +function triangleGrid(bbox, cellSide, options) { + // Optional parameters + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + // var units = options.units; + var properties = options.properties; + var mask = options.mask; + + // Containers + var results = []; + + // Input Validation + if (cellSide === null || cellSide === undefined) throw new Error('cellSide is required'); + if (!isNumber(cellSide)) throw new Error('cellSide is invalid'); + if (!bbox) throw new Error('bbox is required'); + if (!Array.isArray(bbox)) throw new Error('bbox must be array'); + if (bbox.length !== 4) throw new Error('bbox must contain 4 numbers'); + if (mask && ['Polygon', 'MultiPolygon'].indexOf(getType(mask)) === -1) throw new Error('options.mask must be a (Multi)Polygon'); + + // Main + var xFraction = cellSide / (distance([bbox[0], bbox[1]], [bbox[2], bbox[1]], options)); + var cellWidth = xFraction * (bbox[2] - bbox[0]); + var yFraction = cellSide / (distance([bbox[0], bbox[1]], [bbox[0], bbox[3]], options)); + var cellHeight = yFraction * (bbox[3] - bbox[1]); + + var xi = 0; + var currentX = bbox[0]; + while (currentX <= bbox[2]) { + var yi = 0; + var currentY = bbox[1]; + while (currentY <= bbox[3]) { + var cellTriangle1 = null; + var cellTriangle2 = null; + + if (xi % 2 === 0 && yi % 2 === 0) { + cellTriangle1 = polygon([[ + [currentX, currentY], + [currentX, currentY + cellHeight], + [currentX + cellWidth, currentY], + [currentX, currentY] + ]], properties); + cellTriangle2 = polygon([[ + [currentX, currentY + cellHeight], + [currentX + cellWidth, currentY + cellHeight], + [currentX + cellWidth, currentY], + [currentX, currentY + cellHeight] + ]], properties); + } else if (xi % 2 === 0 && yi % 2 === 1) { + cellTriangle1 = polygon([[ + [currentX, currentY], + [currentX + cellWidth, currentY + cellHeight], + [currentX + cellWidth, currentY], + [currentX, currentY] + ]], properties); + cellTriangle2 = polygon([[ + [currentX, currentY], + [currentX, currentY + cellHeight], + [currentX + cellWidth, currentY + cellHeight], + [currentX, currentY] + ]], properties); + } else if (yi % 2 === 0 && xi % 2 === 1) { + cellTriangle1 = polygon([[ + [currentX, currentY], + [currentX, currentY + cellHeight], + [currentX + cellWidth, currentY + cellHeight], + [currentX, currentY] + ]], properties); + cellTriangle2 = polygon([[ + [currentX, currentY], + [currentX + cellWidth, currentY + cellHeight], + [currentX + cellWidth, currentY], + [currentX, currentY] + ]], properties); + } else if (yi % 2 === 1 && xi % 2 === 1) { + cellTriangle1 = polygon([[ + [currentX, currentY], + [currentX, currentY + cellHeight], + [currentX + cellWidth, currentY], + [currentX, currentY] + ]], properties); + cellTriangle2 = polygon([[ + [currentX, currentY + cellHeight], + [currentX + cellWidth, currentY + cellHeight], + [currentX + cellWidth, currentY], + [currentX, currentY + cellHeight] + ]], properties); + } + if (mask) { + if (intersect(mask, cellTriangle1)) results.push(cellTriangle1); + if (intersect(mask, cellTriangle2)) results.push(cellTriangle2); + } else { + results.push(cellTriangle1); + results.push(cellTriangle2); + } + + currentY += cellHeight; + yi++; + } + xi++; + currentX += cellWidth; + } + return featureCollection(results); +} + +export default triangleGrid; diff --git a/src/triangle-grid/test.js b/src/triangle-grid/test.js new file mode 100644 index 0000000000..4fb063c79b --- /dev/null +++ b/src/triangle-grid/test.js @@ -0,0 +1,63 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const bboxPoly = require('../bbox-polygon').default; +const truncate = require('../truncate').default; +const triangleGrid = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + json: load.sync(directories.in + filename) + }; +}); + +test('triangle-grid', t => { + for (const {name, json} of fixtures) { + const {bbox, cellSide} = json; + const options = json; + const result = truncate(triangleGrid(bbox, cellSide, options)); + + // Add styled GeoJSON to the result + const poly = bboxPoly(bbox); + poly.properties = { + stroke: '#F00', + 'stroke-width': 6, + 'fill-opacity': 0 + }; + result.features.push(poly); + if (options.mask) { + options.mask.properties = { + "stroke": "#00F", + "stroke-width": 6, + "fill-opacity": 0 + }; + result.features.push(options.mask); + } + + if (process.env.REGEN) write.sync(directories.out + name + '.geojson', result); + t.deepEqual(result, load.sync(directories.out + name + '.geojson'), name); + } + t.end(); +}); + + +test('square-grid -- throw', t => { + const bbox = [0, 0, 1, 1]; + // Types is managed by Typescript + // t.throws(() => triangleGrid(null, 0), /bbox is required/, 'missing bbox'); + // t.throws(() => triangleGrid('string', 0), /bbox must be array/, 'invalid bbox'); + // t.throws(() => triangleGrid([0, 2], 0), /bbox must contain 4 numbers/, 'invalid bbox'); + // t.throws(() => triangleGrid(bbox, null), /cellSide is required/, 'missing cellSide'); + // t.throws(() => triangleGrid(bbox, 'string'), /cellSide is invalid/, 'invalid cellSide'); + // t.throws(() => triangleGrid(bbox, 1, 'string'), /options is invalid/, 'invalid options'); + t.end(); +}); diff --git a/packages/turf-triangle-grid/test/in/big-bbox.json b/src/triangle-grid/test/in/big-bbox.json similarity index 100% rename from packages/turf-triangle-grid/test/in/big-bbox.json rename to src/triangle-grid/test/in/big-bbox.json diff --git a/packages/turf-triangle-grid/test/in/fiji-10-miles.json b/src/triangle-grid/test/in/fiji-10-miles.json similarity index 100% rename from packages/turf-triangle-grid/test/in/fiji-10-miles.json rename to src/triangle-grid/test/in/fiji-10-miles.json diff --git a/packages/turf-triangle-grid/test/in/london-20-miles.json b/src/triangle-grid/test/in/london-20-miles.json similarity index 100% rename from packages/turf-triangle-grid/test/in/london-20-miles.json rename to src/triangle-grid/test/in/london-20-miles.json diff --git a/packages/turf-triangle-grid/test/in/piedemont-mask.json b/src/triangle-grid/test/in/piedemont-mask.json similarity index 100% rename from packages/turf-triangle-grid/test/in/piedemont-mask.json rename to src/triangle-grid/test/in/piedemont-mask.json diff --git a/packages/turf-triangle-grid/test/in/properties.json b/src/triangle-grid/test/in/properties.json similarity index 100% rename from packages/turf-triangle-grid/test/in/properties.json rename to src/triangle-grid/test/in/properties.json diff --git a/packages/turf-triangle-grid/test/in/resolute.json b/src/triangle-grid/test/in/resolute.json similarity index 100% rename from packages/turf-triangle-grid/test/in/resolute.json rename to src/triangle-grid/test/in/resolute.json diff --git a/packages/turf-triangle-grid/test/out/big-bbox.geojson b/src/triangle-grid/test/out/big-bbox.geojson similarity index 100% rename from packages/turf-triangle-grid/test/out/big-bbox.geojson rename to src/triangle-grid/test/out/big-bbox.geojson diff --git a/packages/turf-triangle-grid/test/out/fiji-10-miles.geojson b/src/triangle-grid/test/out/fiji-10-miles.geojson similarity index 100% rename from packages/turf-triangle-grid/test/out/fiji-10-miles.geojson rename to src/triangle-grid/test/out/fiji-10-miles.geojson diff --git a/packages/turf-triangle-grid/test/out/london-20-miles.geojson b/src/triangle-grid/test/out/london-20-miles.geojson similarity index 100% rename from packages/turf-triangle-grid/test/out/london-20-miles.geojson rename to src/triangle-grid/test/out/london-20-miles.geojson diff --git a/packages/turf-triangle-grid/test/out/piedemont-mask.geojson b/src/triangle-grid/test/out/piedemont-mask.geojson similarity index 100% rename from packages/turf-triangle-grid/test/out/piedemont-mask.geojson rename to src/triangle-grid/test/out/piedemont-mask.geojson diff --git a/packages/turf-triangle-grid/test/out/properties.geojson b/src/triangle-grid/test/out/properties.geojson similarity index 100% rename from packages/turf-triangle-grid/test/out/properties.geojson rename to src/triangle-grid/test/out/properties.geojson diff --git a/packages/turf-triangle-grid/test/out/resolute.geojson b/src/triangle-grid/test/out/resolute.geojson similarity index 100% rename from packages/turf-triangle-grid/test/out/resolute.geojson rename to src/triangle-grid/test/out/resolute.geojson diff --git a/packages/turf-truncate/bench.js b/src/truncate/bench.js similarity index 100% rename from packages/turf-truncate/bench.js rename to src/truncate/bench.js diff --git a/src/truncate/index.js b/src/truncate/index.js new file mode 100644 index 0000000000..ed9b8da861 --- /dev/null +++ b/src/truncate/index.js @@ -0,0 +1,76 @@ +import { coordEach } from '../meta'; +import { checkIfOptionsExist } from '../helpers'; + +/** + * Takes a GeoJSON Feature or FeatureCollection and truncates the precision of the geometry. + * + * @name truncate + * @param {GeoJSON} geojson any GeoJSON Feature, FeatureCollection, Geometry or GeometryCollection. + * @param {Object} [options={}] Optional parameters + * @param {number} [options.precision=6] coordinate decimal precision + * @param {number} [options.coordinates=3] maximum number of coordinates (primarly used to remove z coordinates) + * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) + * @returns {GeoJSON} layer with truncated geometry + * @example + * var point = turf.point([ + * 70.46923055566859, + * 58.11088890802906, + * 1508 + * ]); + * var options = {precision: 3, coordinates: 2}; + * var truncated = turf.truncate(point, options); + * //=truncated.geometry.coordinates => [70.469, 58.111] + * + * //addToMap + * var addToMap = [truncated]; + */ +function truncate(geojson, options) { + + options = checkIfOptionsExist(options); + // Optional parameters + var precision = options.precision; + var coordinates = options.coordinates; + var mutate = options.mutate; + + // default params + precision = (precision === undefined || precision === null || isNaN(precision)) ? 6 : precision; + coordinates = (coordinates === undefined || coordinates === null || isNaN(coordinates)) ? 3 : coordinates; + + // validation + if (!geojson) throw new Error(' is required'); + if (typeof precision !== 'number') throw new Error(' must be a number'); + if (typeof coordinates !== 'number') throw new Error(' must be a number'); + + // prevent input mutation + if (mutate === false || mutate === undefined) geojson = JSON.parse(JSON.stringify(geojson)); + + var factor = Math.pow(10, precision); + + // Truncate Coordinates + coordEach(geojson, function (coords) { + truncateCoords(coords, factor, coordinates); + }); + return geojson; +} + +/** + * Truncate Coordinates - Mutates coordinates in place + * + * @private + * @param {Array} coords Geometry Coordinates + * @param {number} factor rounding factor for coordinate decimal precision + * @param {number} coordinates maximum number of coordinates (primarly used to remove z coordinates) + * @returns {Array} mutated coordinates + */ +function truncateCoords(coords, factor, coordinates) { + // Remove extra coordinates (usually elevation coordinates and more) + if (coords.length > coordinates) coords.splice(coordinates, coords.length); + + // Truncate coordinate decimals + for (var i = 0; i < coords.length; i++) { + coords[i] = Math.round(coords[i] * factor) / factor; + } + return coords; +} + +export default truncate; diff --git a/src/truncate/test.js b/src/truncate/test.js new file mode 100644 index 0000000000..5de8b9a421 --- /dev/null +++ b/src/truncate/test.js @@ -0,0 +1,55 @@ +const fs = require('fs'); +const test = require('tape'); +const path = require('path'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const { point } = require('../helpers'); +const truncate = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +let fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); +// fixtures = fixtures.filter(fixture => fixture.name === 'points'); + +test('turf-truncate', t => { + for (const {filename, name, geojson} of fixtures) { + const {precision, coordinates} = geojson.properties || {}; + const results = truncate(geojson, { + precision: precision, + coordinates: coordinates + }); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + t.deepEqual(results, load.sync(directories.out + filename), name); + } + t.end(); +}); + +test('turf-truncate - precision & coordinates', t => { + t.deepEqual(truncate(point([50.1234567, 40.1234567]), {precision: 3}).geometry.coordinates, [50.123, 40.123], 'precision 3'); + t.deepEqual(truncate(point([50.1234567, 40.1234567]), {precision: 0}).geometry.coordinates, [50, 40], 'precision 0'); + t.deepEqual(truncate(point([50, 40, 1100]), {precision: 6}).geometry.coordinates, [50, 40, 1100], 'coordinates default to 3'); + t.deepEqual(truncate(point([50, 40, 1100]), {precision: 6, coordinates: 2}).geometry.coordinates, [50, 40], 'coordinates 2'); + t.end(); +}); + +test('turf-truncate - prevent input mutation', t => { + const pt = point([120.123, 40.123, 3000]); + const ptBefore = JSON.parse(JSON.stringify(pt)); + + truncate(pt, {precision: 0}); + t.deepEqual(ptBefore, pt, 'does not mutate input'); + + truncate(pt, {precision: 0, coordinates: 2, mutate: true}); + t.deepEqual(pt, point([120, 40]), 'does mutate input'); + t.end(); +}); diff --git a/packages/turf-truncate/test/in/geometry-collection.geojson b/src/truncate/test/in/geometry-collection.geojson similarity index 100% rename from packages/turf-truncate/test/in/geometry-collection.geojson rename to src/truncate/test/in/geometry-collection.geojson diff --git a/packages/turf-truncate/test/in/linestring-geometry.geojson b/src/truncate/test/in/linestring-geometry.geojson similarity index 100% rename from packages/turf-truncate/test/in/linestring-geometry.geojson rename to src/truncate/test/in/linestring-geometry.geojson diff --git a/packages/turf-truncate/test/in/point-elevation.geojson b/src/truncate/test/in/point-elevation.geojson similarity index 100% rename from packages/turf-truncate/test/in/point-elevation.geojson rename to src/truncate/test/in/point-elevation.geojson diff --git a/packages/turf-truncate/test/in/point-geometry.geojson b/src/truncate/test/in/point-geometry.geojson similarity index 100% rename from packages/turf-truncate/test/in/point-geometry.geojson rename to src/truncate/test/in/point-geometry.geojson diff --git a/packages/turf-truncate/test/in/point.geojson b/src/truncate/test/in/point.geojson similarity index 100% rename from packages/turf-truncate/test/in/point.geojson rename to src/truncate/test/in/point.geojson diff --git a/packages/turf-truncate/test/in/points.geojson b/src/truncate/test/in/points.geojson similarity index 100% rename from packages/turf-truncate/test/in/points.geojson rename to src/truncate/test/in/points.geojson diff --git a/packages/turf-truncate/test/in/polygon.geojson b/src/truncate/test/in/polygon.geojson similarity index 100% rename from packages/turf-truncate/test/in/polygon.geojson rename to src/truncate/test/in/polygon.geojson diff --git a/packages/turf-truncate/test/in/polygons.geojson b/src/truncate/test/in/polygons.geojson similarity index 100% rename from packages/turf-truncate/test/in/polygons.geojson rename to src/truncate/test/in/polygons.geojson diff --git a/packages/turf-truncate/test/out/geometry-collection.geojson b/src/truncate/test/out/geometry-collection.geojson similarity index 100% rename from packages/turf-truncate/test/out/geometry-collection.geojson rename to src/truncate/test/out/geometry-collection.geojson diff --git a/packages/turf-truncate/test/out/linestring-geometry.geojson b/src/truncate/test/out/linestring-geometry.geojson similarity index 100% rename from packages/turf-truncate/test/out/linestring-geometry.geojson rename to src/truncate/test/out/linestring-geometry.geojson diff --git a/packages/turf-truncate/test/out/point-elevation.geojson b/src/truncate/test/out/point-elevation.geojson similarity index 100% rename from packages/turf-truncate/test/out/point-elevation.geojson rename to src/truncate/test/out/point-elevation.geojson diff --git a/packages/turf-truncate/test/out/point-geometry.geojson b/src/truncate/test/out/point-geometry.geojson similarity index 100% rename from packages/turf-truncate/test/out/point-geometry.geojson rename to src/truncate/test/out/point-geometry.geojson diff --git a/packages/turf-truncate/test/out/point.geojson b/src/truncate/test/out/point.geojson similarity index 100% rename from packages/turf-truncate/test/out/point.geojson rename to src/truncate/test/out/point.geojson diff --git a/packages/turf-truncate/test/out/points.geojson b/src/truncate/test/out/points.geojson similarity index 100% rename from packages/turf-truncate/test/out/points.geojson rename to src/truncate/test/out/points.geojson diff --git a/packages/turf-truncate/test/out/polygon.geojson b/src/truncate/test/out/polygon.geojson similarity index 100% rename from packages/turf-truncate/test/out/polygon.geojson rename to src/truncate/test/out/polygon.geojson diff --git a/packages/turf-truncate/test/out/polygons.geojson b/src/truncate/test/out/polygons.geojson similarity index 100% rename from packages/turf-truncate/test/out/polygons.geojson rename to src/truncate/test/out/polygons.geojson diff --git a/packages/turf-union/bench.js b/src/union/bench.js similarity index 100% rename from packages/turf-union/bench.js rename to src/union/bench.js diff --git a/src/union/index.js b/src/union/index.js new file mode 100644 index 0000000000..6b6ca01ca4 --- /dev/null +++ b/src/union/index.js @@ -0,0 +1,43 @@ +import polygonClipping from 'polygon-clipping/dist/polygon-clipping.esm.js'; +import { multiPolygon } from '../helpers'; +import { geomEach } from '../meta'; + +/** + * Takes two or more {@link Polygon|polygons} and returns a combined polygon. If the input polygons are not contiguous, this function returns a {@link MultiPolygon} feature. + * + * @name union + * @param {Feature} fc a FeatureCollection containting polygons or multipolygons to union + * @returns {Feature<(Polygon|MultiPolygon)>} a combined {@link Polygon} or {@link MultiPolygon} feature + * @example + * var poly1 = turf.polygon([[ + * [-82.574787, 35.594087], + * [-82.574787, 35.615581], + * [-82.545261, 35.615581], + * [-82.545261, 35.594087], + * [-82.574787, 35.594087] + * ]], {"fill": "#0f0"}); + * var poly2 = turf.polygon([[ + * [-82.560024, 35.585153], + * [-82.560024, 35.602602], + * [-82.52964, 35.602602], + * [-82.52964, 35.585153], + * [-82.560024, 35.585153] + * ]], {"fill": "#00f"}); + * + * var union = turf.union(poly1, poly2); + * + * //addToMap + * var addToMap = [poly1, poly2, union]; + */ +function union(fc) { + const args = []; + geomEach(fc, function (geom) { + if (geom.type === 'MultiPolygon') args.push(geom.coordinates); + if (geom.type === 'Polygon') args.push([geom.coordinates]); + }); + const unioned = polygonClipping.union(...args); + if (unioned.length === 0) return null; + else return multiPolygon(unioned); +} + +export default union; diff --git a/src/union/test.js b/src/union/test.js new file mode 100644 index 0000000000..d3b9c232fe --- /dev/null +++ b/src/union/test.js @@ -0,0 +1,29 @@ +const fs = require('fs'); +const path = require('path'); +const test = require('tape'); +const load = require('load-json-file'); +const write = require('write-json-file'); +const combine = require('../combine').default; +const union = require('./').default; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return { + filename, + name: path.parse(filename).name, + geojson: load.sync(directories.in + filename) + }; +}); + +test('union', function (t) { + for (const {name, geojson, filename} of fixtures) { + let result = union(geojson); + if (process.env.REGEN) write.sync(directories.out + filename, result); + t.deepEqual(result, load.sync(directories.out + filename), name); + } + t.end(); +}); diff --git a/packages/turf-union/test/in/not-overlapping.geojson b/src/union/test/in/not-overlapping.geojson similarity index 100% rename from packages/turf-union/test/in/not-overlapping.geojson rename to src/union/test/in/not-overlapping.geojson diff --git a/src/union/test/in/other.geojson b/src/union/test/in/other.geojson new file mode 100644 index 0000000000..f57ec65c34 --- /dev/null +++ b/src/union/test/in/other.geojson @@ -0,0 +1,10 @@ +{ +"type": "FeatureCollection", +"features": [ +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -75.736, 45.363 ], [ -75.727, 45.361 ], [ -75.723, 45.354 ], [ -75.727, 45.348 ], [ -75.736, 45.345 ], [ -75.745, 45.348 ], [ -75.749, 45.354 ], [ -75.745, 45.361 ], [ -75.736, 45.363 ] ] ] } }, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -75.739, 45.37 ], [ -75.73, 45.368 ], [ -75.726, 45.361 ], [ -75.73, 45.355 ], [ -75.739, 45.352 ], [ -75.748, 45.355 ], [ -75.752, 45.361 ], [ -75.748, 45.368 ], [ -75.739, 45.37 ] ] ] } }, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -75.736, 45.369 ], [ -75.727, 45.366 ], [ -75.723, 45.36 ], [ -75.727, 45.354 ], [ -75.736, 45.351 ], [ -75.745, 45.354 ], [ -75.749, 45.36 ], [ -75.745, 45.366 ], [ -75.736, 45.369 ] ] ] } }, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -75.736, 45.364 ], [ -75.727, 45.361 ], [ -75.723, 45.355 ], [ -75.727, 45.349 ], [ -75.736, 45.346 ], [ -75.745, 45.349 ], [ -75.748, 45.355 ], [ -75.745, 45.361 ], [ -75.736, 45.364 ] ] ] } }, +{ "type": "Feature", "properties": { }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -75.734, 45.372 ], [ -75.725, 45.37 ], [ -75.721, 45.363 ], [ -75.725, 45.357 ], [ -75.734, 45.354 ], [ -75.743, 45.357 ], [ -75.747, 45.363 ], [ -75.743, 45.37 ], [ -75.734, 45.372 ] ] ] } } +] +} \ No newline at end of file diff --git a/packages/turf-union/test/in/union1.geojson b/src/union/test/in/union1.geojson similarity index 100% rename from packages/turf-union/test/in/union1.geojson rename to src/union/test/in/union1.geojson diff --git a/packages/turf-union/test/in/union2.geojson b/src/union/test/in/union2.geojson similarity index 100% rename from packages/turf-union/test/in/union2.geojson rename to src/union/test/in/union2.geojson diff --git a/packages/turf-union/test/in/union3.geojson b/src/union/test/in/union3.geojson similarity index 100% rename from packages/turf-union/test/in/union3.geojson rename to src/union/test/in/union3.geojson diff --git a/packages/turf-union/test/out/jsts/not-overlapping.geojson b/src/union/test/out/jsts/not-overlapping.geojson similarity index 100% rename from packages/turf-union/test/out/jsts/not-overlapping.geojson rename to src/union/test/out/jsts/not-overlapping.geojson diff --git a/packages/turf-union/test/out/jsts/union1.geojson b/src/union/test/out/jsts/union1.geojson similarity index 100% rename from packages/turf-union/test/out/jsts/union1.geojson rename to src/union/test/out/jsts/union1.geojson diff --git a/packages/turf-union/test/out/jsts/union2.geojson b/src/union/test/out/jsts/union2.geojson similarity index 100% rename from packages/turf-union/test/out/jsts/union2.geojson rename to src/union/test/out/jsts/union2.geojson diff --git a/packages/turf-union/test/out/jsts/union3.geojson b/src/union/test/out/jsts/union3.geojson similarity index 100% rename from packages/turf-union/test/out/jsts/union3.geojson rename to src/union/test/out/jsts/union3.geojson diff --git a/packages/turf-union/test/out/not-overlapping.geojson b/src/union/test/out/not-overlapping.geojson similarity index 89% rename from packages/turf-union/test/out/not-overlapping.geojson rename to src/union/test/out/not-overlapping.geojson index 6b690da928..0ea2917779 100644 --- a/packages/turf-union/test/out/not-overlapping.geojson +++ b/src/union/test/out/not-overlapping.geojson @@ -6,14 +6,6 @@ "coordinates": [ [ [ - [ - -79.88571166992188, - 32.887659962078956 - ], - [ - -80.09788513183594, - 32.927436533285565 - ], [ -80.15350341796875, 32.82825010814964 @@ -29,38 +21,46 @@ [ -79.88571166992188, 32.887659962078956 + ], + [ + -80.09788513183594, + 32.927436533285565 + ], + [ + -80.15350341796875, + 32.82825010814964 ] ] ], [ [ [ - -79.85618591308594, - 32.85997876713845 - ], - [ - -79.78958129882812, - 32.913603231028915 + -79.88433837890625, + 32.687931474529464 ], [ - -79.64881896972656, - 32.915908931564864 + -79.79232788085938, + 32.679840539897484 ], [ -79.63233947753906, 32.804590457442565 ], [ - -79.79232788085938, - 32.679840539897484 + -79.64881896972656, + 32.915908931564864 ], [ - -79.88433837890625, - 32.687931474529464 + -79.78958129882812, + 32.913603231028915 ], [ -79.85618591308594, 32.85997876713845 + ], + [ + -79.88433837890625, + 32.687931474529464 ] ] ] diff --git a/src/union/test/out/other.geojson b/src/union/test/out/other.geojson new file mode 100644 index 0000000000..dfbcb3dab3 --- /dev/null +++ b/src/union/test/out/other.geojson @@ -0,0 +1,81 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -75.752, + 45.361 + ], + [ + -75.74823076923077, + 45.35534615384615 + ], + [ + -75.749, + 45.354 + ], + [ + -75.745, + 45.348 + ], + [ + -75.736, + 45.345 + ], + [ + -75.727, + 45.348 + ], + [ + -75.723, + 45.354 + ], + [ + -75.72330769230769, + 45.35453846153846 + ], + [ + -75.723, + 45.355 + ], + [ + -75.72466666666666, + 45.3575 + ], + [ + -75.721, + 45.363 + ], + [ + -75.725, + 45.37 + ], + [ + -75.734, + 45.372 + ], + [ + -75.743, + 45.37 + ], + [ + -75.74358181818181, + 45.36898181818182 + ], + [ + -75.748, + 45.368 + ], + [ + -75.752, + 45.361 + ] + ] + ] + ] + } +} diff --git a/src/union/test/out/union1.geojson b/src/union/test/out/union1.geojson new file mode 100644 index 0000000000..d6e82e237f --- /dev/null +++ b/src/union/test/out/union1.geojson @@ -0,0 +1,49 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -80.15350341796875, + 32.82825010814964 + ], + [ + -80.00312805175781, + 32.69428812316933 + ], + [ + -79.92322780260464, + 32.73910022106017 + ], + [ + -79.80537414550781, + 32.7231762754146 + ], + [ + -79.81773376464844, + 32.923402043498875 + ], + [ + -79.92141723632812, + 32.953944317478246 + ], + [ + -79.94623496447946, + 32.89900638172028 + ], + [ + -80.09788513183594, + 32.927436533285565 + ], + [ + -80.15350341796875, + 32.82825010814964 + ] + ] + ] + ] + } +} diff --git a/src/union/test/out/union2.geojson b/src/union/test/out/union2.geojson new file mode 100644 index 0000000000..ad58c070a3 --- /dev/null +++ b/src/union/test/out/union2.geojson @@ -0,0 +1,73 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -80.14389038085938, + 32.8149783969858 + ], + [ + -80.07453918457031, + 32.85536439443039 + ], + [ + -80.00867471875296, + 32.846454942587876 + ], + [ + -79.99171138057724, + 32.77876713098757 + ], + [ + -80.00175476074217, + 32.732418508353746 + ], + [ + -79.93763756501369, + 32.741047214297545 + ], + [ + -79.80537414550781, + 32.7231762754146 + ], + [ + -79.81773376464844, + 32.923402043498875 + ], + [ + -79.91098503795921, + 32.95087128128811 + ], + [ + -79.95025634765625, + 32.97007559940924 + ], + [ + -79.95741485597671, + 32.93704020740794 + ], + [ + -80.03128051757812, + 32.936657533381286 + ], + [ + -80.02726389659408, + 32.92063024667495 + ], + [ + -80.10543823242188, + 32.94760622243483 + ], + [ + -80.14389038085938, + 32.8149783969858 + ] + ] + ] + ] + } +} diff --git a/src/union/test/out/union3.geojson b/src/union/test/out/union3.geojson new file mode 100644 index 0000000000..c48a45c8ac --- /dev/null +++ b/src/union/test/out/union3.geojson @@ -0,0 +1,73 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + -80.15350341796875, + 32.82825010814964 + ], + [ + -80.00312805175781, + 32.69428812316933 + ], + [ + -79.92322780260464, + 32.73910022106017 + ], + [ + -79.87698786324371, + 32.73285245328464 + ], + [ + -79.88433837890625, + 32.687931474529464 + ], + [ + -79.79232788085938, + 32.679840539897484 + ], + [ + -79.63233947753906, + 32.804590457442565 + ], + [ + -79.64881896972656, + 32.915908931564864 + ], + [ + -79.78958129882812, + 32.913603231028915 + ], + [ + -79.81582464318822, + 32.89247428541929 + ], + [ + -79.81773376464844, + 32.923402043498875 + ], + [ + -79.92141723632812, + 32.953944317478246 + ], + [ + -79.94623496447946, + 32.89900638172028 + ], + [ + -80.09788513183594, + 32.927436533285565 + ], + [ + -80.15350341796875, + 32.82825010814964 + ] + ] + ] + ] + } +} diff --git a/packages/turf-unkink-polygon/bench.js b/src/unkink-polygon/bench.js similarity index 100% rename from packages/turf-unkink-polygon/bench.js rename to src/unkink-polygon/bench.js diff --git a/src/unkink-polygon/index.d.ts b/src/unkink-polygon/index.d.ts new file mode 100644 index 0000000000..ed48579dee --- /dev/null +++ b/src/unkink-polygon/index.d.ts @@ -0,0 +1,8 @@ +import { Polygon, MultiPolygon, Feature, FeatureCollection } from '../helpers'; + +/** + * http://turfjs.org/docs/#unkink-polygon + */ +export default function unkinkPolygon( + geojson: Feature | FeatureCollection | T +): FeatureCollection; diff --git a/src/unkink-polygon/index.js b/src/unkink-polygon/index.js new file mode 100644 index 0000000000..29db4a0e68 --- /dev/null +++ b/src/unkink-polygon/index.js @@ -0,0 +1,31 @@ +import { flattenEach, featureEach } from '../meta'; +import { polygon, featureCollection } from '../helpers'; +import simplepolygon from './lib/simplepolygon'; + +/** + * Takes a kinked polygon and returns a feature collection of polygons that have no kinks. + * Uses [simplepolygon](https://github.com/mclaeysb/simplepolygon) internally. + * + * @name unkinkPolygon + * @param {FeatureCollection|Feature} geojson GeoJSON Polygon or MultiPolygon + * @returns {FeatureCollection} Unkinked polygons + * @example + * var poly = turf.polygon([[[0, 0], [2, 0], [0, 2], [2, 2], [0, 0]]]); + * + * var result = turf.unkinkPolygon(poly); + * + * //addToMap + * var addToMap = [poly, result] + */ +function unkinkPolygon(geojson) { + const features = []; + flattenEach(geojson, function (feature) { + if (feature.geometry.type !== 'Polygon') return; + featureEach(simplepolygon(feature), function (poly) { + features.push(polygon(poly.geometry.coordinates, feature.properties)); + }); + }); + return featureCollection(features); +} + +export default unkinkPolygon; diff --git a/packages/turf-unkink-polygon/lib/geojson-polygon-self-intersections.js b/src/unkink-polygon/lib/geojson-polygon-self-intersections.js similarity index 99% rename from packages/turf-unkink-polygon/lib/geojson-polygon-self-intersections.js rename to src/unkink-polygon/lib/geojson-polygon-self-intersections.js index 00accd9755..a73a59a34b 100644 --- a/packages/turf-unkink-polygon/lib/geojson-polygon-self-intersections.js +++ b/src/unkink-polygon/lib/geojson-polygon-self-intersections.js @@ -1,5 +1,5 @@ // Find self-intersections in geojson polygon (possibly with interior rings) -import rbush from 'rbush'; +import rbush from '../../spatial-index/lib/rbush'; export default function (feature, filterFn, useSpatialIndex) { if (feature.geometry.type !== 'Polygon') throw new Error('The input feature must be a Polygon'); diff --git a/packages/turf-unkink-polygon/lib/simplepolygon.js b/src/unkink-polygon/lib/simplepolygon.js similarity index 96% rename from packages/turf-unkink-polygon/lib/simplepolygon.js rename to src/unkink-polygon/lib/simplepolygon.js index 67bcc64469..859eb613aa 100644 --- a/packages/turf-unkink-polygon/lib/simplepolygon.js +++ b/src/unkink-polygon/lib/simplepolygon.js @@ -1,8 +1,8 @@ import isects from './geojson-polygon-self-intersections'; -import area from '@turf/area'; -import { featureCollection, polygon } from '@turf/helpers'; -import booleanPointInPolygon from '@turf/boolean-point-in-polygon'; -import rbush from 'rbush'; +import area from '../../area'; +import { featureCollection, polygon } from '../../helpers'; +import booleanPointInPolygon from '../../boolean-point-in-polygon'; +import rbush from '../../spatial-index/lib/rbush'; /** * Takes a complex (i.e. self-intersecting) geojson polygon, and breaks it down into its composite simple, non-self-intersecting one-ring polygons. @@ -74,9 +74,9 @@ export default function (feature) { pseudoVtxListByRingAndEdge.push([]); for (var j = 0; j < feature.geometry.coordinates[i].length - 1; j++) { // Each edge will feature one ring-pseudo-vertex in its array, on the last position. i.e. edge j features the ring-pseudo-vertex of the ring vertex j+1, which has ringAndEdgeIn = [i,j], on the last position. - pseudoVtxListByRingAndEdge[i].push([new PseudoVtx(feature.geometry.coordinates[i][(j + 1).modulo(feature.geometry.coordinates[i].length - 1)], 1, [i, j], [i, (j + 1).modulo(feature.geometry.coordinates[i].length - 1)], undefined)]); + pseudoVtxListByRingAndEdge[i].push([new PseudoVtx(feature.geometry.coordinates[i][calculateModulo((j + 1), feature.geometry.coordinates[i].length - 1)], 1, [i, j], [i, calculateModulo((j + 1), feature.geometry.coordinates[i].length - 1)], undefined)]); // The first numvertices elements in isectList correspond to the ring-vertex-intersections - isectList.push(new Isect(feature.geometry.coordinates[i][j], [i, (j - 1).modulo(feature.geometry.coordinates[i].length - 1)], [i, j], undefined, undefined, false, true)); + isectList.push(new Isect(feature.geometry.coordinates[i][j], [i, calculateModulo((j - 1), feature.geometry.coordinates[i].length - 1)], [i, j], undefined, undefined, false, true)); } } // Adding intersection-pseudo-vertices to pseudoVtxListByRingAndEdge and self-intersections to isectList @@ -110,7 +110,7 @@ export default function (feature) { for (var k = 0; k < pseudoVtxListByRingAndEdge[i][j].length; k++) { var coordToFind; if (k == pseudoVtxListByRingAndEdge[i][j].length - 1) { // If it's the last pseudoVertex on that edge, then the next pseudoVertex is the first one on the next edge of that ring. - coordToFind = pseudoVtxListByRingAndEdge[i][(j + 1).modulo(feature.geometry.coordinates[i].length - 1)][0].coord; + coordToFind = pseudoVtxListByRingAndEdge[i][calculateModulo((j + 1), feature.geometry.coordinates[i].length - 1)][0].coord; } else { coordToFind = pseudoVtxListByRingAndEdge[i][j][k + 1].coord; } @@ -337,7 +337,7 @@ function windingOfRing(ring) { // Compute the winding number based on the vertex with the smallest x-value, it precessor and successor. An extremal vertex of a simple, non-self-intersecting ring is always convex, so the only reason it is not is because the winding number we use to compute it is wrong var leftVtx = 0; for (var i = 0; i < ring.length - 1; i++) { if (ring[i][0] < ring[leftVtx][0]) leftVtx = i; } - if (isConvex([ring[(leftVtx - 1).modulo(ring.length - 1)], ring[leftVtx], ring[(leftVtx + 1).modulo(ring.length - 1)]], true)) { + if (isConvex([ring[calculateModulo((leftVtx - 1), ring.length - 1)], ring[leftVtx], ring[calculateModulo((leftVtx + 1), ring.length - 1)]], true)) { var winding = 1; } else { var winding = -1; @@ -370,8 +370,8 @@ function equalArrays(array1, array2) { } // Fix Javascript modulo for negative number. From http://stackoverflow.com/questions/4467539/javascript-modulo-not-behaving -Number.prototype.modulo = function (n) { - return ((this % n) + n) % n; +function calculateModulo (n1, n2) { + return ((n1 % n2) + n2) % n2; }; // Function to get array with only unique elements. From http://stackoverflow.com/questions/1960473/unique-values-in-an-array diff --git a/src/unkink-polygon/test.js b/src/unkink-polygon/test.js new file mode 100644 index 0000000000..a0659d596d --- /dev/null +++ b/src/unkink-polygon/test.js @@ -0,0 +1,62 @@ +import fs from 'fs'; +import path from 'path'; +import test from 'tape'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import glob from 'glob'; +import { featureEach } from '../meta'; +import { featureCollection } from '../helpers'; +import kinks from '../kinks'; +import unkinkPolygon from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +test('unkink-polygon', t => { + glob.sync(directories.in + '*.geojson').forEach(filepath => { + const { name, base } = path.parse(filepath); + const geojson = load.sync(filepath); + + const unkinked = unkinkPolygon(geojson); + + // Detect if kinks exists + featureEach(unkinked, feature => { + // Throw Error when Issue #1094 is fixed + if (kinks(feature).features.length) t.skip(filepath + ' has kinks') + }) + + // Style results + const results = colorize(unkinked); + if (process.env.REGEN) write.sync(directories.out + base, results); + t.deepEqual(results, load.sync(directories.out + base), name); + }) + t.end(); +}); + +test('unkink-polygon -- throws', t => { + var array = [1, 2, 3, 4, 5]; + for (const value in array) { + t.true(value !== 'isUnique', 'isUnique'); + t.true(value !== 'getUnique', 'getUnique'); + } + t.throws(() => Array.isUnique(), 'isUnique()'); + t.throws(() => Array.getUnique(), 'getUnique()'); + t.end(); +}); + +function colorize(features, colors = ['#F00', '#00F', '#0F0', '#F0F', '#FFF'], width = 6) { + const results = []; + featureEach(features, (feature, index) => { + const color = colors[index % colors.length]; + feature.properties = Object.assign({ + stroke: color, + fill: color, + 'stroke-width': width, + 'fill-opacity': 0.5 + }, feature.properties); + results.push(feature); + }); + return featureCollection(results); +} diff --git a/packages/turf-unkink-polygon/test/in/complex.geojson b/src/unkink-polygon/test/in/complex.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/in/complex.geojson rename to src/unkink-polygon/test/in/complex.geojson diff --git a/packages/turf-unkink-polygon/test/in/hourglass.geojson b/src/unkink-polygon/test/in/hourglass.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/in/hourglass.geojson rename to src/unkink-polygon/test/in/hourglass.geojson diff --git a/packages/turf-unkink-polygon/test/in/hourglassFeatureCollection.geojson b/src/unkink-polygon/test/in/hourglassFeatureCollection.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/in/hourglassFeatureCollection.geojson rename to src/unkink-polygon/test/in/hourglassFeatureCollection.geojson diff --git a/packages/turf-unkink-polygon/test/in/hourglassFeatureCollectionMultiPolygon.geojson b/src/unkink-polygon/test/in/hourglassFeatureCollectionMultiPolygon.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/in/hourglassFeatureCollectionMultiPolygon.geojson rename to src/unkink-polygon/test/in/hourglassFeatureCollectionMultiPolygon.geojson diff --git a/packages/turf-unkink-polygon/test/in/hourglassMultiPolygon.geojson b/src/unkink-polygon/test/in/hourglassMultiPolygon.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/in/hourglassMultiPolygon.geojson rename to src/unkink-polygon/test/in/hourglassMultiPolygon.geojson diff --git a/packages/turf-unkink-polygon/test/in/issue-#1094.geojson b/src/unkink-polygon/test/in/issue-#1094.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/in/issue-#1094.geojson rename to src/unkink-polygon/test/in/issue-#1094.geojson diff --git a/packages/turf-unkink-polygon/test/in/polygon-with-holes.geojson b/src/unkink-polygon/test/in/polygon-with-holes.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/in/polygon-with-holes.geojson rename to src/unkink-polygon/test/in/polygon-with-holes.geojson diff --git a/packages/turf-unkink-polygon/test/in/polygon.geojson b/src/unkink-polygon/test/in/polygon.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/in/polygon.geojson rename to src/unkink-polygon/test/in/polygon.geojson diff --git a/packages/turf-unkink-polygon/test/out/complex.geojson b/src/unkink-polygon/test/out/complex.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/out/complex.geojson rename to src/unkink-polygon/test/out/complex.geojson diff --git a/packages/turf-unkink-polygon/test/out/hourglass.geojson b/src/unkink-polygon/test/out/hourglass.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/out/hourglass.geojson rename to src/unkink-polygon/test/out/hourglass.geojson diff --git a/packages/turf-unkink-polygon/test/out/hourglassFeatureCollection.geojson b/src/unkink-polygon/test/out/hourglassFeatureCollection.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/out/hourglassFeatureCollection.geojson rename to src/unkink-polygon/test/out/hourglassFeatureCollection.geojson diff --git a/packages/turf-unkink-polygon/test/out/hourglassFeatureCollectionMultiPolygon.geojson b/src/unkink-polygon/test/out/hourglassFeatureCollectionMultiPolygon.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/out/hourglassFeatureCollectionMultiPolygon.geojson rename to src/unkink-polygon/test/out/hourglassFeatureCollectionMultiPolygon.geojson diff --git a/packages/turf-unkink-polygon/test/out/hourglassMultiPolygon.geojson b/src/unkink-polygon/test/out/hourglassMultiPolygon.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/out/hourglassMultiPolygon.geojson rename to src/unkink-polygon/test/out/hourglassMultiPolygon.geojson diff --git a/packages/turf-unkink-polygon/test/out/issue-#1094.geojson b/src/unkink-polygon/test/out/issue-#1094.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/out/issue-#1094.geojson rename to src/unkink-polygon/test/out/issue-#1094.geojson diff --git a/packages/turf-unkink-polygon/test/out/polygon-with-holes.geojson b/src/unkink-polygon/test/out/polygon-with-holes.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/out/polygon-with-holes.geojson rename to src/unkink-polygon/test/out/polygon-with-holes.geojson diff --git a/packages/turf-unkink-polygon/test/out/polygon.geojson b/src/unkink-polygon/test/out/polygon.geojson similarity index 100% rename from packages/turf-unkink-polygon/test/out/polygon.geojson rename to src/unkink-polygon/test/out/polygon.geojson diff --git a/packages/turf-voronoi/bench.js b/src/voronoi/bench.js similarity index 100% rename from packages/turf-voronoi/bench.js rename to src/voronoi/bench.js diff --git a/src/voronoi/index.d.ts b/src/voronoi/index.d.ts new file mode 100644 index 0000000000..0a7e5aa97c --- /dev/null +++ b/src/voronoi/index.d.ts @@ -0,0 +1,9 @@ +import { FeatureCollection, BBox, Point, Polygon } from '../helpers'; + +/** + * http://turfjs.org/docs/#voronoi + */ +export default function voronoi( + points: FeatureCollection, + bbox: BBox +): FeatureCollection; diff --git a/src/voronoi/index.js b/src/voronoi/index.js new file mode 100644 index 0000000000..2390be308a --- /dev/null +++ b/src/voronoi/index.js @@ -0,0 +1,66 @@ +import { polygon, featureCollection, isObject } from '../helpers'; +import { collectionOf } from '../invariant'; +import * as d3voronoi from 'd3-voronoi'; + +/** + * @private + * @param {Array>} coords representing a polygon + * @returns {Feature} polygon + */ +function coordsToPolygon(coords) { + coords = coords.slice(); + coords.push(coords[0]); + return polygon([coords]); +} + +/** + * Takes a FeatureCollection of points, and a bounding box, and returns a FeatureCollection + * of Voronoi polygons. + * + * The Voronoi algorithim used comes from the d3-voronoi package. + * + * @name voronoi + * @param {FeatureCollection} points to find the Voronoi polygons around. + * @param {Object} [options={}] Optional parameters + * @param {number[]} [options.bbox=[-180, -85, 180, -85]] clipping rectangle, in [minX, minY, maxX, MaxY] order. + * @pararm {Boolean} [options.addPropertiesToPolygons=false] add properties to the polygons from the points + * @returns {FeatureCollection} a set of polygons, one per input point. + * @example + * var options = { + * bbox: [-70, 40, -60, 60] + * }; + * var points = turf.randomPoint(100, options); + * var voronoiPolygons = turf.voronoi(points, options); + * + * //addToMap + * var addToMap = [voronoiPolygons, points]; + */ +function voronoi(points, options) { + // Optional params + options = options || {}; + if (!isObject(options)) throw new Error('options is invalid'); + var bbox = options.bbox || [-180, -85, 180, 85]; + + // Input Validation + if (!points) throw new Error('points is required'); + if (!Array.isArray(bbox)) throw new Error('bbox is invalid'); + collectionOf(points, 'Point', 'points'); + + // Main + var fc = featureCollection( + d3voronoi.voronoi() + .x(function (feature) { return feature.geometry.coordinates[0]; }) + .y(function (feature) { return feature.geometry.coordinates[1]; }) + .extent([[bbox[0], bbox[1]], [bbox[2], bbox[3]]]) + .polygons(points.features) + .map(coordsToPolygon) + ); + if (options.addPropertiesToPolygons) { + fc.features.forEach(function (polygon, i) { + polygon.properties = JSON.parse(JSON.stringify(points.features[i].properties)); + }); + } + return fc; +} + +export default voronoi; diff --git a/src/voronoi/test.js b/src/voronoi/test.js new file mode 100644 index 0000000000..e90b91285e --- /dev/null +++ b/src/voronoi/test.js @@ -0,0 +1,46 @@ +import fs from 'fs'; +import test from 'tape'; +import glob from 'glob'; +import path from 'path'; +import load from 'load-json-file'; +import write from 'write-json-file'; +import { point, featureCollection } from '../helpers'; +import voronoi from '.'; + +const directories = { + in: path.join(__dirname, 'test', 'in') + path.sep, + out: path.join(__dirname, 'test', 'out') + path.sep +}; + +const fixtures = fs.readdirSync(directories.in).map(filename => { + return {filename, geojson: load.sync(directories.in + filename)}; +}); + +test('turf-voronoi', t => { + for (const {filename, geojson} of fixtures) { + const results = voronoi(geojson, {bbox: geojson.bbox}); + + if (process.env.REGEN) write.sync(directories.out + filename, results); + + const expected = load.sync(directories.out + filename); + t.deepEquals(results, expected, path.parse(filename).name); + }; + t.end(); +}); + +test('turf-voronoi - test properties', t => { + + const result = voronoi(featureCollection([point([145, -37], {foo: 'bar'})]), { + bbox: [140, -40, 160, -30], + addPropertiesToPolygons: true + }); + t.equal(result.features[0].properties.foo, 'bar') + + const result2 = voronoi(featureCollection([point([145, -37], {foo: 'bar'})]), { + bbox: [140, -40, 160, -30], + addPropertiesToPolygons: false + }); + t.equal(Object.keys(result2.features[0].properties).length, 0) + + t.end(); +}); \ No newline at end of file diff --git a/packages/turf-voronoi/test/in/ninepoints.json b/src/voronoi/test/in/ninepoints.json similarity index 100% rename from packages/turf-voronoi/test/in/ninepoints.json rename to src/voronoi/test/in/ninepoints.json diff --git a/packages/turf-voronoi/test/in/simple.json b/src/voronoi/test/in/simple.json similarity index 100% rename from packages/turf-voronoi/test/in/simple.json rename to src/voronoi/test/in/simple.json diff --git a/packages/turf-voronoi/test/in/world.json b/src/voronoi/test/in/world.json similarity index 100% rename from packages/turf-voronoi/test/in/world.json rename to src/voronoi/test/in/world.json diff --git a/packages/turf-voronoi/test/out/ninepoints.json b/src/voronoi/test/out/ninepoints.json similarity index 100% rename from packages/turf-voronoi/test/out/ninepoints.json rename to src/voronoi/test/out/ninepoints.json diff --git a/packages/turf-voronoi/test/out/simple.json b/src/voronoi/test/out/simple.json similarity index 100% rename from packages/turf-voronoi/test/out/simple.json rename to src/voronoi/test/out/simple.json diff --git a/packages/turf-voronoi/test/out/world.json b/src/voronoi/test/out/world.json similarity index 100% rename from packages/turf-voronoi/test/out/world.json rename to src/voronoi/test/out/world.json diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 3edf25b690..0000000000 --- a/yarn.lock +++ /dev/null @@ -1,6256 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@mapbox/geojsonhint@*": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@mapbox/geojsonhint/-/geojsonhint-2.0.1.tgz#32dac7300f04b3ebaec74b5ba9853dfb42532354" - dependencies: - concat-stream "~1.5.1" - jsonlint-lines "1.7.1" - minimist "1.2.0" - vfile "2.0.0" - vfile-reporter "3.0.0" - -"@std/esm@*", "@std/esm@0.21.x": - version "0.21.7" - resolved "https://registry.yarnpkg.com/@std/esm/-/esm-0.21.7.tgz#492d7931aed03e91a133deac4d9062fbfce5fd6b" - -"@turf/area@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/area/-/area-5.1.5.tgz#efd899bfd260cdbd1541b2a3c155f8a5d2eefa1d" - dependencies: - "@turf/helpers" "^5.1.5" - "@turf/meta" "^5.1.5" - -"@turf/bbox@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/bbox/-/bbox-5.1.5.tgz#3051df514ad4c50f4a4f9b8a2d15fd8b6840eda3" - dependencies: - "@turf/helpers" "^5.1.5" - "@turf/meta" "^5.1.5" - -"@turf/bearing@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/bearing/-/bearing-5.1.5.tgz#7a0b790136c4ef4797f0246305d45cbe2d27b3f7" - dependencies: - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - -"@turf/boolean-clockwise@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/boolean-clockwise/-/boolean-clockwise-5.1.5.tgz#3302b7dac62c5e291a0789e29af7283387fa9deb" - dependencies: - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - -"@turf/boolean-contains@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/boolean-contains/-/boolean-contains-5.1.5.tgz#596d63aee636f7ad53ee99f9ff24c96994a0ef14" - dependencies: - "@turf/bbox" "^5.1.5" - "@turf/boolean-point-in-polygon" "^5.1.5" - "@turf/boolean-point-on-line" "^5.1.5" - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - -"@turf/boolean-overlap@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/boolean-overlap/-/boolean-overlap-5.1.5.tgz#0d4e64c52c770a28e93d9efcdf8a8b8373acce75" - dependencies: - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - "@turf/line-intersect" "^5.1.5" - "@turf/line-overlap" "^5.1.5" - "@turf/meta" "^5.1.5" - geojson-equality "0.1.6" - -"@turf/boolean-point-in-polygon@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/boolean-point-in-polygon/-/boolean-point-in-polygon-5.1.5.tgz#f01cc194d1e030a548bfda981cba43cfd62941b7" - dependencies: - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - -"@turf/boolean-point-on-line@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/boolean-point-on-line/-/boolean-point-on-line-5.1.5.tgz#f633c5ff802ad24bb8f158dadbaf6ff4a023dd7b" - dependencies: - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - -"@turf/circle@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/circle/-/circle-5.1.5.tgz#9b1577835508ab52fb1c10b2a5065cba2b87b6a5" - dependencies: - "@turf/destination" "^5.1.5" - "@turf/helpers" "^5.1.5" - -"@turf/clean-coords@6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@turf/clean-coords/-/clean-coords-6.0.0.tgz#edac2b00dcbfd61c42dd035bfd5f21075c887565" - dependencies: - "@turf/helpers" "6.x" - "@turf/invariant" "6.x" - -"@turf/clean-coords@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/clean-coords/-/clean-coords-5.1.5.tgz#12800a98a78c9a452a72ec428493c43acf2ada1f" - dependencies: - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - -"@turf/clone@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/clone/-/clone-5.1.5.tgz#253e8d35477181976e33adfab50a0f02a7f0e367" - dependencies: - "@turf/helpers" "^5.1.5" - -"@turf/destination@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/destination/-/destination-5.1.5.tgz#ed35381bdce83bbddcbd07a2e2bce2bddffbcc26" - dependencies: - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - -"@turf/difference@5.1.x": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/difference/-/difference-5.1.5.tgz#a24d690a7bca803f1090a9ee3b9d906fc4371f42" - dependencies: - "@turf/area" "^5.1.5" - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - "@turf/meta" "^5.1.5" - turf-jsts "*" - -"@turf/distance@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/distance/-/distance-5.1.5.tgz#39cf18204bbf87587d707e609a60118909156409" - dependencies: - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - -"@turf/helpers@5.x", "@turf/helpers@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/helpers/-/helpers-5.1.5.tgz#153405227ab933d004a5bb9641a9ed999fcbe0cf" - -"@turf/hex-grid@5.1.x", "@turf/hex-grid@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/hex-grid/-/hex-grid-5.1.5.tgz#9b7ba5fecf5051f1e85892f713fce5c550502a6a" - dependencies: - "@turf/distance" "^5.1.5" - "@turf/helpers" "^5.1.5" - "@turf/intersect" "^5.1.5" - "@turf/invariant" "^5.1.5" - -"@turf/intersect@^5.1.5": - version "5.1.6" - resolved "https://registry.yarnpkg.com/@turf/intersect/-/intersect-5.1.6.tgz#13ffcceb7a529c2a7e5d6681ab3ba671f868e95f" - dependencies: - "@turf/clean-coords" "^5.1.5" - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - "@turf/truncate" "^5.1.5" - turf-jsts "*" - -"@turf/invariant@^5.1.5": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@turf/invariant/-/invariant-5.2.0.tgz#f0150ff7290b38577b73d088b7932c1ee0aa90a7" - dependencies: - "@turf/helpers" "^5.1.5" - -"@turf/line-arc@5.1.x", "@turf/line-arc@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/line-arc/-/line-arc-5.1.5.tgz#0078a7447835a12ae414a211f9a64d1186150e15" - dependencies: - "@turf/circle" "^5.1.5" - "@turf/destination" "^5.1.5" - "@turf/helpers" "^5.1.5" - -"@turf/line-intersect@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/line-intersect/-/line-intersect-5.1.5.tgz#0e29071ae403295e491723bc49f5cfac8d11ddf3" - dependencies: - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - "@turf/line-segment" "^5.1.5" - "@turf/meta" "^5.1.5" - geojson-rbush "2.1.0" - -"@turf/line-overlap@5.1.x", "@turf/line-overlap@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/line-overlap/-/line-overlap-5.1.5.tgz#943c6f87a0386dc43dfac11d2b3ff9c112cd3f60" - dependencies: - "@turf/boolean-point-on-line" "^5.1.5" - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - "@turf/line-segment" "^5.1.5" - "@turf/meta" "^5.1.5" - "@turf/nearest-point-on-line" "^5.1.5" - geojson-rbush "2.1.0" - -"@turf/line-segment@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/line-segment/-/line-segment-5.1.5.tgz#3207aaee546ab24c3d8dc3cc63f91c770b8013e5" - dependencies: - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - "@turf/meta" "^5.1.5" - -"@turf/meta@^5.1.5": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@turf/meta/-/meta-5.2.0.tgz#3b1ad485ee0c3b0b1775132a32c384d53e4ba53d" - dependencies: - "@turf/helpers" "^5.1.5" - -"@turf/nearest-point-on-line@5.1.x", "@turf/nearest-point-on-line@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/nearest-point-on-line/-/nearest-point-on-line-5.1.5.tgz#5606ae297f15947524bea51a2a9ef51ec1bf9c36" - dependencies: - "@turf/bearing" "^5.1.5" - "@turf/destination" "^5.1.5" - "@turf/distance" "^5.1.5" - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - "@turf/line-intersect" "^5.1.5" - "@turf/meta" "^5.1.5" - -"@turf/nearest-point@5.1.x", "@turf/nearest-point@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/nearest-point/-/nearest-point-5.1.5.tgz#12050de41c398443224c7978de0f6213900d34fb" - dependencies: - "@turf/clone" "^5.1.5" - "@turf/distance" "^5.1.5" - "@turf/helpers" "^5.1.5" - "@turf/meta" "^5.1.5" - -"@turf/random@5.x": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/random/-/random-5.1.5.tgz#b32efc934560ae8ba57e8ebb51f241c39fba2e7b" - dependencies: - "@turf/helpers" "^5.1.5" - -"@turf/rhumb-destination@5.x": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/rhumb-destination/-/rhumb-destination-5.1.5.tgz#b1b2aeb921547f2ac0c1a994b6a130f92463c742" - dependencies: - "@turf/helpers" "^5.1.5" - "@turf/invariant" "^5.1.5" - -"@turf/square-grid@5.1.x", "@turf/square-grid@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/square-grid/-/square-grid-5.1.5.tgz#1bd5f7b9eb14f0b60bc231fefe7351d1a32f1a51" - dependencies: - "@turf/boolean-contains" "^5.1.5" - "@turf/boolean-overlap" "^5.1.5" - "@turf/distance" "^5.1.5" - "@turf/helpers" "^5.1.5" - "@turf/intersect" "^5.1.5" - "@turf/invariant" "^5.1.5" - -"@turf/triangle-grid@5.1.x", "@turf/triangle-grid@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/triangle-grid/-/triangle-grid-5.1.5.tgz#7b36762108554c14f28caff3c48b1cfc82c8dc81" - dependencies: - "@turf/distance" "^5.1.5" - "@turf/helpers" "^5.1.5" - "@turf/intersect" "^5.1.5" - "@turf/invariant" "^5.1.5" - -"@turf/truncate@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/truncate/-/truncate-5.1.5.tgz#9eedfb3b18ba81f2c98d3ead09431cca1884ad89" - dependencies: - "@turf/helpers" "^5.1.5" - "@turf/meta" "^5.1.5" - -"@turf/union@5.1.x", "@turf/union@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@turf/union/-/union-5.1.5.tgz#53285b6094047fc58d96aac0ea90865ec34d454b" - dependencies: - "@turf/helpers" "^5.1.5" - turf-jsts "*" - -"@types/concaveman@*": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@types/concaveman/-/concaveman-1.1.3.tgz#ffb07771b29cf764fdafa263d01aa109da1478a3" - -"@types/geojson@*": - version "7946.0.1" - resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.1.tgz#1fc41280e42f08f0d568401a556bc97c34f5262e" - -"@types/node@*": - version "9.4.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-9.4.6.tgz#d8176d864ee48753d053783e4e463aec86b8d82e" - -"@types/object-assign@*": - version "4.0.30" - resolved "https://registry.yarnpkg.com/@types/object-assign/-/object-assign-4.0.30.tgz#8949371d5a99f4381ee0f1df0a9b7a187e07e652" - -"@types/tape@*": - version "4.2.32" - resolved "https://registry.yarnpkg.com/@types/tape/-/tape-4.2.32.tgz#1188330d22c4e822648c344faa070277737982d9" - dependencies: - "@types/node" "*" - -"@types/topojson@*": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@types/topojson/-/topojson-3.2.0.tgz#f84ba27966b8007dc1c6167a9c6cd1566f0ab5d1" - dependencies: - "@types/geojson" "*" - -JSONStream@^1.0.3, JSONStream@^1.0.4: - version "1.3.2" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea" - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - -"JSV@>= 4.0.x": - version "4.0.2" - resolved "https://registry.yarnpkg.com/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57" - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - -acorn-dynamic-import@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" - dependencies: - acorn "^5.0.0" - -acorn-jsx@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" - dependencies: - acorn "^3.0.4" - -acorn-jsx@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-4.1.1.tgz#e8e41e48ea2fe0c896740610ab6a4ffd8add225e" - dependencies: - acorn "^5.0.3" - -acorn@^3.0.4: - version "3.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" - -acorn@^5.0.0, acorn@^5.0.3, acorn@^5.2.1, acorn@^5.4.0, acorn@^5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.4.1.tgz#fdc58d9d17f4a4e98d102ded826a9b9759125102" - -add-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" - -ajv-keywords@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" - -ajv@^4.9.1: - version "4.11.8" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" - dependencies: - co "^4.6.0" - json-stable-stringify "^1.0.1" - -ajv@^5.2.3, ajv@^5.3.0: - version "5.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" - dependencies: - co "^4.6.0" - fast-deep-equal "^1.0.0" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" - -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - -ansi-escapes@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" - -ansi-escapes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92" - -ansi-html@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - -ansi-styles@^2.0.1, ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - -ansi-styles@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" - dependencies: - color-convert "^1.9.0" - -ansi-styles@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -append-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" - dependencies: - buffer-equal "^1.0.0" - -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - -are-we-there-yet@~1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -argparse@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - dependencies: - arr-flatten "^1.0.1" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - -arr-flatten@^1.0.1, arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - -array-ify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" - -array-iterate@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-iterate/-/array-iterate-1.1.1.tgz#865bf7f8af39d6b0982c60902914ac76bc0108f6" - -array-union@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - dependencies: - array-uniq "^1.0.1" - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - -arrify@^1.0.0, arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - -asn1@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - -assert-plus@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - -async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - -async@^1.4.0, async@^1.5.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - -atob@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.0.3.tgz#19c7a760473774468f20b2d2d03372ad7d4cbf5d" - -aws-sign2@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" - -aws4@^1.2.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" - -babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-core@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.0" - debug "^2.6.8" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.7" - slash "^1.0.0" - source-map "^0.5.6" - -babel-generator@^6.26.0: - version "6.26.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.7" - trim-right "^1.0.1" - -babel-helper-bindify-decorators@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" - dependencies: - babel-helper-explode-assignable-expression "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-builder-react-jsx@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - esutils "^2.0.2" - -babel-helper-call-delegate@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-define-map@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-explode-assignable-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-explode-class@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" - dependencies: - babel-helper-bindify-decorators "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-function-name@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" - dependencies: - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-get-function-arity@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-hoist-variables@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-optimise-call-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-regex@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-remap-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-replace-supers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" - dependencies: - babel-helper-optimise-call-expression "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helpers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-check-es2015-constants@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-syntax-async-functions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" - -babel-plugin-syntax-async-generators@^6.5.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" - -babel-plugin-syntax-class-constructor-call@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz#9cb9d39fe43c8600bec8146456ddcbd4e1a76416" - -babel-plugin-syntax-class-properties@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" - -babel-plugin-syntax-decorators@^6.1.18, babel-plugin-syntax-decorators@^6.13.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" - -babel-plugin-syntax-do-expressions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz#5747756139aa26d390d09410b03744ba07e4796d" - -babel-plugin-syntax-dynamic-import@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" - -babel-plugin-syntax-exponentiation-operator@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" - -babel-plugin-syntax-export-extensions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721" - -babel-plugin-syntax-flow@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" - -babel-plugin-syntax-function-bind@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz#48c495f177bdf31a981e732f55adc0bdd2601f46" - -babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" - -babel-plugin-syntax-object-rest-spread@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" - -babel-plugin-syntax-trailing-function-commas@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" - -babel-plugin-system-import-transformer@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-system-import-transformer/-/babel-plugin-system-import-transformer-3.1.0.tgz#d37f0cae8e61ef39060208331d931b5e630d7c5f" - dependencies: - babel-plugin-syntax-dynamic-import "^6.18.0" - -babel-plugin-transform-async-generator-functions@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db" - dependencies: - babel-helper-remap-async-to-generator "^6.24.1" - babel-plugin-syntax-async-generators "^6.5.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" - dependencies: - babel-helper-remap-async-to-generator "^6.24.1" - babel-plugin-syntax-async-functions "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-class-constructor-call@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz#80dc285505ac067dcb8d6c65e2f6f11ab7765ef9" - dependencies: - babel-plugin-syntax-class-constructor-call "^6.18.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-class-properties@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" - dependencies: - babel-helper-function-name "^6.24.1" - babel-plugin-syntax-class-properties "^6.8.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-decorators-legacy@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.4.tgz#741b58f6c5bce9e6027e0882d9c994f04f366925" - dependencies: - babel-plugin-syntax-decorators "^6.1.18" - babel-runtime "^6.2.0" - babel-template "^6.3.0" - -babel-plugin-transform-decorators@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d" - dependencies: - babel-helper-explode-class "^6.24.1" - babel-plugin-syntax-decorators "^6.13.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-do-expressions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz#28ccaf92812d949c2cd1281f690c8fdc468ae9bb" - dependencies: - babel-plugin-syntax-do-expressions "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-arrow-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoping@^6.23.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" - dependencies: - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-plugin-transform-es2015-classes@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" - dependencies: - babel-helper-define-map "^6.24.1" - babel-helper-function-name "^6.24.1" - babel-helper-optimise-call-expression "^6.24.1" - babel-helper-replace-supers "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-computed-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-destructuring@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-duplicate-keys@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-for-of@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-function-name@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" - dependencies: - babel-plugin-transform-es2015-modules-commonjs "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" - dependencies: - babel-plugin-transform-strict-mode "^6.24.1" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-types "^6.26.0" - -babel-plugin-transform-es2015-modules-systemjs@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-umd@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" - dependencies: - babel-plugin-transform-es2015-modules-amd "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-object-super@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" - dependencies: - babel-helper-replace-supers "^6.24.1" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-parameters@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" - dependencies: - babel-helper-call-delegate "^6.24.1" - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-shorthand-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-spread@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-sticky-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-template-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-typeof-symbol@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-unicode-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - regexpu-core "^2.0.0" - -babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" - dependencies: - babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" - babel-plugin-syntax-exponentiation-operator "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-export-extensions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz#53738b47e75e8218589eea946cbbd39109bbe653" - dependencies: - babel-plugin-syntax-export-extensions "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-flow-strip-types@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" - dependencies: - babel-plugin-syntax-flow "^6.18.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-function-bind@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz#c6fb8e96ac296a310b8cf8ea401462407ddf6a97" - dependencies: - babel-plugin-syntax-function-bind "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-object-rest-spread@^6.22.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" - dependencies: - babel-plugin-syntax-object-rest-spread "^6.8.0" - babel-runtime "^6.26.0" - -babel-plugin-transform-react-display-name@^6.23.0: - version "6.25.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-react-jsx-self@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e" - dependencies: - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-react-jsx-source@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6" - dependencies: - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-react-jsx@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3" - dependencies: - babel-helper-builder-react-jsx "^6.24.1" - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-regenerator@^6.22.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" - dependencies: - regenerator-transform "^0.10.0" - -babel-plugin-transform-strict-mode@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-polyfill@6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" - dependencies: - babel-runtime "^6.22.0" - core-js "^2.4.0" - regenerator-runtime "^0.10.0" - -babel-preset-env@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48" - dependencies: - babel-plugin-check-es2015-constants "^6.22.0" - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-to-generator "^6.22.0" - babel-plugin-transform-es2015-arrow-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoping "^6.23.0" - babel-plugin-transform-es2015-classes "^6.23.0" - babel-plugin-transform-es2015-computed-properties "^6.22.0" - babel-plugin-transform-es2015-destructuring "^6.23.0" - babel-plugin-transform-es2015-duplicate-keys "^6.22.0" - babel-plugin-transform-es2015-for-of "^6.23.0" - babel-plugin-transform-es2015-function-name "^6.22.0" - babel-plugin-transform-es2015-literals "^6.22.0" - babel-plugin-transform-es2015-modules-amd "^6.22.0" - babel-plugin-transform-es2015-modules-commonjs "^6.23.0" - babel-plugin-transform-es2015-modules-systemjs "^6.23.0" - babel-plugin-transform-es2015-modules-umd "^6.23.0" - babel-plugin-transform-es2015-object-super "^6.22.0" - babel-plugin-transform-es2015-parameters "^6.23.0" - babel-plugin-transform-es2015-shorthand-properties "^6.22.0" - babel-plugin-transform-es2015-spread "^6.22.0" - babel-plugin-transform-es2015-sticky-regex "^6.22.0" - babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.23.0" - babel-plugin-transform-es2015-unicode-regex "^6.22.0" - babel-plugin-transform-exponentiation-operator "^6.22.0" - babel-plugin-transform-regenerator "^6.22.0" - browserslist "^2.1.2" - invariant "^2.2.2" - semver "^5.3.0" - -babel-preset-flow@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d" - dependencies: - babel-plugin-transform-flow-strip-types "^6.22.0" - -babel-preset-react@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380" - dependencies: - babel-plugin-syntax-jsx "^6.3.13" - babel-plugin-transform-react-display-name "^6.23.0" - babel-plugin-transform-react-jsx "^6.24.1" - babel-plugin-transform-react-jsx-self "^6.22.0" - babel-plugin-transform-react-jsx-source "^6.22.0" - babel-preset-flow "^6.23.0" - -babel-preset-stage-0@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz#5642d15042f91384d7e5af8bc88b1db95b039e6a" - dependencies: - babel-plugin-transform-do-expressions "^6.22.0" - babel-plugin-transform-function-bind "^6.22.0" - babel-preset-stage-1 "^6.24.1" - -babel-preset-stage-1@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz#7692cd7dcd6849907e6ae4a0a85589cfb9e2bfb0" - dependencies: - babel-plugin-transform-class-constructor-call "^6.24.1" - babel-plugin-transform-export-extensions "^6.22.0" - babel-preset-stage-2 "^6.24.1" - -babel-preset-stage-2@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1" - dependencies: - babel-plugin-syntax-dynamic-import "^6.18.0" - babel-plugin-transform-class-properties "^6.24.1" - babel-plugin-transform-decorators "^6.24.1" - babel-preset-stage-3 "^6.24.1" - -babel-preset-stage-3@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395" - dependencies: - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-generator-functions "^6.24.1" - babel-plugin-transform-async-to-generator "^6.24.1" - babel-plugin-transform-exponentiation-operator "^6.24.1" - babel-plugin-transform-object-rest-spread "^6.22.0" - -babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" - dependencies: - babel-core "^6.26.0" - babel-runtime "^6.26.0" - core-js "^2.5.0" - home-or-tmp "^2.0.0" - lodash "^4.17.4" - mkdirp "^0.5.1" - source-map-support "^0.4.15" - -babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-template@^6.24.1, babel-template@^6.26.0, babel-template@^6.3.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - dependencies: - babel-runtime "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - lodash "^4.17.4" - -babel-traverse@^6.24.1, babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - dependencies: - babel-code-frame "^6.26.0" - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - debug "^2.6.8" - globals "^9.18.0" - invariant "^2.2.2" - lodash "^4.17.4" - -babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babelify@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/babelify/-/babelify-8.0.0.tgz#6f60f5f062bfe7695754ef2403b842014a580ed3" - -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - -bail@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.2.tgz#f7d6c1731630a9f9f0d4d35ed1f962e2074a1764" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -bcrypt-pbkdf@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" - dependencies: - tweetnacl "^0.14.3" - -benchmark@*: - version "2.1.4" - resolved "https://registry.yarnpkg.com/benchmark/-/benchmark-2.1.4.tgz#09f3de31c916425d498cc2ee565a0ebf3c2a5629" - dependencies: - lodash "^4.17.4" - platform "^1.3.3" - -binary-extensions@^1.0.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" - -block-stream@*: - version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" - dependencies: - inherits "~2.0.0" - -body@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/body/-/body-5.1.0.tgz#e4ba0ce410a46936323367609ecb4e6553125069" - dependencies: - continuable-cache "^0.3.1" - error "^7.0.0" - raw-body "~1.1.0" - safe-json-parse "~1.0.1" - -boolean-jsts@*: - version "0.0.1" - resolved "https://registry.yarnpkg.com/boolean-jsts/-/boolean-jsts-0.0.1.tgz#66c699bcde3df1b54efe2cb79562cb780d222af3" - dependencies: - jsts "^1.4.0" - -boolean-shapely@*: - version "0.1.2" - resolved "https://registry.yarnpkg.com/boolean-shapely/-/boolean-shapely-0.1.2.tgz#465fe962c99c35d4c7a6a4978da0d1df95b81b7b" - dependencies: - python-shell "^0.4.0" - -boom@2.x.x: - version "2.10.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" - dependencies: - hoek "2.x.x" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - -braces@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.0.tgz#a46941cb5fb492156b3d6a656e06c35364e3e66e" - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - define-property "^1.0.0" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -browser-resolve@^1.7.0: - version "1.11.2" - resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" - dependencies: - resolve "1.1.7" - -browserslist@^2.1.2: - version "2.11.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2" - dependencies: - caniuse-lite "^1.0.30000792" - electron-to-chromium "^1.3.30" - -buble@^0.19.2: - version "0.19.3" - resolved "https://registry.yarnpkg.com/buble/-/buble-0.19.3.tgz#01e9412062cff1da6f20342b6ecd72e7bf699d02" - dependencies: - acorn "^5.4.1" - acorn-dynamic-import "^3.0.0" - acorn-jsx "^4.1.1" - chalk "^2.3.1" - magic-string "^0.22.4" - minimist "^1.2.0" - os-homedir "^1.0.1" - vlq "^1.0.0" - -buffer-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" - -buffer-shims@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" - -builtin-modules@^1.0.0, builtin-modules@^1.1.0, builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - -byline@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" - -bytes@1: - version "1.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-1.0.0.tgz#3569ede8ba34315fab99c3e92cb04c7220de1fa8" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -caller-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" - dependencies: - callsites "^0.2.0" - -callsites@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" - -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" - -camelcase-keys@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" - dependencies: - camelcase "^4.1.0" - map-obj "^2.0.0" - quick-lru "^1.0.0" - -camelcase@*, camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - -camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - -caniuse-lite@^1.0.30000792: - version "1.0.30000808" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000808.tgz#7d759b5518529ea08b6705a19e70dbf401628ffc" - -capture-stack-trace@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - -ccount@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.2.tgz#53b6a2f815bb77b9c2871f7b9a72c3a25f1d8e89" - -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - -chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796" - dependencies: - ansi-styles "^3.2.0" - escape-string-regexp "^1.0.5" - supports-color "^5.2.0" - -chalk@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" - dependencies: - ansi-styles "~1.0.0" - has-color "~0.1.0" - strip-ansi "~0.1.0" - -character-entities-html4@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.1.1.tgz#359a2a4a0f7e29d3dc2ac99bdbe21ee39438ea50" - -character-entities-legacy@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.1.tgz#f40779df1a101872bb510a3d295e1fccf147202f" - -character-entities@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.1.tgz#f76871be5ef66ddb7f8f8e3478ecc374c27d6dca" - -character-reference-invalid@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.1.tgz#942835f750e4ec61a308e60c2ef8cc1011202efc" - -chardet@^0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" - -chokidar@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.1.tgz#6e67e9998fe10e8f651e975ca62460456ff8e297" - dependencies: - anymatch "^2.0.0" - async-each "^1.0.0" - braces "^2.3.0" - glob-parent "^3.1.0" - inherits "^2.0.1" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^2.1.1" - path-is-absolute "^1.0.0" - readdirp "^2.0.0" - upath "1.0.0" - optionalDependencies: - fsevents "^1.0.0" - -chroma-js@*: - version "1.3.6" - resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-1.3.6.tgz#22dd7220ef6b55dcfcb8ef92982baaf55dced45d" - -chromatism@*: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chromatism/-/chromatism-3.0.0.tgz#a7249d353c1e4f3577e444ac41171c4e2e624b12" - -ci-info@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.2.tgz#03561259db48d0474c8bdc90f5b47b068b6bbfb4" - -circular-json@^0.3.1: - version "0.3.3" - resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - dependencies: - restore-cursor "^2.0.0" - -cli-width@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" - -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -clone-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" - -clone-stats@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" - -clone@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f" - -clone@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" - -cloneable-readable@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.0.0.tgz#a6290d413f217a61232f95e458ff38418cfb0117" - dependencies: - inherits "^2.0.1" - process-nextick-args "^1.0.6" - through2 "^2.0.1" - -cmd-shim@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" - dependencies: - graceful-fs "^4.1.2" - mkdirp "~0.5.0" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - -collapse-white-space@^1.0.0, collapse-white-space@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.3.tgz#4b906f670e5a963a87b76b0e1689643341b6023c" - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" - dependencies: - color-name "^1.1.1" - -color-name@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - -columnify@^1.5.4: - version "1.5.4" - resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" - dependencies: - strip-ansi "^3.0.0" - wcwidth "^1.0.0" - -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" - dependencies: - delayed-stream "~1.0.0" - -comma-separated-tokens@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.4.tgz#72083e58d4a462f01866f6617f4d98a3cd3b8a46" - dependencies: - trim "0.0.1" - -command-join@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/command-join/-/command-join-2.0.0.tgz#52e8b984f4872d952ff1bdc8b98397d27c7144cf" - -commander@2: - version "2.14.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa" - -commander@^2.12.1: - version "2.15.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" - -commander@~2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" - -compare-func@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648" - dependencies: - array-ify "^1.0.0" - dot-prop "^3.0.0" - -compare-versions@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-2.0.1.tgz#1edc1f93687fd97a325c59f55e45a07db106aca6" - -component-emitter@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - -concat-stream@^1.4.10, concat-stream@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" - dependencies: - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -concat-stream@~1.4.4: - version "1.4.10" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.4.10.tgz#acc3bbf5602cb8cc980c6ac840fa7d8603e3ef36" - dependencies: - inherits "~2.0.1" - readable-stream "~1.1.9" - typedarray "~0.0.5" - -concat-stream@~1.5.0, concat-stream@~1.5.1: - version "1.5.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266" - dependencies: - inherits "~2.0.1" - readable-stream "~2.0.0" - typedarray "~0.0.5" - -concaveman@*: - version "1.1.1" - resolved "https://registry.yarnpkg.com/concaveman/-/concaveman-1.1.1.tgz#6c2482580b2523cef82fc2bec00a0415e6e68162" - dependencies: - monotone-convex-hull-2d "^1.0.1" - point-in-polygon "^1.0.1" - rbush "^2.0.1" - robust-orientation "^1.1.3" - tinyqueue "^1.1.0" - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - -continuable-cache@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/continuable-cache/-/continuable-cache-0.3.1.tgz#bd727a7faed77e71ff3985ac93351a912733ad0f" - -conventional-changelog-angular@^1.6.4: - version "1.6.4" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-1.6.4.tgz#47debaf92b75b0bd6b39fcba8f9c70dd97552be6" - dependencies: - compare-func "^1.3.1" - q "^1.4.1" - -conventional-changelog-atom@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/conventional-changelog-atom/-/conventional-changelog-atom-0.2.2.tgz#2c7326a8f24686f51500a290ed897d47612be4c3" - dependencies: - q "^1.4.1" - -conventional-changelog-cli@^1.3.2: - version "1.3.13" - resolved "https://registry.yarnpkg.com/conventional-changelog-cli/-/conventional-changelog-cli-1.3.13.tgz#8cb5855bc3c684aa8f5dc96e848d1fa5a82eee1e" - dependencies: - add-stream "^1.0.0" - conventional-changelog "^1.1.15" - lodash "^4.1.0" - meow "^3.7.0" - tempfile "^1.1.1" - -conventional-changelog-codemirror@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/conventional-changelog-codemirror/-/conventional-changelog-codemirror-0.3.2.tgz#65ef0ab738c40bdf953951edfdb0cb17302606aa" - dependencies: - q "^1.4.1" - -conventional-changelog-core@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-2.0.3.tgz#30797b91d5f510188288d5ff54905e5cf4628e3c" - dependencies: - conventional-changelog-writer "^3.0.2" - conventional-commits-parser "^2.1.3" - dateformat "^1.0.12" - get-pkg-repo "^1.0.0" - git-raw-commits "^1.3.2" - git-remote-origin-url "^2.0.0" - git-semver-tags "^1.3.2" - lodash "^4.0.0" - normalize-package-data "^2.3.5" - q "^1.4.1" - read-pkg "^1.1.0" - read-pkg-up "^1.0.1" - through2 "^2.0.0" - -conventional-changelog-ember@^0.3.4: - version "0.3.4" - resolved "https://registry.yarnpkg.com/conventional-changelog-ember/-/conventional-changelog-ember-0.3.4.tgz#76240e769b2f5298e78e85cb4eda69ef2f1358d2" - dependencies: - q "^1.4.1" - -conventional-changelog-eslint@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/conventional-changelog-eslint/-/conventional-changelog-eslint-1.0.2.tgz#3f9e6b0b60f98042f6f4dfc85a611a50b5e79cf9" - dependencies: - q "^1.4.1" - -conventional-changelog-express@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/conventional-changelog-express/-/conventional-changelog-express-0.3.2.tgz#f5af4770a31f147986db548b49f9952fc55e3eb6" - dependencies: - q "^1.4.1" - -conventional-changelog-jquery@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-jquery/-/conventional-changelog-jquery-0.1.0.tgz#0208397162e3846986e71273b6c79c5b5f80f510" - dependencies: - q "^1.4.1" - -conventional-changelog-jscs@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-jscs/-/conventional-changelog-jscs-0.1.0.tgz#0479eb443cc7d72c58bf0bcf0ef1d444a92f0e5c" - dependencies: - q "^1.4.1" - -conventional-changelog-jshint@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/conventional-changelog-jshint/-/conventional-changelog-jshint-0.3.2.tgz#4d45d2601c944687abceabbc1789323719234cbe" - dependencies: - compare-func "^1.3.1" - q "^1.4.1" - -conventional-changelog-preset-loader@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-1.1.4.tgz#5096165f2742a18dc0e33ff2ab9ee08dc9d77f08" - -conventional-changelog-writer@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-3.0.2.tgz#f3f934028379c0cab90aecfcaf009bf8a187ef14" - dependencies: - compare-func "^1.3.1" - conventional-commits-filter "^1.1.3" - dateformat "^1.0.11" - handlebars "^4.0.2" - json-stringify-safe "^5.0.1" - lodash "^4.0.0" - meow "^3.3.0" - semver "^5.0.1" - split "^1.0.0" - through2 "^2.0.0" - -conventional-changelog@^1.1.15: - version "1.1.15" - resolved "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-1.1.15.tgz#a5c3d281efb40f61c7d21eeffb19e6f6a8429df0" - dependencies: - conventional-changelog-angular "^1.6.4" - conventional-changelog-atom "^0.2.2" - conventional-changelog-codemirror "^0.3.2" - conventional-changelog-core "^2.0.3" - conventional-changelog-ember "^0.3.4" - conventional-changelog-eslint "^1.0.2" - conventional-changelog-express "^0.3.2" - conventional-changelog-jquery "^0.1.0" - conventional-changelog-jscs "^0.1.0" - conventional-changelog-jshint "^0.3.2" - conventional-changelog-preset-loader "^1.1.4" - -conventional-commits-filter@^1.1.1, conventional-commits-filter@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-1.1.3.tgz#5bf591bc4882fc8c9bd329e5a83ca1fa8721d9fb" - dependencies: - is-subset "^0.1.1" - modify-values "^1.0.0" - -conventional-commits-parser@^2.1.1, conventional-commits-parser@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-2.1.3.tgz#fbbfcfe4901ccbae63bb3834f982325e0b7c663f" - dependencies: - JSONStream "^1.0.4" - is-text-path "^1.0.0" - lodash "^4.2.1" - meow "^3.3.0" - split2 "^2.0.0" - through2 "^2.0.0" - trim-off-newlines "^1.0.0" - -conventional-recommended-bump@^1.0.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-1.2.1.tgz#1b7137efb5091f99fe009e2fe9ddb7cc490e9375" - dependencies: - concat-stream "^1.4.10" - conventional-commits-filter "^1.1.1" - conventional-commits-parser "^2.1.1" - git-raw-commits "^1.3.0" - git-semver-tags "^1.3.0" - meow "^3.3.0" - object-assign "^4.0.1" - -convert-source-map@^1.5.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - -core-js@^2.4.0, core-js@^2.5.0: - version "2.5.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - -create-error-class@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" - dependencies: - capture-stack-trace "^1.0.0" - -cross-spawn@^5.0.1, cross-spawn@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cryptiles@2.x.x: - version "2.0.5" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" - dependencies: - boom "2.x.x" - -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - dependencies: - array-find-index "^1.0.1" - -d3-array@1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.1.tgz#d1ca33de2f6ac31efadb8e050a021d7e2396d5dc" - -d3-geo@1.7.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.7.1.tgz#44bbc7a218b1fd859f3d8fd7c443ca836569ce99" - dependencies: - d3-array "1" - -d3-queue@*: - version "3.0.7" - resolved "https://registry.yarnpkg.com/d3-queue/-/d3-queue-3.0.7.tgz#c93a2e54b417c0959129d7d73f6cf7d4292e7618" - -d3-voronoi@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.2.tgz#1687667e8f13a2d158c80c1480c5a29cb0d8973c" - -dargs@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17" - dependencies: - number-is-nan "^1.0.0" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - dependencies: - assert-plus "^1.0.0" - -dateformat@^1.0.11, dateformat@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" - dependencies: - get-stdin "^4.0.1" - meow "^3.3.0" - -debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@~2.6.7: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - dependencies: - ms "2.0.0" - -debug@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - dependencies: - ms "2.0.0" - -decamelize-keys@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" - dependencies: - decamelize "^1.1.0" - map-obj "^1.0.0" - -decamelize@*: - version "2.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7" - dependencies: - xregexp "4.0.0" - -decamelize@^1.0.0, decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - -dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - -deep-equal@1.x, deep-equal@^1.0.0, deep-equal@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" - -deep-extend@~0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - -defaults@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" - dependencies: - clone "^1.0.2" - -define-properties@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" - dependencies: - foreach "^2.0.5" - object-keys "^1.0.8" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - dependencies: - is-descriptor "^1.0.0" - -defined@^1.0.0, defined@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - -del@^2.0.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" - dependencies: - globby "^5.0.0" - is-path-cwd "^1.0.0" - is-path-in-cwd "^1.0.0" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - rimraf "^2.2.8" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - -density-clustering@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/density-clustering/-/density-clustering-1.3.0.tgz#dc9f59c8f0ab97e1624ac64930fd3194817dcac5" - -detab@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.1.tgz#531f5e326620e2fd4f03264a905fb3bcc8af4df4" - dependencies: - repeat-string "^1.5.4" - -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - dependencies: - repeating "^2.0.0" - -detect-indent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" - -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - -detective@^4.0.0: - version "4.7.1" - resolved "https://registry.yarnpkg.com/detective/-/detective-4.7.1.tgz#0eca7314338442febb6d65da54c10bb1c82b246e" - dependencies: - acorn "^5.2.1" - defined "^1.0.0" - -diff@^1.3.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" - -diff@^3.2.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - -disparity@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/disparity/-/disparity-2.0.0.tgz#57ddacb47324ae5f58d2cc0da886db4ce9eeb718" - dependencies: - ansi-styles "^2.0.1" - diff "^1.3.2" - -doctrine-temporary-fork@2.0.0-alpha-allowarrayindex: - version "2.0.0-alpha-allowarrayindex" - resolved "https://registry.yarnpkg.com/doctrine-temporary-fork/-/doctrine-temporary-fork-2.0.0-alpha-allowarrayindex.tgz#40015a867eb27e75b26c828b71524f137f89f9f0" - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - dependencies: - esutils "^2.0.2" - -documentation@*: - version "5.4.0" - resolved "https://registry.yarnpkg.com/documentation/-/documentation-5.4.0.tgz#49006a8ca444e835f03a990fe8c393e15cb4f853" - dependencies: - ansi-html "^0.0.7" - babel-core "^6.26.0" - babel-generator "^6.26.0" - babel-plugin-system-import-transformer "3.1.0" - babel-plugin-transform-decorators-legacy "^1.3.4" - babel-preset-env "^1.6.1" - babel-preset-react "^6.24.1" - babel-preset-stage-0 "^6.24.1" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babelify "^8.0.0" - babylon "^6.18.0" - chalk "^2.3.0" - chokidar "^2.0.0" - concat-stream "^1.6.0" - disparity "^2.0.0" - doctrine-temporary-fork "2.0.0-alpha-allowarrayindex" - get-port "^3.2.0" - git-url-parse "^8.0.0" - github-slugger "1.2.0" - glob "^7.1.2" - globals-docs "^2.4.0" - highlight.js "^9.12.0" - js-yaml "^3.10.0" - lodash "^4.17.4" - mdast-util-inject "^1.1.0" - micromatch "^3.1.5" - mime "^2.2.0" - module-deps-sortable "4.0.6" - parse-filepath "^1.0.2" - pify "^3.0.0" - read-pkg-up "^3.0.0" - remark "^9.0.0" - remark-html "7.0.0" - remark-toc "^5.0.0" - remote-origin-url "0.4.0" - shelljs "^0.8.1" - stream-array "^1.1.2" - strip-json-comments "^2.0.1" - tiny-lr "^1.1.0" - unist-builder "^1.0.2" - unist-util-visit "^1.3.0" - vfile "^2.3.0" - vfile-reporter "^4.0.0" - vfile-sort "^2.1.0" - vinyl "^2.1.0" - vinyl-fs "^3.0.2" - yargs "^9.0.1" - -dot-prop@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" - dependencies: - is-obj "^1.0.0" - -duplexer2@^0.1.2, duplexer2@~0.1.0: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" - dependencies: - readable-stream "^2.0.2" - -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - -duplexer@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" - -duplexify@^3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.3.tgz#8b5818800df92fd0125b27ab896491912858243e" - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -earcut@^2.0.0: - version "2.1.3" - resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.1.3.tgz#ca579545f351941af7c3d0df49c9f7d34af99b0c" - -ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" - dependencies: - jsbn "~0.1.0" - -electron-to-chromium@^1.3.30: - version "1.3.33" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.33.tgz#bf00703d62a7c65238136578c352d6c5c042a545" - -"emoji-regex@>=6.0.0 <=6.1.1": - version "6.1.1" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.1.1.tgz#c6cd0ec1b0642e2a3c67a1137efc5e796da4f88e" - -encoding@^0.1.11: - version "0.1.12" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" - dependencies: - iconv-lite "~0.4.13" - -end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" - dependencies: - once "^1.4.0" - -error-ex@^1.2.0, error-ex@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" - dependencies: - is-arrayish "^0.2.1" - -error@^7.0.0: - version "7.0.2" - resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02" - dependencies: - string-template "~0.2.1" - xtend "~4.0.0" - -es-abstract@^1.5.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" - dependencies: - es-to-primitive "^1.1.1" - function-bind "^1.1.1" - has "^1.0.1" - is-callable "^1.1.3" - is-regex "^1.0.4" - -es-to-primitive@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" - dependencies: - is-callable "^1.1.1" - is-date-object "^1.0.1" - is-symbol "^1.0.1" - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - -eslint-config-mourner@*: - version "2.0.3" - resolved "https://registry.yarnpkg.com/eslint-config-mourner/-/eslint-config-mourner-2.0.3.tgz#c858a7bdd03ceb5c124bc307af1270bb054f6c0c" - -eslint-scope@^3.7.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-visitor-keys@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" - -eslint@*: - version "4.17.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.17.0.tgz#dc24bb51ede48df629be7031c71d9dc0ee4f3ddf" - dependencies: - ajv "^5.3.0" - babel-code-frame "^6.22.0" - chalk "^2.1.0" - concat-stream "^1.6.0" - cross-spawn "^5.1.0" - debug "^3.1.0" - doctrine "^2.1.0" - eslint-scope "^3.7.1" - eslint-visitor-keys "^1.0.0" - espree "^3.5.2" - esquery "^1.0.0" - esutils "^2.0.2" - file-entry-cache "^2.0.0" - functional-red-black-tree "^1.0.1" - glob "^7.1.2" - globals "^11.0.1" - ignore "^3.3.3" - imurmurhash "^0.1.4" - inquirer "^3.0.6" - is-resolvable "^1.0.0" - js-yaml "^3.9.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.4" - minimatch "^3.0.2" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.2" - path-is-inside "^1.0.2" - pluralize "^7.0.0" - progress "^2.0.0" - require-uncached "^1.0.3" - semver "^5.3.0" - strip-ansi "^4.0.0" - strip-json-comments "~2.0.1" - table "^4.0.1" - text-table "~0.2.0" - -espree@^3.5.2: - version "3.5.3" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.3.tgz#931e0af64e7fbbed26b050a29daad1fc64799fa6" - dependencies: - acorn "^5.4.0" - acorn-jsx "^3.0.0" - -esprima@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" - -esquery@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" - dependencies: - estraverse "^4.0.0" - -esrecurse@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" - dependencies: - estraverse "^4.1.0" - object-assign "^4.0.1" - -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - -estree-walker@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" - -estree-walker@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.3.1.tgz#e6b1a51cf7292524e7237c312e5fe6660c1ce1aa" - -estree-walker@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.5.1.tgz#64fc375053abc6f57d73e9bd2f004644ad3c5854" - -esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - dependencies: - is-posix-bracket "^0.1.0" - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - dependencies: - fill-range "^2.1.0" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@^3.0.0, extend@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" - -external-editor@^2.0.1, external-editor@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48" - dependencies: - chardet "^0.4.0" - iconv-lite "^0.4.17" - tmp "^0.0.33" - -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - dependencies: - is-extglob "^1.0.0" - -extglob@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - -fast-deep-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" - -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - -fast-levenshtein@~2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - -faye-websocket@~0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" - dependencies: - websocket-driver ">=0.5.1" - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" - dependencies: - flat-cache "^1.2.1" - object-assign "^4.0.1" - -filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - -fill-range@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^1.1.3" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - dependencies: - locate-path "^2.0.0" - -flat-cache@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" - dependencies: - circular-json "^0.3.1" - del "^2.0.2" - graceful-fs "^4.1.2" - write "^0.2.1" - -flush-write-stream@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.2.tgz#c81b90d8746766f1a609a46809946c45dd8ae417" - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.4" - -for-each@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.2.tgz#2c40450b9348e97f281322593ba96704b9abd4d4" - dependencies: - is-function "~1.0.0" - -for-in@^1.0.1, for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - -for-own@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - dependencies: - for-in "^1.0.1" - -foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - -form-data@~2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - dependencies: - map-cache "^0.2.2" - -fs-extra@*: - version "5.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-mkdirp-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" - dependencies: - graceful-fs "^4.1.11" - through2 "^2.0.3" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - -fsevents@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8" - dependencies: - nan "^2.3.0" - node-pre-gyp "^0.6.39" - -fstream-ignore@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" - dependencies: - fstream "^1.0.0" - inherits "2" - minimatch "^3.0.0" - -fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: - version "1.0.11" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" - -function-bind@^1.0.2, function-bind@^1.1.1, function-bind@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -geojson-equality@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/geojson-equality/-/geojson-equality-0.1.6.tgz#a171374ef043e5d4797995840bae4648e0752d72" - dependencies: - deep-equal "^1.0.0" - -geojson-fixtures@*: - version "1.0.0" - resolved "https://registry.yarnpkg.com/geojson-fixtures/-/geojson-fixtures-1.0.0.tgz#7d2cf22b176cecf4b98efc1d65f3c5d3ee1b0ae8" - dependencies: - geojsonhint "^1.0.0" - -geojson-polygon-self-intersections@1.2.x: - version "1.2.0" - resolved "https://registry.yarnpkg.com/geojson-polygon-self-intersections/-/geojson-polygon-self-intersections-1.2.0.tgz#451c49e89e0103588c6252363c598d73716b1746" - dependencies: - rbush "^2.0.1" - -geojson-rbush@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/geojson-rbush/-/geojson-rbush-2.1.0.tgz#3bd73be391fc10b0ae693d9b8acea2aae0b83a8d" - dependencies: - "@turf/helpers" "*" - "@turf/meta" "*" - rbush "*" - -geojson-rbush@3.x: - version "3.1.1" - resolved "https://registry.yarnpkg.com/geojson-rbush/-/geojson-rbush-3.1.1.tgz#dd40bdd26e92813d888d7b489e8d2980695a49b4" - dependencies: - "@turf/bbox" "*" - "@turf/helpers" "6.x" - "@turf/meta" "6.x" - rbush "*" - -geojsonhint@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/geojsonhint/-/geojsonhint-1.2.1.tgz#5348270ecac3c428b455cfedab245d40a5ae9fc7" - dependencies: - chalk "^1.1.0" - concat-stream "~1.4.4" - jsonlint-lines "1.7.1" - minimist "1.1.1" - text-table "^0.2.0" - -get-caller-file@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" - -get-closest@*: - version "0.0.4" - resolved "https://registry.yarnpkg.com/get-closest/-/get-closest-0.0.4.tgz#269ac776d1e6022aa0fd586dd708e8a7d32269af" - -get-pkg-repo@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" - dependencies: - hosted-git-info "^2.1.4" - meow "^3.3.0" - normalize-package-data "^2.3.0" - parse-github-repo-url "^1.3.0" - through2 "^2.0.0" - -get-port@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" - -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - dependencies: - assert-plus "^1.0.0" - -git-raw-commits@^1.3.0, git-raw-commits@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-1.3.2.tgz#0766c14d33566ba0094869697e13b0eb06147c07" - dependencies: - dargs "^4.0.1" - lodash.template "^4.0.2" - meow "^3.3.0" - split2 "^2.0.0" - through2 "^2.0.0" - -git-remote-origin-url@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" - dependencies: - gitconfiglocal "^1.0.0" - pify "^2.3.0" - -git-semver-tags@^1.3.0, git-semver-tags@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-1.3.2.tgz#94afa43c9070ae527a3ab86b978e59ae207803cc" - dependencies: - meow "^3.3.0" - semver "^5.0.1" - -git-up@^2.0.0: - version "2.0.10" - resolved "https://registry.yarnpkg.com/git-up/-/git-up-2.0.10.tgz#20fe6bafbef4384cae253dc4f463c49a0c3bd2ec" - dependencies: - is-ssh "^1.3.0" - parse-url "^1.3.0" - -git-url-parse@^8.0.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-8.1.0.tgz#d1ee09213efce5d8dc7a21bb03f17cfe0c111122" - dependencies: - git-up "^2.0.0" - -gitconfiglocal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" - dependencies: - ini "^1.3.2" - -github-slugger@1.2.0, github-slugger@^1.0.0, github-slugger@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.2.0.tgz#8ada3286fd046d8951c3c952a8d7854cfd90fd9a" - dependencies: - emoji-regex ">=6.0.0 <=6.1.1" - -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - dependencies: - is-glob "^2.0.0" - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-stream@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" - dependencies: - extend "^3.0.0" - glob "^7.1.1" - glob-parent "^3.1.0" - is-negated-glob "^1.0.0" - ordered-read-streams "^1.0.0" - pumpify "^1.3.5" - readable-stream "^2.1.5" - remove-trailing-separator "^1.0.1" - to-absolute-glob "^2.0.0" - unique-stream "^2.0.2" - -glob@*, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals-docs@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/globals-docs/-/globals-docs-2.4.0.tgz#f2c647544eb6161c7c38452808e16e693c2dafbb" - -globals@^11.0.1: - version "11.3.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.3.0.tgz#e04fdb7b9796d8adac9c8f64c14837b2313378b0" - -globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - -globby@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" - dependencies: - array-union "^1.0.1" - arrify "^1.0.0" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -globby@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -got@^6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" - dependencies: - create-error-class "^3.0.0" - duplexer3 "^0.1.4" - get-stream "^3.0.0" - is-redirect "^1.0.0" - is-retry-allowed "^1.0.0" - is-stream "^1.0.0" - lowercase-keys "^1.0.0" - safe-buffer "^5.0.1" - timed-out "^4.0.0" - unzip-response "^2.0.1" - url-parse-lax "^1.0.0" - -graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - -handlebars@^4.0.2: - version "4.0.11" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" - dependencies: - async "^1.4.0" - optimist "^0.6.1" - source-map "^0.4.4" - optionalDependencies: - uglify-js "^2.6" - -har-schema@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" - -har-validator@~4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" - dependencies: - ajv "^4.9.1" - har-schema "^1.0.5" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - dependencies: - ansi-regex "^2.0.0" - -has-color@~0.1.0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" - -has-flag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - -has-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.1, has@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" - dependencies: - function-bind "^1.0.2" - -hast-util-is-element@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/hast-util-is-element/-/hast-util-is-element-1.0.0.tgz#3f7216978b2ae14d98749878782675f33be3ce00" - -hast-util-sanitize@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/hast-util-sanitize/-/hast-util-sanitize-1.1.2.tgz#d10bd6757a21e59c13abc8ae3530dd3b6d7d679e" - dependencies: - xtend "^4.0.1" - -hast-util-to-html@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-3.1.0.tgz#882c99849e40130e991c042e456d453d95c36cff" - dependencies: - ccount "^1.0.0" - comma-separated-tokens "^1.0.1" - hast-util-is-element "^1.0.0" - hast-util-whitespace "^1.0.0" - html-void-elements "^1.0.0" - kebab-case "^1.0.0" - property-information "^3.1.0" - space-separated-tokens "^1.0.0" - stringify-entities "^1.0.1" - unist-util-is "^2.0.0" - xtend "^4.0.1" - -hast-util-whitespace@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-1.0.0.tgz#bd096919625d2936e1ff17bc4df7fd727f17ece9" - -hawk@3.1.3, hawk@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" - dependencies: - boom "2.x.x" - cryptiles "2.x.x" - hoek "2.x.x" - sntp "1.x.x" - -highlight.js@^9.12.0: - version "9.12.0" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e" - -hoek@2.x.x: - version "2.16.3" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" - -home-or-tmp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" - -hosted-git-info@^2.1.4, hosted-git-info@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" - -html-void-elements@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.2.tgz#9d22e0ca32acc95b3f45b8d5b4f6fbdc05affd55" - -http-parser-js@>=0.4.0: - version "0.4.10" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" - -http-signature@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" - dependencies: - assert-plus "^0.2.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -iconv-lite@^0.4.17, iconv-lite@~0.4.13: - version "0.4.19" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" - -ignore@^3.3.3: - version "3.3.7" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - dependencies: - repeating "^2.0.0" - -indent-string@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - -ini@^1.3.2, ini@^1.3.3, ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - -inquirer@3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347" - dependencies: - ansi-escapes "^1.1.0" - chalk "^1.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^2.0.1" - figures "^2.0.0" - lodash "^4.3.0" - mute-stream "0.0.7" - run-async "^2.2.0" - rx "^4.1.0" - string-width "^2.0.0" - strip-ansi "^3.0.0" - through "^2.3.6" - -inquirer@^3.0.6, inquirer@^3.2.2: - version "3.3.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^2.0.4" - figures "^2.0.0" - lodash "^4.3.0" - mute-stream "0.0.7" - run-async "^2.2.0" - rx-lite "^4.0.8" - rx-lite-aggregates "^4.0.8" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - -interpret@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" - -invariant@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" - dependencies: - loose-envify "^1.0.0" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - -irregular-plurals@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.4.0.tgz#2ca9b033651111855412f16be5d77c62a458a766" - -is-absolute@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" - dependencies: - is-relative "^1.0.0" - is-windows "^1.0.1" - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - dependencies: - kind-of "^6.0.0" - -is-alphabetical@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.1.tgz#c77079cc91d4efac775be1034bf2d243f95e6f08" - -is-alphanumeric@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz#4a9cef71daf4c001c1d81d63d140cf53fd6889f4" - -is-alphanumerical@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.1.tgz#dfb4aa4d1085e33bdb61c2dee9c80e9c6c19f53b" - dependencies: - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.1.4, is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - -is-builtin-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - dependencies: - builtin-modules "^1.0.0" - -is-callable@^1.1.1, is-callable@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" - -is-ci@^1.0.10: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5" - dependencies: - ci-info "^1.0.0" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - dependencies: - kind-of "^6.0.0" - -is-date-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - -is-decimal@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.1.tgz#f5fb6a94996ad9e8e3761fbfbd091f1fca8c4e82" - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - dependencies: - is-primitive "^2.0.0" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - -is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - -is-function@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" - -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - dependencies: - is-extglob "^1.0.0" - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" - dependencies: - is-extglob "^2.1.1" - -is-hexadecimal@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.1.tgz#6e084bbc92061fbb0971ec58b6ce6d404e24da69" - -is-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" - -is-negated-glob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" - -is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - dependencies: - kind-of "^3.0.2" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - dependencies: - kind-of "^3.0.2" - -is-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - -is-odd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-1.0.0.tgz#3b8a932eb028b3775c39bb09e91767accdb69088" - dependencies: - is-number "^3.0.0" - -is-path-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" - -is-path-in-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" - dependencies: - is-path-inside "^1.0.0" - -is-path-inside@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" - dependencies: - path-is-inside "^1.0.1" - -is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - -is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - dependencies: - isobject "^3.0.1" - -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - -is-promise@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - -is-redirect@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" - -is-regex@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - dependencies: - has "^1.0.1" - -is-relative@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" - dependencies: - is-unc-path "^1.0.0" - -is-resolvable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" - -is-retry-allowed@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" - -is-ssh@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.3.0.tgz#ebea1169a2614da392a63740366c3ce049d8dff6" - dependencies: - protocols "^1.1.0" - -is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - -is-subset@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" - -is-symbol@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" - -is-text-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" - dependencies: - text-extensions "^1.0.0" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - -is-unc-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" - dependencies: - unc-path-regex "^0.1.2" - -is-utf8@^0.2.0, is-utf8@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - -is-valid-glob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" - -is-whitespace-character@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.1.tgz#9ae0176f3282b65457a1992cdb084f8a5f833e3b" - -is-windows@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - -is-word-character@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.1.tgz#5a03fa1ea91ace8a6eb0c7cd770eb86d65c8befb" - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - -js-tokens@^3.0.0, js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - -js-yaml@^3.10.0, js-yaml@^3.9.1: - version "3.10.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^3.7.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - -json-parse-better-errors@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz#50183cd1b2d25275de069e9e71b467ac9eab973a" - -json-schema-traverse@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - -json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - dependencies: - jsonify "~0.0.0" - -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - -json5@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - -jsonlint-lines@1.7.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/jsonlint-lines/-/jsonlint-lines-1.7.1.tgz#507de680d3fb8c4be1641cc57d6f679f29f178ff" - dependencies: - JSV ">= 4.0.x" - nomnom ">= 1.5.x" - -jsonparse@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -jsts@^1.4.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/jsts/-/jsts-1.6.0.tgz#ab5d47ca3f9962c4ef94bbe6a317efeacdb41c93" - -kebab-case@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/kebab-case/-/kebab-case-1.0.0.tgz#3f9e4990adcad0c686c0e701f7645868f75f91eb" - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0, kind-of@^5.0.2: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - -lazy-cache@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264" - dependencies: - set-getter "^0.1.0" - -lazystream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" - dependencies: - readable-stream "^2.0.5" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - dependencies: - invert-kv "^1.0.0" - -lead@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lead/-/lead-1.0.0.tgz#6f14f99a37be3a9dd784f5495690e5903466ee42" - dependencies: - flush-write-stream "^1.0.2" - -lerna@2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/lerna/-/lerna-2.8.0.tgz#309a816fca5c73ea38f9f20e314a836e99b54cf0" - dependencies: - async "^1.5.0" - chalk "^2.1.0" - cmd-shim "^2.0.2" - columnify "^1.5.4" - command-join "^2.0.0" - conventional-changelog-cli "^1.3.2" - conventional-recommended-bump "^1.0.1" - dedent "^0.7.0" - execa "^0.8.0" - find-up "^2.1.0" - fs-extra "^4.0.1" - get-port "^3.2.0" - glob "^7.1.2" - glob-parent "^3.1.0" - globby "^6.1.0" - graceful-fs "^4.1.11" - hosted-git-info "^2.5.0" - inquirer "^3.2.2" - is-ci "^1.0.10" - load-json-file "^4.0.0" - lodash "^4.17.4" - minimatch "^3.0.4" - npmlog "^4.1.2" - p-finally "^1.0.0" - package-json "^4.0.1" - path-exists "^3.0.0" - read-cmd-shim "^1.0.1" - read-pkg "^3.0.0" - rimraf "^2.6.1" - safe-buffer "^5.1.1" - semver "^5.4.1" - signal-exit "^3.0.2" - slash "^1.0.0" - strong-log-transformer "^1.0.6" - temp-write "^3.3.0" - write-file-atomic "^2.3.0" - write-json-file "^2.2.0" - write-pkg "^3.1.0" - yargs "^8.0.2" - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -livereload-js@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.3.0.tgz#c3ab22e8aaf5bf3505d80d098cbad67726548c9a" - -load-json-file@*, load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -lodash._reinterpolate@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - -lodash.template@^4.0.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" - dependencies: - lodash._reinterpolate "~3.0.0" - lodash.templatesettings "^4.0.0" - -lodash.templatesettings@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316" - dependencies: - lodash._reinterpolate "~3.0.0" - -lodash@3.x: - version "3.10.1" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" - -lodash@^4.0.0, lodash@^4.1.0, lodash@^4.17.4, lodash@^4.2.1, lodash@^4.3.0: - version "4.17.5" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" - -log-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" - dependencies: - chalk "^1.0.0" - -longest-streak@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.2.tgz#2421b6ba939a443bb9ffebf596585a50b4c38e2e" - -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - -loose-envify@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" - dependencies: - js-tokens "^3.0.0" - -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - -lowercase-keys@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" - -lru-cache@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -magic-string@^0.22.4: - version "0.22.4" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.4.tgz#31039b4e40366395618c1d6cf8193c53917475ff" - dependencies: - vlq "^0.2.1" - -make-dir@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.1.0.tgz#19b4369fe48c116f53c2af95ad102c0e39e85d51" - dependencies: - pify "^3.0.0" - -map-cache@^0.2.0, map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - -map-obj@^1.0.0, map-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - -map-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - dependencies: - object-visit "^1.0.0" - -markdown-escapes@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.1.tgz#1994df2d3af4811de59a6714934c2b2292734518" - -markdown-table@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.1.tgz#4b3dd3a133d1518b8ef0dbc709bf2a1b4824bc8c" - -martinez-polygon-clipping@*: - version "0.4.3" - resolved "https://registry.yarnpkg.com/martinez-polygon-clipping/-/martinez-polygon-clipping-0.4.3.tgz#a3971ddf1da147104b5d0fbbf68f728bb62885c1" - dependencies: - splaytree "^0.1.4" - tinyqueue "^1.2.0" - -matrix-to-grid@*: - version "4.0.0" - resolved "https://registry.yarnpkg.com/matrix-to-grid/-/matrix-to-grid-4.0.0.tgz#9b22e2ff1cb53629597f1aa51975708620adf2d4" - dependencies: - "@turf/helpers" "5.x" - "@turf/rhumb-destination" "5.x" - -mdast-util-compact@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-compact/-/mdast-util-compact-1.0.1.tgz#cdb5f84e2b6a2d3114df33bd05d9cb32e3c4083a" - dependencies: - unist-util-modify-children "^1.0.0" - unist-util-visit "^1.1.0" - -mdast-util-definitions@^1.2.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-1.2.2.tgz#673f4377c3e23d3de7af7a4fe2214c0e221c5ac7" - dependencies: - unist-util-visit "^1.0.0" - -mdast-util-inject@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mdast-util-inject/-/mdast-util-inject-1.1.0.tgz#db06b8b585be959a2dcd2f87f472ba9b756f3675" - dependencies: - mdast-util-to-string "^1.0.0" - -mdast-util-to-hast@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-3.0.0.tgz#69e367fb2a9eb02474dfc017733b8fd272d55d3a" - dependencies: - collapse-white-space "^1.0.0" - detab "^2.0.0" - mdast-util-definitions "^1.2.0" - mdurl "^1.0.1" - trim "0.0.1" - trim-lines "^1.0.0" - unist-builder "^1.0.1" - unist-util-generated "^1.1.0" - unist-util-position "^3.0.0" - unist-util-visit "^1.1.0" - xtend "^4.0.1" - -mdast-util-to-string@^1.0.0, mdast-util-to-string@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.0.4.tgz#5c455c878c9355f0c1e7f3e8b719cf583691acfb" - -mdast-util-toc@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-toc/-/mdast-util-toc-2.0.1.tgz#b1d2cb23bfb01f812fa7b55bffe8b0a8bedf6f21" - dependencies: - github-slugger "^1.1.1" - mdast-util-to-string "^1.0.2" - unist-util-visit "^1.1.0" - -mdurl@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - dependencies: - mimic-fn "^1.0.0" - -meow@*: - version "4.0.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-4.0.0.tgz#fd5855dd008db5b92c552082db1c307cba20b29d" - dependencies: - camelcase-keys "^4.0.0" - decamelize-keys "^1.0.0" - loud-rejection "^1.0.0" - minimist "^1.1.3" - minimist-options "^3.0.1" - normalize-package-data "^2.3.4" - read-pkg-up "^3.0.0" - redent "^2.0.0" - trim-newlines "^2.0.0" - -meow@^3.3.0, meow@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" - -mgrs@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/mgrs/-/mgrs-1.0.0.tgz#fb91588e78c90025672395cb40b25f7cd6ad1829" - -micromatch@^2.3.11: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - -micromatch@^3.1.4, micromatch@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.5.tgz#d05e168c206472dfbca985bfef4f57797b4cd4ba" - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.0" - define-property "^1.0.0" - extend-shallow "^2.0.1" - extglob "^2.0.2" - fragment-cache "^0.2.1" - kind-of "^6.0.0" - nanomatch "^1.2.5" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -mime-db@~1.30.0: - version "1.30.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" - -mime-types@^2.1.12, mime-types@~2.1.7: - version "2.1.17" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" - dependencies: - mime-db "~1.30.0" - -mime@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.2.0.tgz#161e541965551d3b549fa1114391e3a3d55b923b" - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - dependencies: - brace-expansion "^1.1.7" - -minimist-options@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" - dependencies: - arrify "^1.0.1" - is-plain-obj "^1.1.0" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - -minimist@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.1.1.tgz#1bc2bc71658cdca5712475684363615b0b4f695b" - -minimist@1.2.0, minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0, minimist@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - -minimist@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.1.0.tgz#99df657a52574c21c9057497df742790b2b4c0de" - -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - -mixin-deep@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@*, "mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - dependencies: - minimist "0.0.8" - -modify-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.0.tgz#e2b6cdeb9ce19f99317a53722f3dbf5df5eaaab2" - -module-deps-sortable@4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/module-deps-sortable/-/module-deps-sortable-4.0.6.tgz#1251a4ba2c44a92df6989bd029da121a4f2109b0" - dependencies: - JSONStream "^1.0.3" - browser-resolve "^1.7.0" - concat-stream "~1.5.0" - defined "^1.0.0" - detective "^4.0.0" - duplexer2 "^0.1.2" - inherits "^2.0.1" - parents "^1.0.0" - readable-stream "^2.0.2" - resolve "^1.1.3" - stream-combiner2 "^1.1.1" - subarg "^1.0.0" - through2 "^2.0.0" - xtend "^4.0.0" - -moment@^2.6.0: - version "2.20.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd" - -monotone-convex-hull-2d@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/monotone-convex-hull-2d/-/monotone-convex-hull-2d-1.0.1.tgz#47f5daeadf3c4afd37764baa1aa8787a40eee08c" - dependencies: - robust-orientation "^1.1.3" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - -nan@^2.3.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" - -nanomatch@^1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.7.tgz#53cd4aa109ff68b7f869591fdc9d10daeeea3e79" - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^1.0.0" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - is-odd "^1.0.0" - kind-of "^5.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - -node-fetch@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" - dependencies: - encoding "^0.1.11" - is-stream "^1.0.1" - -node-pre-gyp@^0.6.39: - version "0.6.39" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" - dependencies: - detect-libc "^1.0.2" - hawk "3.1.3" - mkdirp "^0.5.1" - nopt "^4.0.1" - npmlog "^4.0.2" - rc "^1.1.7" - request "2.81.0" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^2.2.1" - tar-pack "^3.4.0" - -"nomnom@>= 1.5.x": - version "1.8.1" - resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" - dependencies: - chalk "~0.4.0" - underscore "~1.6.0" - -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - dependencies: - abbrev "1" - osenv "^0.1.4" - -normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5: - version "2.4.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" - dependencies: - hosted-git-info "^2.1.4" - is-builtin-module "^1.0.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^2.0.1, normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - dependencies: - remove-trailing-separator "^1.0.1" - -now-and-later@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.0.tgz#bc61cbb456d79cb32207ce47ca05136ff2e7d6ee" - dependencies: - once "^1.3.2" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - dependencies: - path-key "^2.0.0" - -npmlog@^4.0.2, npmlog@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - -oauth-sign@~0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - -object-assign@*, object-assign@^4.0.1, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-inspect@~1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.3.0.tgz#5b1eb8e6742e2ee83342a637034d844928ba2f6d" - -object-keys@^1.0.11, object-keys@^1.0.8: - version "1.0.11" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - dependencies: - isobject "^3.0.0" - -object.assign@^4.0.4: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - dependencies: - isobject "^3.0.1" - -once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.3.3, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - dependencies: - wrappy "1" - -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - dependencies: - mimic-fn "^1.0.0" - -opencollective@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/opencollective/-/opencollective-1.0.3.tgz#aee6372bc28144583690c3ca8daecfc120dd0ef1" - dependencies: - babel-polyfill "6.23.0" - chalk "1.1.3" - inquirer "3.0.6" - minimist "1.2.0" - node-fetch "1.6.3" - opn "4.0.2" - -opn@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" - dependencies: - object-assign "^4.0.1" - pinkie-promise "^2.0.0" - -optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - -optionator@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.4" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - wordwrap "~1.0.0" - -ordered-read-streams@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" - dependencies: - readable-stream "^2.0.1" - -os-homedir@^1.0.0, os-homedir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - -os-locale@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" - dependencies: - execa "^0.7.0" - lcid "^1.0.0" - mem "^1.1.0" - -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - -osenv@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - -p-limit@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" - dependencies: - p-try "^1.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - dependencies: - p-limit "^1.1.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - -package-json@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" - dependencies: - got "^6.7.1" - registry-auth-token "^3.0.1" - registry-url "^3.0.3" - semver "^5.1.0" - -parents@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parents/-/parents-1.0.1.tgz#fedd4d2bf193a77745fe71e371d73c3307d9c751" - dependencies: - path-platform "~0.11.15" - -parse-entities@^1.0.2, parse-entities@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.1.1.tgz#8112d88471319f27abae4d64964b122fe4e1b890" - dependencies: - character-entities "^1.0.0" - character-entities-legacy "^1.0.0" - character-reference-invalid "^1.0.0" - is-alphanumerical "^1.0.0" - is-decimal "^1.0.0" - is-hexadecimal "^1.0.0" - -parse-filepath@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" - dependencies: - is-absolute "^1.0.0" - map-cache "^0.2.0" - path-root "^0.1.1" - -parse-git-config@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/parse-git-config/-/parse-git-config-0.2.0.tgz#272833fdd15fea146fb75d336d236b963b6ff706" - dependencies: - ini "^1.3.3" - -parse-github-repo-url@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50" - -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - dependencies: - error-ex "^1.2.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-url@^1.3.0: - version "1.3.11" - resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-1.3.11.tgz#57c15428ab8a892b1f43869645c711d0e144b554" - dependencies: - is-ssh "^1.3.0" - protocols "^1.4.0" - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - -path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - -path-is-inside@^1.0.1, path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - -path-key@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - -path-parse@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" - -path-platform@~0.11.15: - version "0.11.15" - resolved "https://registry.yarnpkg.com/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2" - -path-root-regex@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" - -path-root@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" - dependencies: - path-root-regex "^0.1.0" - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - dependencies: - pify "^2.0.0" - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - dependencies: - pify "^3.0.0" - -performance-now@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" - -pify@^2.0.0, pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - -platform@^1.3.3: - version "1.3.5" - resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.5.tgz#fb6958c696e07e2918d2eeda0f0bc9448d733444" - -plur@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" - dependencies: - irregular-plurals "^1.0.0" - -pluralize@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" - -point-in-polygon@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/point-in-polygon/-/point-in-polygon-1.0.1.tgz#d59b64e8fee41c49458aac82b56718c5957b2af7" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - -prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - -private@^0.1.6, private@^0.1.7: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - -process-nextick-args@^1.0.6, process-nextick-args@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" - -process-nextick-args@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - -progress@*, progress@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" - -proj4@*: - version "2.4.4" - resolved "https://registry.yarnpkg.com/proj4/-/proj4-2.4.4.tgz#c03d825e380f6850a4a7af5d20d365f6b72c4042" - dependencies: - mgrs "1.0.0" - wkt-parser "^1.2.0" - -property-information@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-3.2.0.tgz#fd1483c8fbac61808f5fe359e7693a1f48a58331" - -protocols@^1.1.0, protocols@^1.4.0: - version "1.4.6" - resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.6.tgz#f8bb263ea1b5fd7a7604d26b8be39bd77678bf8a" - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pumpify@^1.3.5: - version "1.4.0" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.4.0.tgz#80b7c5df7e24153d03f0e7ac8a05a5d068bd07fb" - dependencies: - duplexify "^3.5.3" - inherits "^2.0.3" - pump "^2.0.0" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - -python-shell@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/python-shell/-/python-shell-0.4.0.tgz#259c5470d885292b22e906a57b085f651752f956" - -q@^1.4.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - -qs@^6.4.0: - version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" - -qs@~6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" - -quick-lru@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" - -quickselect@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-1.0.1.tgz#1e6ceaa9db1ca7c75aafcc863c7bef2037ca62a1" - -randomatic@^1.1.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -raw-body@~1.1.0: - version "1.1.7" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-1.1.7.tgz#1d027c2bfa116acc6623bca8f00016572a87d425" - dependencies: - bytes "1" - string_decoder "0.10" - -rbush@*, rbush@2.x, rbush@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/rbush/-/rbush-2.0.2.tgz#bb6005c2731b7ba1d5a9a035772927d16a614605" - dependencies: - quickselect "^1.0.1" - -rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: - version "1.2.5" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.5.tgz#275cd687f6e3b36cc756baa26dfee80a790301fd" - dependencies: - deep-extend "~0.4.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -read-cmd-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b" - dependencies: - graceful-fs "^4.1.2" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg@^1.0.0, read-pkg@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3: - version "2.3.4" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.4.tgz#c946c3f47fa7d8eabc0b6150f4a12f69a4574071" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.0.3" - util-deprecate "~1.0.1" - -readable-stream@~1.1.9: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@~2.0.0: - version "2.0.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - string_decoder "~0.10.x" - util-deprecate "~1.0.1" - -readable-stream@~2.1.0: - version "2.1.5" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" - dependencies: - buffer-shims "^1.0.0" - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - string_decoder "~0.10.x" - util-deprecate "~1.0.1" - -readdirp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" - dependencies: - graceful-fs "^4.1.2" - minimatch "^3.0.2" - readable-stream "^2.0.2" - set-immediate-shim "^1.0.1" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - dependencies: - resolve "^1.1.6" - -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - -redent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" - dependencies: - indent-string "^3.0.0" - strip-indent "^2.0.0" - -regenerate@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" - -regenerator-runtime@^0.10.0: - version "0.10.5" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" - -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - -regenerator-transform@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" - dependencies: - babel-runtime "^6.18.0" - babel-types "^6.19.0" - private "^0.1.6" - -regex-cache@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" - dependencies: - is-equal-shallow "^0.1.3" - -regex-not@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.0.tgz#42f83e39771622df826b02af176525d6a5f157f9" - dependencies: - extend-shallow "^2.0.1" - -regexpu-core@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - -registry-auth-token@^3.0.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" - dependencies: - rc "^1.1.6" - safe-buffer "^5.0.1" - -registry-url@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" - dependencies: - rc "^1.0.1" - -regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - -regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" - dependencies: - jsesc "~0.5.0" - -remark-html@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/remark-html/-/remark-html-7.0.0.tgz#d13dc1ba9352e257fce8800c42c7690d9e3690c8" - dependencies: - hast-util-sanitize "^1.0.0" - hast-util-to-html "^3.0.0" - mdast-util-to-hast "^3.0.0" - xtend "^4.0.1" - -remark-parse@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-5.0.0.tgz#4c077f9e499044d1d5c13f80d7a98cf7b9285d95" - dependencies: - collapse-white-space "^1.0.2" - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - is-whitespace-character "^1.0.0" - is-word-character "^1.0.0" - markdown-escapes "^1.0.0" - parse-entities "^1.1.0" - repeat-string "^1.5.4" - state-toggle "^1.0.0" - trim "0.0.1" - trim-trailing-lines "^1.0.0" - unherit "^1.0.4" - unist-util-remove-position "^1.0.0" - vfile-location "^2.0.0" - xtend "^4.0.1" - -remark-slug@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-5.0.0.tgz#9de71fcdc2bfae33ebb4a41eb83035288a829980" - dependencies: - github-slugger "^1.0.0" - mdast-util-to-string "^1.0.0" - unist-util-visit "^1.0.0" - -remark-stringify@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-5.0.0.tgz#336d3a4d4a6a3390d933eeba62e8de4bd280afba" - dependencies: - ccount "^1.0.0" - is-alphanumeric "^1.0.0" - is-decimal "^1.0.0" - is-whitespace-character "^1.0.0" - longest-streak "^2.0.1" - markdown-escapes "^1.0.0" - markdown-table "^1.1.0" - mdast-util-compact "^1.0.0" - parse-entities "^1.0.2" - repeat-string "^1.5.4" - state-toggle "^1.0.0" - stringify-entities "^1.0.1" - unherit "^1.0.4" - xtend "^4.0.1" - -remark-toc@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/remark-toc/-/remark-toc-5.0.0.tgz#f1e13ed11062ad4d102b02e70168bd85015bf129" - dependencies: - mdast-util-toc "^2.0.0" - remark-slug "^5.0.0" - -remark@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/remark/-/remark-9.0.0.tgz#c5cfa8ec535c73a67c4b0f12bfdbd3a67d8b2f60" - dependencies: - remark-parse "^5.0.0" - remark-stringify "^5.0.0" - unified "^6.0.0" - -remote-origin-url@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/remote-origin-url/-/remote-origin-url-0.4.0.tgz#4d3e2902f34e2d37d1c263d87710b77eb4086a30" - dependencies: - parse-git-config "^0.2.0" - -remove-bom-buffer@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" - dependencies: - is-buffer "^1.1.5" - is-utf8 "^0.2.1" - -remove-bom-stream@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz#05f1a593f16e42e1fb90ebf59de8e569525f9523" - dependencies: - remove-bom-buffer "^3.0.0" - safe-buffer "^5.1.0" - through2 "^2.0.3" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - -repeat-element@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" - -repeat-string@^1.5.0, repeat-string@^1.5.2, repeat-string@^1.5.4, repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - dependencies: - is-finite "^1.0.0" - -replace-ext@1.0.0, replace-ext@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" - -request@2.81.0: - version "2.81.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~4.2.1" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" - performance-now "^0.2.0" - qs "~6.4.0" - safe-buffer "^5.0.1" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "^0.6.0" - uuid "^3.0.0" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - -require-uncached@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" - dependencies: - caller-path "^0.1.0" - resolve-from "^1.0.0" - -resolve-from@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" - -resolve-options@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" - dependencies: - value-or-function "^3.0.0" - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - -resolve@1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - -resolve@^1.1.3, resolve@^1.1.6, resolve@^1.4.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" - dependencies: - path-parse "^1.0.5" - -resolve@^1.3.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.6.0.tgz#0fbd21278b27b4004481c395349e7aba60a9ff5c" - dependencies: - path-parse "^1.0.5" - -resolve@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86" - dependencies: - path-parse "^1.0.5" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -resumer@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" - dependencies: - through "~2.3.4" - -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - dependencies: - align-text "^0.1.1" - -rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - dependencies: - glob "^7.0.5" - -robust-orientation@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/robust-orientation/-/robust-orientation-1.1.3.tgz#daff5b00d3be4e60722f0e9c0156ef967f1c2049" - dependencies: - robust-scale "^1.0.2" - robust-subtract "^1.0.0" - robust-sum "^1.0.0" - two-product "^1.0.2" - -robust-scale@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/robust-scale/-/robust-scale-1.0.2.tgz#775132ed09542d028e58b2cc79c06290bcf78c32" - dependencies: - two-product "^1.0.2" - two-sum "^1.0.0" - -robust-subtract@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/robust-subtract/-/robust-subtract-1.0.0.tgz#e0b164e1ed8ba4e3a5dda45a12038348dbed3e9a" - -robust-sum@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/robust-sum/-/robust-sum-1.0.0.tgz#16646e525292b4d25d82757a286955e0bbfa53d9" - -rollup-plugin-buble@*: - version "0.19.2" - resolved "https://registry.yarnpkg.com/rollup-plugin-buble/-/rollup-plugin-buble-0.19.2.tgz#c0590c7d3d475b5ed59f129764ec93710cc6e8dd" - dependencies: - buble "^0.19.2" - rollup-pluginutils "^2.0.1" - -rollup-plugin-commonjs@*: - version "8.3.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-8.3.0.tgz#91b4ba18f340951e39ed7b1901f377a80ab3f9c3" - dependencies: - acorn "^5.2.1" - estree-walker "^0.5.0" - magic-string "^0.22.4" - resolve "^1.4.0" - rollup-pluginutils "^2.0.1" - -rollup-plugin-node-resolve@*: - version "3.0.3" - resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.0.3.tgz#8f57b253edd00e5b0ad0aed7b7e9cf5982e98fa4" - dependencies: - builtin-modules "^1.1.0" - is-module "^1.0.0" - resolve "^1.1.6" - -rollup-plugin-typescript@*: - version "0.8.1" - resolved "https://registry.yarnpkg.com/rollup-plugin-typescript/-/rollup-plugin-typescript-0.8.1.tgz#2ff7eecc21cf6bb2b43fc27e5b688952ce71924a" - dependencies: - compare-versions "2.0.1" - object-assign "^4.0.1" - rollup-pluginutils "^1.3.1" - tippex "^2.1.1" - typescript "^1.8.9" - -rollup-plugin-uglify@*: - version "3.0.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-uglify/-/rollup-plugin-uglify-3.0.0.tgz#a34eca24617709c6bf1778e9653baafa06099b86" - dependencies: - uglify-es "^3.3.7" - -rollup-pluginutils@^1.3.1: - version "1.5.2" - resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" - dependencies: - estree-walker "^0.2.1" - minimatch "^3.0.2" - -rollup-pluginutils@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.0.1.tgz#7ec95b3573f6543a46a6461bd9a7c544525d0fc0" - dependencies: - estree-walker "^0.3.0" - micromatch "^2.3.11" - -rollup@*: - version "0.55.5" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.55.5.tgz#2f88c300f7cf24b5ec2dca8a6aba73b04e087e93" - -run-async@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - dependencies: - is-promise "^2.1.0" - -rx-lite-aggregates@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" - dependencies: - rx-lite "*" - -rx-lite@*, rx-lite@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" - -rx@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - -safe-json-parse@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/safe-json-parse/-/safe-json-parse-1.0.1.tgz#3e76723e38dfdda13c9b1d29a1e07ffee4b30b57" - -"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1: - version "5.5.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" - -set-blocking@^2.0.0, set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - -set-getter@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376" - dependencies: - to-object-path "^0.3.0" - -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - -set-value@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.1" - to-object-path "^0.3.0" - -set-value@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - -shelljs@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.1.tgz#729e038c413a2254c4078b95ed46e0397154a9f1" - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - -skmeans@0.9.7: - version "0.9.7" - resolved "https://registry.yarnpkg.com/skmeans/-/skmeans-0.9.7.tgz#72670cebb728508f56e29c0e10d11e623529ce5d" - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - -slice-ansi@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" - dependencies: - is-fullwidth-code-point "^2.0.0" - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.1.tgz#e12b5487faded3e3dea0ac91e9400bf75b401370" - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^2.0.0" - -sntp@1.x.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" - dependencies: - hoek "2.x.x" - -sort-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" - dependencies: - is-plain-obj "^1.0.0" - -source-map-resolve@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.1.tgz#7ad0f593f2281598e854df80f19aae4b92d7a11a" - dependencies: - atob "^2.0.0" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@^0.4.15: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" - dependencies: - source-map "^0.5.6" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - -source-map@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" - dependencies: - amdefine ">=0.0.4" - -source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - -source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - -space-separated-tokens@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.1.tgz#9695b9df9e65aec1811d4c3f9ce52520bc2f7e4d" - dependencies: - trim "0.0.1" - -spdx-correct@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" - dependencies: - spdx-license-ids "^1.0.2" - -spdx-expression-parse@~1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" - -spdx-license-ids@^1.0.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" - -splaytree@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/splaytree/-/splaytree-0.1.4.tgz#fc35475248edcc29d4938c9b67e43c6b7e55a659" - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - dependencies: - extend-shallow "^3.0.0" - -split2@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" - dependencies: - through2 "^2.0.2" - -split@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" - dependencies: - through "2" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - -sshpk@^1.7.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - dashdash "^1.12.0" - getpass "^0.1.1" - optionalDependencies: - bcrypt-pbkdf "^1.0.0" - ecc-jsbn "~0.1.1" - jsbn "~0.1.0" - tweetnacl "~0.14.0" - -state-toggle@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.0.tgz#d20f9a616bb4f0c3b98b91922d25b640aa2bc425" - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -stream-array@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/stream-array/-/stream-array-1.1.2.tgz#9e5f7345f2137c30ee3b498b9114e80b52bb7eb5" - dependencies: - readable-stream "~2.1.0" - -stream-combiner2@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe" - dependencies: - duplexer2 "~0.1.0" - readable-stream "^2.0.2" - -stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" - -string-template@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" - -string-width@^1.0.0, string-width@^1.0.1, string-width@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string.prototype.trim@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea" - dependencies: - define-properties "^1.1.2" - es-abstract "^1.5.0" - function-bind "^1.0.2" - -string_decoder@0.10, string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - -string_decoder@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" - dependencies: - safe-buffer "~5.1.0" - -stringify-entities@^1.0.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-1.3.1.tgz#b150ec2d72ac4c1b5f324b51fb6b28c9cdff058c" - dependencies: - character-entities-html4 "^1.0.0" - character-entities-legacy "^1.0.0" - is-alphanumerical "^1.0.0" - is-hexadecimal "^1.0.0" - -stringstream@~0.0.4: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - dependencies: - is-utf8 "^0.2.0" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - dependencies: - get-stdin "^4.0.1" - -strip-indent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" - -strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - -strong-log-transformer@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-1.0.6.tgz#f7fb93758a69a571140181277eea0c2eb1301fa3" - dependencies: - byline "^5.0.0" - duplexer "^0.1.1" - minimist "^0.1.0" - moment "^2.6.0" - through "^2.3.4" - -subarg@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2" - dependencies: - minimist "^1.1.0" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - -supports-color@^4.1.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" - dependencies: - has-flag "^2.0.0" - -supports-color@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.2.0.tgz#b0d5333b1184dd3666cbe5aa0b45c5ac7ac17a4a" - dependencies: - has-flag "^3.0.0" - -table@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" - dependencies: - ajv "^5.2.3" - ajv-keywords "^2.1.0" - chalk "^2.1.0" - lodash "^4.17.4" - slice-ansi "1.0.0" - string-width "^2.1.1" - -tape@*: - version "4.8.0" - resolved "https://registry.yarnpkg.com/tape/-/tape-4.8.0.tgz#f6a9fec41cc50a1de50fa33603ab580991f6068e" - dependencies: - deep-equal "~1.0.1" - defined "~1.0.0" - for-each "~0.3.2" - function-bind "~1.1.0" - glob "~7.1.2" - has "~1.0.1" - inherits "~2.0.3" - minimist "~1.2.0" - object-inspect "~1.3.0" - resolve "~1.4.0" - resumer "~0.0.0" - string.prototype.trim "~1.1.2" - through "~2.3.8" - -tar-pack@^3.4.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" - dependencies: - debug "^2.2.0" - fstream "^1.0.10" - fstream-ignore "^1.0.5" - once "^1.3.3" - readable-stream "^2.1.4" - rimraf "^2.5.1" - tar "^2.2.1" - uid-number "^0.0.6" - -tar@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" - dependencies: - block-stream "*" - fstream "^1.0.2" - inherits "2" - -temp-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" - -temp-write@^3.3.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/temp-write/-/temp-write-3.4.0.tgz#8cff630fb7e9da05f047c74ce4ce4d685457d492" - dependencies: - graceful-fs "^4.1.2" - is-stream "^1.1.0" - make-dir "^1.0.0" - pify "^3.0.0" - temp-dir "^1.0.0" - uuid "^3.0.1" - -tempfile@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-1.1.1.tgz#5bcc4eaecc4ab2c707d8bc11d99ccc9a2cb287f2" - dependencies: - os-tmpdir "^1.0.0" - uuid "^2.0.1" - -text-extensions@^1.0.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.7.0.tgz#faaaba2625ed746d568a23e4d0aacd9bf08a8b39" - -text-table@^0.2.0, text-table@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - -through2-filter@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec" - dependencies: - through2 "~2.0.0" - xtend "~4.0.0" - -through2@^2.0.0, through2@^2.0.1, through2@^2.0.2, through2@^2.0.3, through2@~2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" - dependencies: - readable-stream "^2.1.5" - xtend "~4.0.1" - -through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6, through@~2.3.4, through@~2.3.8: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - -timed-out@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - -tiny-lr@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-1.1.0.tgz#a373bce2a4b58cef9a64433360ba593155f4cd45" - dependencies: - body "^5.1.0" - debug "~2.6.7" - faye-websocket "~0.10.0" - livereload-js "^2.3.0" - object-assign "^4.1.0" - qs "^6.4.0" - -tinyqueue@^1.1.0, tinyqueue@^1.2.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-1.2.3.tgz#b6a61de23060584da29f82362e45df1ec7353f3d" - -tippex@^2.1.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/tippex/-/tippex-2.3.1.tgz#a2fd5b7087d7cbfb20c9806a6c16108c2c0fafda" - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - dependencies: - os-tmpdir "~1.0.2" - -to-absolute-glob@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" - dependencies: - is-absolute "^1.0.0" - is-negated-glob "^1.0.0" - -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.1.tgz#15358bee4a2c83bd76377ba1dc049d0f18837aae" - dependencies: - define-property "^0.2.5" - extend-shallow "^2.0.1" - regex-not "^1.0.0" - -to-through@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-through/-/to-through-2.0.0.tgz#fc92adaba072647bc0b67d6b03664aa195093af6" - dependencies: - through2 "^2.0.3" - -topojson-client@3, topojson-client@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/topojson-client/-/topojson-client-3.0.0.tgz#1f99293a77ef42a448d032a81aa982b73f360d2f" - dependencies: - commander "2" - -topojson-server@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/topojson-server/-/topojson-server-3.0.0.tgz#378e78e87c3972a7b5be2c5d604369b6bae69c5e" - dependencies: - commander "2" - -topojson-simplify@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/topojson-simplify/-/topojson-simplify-3.0.2.tgz#8a2403e639531500fafa0c6594e8b0fadebc2c02" - dependencies: - commander "2" - topojson-client "3" - -topojson@3.x: - version "3.0.2" - resolved "https://registry.yarnpkg.com/topojson/-/topojson-3.0.2.tgz#fcb927306c3e0fa76656fa58deed4555d2346fb4" - dependencies: - topojson-client "3.0.0" - topojson-server "3.0.0" - topojson-simplify "3.0.2" - -tough-cookie@~2.3.0: - version "2.3.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" - dependencies: - punycode "^1.4.1" - -trim-lines@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-1.1.0.tgz#9926d03ede13ba18f7d42222631fb04c79ff26fe" - -trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - -trim-newlines@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" - -trim-off-newlines@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" - -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - -trim-trailing-lines@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.0.tgz#7aefbb7808df9d669f6da2e438cac8c46ada7684" - -trim@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" - -trough@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.1.tgz#a9fd8b0394b0ae8fff82e0633a0a36ccad5b5f86" - -tslib@^1.8.0, tslib@^1.8.1: - version "1.9.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" - -tslint@*: - version "5.9.1" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.9.1.tgz#1255f87a3ff57eb0b0e1f0e610a8b4748046c9ae" - dependencies: - babel-code-frame "^6.22.0" - builtin-modules "^1.1.1" - chalk "^2.3.0" - commander "^2.12.1" - diff "^3.2.0" - glob "^7.1.1" - js-yaml "^3.7.0" - minimatch "^3.0.4" - resolve "^1.3.2" - semver "^5.3.0" - tslib "^1.8.0" - tsutils "^2.12.1" - -tsutils@^2.12.1: - version "2.22.2" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.22.2.tgz#0b9f3d87aa3eb95bd32d26ce2b88aa329a657951" - dependencies: - tslib "^1.8.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - dependencies: - safe-buffer "^5.0.1" - -turf-jsts@*: - version "1.2.3" - resolved "https://registry.yarnpkg.com/turf-jsts/-/turf-jsts-1.2.3.tgz#59757f542afbff9a577bbf411f183b8f48d38aa4" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - -two-product@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/two-product/-/two-product-1.0.2.tgz#67d95d4b257a921e2cb4bd7af9511f9088522eaa" - -two-sum@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/two-sum/-/two-sum-1.0.0.tgz#31d3f32239e4f731eca9df9155e2b297f008ab64" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - dependencies: - prelude-ls "~1.1.2" - -typedarray@^0.0.6, typedarray@~0.0.5: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - -typescript@*: - version "2.7.1" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.1.tgz#bb3682c2c791ac90e7c6210b26478a8da085c359" - -typescript@^1.8.9: - version "1.8.10" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-1.8.10.tgz#b475d6e0dff0bf50f296e5ca6ef9fbb5c7320f1e" - -uglify-es@^3.3.7: - version "3.3.9" - resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" - dependencies: - commander "~2.13.0" - source-map "~0.6.1" - -uglify-js@^2.6: - version "2.8.29" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" - dependencies: - source-map "~0.5.1" - yargs "~3.10.0" - optionalDependencies: - uglify-to-browserify "~1.0.0" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" - -uid-number@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - -unc-path-regex@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" - -underscore.string@2.3.x: - version "2.3.3" - resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-2.3.3.tgz#71c08bf6b428b1133f37e78fa3a21c82f7329b0d" - -underscore@~1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" - -unherit@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.0.tgz#6b9aaedfbf73df1756ad9e316dd981885840cd7d" - dependencies: - inherits "^2.0.1" - xtend "^4.0.1" - -unified@^6.0.0: - version "6.1.6" - resolved "https://registry.yarnpkg.com/unified/-/unified-6.1.6.tgz#5ea7f807a0898f1f8acdeefe5f25faa010cc42b1" - dependencies: - bail "^1.0.0" - extend "^3.0.0" - is-plain-obj "^1.1.0" - trough "^1.0.0" - vfile "^2.0.0" - x-is-function "^1.0.4" - x-is-string "^0.1.0" - -union-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^0.4.3" - -unique-stream@^2.0.2: - version "2.2.1" - resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369" - dependencies: - json-stable-stringify "^1.0.0" - through2-filter "^2.0.0" - -unist-builder@^1.0.1, unist-builder@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-1.0.2.tgz#8c3b9903ef64bcfb117dd7cf6a5d98fc1b3b27b6" - dependencies: - object-assign "^4.1.0" - -unist-util-generated@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.1.tgz#99f16c78959ac854dee7c615c291924c8bf4de7f" - -unist-util-is@^2.0.0, unist-util-is@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.1.1.tgz#0c312629e3f960c66e931e812d3d80e77010947b" - -unist-util-modify-children@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unist-util-modify-children/-/unist-util-modify-children-1.1.1.tgz#66d7e6a449e6f67220b976ab3cb8b5ebac39e51d" - dependencies: - array-iterate "^1.0.0" - -unist-util-position@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.0.0.tgz#e6e1e03eeeb81c5e1afe553e8d4adfbd7c0d8f82" - -unist-util-remove-position@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.1.tgz#5a85c1555fc1ba0c101b86707d15e50fa4c871bb" - dependencies: - unist-util-visit "^1.1.0" - -unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.1.tgz#3ccbdc53679eed6ecf3777dd7f5e3229c1b6aa3c" - -unist-util-visit@^1.0.0, unist-util-visit@^1.1.0, unist-util-visit@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.3.0.tgz#41ca7c82981fd1ce6c762aac397fc24e35711444" - dependencies: - unist-util-is "^2.1.1" - -universalify@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -unzip-response@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" - -upath@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.0.0.tgz#b4706b9461ca8473adf89133d235689ca17f3656" - dependencies: - lodash "3.x" - underscore.string "2.3.x" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - dependencies: - prepend-http "^1.0.1" - -use@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/use/-/use-2.0.2.tgz#ae28a0d72f93bf22422a18a2e379993112dec8e8" - dependencies: - define-property "^0.2.5" - isobject "^3.0.0" - lazy-cache "^2.0.2" - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - -uuid@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" - -uuid@^3.0.0, uuid@^3.0.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" - -validate-npm-package-license@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" - dependencies: - spdx-correct "~1.0.0" - spdx-expression-parse "~1.0.0" - -value-or-function@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -vfile-location@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.2.tgz#d3675c59c877498e492b4756ff65e4af1a752255" - -vfile-message@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-1.0.0.tgz#a6adb0474ea400fa25d929f1d673abea6a17e359" - dependencies: - unist-util-stringify-position "^1.1.1" - -vfile-reporter@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/vfile-reporter/-/vfile-reporter-3.0.0.tgz#fe50714e373e0d2940510038a99bd609bdc8209f" - dependencies: - chalk "^1.1.0" - log-symbols "^1.0.2" - plur "^2.0.0" - repeat-string "^1.5.0" - string-width "^1.0.0" - strip-ansi "^3.0.1" - trim "0.0.1" - unist-util-stringify-position "^1.0.0" - -vfile-reporter@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/vfile-reporter/-/vfile-reporter-4.0.0.tgz#ea6f0ae1342f4841573985e05f941736f27de9da" - dependencies: - repeat-string "^1.5.0" - string-width "^1.0.0" - supports-color "^4.1.0" - unist-util-stringify-position "^1.0.0" - vfile-statistics "^1.1.0" - -vfile-sort@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/vfile-sort/-/vfile-sort-2.1.0.tgz#49501c9e8bbe5adff2e9b3a7671ee1b1e20c5210" - -vfile-statistics@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/vfile-statistics/-/vfile-statistics-1.1.0.tgz#02104c60fdeed1d11b1f73ad65330b7634b3d895" - -vfile@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-2.0.0.tgz#88620500e36bad025a0b01cc25106dbcb3090548" - dependencies: - has "^1.0.1" - is-buffer "^1.1.4" - replace-ext "1.0.0" - unist-util-stringify-position "^1.0.0" - x-is-string "^0.1.0" - -vfile@^2.0.0, vfile@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-2.3.0.tgz#e62d8e72b20e83c324bc6c67278ee272488bf84a" - dependencies: - is-buffer "^1.1.4" - replace-ext "1.0.0" - unist-util-stringify-position "^1.0.0" - vfile-message "^1.0.0" - -vinyl-fs@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.2.tgz#1b86258844383f57581fcaac081fe09ef6d6d752" - dependencies: - fs-mkdirp-stream "^1.0.0" - glob-stream "^6.1.0" - graceful-fs "^4.0.0" - is-valid-glob "^1.0.0" - lazystream "^1.0.0" - lead "^1.0.0" - object.assign "^4.0.4" - pumpify "^1.3.5" - readable-stream "^2.3.3" - remove-bom-buffer "^3.0.0" - remove-bom-stream "^1.2.0" - resolve-options "^1.1.0" - through2 "^2.0.0" - to-through "^2.0.0" - value-or-function "^3.0.0" - vinyl "^2.0.0" - vinyl-sourcemap "^1.1.0" - -vinyl-sourcemap@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz#92a800593a38703a8cdb11d8b300ad4be63b3e16" - dependencies: - append-buffer "^1.0.2" - convert-source-map "^1.5.0" - graceful-fs "^4.1.6" - normalize-path "^2.1.1" - now-and-later "^2.0.0" - remove-bom-buffer "^3.0.0" - vinyl "^2.0.0" - -vinyl@^2.0.0, vinyl@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.1.0.tgz#021f9c2cf951d6b939943c89eb5ee5add4fd924c" - dependencies: - clone "^2.1.1" - clone-buffer "^1.0.0" - clone-stats "^1.0.0" - cloneable-readable "^1.0.0" - remove-trailing-separator "^1.0.1" - replace-ext "^1.0.0" - -vlq@^0.2.1: - version "0.2.3" - resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26" - -vlq@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.0.tgz#8101be90843422954c2b13eb27f2f3122bdcc806" - -wcwidth@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - dependencies: - defaults "^1.0.3" - -websocket-driver@>=0.5.1: - version "0.7.0" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb" - dependencies: - http-parser-js ">=0.4.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - -which@^1.2.9: - version "1.3.0" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" - dependencies: - string-width "^1.0.2" - -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - -wkt-parser@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/wkt-parser/-/wkt-parser-1.2.1.tgz#3339689dbc549c103fc5c7447543534785ff8d4d" - -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - -wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - -write-file-atomic@^2.0.0, write-file-atomic@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -write-json-file@*, write-json-file@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f" - dependencies: - detect-indent "^5.0.0" - graceful-fs "^4.1.2" - make-dir "^1.0.0" - pify "^3.0.0" - sort-keys "^2.0.0" - write-file-atomic "^2.0.0" - -write-pkg@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-3.1.0.tgz#030a9994cc9993d25b4e75a9f1a1923607291ce9" - dependencies: - sort-keys "^2.0.0" - write-json-file "^2.2.0" - -write@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" - dependencies: - mkdirp "^0.5.1" - -x-is-function@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/x-is-function/-/x-is-function-1.0.4.tgz#5d294dc3d268cbdd062580e0c5df77a391d1fa1e" - -x-is-string@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" - -xregexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" - -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - -y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - -yamljs@*: - version "0.3.0" - resolved "https://registry.yarnpkg.com/yamljs/-/yamljs-0.3.0.tgz#dc060bf267447b39f7304e9b2bfbe8b5a7ddb03b" - dependencies: - argparse "^1.0.7" - glob "^7.0.5" - -yargs-parser@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" - dependencies: - camelcase "^4.1.0" - -yargs@^8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" - dependencies: - camelcase "^4.1.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - read-pkg-up "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^7.0.0" - -yargs@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c" - dependencies: - camelcase "^4.1.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - read-pkg-up "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^7.0.0" - -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0"