From e4ac32f0bb4df2a7e0ad9521306e95fcfe5d88bf Mon Sep 17 00:00:00 2001 From: James Beard Date: Sun, 4 Jan 2026 11:18:22 +1100 Subject: [PATCH 01/14] Converted turf-union to use clipper2-ts. Some input test data was incorrectly wound so fixed those, as well as truncated input coords to more realistic 6 decimal places. Split out some (hopefully) common code to a new, not to be published seperately turf-internals package. Implementation currently implies limit of 6 decimal places, so may need to make this configurable / more generous before release. --- .monorepolint.config.mjs | 8 +- packages/turf-internal/README.md | 23 ++++ packages/turf-internal/clipper2/index.ts | 129 ++++++++++++++++++ packages/turf-internal/index.ts | 1 + packages/turf-internal/package.json | 17 +++ packages/turf-union/index.ts | 55 ++++++-- packages/turf-union/package.json | 3 +- .../test/in/not-overlapping.geojson | 26 ++-- packages/turf-union/test/in/union1.geojson | 28 ++-- packages/turf-union/test/in/union2.geojson | 52 +++---- packages/turf-union/test/in/union3.geojson | 42 +++--- packages/turf-union/test/in/union4.geojson | 18 +-- packages/turf-union/test/in/union5.geojson | 91 ++++++++++++ .../test/out/not-overlapping.geojson | 26 ++-- packages/turf-union/test/out/union1.geojson | 18 +-- packages/turf-union/test/out/union2.geojson | 30 ++-- packages/turf-union/test/out/union3.geojson | 30 ++-- packages/turf-union/test/out/union4.geojson | 14 +- packages/turf-union/test/out/union5.geojson | 75 ++++++++++ pnpm-lock.yaml | 27 +++- 20 files changed, 555 insertions(+), 158 deletions(-) create mode 100644 packages/turf-internal/README.md create mode 100644 packages/turf-internal/clipper2/index.ts create mode 100644 packages/turf-internal/index.ts create mode 100644 packages/turf-internal/package.json create mode 100644 packages/turf-union/test/in/union5.geojson create mode 100644 packages/turf-union/test/out/union5.geojson diff --git a/.monorepolint.config.mjs b/.monorepolint.config.mjs index 58617304cd..fcbf980389 100644 --- a/.monorepolint.config.mjs +++ b/.monorepolint.config.mjs @@ -148,6 +148,7 @@ export default { }, }, includePackages: [...TS_PACKAGES, ...JS_PACKAGES], + excludePackages: ["@turf/internal"], }), packageEntry({ @@ -157,6 +158,7 @@ export default { }, }, includePackages: [...TS_PACKAGES, ...JS_PACKAGES], + excludePackages: ["@turf/internal"], }), packageEntry({ @@ -165,6 +167,7 @@ export default { funding: "https://opencollective.com/turf", }, }, + excludePackages: ["@turf/internal"], }), packageScript({ @@ -174,7 +177,7 @@ export default { test: "pnpm run /test:.*/", }, }, - excludePackages: [MAIN_PACKAGE], + excludePackages: [MAIN_PACKAGE, "@turf/internal"], }), packageScript({ @@ -184,6 +187,7 @@ export default { }, }, includePackages: [...TS_PACKAGES, ...JS_PACKAGES], + excludePackages: ["@turf/internal"], }), packageScript({ @@ -226,6 +230,7 @@ export default { }, }, includePackages: [...TS_PACKAGES, ...JS_PACKAGES], + excludePackages: ["@turf/internal"], }), requireDependency({ @@ -240,6 +245,7 @@ export default { }, }, includePackages: TS_PACKAGES, + excludePackages: ["@turf/internal"], }), requireDependency({ diff --git a/packages/turf-internal/README.md b/packages/turf-internal/README.md new file mode 100644 index 0000000000..d1752bfea9 --- /dev/null +++ b/packages/turf-internal/README.md @@ -0,0 +1,23 @@ +# @turf/internal + + + + + +--- + +This module is part of the [Turfjs project](https://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 single module individually: + +```sh +$ npm install @turf/internal +``` + +Or install the all-encompassing @turf/turf module that includes all modules as functions: + +```sh +$ npm install @turf/turf +``` diff --git a/packages/turf-internal/clipper2/index.ts b/packages/turf-internal/clipper2/index.ts new file mode 100644 index 0000000000..c97e51e0b3 --- /dev/null +++ b/packages/turf-internal/clipper2/index.ts @@ -0,0 +1,129 @@ +import { PolyTree64, Path64, Paths64, PolyPath64 } from "clipper2-ts"; +import { Polygon, MultiPolygon, Position } from "geojson"; + +// Multiplier applied to lat lng before passing to clipper2. Implies +// calculations are limited to 6 decimal places. +const INT_MULT = 1_000_000; + +/** + * Converts a multipolygon to a flattened array of clipper2 paths. + */ +function multiPolygonToPaths(coords: Position[][][]): Paths64 { + const paths: Paths64 = []; + + for (const polygon of coords) { + paths.push(...polygonToPaths(polygon)); + } + + return paths; +} + +/** + * Converts a polygon to a flattened array of clipper2 paths. + */ +function polygonToPaths(coords: Position[][]): Paths64 { + const paths: Paths64 = []; + + for (const ring of coords) { + paths.push(ringToPath(ring)); + } + + return paths; +} + +/** + * Converts a ring to a clipper2 paths. + */ +function ringToPath(ring: Position[]): Path64 { + return ring.map(([x, y]) => ({ + x: Math.trunc(x * INT_MULT), + y: Math.trunc(y * INT_MULT), + })); +} + +/** + * Construct the output Geojson based on a clipper2 tree. The tree is useful for propertly handing holes. + */ +function polyTreeToGeoJSON(polyTree: PolyTree64): Polygon | MultiPolygon { + const polygons: Position[][][] = []; + + // Process each top-level polygon (outer contours) + for (let i = 0; i < polyTree.count; i++) { + const child = polyTree.child(i); + if (child && !child.isHole) { + const polygon = processPolyPath(child); + if (polygon.length > 0) { + polygons.push(polygon); + } + } + } + + // If exactly 1 polygon return as Geojson Polygon + if (polygons.length === 1) { + return { + type: "Polygon", + coordinates: polygons[0], + }; + } + + // If anything else (including 0) return as MultiPolygon + return { + type: "MultiPolygon", + coordinates: polygons, + }; +} + +function processPolyPath(polyPath: PolyPath64): Position[][] { + const rings: Position[][] = []; + + // Add the outer ring (contour) + const outerRing = pathToCoordinates(polyPath.polygon); + if (outerRing.length > 0) { + rings.push(outerRing); + } + + // Add any holes (children are the holes) + for (let i = 0; i < polyPath.count; i++) { + const child = polyPath.child(i); + if (child && child.isHole) { + const holeRing = pathToCoordinates(child.polygon); + if (holeRing.length > 0) { + rings.push(holeRing); + } + + // Expectation is pools within islands within lakes within continents ... + // are handled as multipolygons. So further recursion is not required. + } + } + + return rings; +} + +/** + * Converts a clipper2 integer path to an array of Geojson Positions. + */ +function pathToCoordinates(path: Path64 | null): Position[] { + const coords: Position[] = []; + + if (!path || typeof path.length !== "number") { + return coords; + } + + for (let i = 0; i < path.length; i++) { + const pt = path[i]; + coords.push([Number(pt.x) / INT_MULT, Number(pt.y) / INT_MULT]); + } + + // GeoJSON requires the first and last coordinates to be identical (closed ring) + if (coords.length > 0) { + const first = coords[0]; + const last = coords[coords.length - 1]; + if (first[0] !== last[0] || first[1] !== last[1]) { + coords.push([first[0], first[1]]); + } + } + + return coords; +} + +export { multiPolygonToPaths, polygonToPaths, polyTreeToGeoJSON }; diff --git a/packages/turf-internal/index.ts b/packages/turf-internal/index.ts new file mode 100644 index 0000000000..e89e4bea11 --- /dev/null +++ b/packages/turf-internal/index.ts @@ -0,0 +1 @@ +export * from "./clipper2"; diff --git a/packages/turf-internal/package.json b/packages/turf-internal/package.json new file mode 100644 index 0000000000..27ab9e3567 --- /dev/null +++ b/packages/turf-internal/package.json @@ -0,0 +1,17 @@ +{ + "name": "@turf/internal", + "version": "7.3.1", + "private": true, + "type": "module", + "main": "index.ts", + "types": "index.ts", + "exports": { + ".": "./index.ts", + "./clipper2": "./clipper2/index.ts" + }, + "dependencies": { + "@types/geojson": "^7946.0.10", + "clipper2-ts": "^2.0.1", + "tslib": "^2.8.1" + } +} diff --git a/packages/turf-union/index.ts b/packages/turf-union/index.ts index 94428494af..eb5854f87b 100644 --- a/packages/turf-union/index.ts +++ b/packages/turf-union/index.ts @@ -1,5 +1,4 @@ -import * as polyclip from "polyclip-ts"; -import { multiPolygon, polygon } from "@turf/helpers"; +import { feature } from "@turf/helpers"; import { geomEach } from "@turf/meta"; import { FeatureCollection, @@ -8,6 +7,12 @@ import { MultiPolygon, GeoJsonProperties, } from "geojson"; +import { Clipper, FillRule, ClipType, PolyTree64, Paths64 } from "clipper2-ts"; +import { + multiPolygonToPaths, + polygonToPaths, + polyTreeToGeoJSON, +} from "@turf/internal/clipper2"; /** * Takes a collection of input polygons and returns a combined polygon. If the @@ -61,19 +66,47 @@ function union

( features: FeatureCollection, options: { properties?: P } = {} ): Feature | null { - const geoms: polyclip.Geom[] = []; - geomEach(features, (geom) => { - geoms.push(geom.coordinates as polyclip.Geom); + let subject: Paths64; + let clippers: Paths64[] = []; + + if (features.features.length < 2) { + throw new Error("Must have at least 2 features"); + } + + geomEach(features, (geom, idx) => { + if (geom.type === "MultiPolygon") { + if (idx === 0) { + subject = multiPolygonToPaths(geom.coordinates); + } else { + clippers.push(multiPolygonToPaths(geom.coordinates)); + } + } else { + if (idx === 0) { + subject = polygonToPaths(geom.coordinates); + } else { + clippers.push(polygonToPaths(geom.coordinates)); + } + } }); - if (geoms.length < 2) { - throw new Error("Must have at least 2 geometries"); + subject = subject!; + + for (const clipper of clippers) { + subject = Clipper.union(subject, clipper, FillRule.EvenOdd); } - const unioned = polyclip.union(geoms[0], ...geoms.slice(1)); - if (unioned.length === 0) return null; - if (unioned.length === 1) return polygon(unioned[0], options.properties); - else return multiPolygon(unioned, options.properties); + // Do one final conversion to PolyTree to better allow handing of holes when + // constructing return Geojson. + let tree: PolyTree64 = new PolyTree64(); + Clipper.booleanOpWithPolyTree( + ClipType.Union, + subject, + [], + tree, + FillRule.EvenOdd + ); + + return feature(polyTreeToGeoJSON(tree), options.properties); } export { union }; diff --git a/packages/turf-union/package.json b/packages/turf-union/package.json index ca470742f2..5dec1e6311 100644 --- a/packages/turf-union/package.json +++ b/packages/turf-union/package.json @@ -63,9 +63,10 @@ }, "dependencies": { "@turf/helpers": "workspace:*", + "@turf/internal": "workspace:*", "@turf/meta": "workspace:*", "@types/geojson": "^7946.0.10", - "polyclip-ts": "^0.16.8", + "clipper2-ts": "^2.0.1", "tslib": "^2.8.1" } } diff --git a/packages/turf-union/test/in/not-overlapping.geojson b/packages/turf-union/test/in/not-overlapping.geojson index e98d104a76..5b4209cd7c 100644 --- a/packages/turf-union/test/in/not-overlapping.geojson +++ b/packages/turf-union/test/in/not-overlapping.geojson @@ -8,12 +8,12 @@ "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] + [-79.885711, 32.887659], + [-80.097885, 32.927436], + [-80.153503, 32.82825], + [-80.003128, 32.694288], + [-79.893951, 32.755519], + [-79.885711, 32.887659] ] ] } @@ -25,13 +25,13 @@ "type": "Polygon", "coordinates": [ [ - [-79.85618591308594, 32.85997876713845], - [-79.78958129882812, 32.913603231028915], - [-79.64881896972656, 32.915908931564864], - [-79.63233947753906, 32.804590457442565], - [-79.79232788085938, 32.679840539897484], - [-79.88433837890625, 32.687931474529464], - [-79.85618591308594, 32.85997876713845] + [-79.856185, 32.859978], + [-79.884338, 32.687931], + [-79.792327, 32.67984], + [-79.632339, 32.80459], + [-79.648818, 32.915908], + [-79.789581, 32.913603], + [-79.856185, 32.859978] ] ] } diff --git a/packages/turf-union/test/in/union1.geojson b/packages/turf-union/test/in/union1.geojson index b4ce111844..937d0986b9 100644 --- a/packages/turf-union/test/in/union1.geojson +++ b/packages/turf-union/test/in/union1.geojson @@ -8,12 +8,12 @@ "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] + [-79.885712, 32.88766], + [-80.097885, 32.927437], + [-80.153503, 32.82825], + [-80.003128, 32.694288], + [-79.893951, 32.75552], + [-79.885712, 32.88766] ] ] } @@ -25,14 +25,14 @@ "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] + [-79.921417, 32.953944], + [-79.974289, 32.836905], + [-79.973602, 32.760717], + [-79.930344, 32.764759], + [-79.937897, 32.741082], + [-79.805374, 32.723176], + [-79.817734, 32.923402], + [-79.921417, 32.953944] ] ] } diff --git a/packages/turf-union/test/in/union2.geojson b/packages/turf-union/test/in/union2.geojson index ff33ee9c99..6ad73a5682 100644 --- a/packages/turf-union/test/in/union2.geojson +++ b/packages/turf-union/test/in/union2.geojson @@ -8,14 +8,14 @@ "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] + [-79.921417, 32.953944], + [-79.974289, 32.836905], + [-79.973602, 32.760717], + [-79.930344, 32.764759], + [-79.937897, 32.741082], + [-79.805374, 32.723176], + [-79.817734, 32.923402], + [-79.921417, 32.953944] ] ] } @@ -27,12 +27,12 @@ "type": "Polygon", "coordinates": [ [ - [-80.10543823242188, 32.94760622243483], - [-80.14389038085938, 32.8149783969858], - [-80.07453918457031, 32.85536439443039], - [-79.99351501464844, 32.84440429734253], - [-79.98184204101562, 32.90495631913751], - [-80.10543823242188, 32.94760622243483] + [-80.105438, 32.947606], + [-80.14389, 32.814978], + [-80.074539, 32.855364], + [-79.993515, 32.844404], + [-79.981842, 32.904956], + [-80.105438, 32.947606] ] ] } @@ -44,12 +44,12 @@ "type": "Polygon", "coordinates": [ [ - [-79.9200439453125, 32.9372338139709], - [-80.03128051757812, 32.936657533381286], - [-79.99008178710938, 32.77226465992344], - [-79.90219116210938, 32.8432505241666], - [-79.96604919433594, 32.87497382061986], - [-79.9200439453125, 32.9372338139709] + [-79.920044, 32.937234], + [-80.031281, 32.936658], + [-79.990082, 32.772265], + [-79.902191, 32.843251], + [-79.966049, 32.874974], + [-79.920044, 32.937234] ] ] } @@ -61,12 +61,12 @@ "type": "Polygon", "coordinates": [ [ - [-79.95025634765625, 32.97007559940924], - [-80.00175476074217, 32.732418508353746], - [-79.84725952148438, 32.753210028851896], - [-79.82048034667969, 32.848442385344136], - [-79.85481262207031, 32.923402043498875], - [-79.95025634765625, 32.97007559940924] + [-79.950256, 32.970076], + [-80.001755, 32.732419], + [-79.84726, 32.75321], + [-79.82048, 32.848442], + [-79.854813, 32.923402], + [-79.950256, 32.970076] ] ] } diff --git a/packages/turf-union/test/in/union3.geojson b/packages/turf-union/test/in/union3.geojson index aa4e7059d6..b78bec2153 100644 --- a/packages/turf-union/test/in/union3.geojson +++ b/packages/turf-union/test/in/union3.geojson @@ -8,12 +8,12 @@ "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] + [-79.885712, 32.88766], + [-80.097885, 32.927437], + [-80.153503, 32.82825], + [-80.003128, 32.694288], + [-79.893951, 32.75552], + [-79.885712, 32.88766] ] ] } @@ -25,14 +25,14 @@ "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] + [-79.921417, 32.953944], + [-79.974289, 32.836905], + [-79.973602, 32.760717], + [-79.930344, 32.764759], + [-79.937897, 32.741082], + [-79.805374, 32.723176], + [-79.817734, 32.923402], + [-79.921417, 32.953944] ] ] } @@ -44,13 +44,13 @@ "type": "Polygon", "coordinates": [ [ - [-79.85618591308594, 32.85997876713845], - [-79.78958129882812, 32.913603231028915], - [-79.64881896972656, 32.915908931564864], - [-79.63233947753906, 32.804590457442565], - [-79.79232788085938, 32.679840539897484], - [-79.88433837890625, 32.687931474529464], - [-79.85618591308594, 32.85997876713845] + [-79.856186, 32.859979], + [-79.884338, 32.687931], + [-79.792328, 32.679841], + [-79.632339, 32.80459], + [-79.648819, 32.915909], + [-79.789581, 32.913603], + [-79.856186, 32.859979] ] ] } diff --git a/packages/turf-union/test/in/union4.geojson b/packages/turf-union/test/in/union4.geojson index bbefadf686..b42a98b0d3 100644 --- a/packages/turf-union/test/in/union4.geojson +++ b/packages/turf-union/test/in/union4.geojson @@ -12,12 +12,12 @@ [-75.728, 45.331], [-75.719, 45.328], [-75.71, 45.331], - [-75.70745454545455, 45.33481818181818], + [-75.707454, 45.334818], [-75.702, 45.333], [-75.693, 45.336], [-75.689, 45.342], [-75.693, 45.349], - [-75.69445161290322, 45.34932258064516], + [-75.694451, 45.349322], [-75.692, 45.353], [-75.696, 45.36], [-75.705, 45.362], @@ -25,7 +25,7 @@ [-75.717, 45.353], [-75.714, 45.347], [-75.71244, 45.34648], - [-75.71342253521127, 45.344760563380284], + [-75.713422, 45.34476], [-75.719, 45.346], [-75.728, 45.344], [-75.732, 45.337] @@ -41,13 +41,13 @@ "coordinates": [ [ [-75.719, 45.346], - [-75.71, 45.344], - [-75.706, 45.337], - [-75.71, 45.331], - [-75.719, 45.328], - [-75.728, 45.331], - [-75.732, 45.337], [-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] ] ] diff --git a/packages/turf-union/test/in/union5.geojson b/packages/turf-union/test/in/union5.geojson new file mode 100644 index 0000000000..0fa4d55ae0 --- /dev/null +++ b/packages/turf-union/test/in/union5.geojson @@ -0,0 +1,91 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "coordinates": [ + [ + [ + [-79.885712, 32.88766], + [-80.097885, 32.927437], + [-80.153503, 32.82825], + [-80.003128, 32.694288], + [-79.893951, 32.75552], + [-79.885712, 32.88766] + ], + [ + [-80.033715, 32.875508], + [-79.941087, 32.866098], + [-79.916897, 32.783297], + [-80.01425, 32.754522], + [-80.079736, 32.836853], + [-80.033715, 32.875508] + ] + ], + [ + [ + [-80.046825, 32.846002], + [-80.012242, 32.803534], + [-79.965252, 32.807258], + [-79.964808, 32.835201], + [-80.009581, 32.857916], + [-80.046825, 32.846002] + ], + [ + [-80.002268, 32.845442], + [-79.999388, 32.836876], + [-79.984315, 32.8352], + [-79.997836, 32.829426], + [-79.995398, 32.815456], + [-80.004708, 32.82626], + [-80.017562, 32.820299], + [-80.011136, 32.831103], + [-80.020224, 32.838552], + [-80.00914, 32.837435], + [-80.002268, 32.845442] + ] + ], + [ + [ + [-79.936652, 32.964886], + [-80.041397, 32.98246], + [-80.079302, 32.946468], + [-79.963587, 32.919675], + [-79.936652, 32.964886] + ] + ] + ], + "type": "MultiPolygon" + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "coordinates": [ + [ + [-79.921417, 32.953944], + [-79.994467, 32.83401], + [-79.973602, 32.760717], + [-79.930344, 32.764759], + [-79.937897, 32.741082], + [-79.805374, 32.723176], + [-79.817734, 32.923402], + [-79.921417, 32.953944] + ], + [ + [-79.902742, 32.913654], + [-79.841373, 32.895333], + [-79.837838, 32.793218], + [-79.884445, 32.75204], + [-79.946398, 32.814046], + [-79.902742, 32.913654] + ] + ], + "type": "Polygon" + } + } + ] +} diff --git a/packages/turf-union/test/out/not-overlapping.geojson b/packages/turf-union/test/out/not-overlapping.geojson index d38e089ee1..f57e507b3f 100644 --- a/packages/turf-union/test/out/not-overlapping.geojson +++ b/packages/turf-union/test/out/not-overlapping.geojson @@ -6,23 +6,23 @@ "coordinates": [ [ [ - [-80.15350341796875, 32.82825010814964], - [-80.00312805175781, 32.69428812316933], - [-79.89395141601562, 32.75551989829049], - [-79.88571166992188, 32.887659962078956], - [-80.09788513183594, 32.927436533285565], - [-80.15350341796875, 32.82825010814964] + [-79.893951, 32.755519], + [-79.885711, 32.887659], + [-80.097885, 32.927436], + [-80.153503, 32.828249], + [-80.003128, 32.694288], + [-79.893951, 32.755519] ] ], [ [ - [-79.88433837890625, 32.687931474529464], - [-79.79232788085938, 32.679840539897484], - [-79.63233947753906, 32.804590457442565], - [-79.64881896972656, 32.915908931564864], - [-79.78958129882812, 32.913603231028915], - [-79.85618591308594, 32.85997876713845], - [-79.88433837890625, 32.687931474529464] + [-79.632339, 32.804589], + [-79.648818, 32.915908], + [-79.789581, 32.913603], + [-79.856185, 32.859977], + [-79.884338, 32.687931], + [-79.792327, 32.67984], + [-79.632339, 32.804589] ] ] ] diff --git a/packages/turf-union/test/out/union1.geojson b/packages/turf-union/test/out/union1.geojson index 11a16df8e0..69d10e896b 100644 --- a/packages/turf-union/test/out/union1.geojson +++ b/packages/turf-union/test/out/union1.geojson @@ -5,15 +5,15 @@ "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] + [-79.923226, 32.739099], + [-79.805374, 32.723176], + [-79.817734, 32.923402], + [-79.921417, 32.953944], + [-79.946235, 32.899005], + [-80.097885, 32.927436], + [-80.153503, 32.828249], + [-80.003128, 32.694288], + [-79.923226, 32.739099] ] ] } diff --git a/packages/turf-union/test/out/union2.geojson b/packages/turf-union/test/out/union2.geojson index f064ff9c8a..5160bbd69a 100644 --- a/packages/turf-union/test/out/union2.geojson +++ b/packages/turf-union/test/out/union2.geojson @@ -5,21 +5,21 @@ "type": "Polygon", "coordinates": [ [ - [-80.14389038085938, 32.8149783969858], - [-80.07453918457031, 32.85536439443039], - [-80.00867471875296, 32.84645494258788], - [-79.99171138057724, 32.77876713098755], - [-80.00175476074217, 32.732418508353746], - [-79.9376375650137, 32.741047214297545], - [-79.80537414550781, 32.7231762754146], - [-79.81773376464844, 32.923402043498875], - [-79.91098503795921, 32.950871281288116], - [-79.95025634765625, 32.97007559940924], - [-79.95741485597672, 32.93704020740794], - [-80.03128051757812, 32.936657533381286], - [-80.02726389659406, 32.92063024667495], - [-80.10543823242188, 32.94760622243483], - [-80.14389038085938, 32.8149783969858] + [-79.817734, 32.923402], + [-79.910982, 32.95087], + [-79.950256, 32.970076], + [-79.957414, 32.937039], + [-80.031281, 32.936658], + [-80.027264, 32.92063], + [-80.105438, 32.947606], + [-80.14389, 32.814978], + [-80.074539, 32.855364], + [-80.008674, 32.846453], + [-79.991711, 32.778766], + [-80.001755, 32.732419], + [-79.937639, 32.741047], + [-79.805374, 32.723176], + [-79.817734, 32.923402] ] ] } diff --git a/packages/turf-union/test/out/union3.geojson b/packages/turf-union/test/out/union3.geojson index 583bb0aea4..5d8b92d34d 100644 --- a/packages/turf-union/test/out/union3.geojson +++ b/packages/turf-union/test/out/union3.geojson @@ -5,21 +5,21 @@ "type": "Polygon", "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] + [-79.632339, 32.804589], + [-79.648819, 32.915909], + [-79.789581, 32.913603], + [-79.815824, 32.892473], + [-79.817734, 32.923402], + [-79.921417, 32.953944], + [-79.946235, 32.899005], + [-80.097885, 32.927436], + [-80.153503, 32.828249], + [-80.003128, 32.694288], + [-79.923226, 32.739099], + [-79.876987, 32.732851], + [-79.884338, 32.687931], + [-79.792328, 32.679841], + [-79.632339, 32.804589] ] ] } diff --git a/packages/turf-union/test/out/union4.geojson b/packages/turf-union/test/out/union4.geojson index 80b68d7a55..4a7728bc7b 100644 --- a/packages/turf-union/test/out/union4.geojson +++ b/packages/turf-union/test/out/union4.geojson @@ -5,16 +5,13 @@ "type": "Polygon", "coordinates": [ [ - [-75.732, 45.337], - [-75.728, 45.331], - [-75.719, 45.328], [-75.71, 45.331], - [-75.70745454545455, 45.33481818181818], + [-75.707454, 45.334818], [-75.702, 45.333], [-75.693, 45.336], [-75.689, 45.342], [-75.693, 45.349], - [-75.69445161290322, 45.34932258064516], + [-75.694451, 45.349322], [-75.692, 45.353], [-75.696, 45.36], [-75.705, 45.362], @@ -22,10 +19,13 @@ [-75.717, 45.353], [-75.714, 45.347], [-75.71244, 45.34648], - [-75.71342253521127, 45.344760563380284], + [-75.713421, 45.34476], [-75.719, 45.346], [-75.728, 45.344], - [-75.732, 45.337] + [-75.732, 45.337], + [-75.728, 45.331], + [-75.719, 45.328], + [-75.71, 45.331] ] ] } diff --git a/packages/turf-union/test/out/union5.geojson b/packages/turf-union/test/out/union5.geojson new file mode 100644 index 0000000000..d89b81d984 --- /dev/null +++ b/packages/turf-union/test/out/union5.geojson @@ -0,0 +1,75 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [-79.936652, 32.964886], + [-80.041397, 32.98246], + [-80.079302, 32.946468], + [-79.963587, 32.919674], + [-79.936652, 32.964886] + ] + ], + [ + [ + [-79.923226, 32.739099], + [-79.805374, 32.723176], + [-79.817734, 32.923402], + [-79.921417, 32.953944], + [-79.953993, 32.900459], + [-80.097885, 32.927436], + [-80.153503, 32.828249], + [-80.003128, 32.694288], + [-79.923226, 32.739099] + ], + [ + [-79.893596, 32.761199], + [-79.885712, 32.887659], + [-79.911976, 32.892582], + [-79.902742, 32.913654], + [-79.841373, 32.895333], + [-79.837838, 32.793218], + [-79.884445, 32.75204], + [-79.893596, 32.761199] + ], + [ + [-80.079736, 32.836852], + [-80.033715, 32.875508], + [-79.972951, 32.869335], + [-79.986911, 32.846414], + [-80.009581, 32.857916], + [-80.046825, 32.846002], + [-80.012242, 32.803534], + [-79.986374, 32.805583], + [-79.97513, 32.766084], + [-80.01425, 32.754522], + [-80.079736, 32.836852] + ], + [ + [-80.004708, 32.826259], + [-80.017562, 32.820299], + [-80.011136, 32.831103], + [-80.020224, 32.838552], + [-80.00914, 32.837435], + [-80.002268, 32.845442], + [-79.999388, 32.836875], + [-79.993144, 32.836181], + [-79.994467, 32.83401], + [-79.993668, 32.831205], + [-79.997836, 32.829425], + [-79.995398, 32.815455], + [-80.004708, 32.826259] + ], + [ + [-79.946398, 32.814045], + [-79.934086, 32.842135], + [-79.917402, 32.785024], + [-79.946398, 32.814045] + ] + ] + ] + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aa28541de7..1c3a4eb201 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3180,6 +3180,18 @@ importers: specifier: ^6.0.0 version: 6.0.0 + packages/turf-internal: + dependencies: + '@types/geojson': + specifier: ^7946.0.10 + version: 7946.0.14 + clipper2-ts: + specifier: ^2.0.1 + version: 2.0.1 + tslib: + specifier: ^2.8.1 + version: 2.8.1 + packages/turf-interpolate: dependencies: '@turf/bbox': @@ -6141,15 +6153,18 @@ importers: '@turf/helpers': specifier: workspace:* version: link:../turf-helpers + '@turf/internal': + specifier: workspace:* + version: link:../turf-internal '@turf/meta': specifier: workspace:* version: link:../turf-meta '@types/geojson': specifier: ^7946.0.10 version: 7946.0.14 - polyclip-ts: - specifier: ^0.16.8 - version: 0.16.8 + clipper2-ts: + specifier: ^2.0.1 + version: 2.0.1 tslib: specifier: ^2.8.1 version: 2.8.1 @@ -8287,6 +8302,10 @@ packages: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} + clipper2-ts@2.0.1: + resolution: {integrity: sha512-raIgNMpYN/PFYk/T9iRzaG99rf5nlXBWL1FyAdR3wjEYSzJy+pPfolLH5bCdRqCFQqn/eYUsF1jb3cQEMxmWGw==} + engines: {node: '>=14.0.0'} + cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -14132,6 +14151,8 @@ snapshots: cli-width@4.1.0: {} + clipper2-ts@2.0.1: {} + cliui@7.0.4: dependencies: string-width: 4.2.3 From e6c74317e43eb90e637826eb794b1b9a69fab06e Mon Sep 17 00:00:00 2001 From: James Beard Date: Sun, 4 Jan 2026 16:21:11 +1100 Subject: [PATCH 02/14] Ported intersect to clipper2. Fixed windings of some geojson input test data. --- packages/turf-internal/clipper2/index.ts | 10 +- packages/turf-intersect/index.ts | 46 ++++-- packages/turf-intersect/package.json | 3 +- packages/turf-intersect/test.ts | 7 +- .../turf-intersect/test/in/Intersect1.geojson | 28 ++-- .../turf-intersect/test/in/Intersect2.geojson | 30 ++-- .../turf-intersect/test/in/Intersect3.geojson | 91 +++++++++++ .../turf-intersect/test/in/armenia.geojson | 44 +++--- .../turf-intersect/test/in/linestring.geojson | 38 ++--- .../test/in/multilinestring.geojson | 46 +++--- .../turf-intersect/test/in/multipoint.geojson | 26 ++-- .../test/in/multipolygon-input.geojson | 44 +++--- .../turf-intersect/test/in/no-overlap.geojson | 20 +-- .../test/in/output-multipolygon.geojson | 30 ++-- packages/turf-intersect/test/in/point.geojson | 30 ++-- .../test/out/Intersect1.geojson | 46 +++--- .../test/out/Intersect2.geojson | 44 +++--- .../test/out/Intersect3.geojson | 145 ++++++++++++++++++ .../turf-intersect/test/out/armenia.geojson | 52 +++---- .../test/out/issue-1004.geojson | 8 +- .../test/out/issue-1394.geojson | 18 --- .../turf-intersect/test/out/issue-412.geojson | 11 +- .../test/out/linestring.geojson | 38 ++--- .../test/out/multilinestring.geojson | 46 +++--- .../test/out/multipoint.geojson | 26 ++-- .../test/out/multipolygon-input.geojson | 68 ++++---- .../test/out/no-overlap.geojson | 20 +-- .../test/out/output-multipolygon.geojson | 50 +++--- .../turf-intersect/test/out/point.geojson | 30 ++-- pnpm-lock.yaml | 9 +- 30 files changed, 678 insertions(+), 426 deletions(-) create mode 100644 packages/turf-intersect/test/in/Intersect3.geojson create mode 100644 packages/turf-intersect/test/out/Intersect3.geojson diff --git a/packages/turf-internal/clipper2/index.ts b/packages/turf-internal/clipper2/index.ts index c97e51e0b3..edf648b2d4 100644 --- a/packages/turf-internal/clipper2/index.ts +++ b/packages/turf-internal/clipper2/index.ts @@ -44,7 +44,9 @@ function ringToPath(ring: Position[]): Path64 { /** * Construct the output Geojson based on a clipper2 tree. The tree is useful for propertly handing holes. */ -function polyTreeToGeoJSON(polyTree: PolyTree64): Polygon | MultiPolygon { +function polyTreeToGeoJSON( + polyTree: PolyTree64 +): Polygon | MultiPolygon | null { const polygons: Position[][][] = []; // Process each top-level polygon (outer contours) @@ -58,6 +60,10 @@ function polyTreeToGeoJSON(polyTree: PolyTree64): Polygon | MultiPolygon { } } + if (polygons.length === 0) { + return null; + } + // If exactly 1 polygon return as Geojson Polygon if (polygons.length === 1) { return { @@ -66,7 +72,7 @@ function polyTreeToGeoJSON(polyTree: PolyTree64): Polygon | MultiPolygon { }; } - // If anything else (including 0) return as MultiPolygon + // If anything else return as MultiPolygon return { type: "MultiPolygon", coordinates: polygons, diff --git a/packages/turf-intersect/index.ts b/packages/turf-intersect/index.ts index 55a2d74cd7..74f82f8403 100644 --- a/packages/turf-intersect/index.ts +++ b/packages/turf-intersect/index.ts @@ -5,9 +5,14 @@ import { Polygon, FeatureCollection, } from "geojson"; -import { multiPolygon, polygon } from "@turf/helpers"; +import { feature } from "@turf/helpers"; import { geomEach } from "@turf/meta"; -import * as polyclip from "polyclip-ts"; +import { FillRule, ClipType, PolyTree64, Clipper64 } from "clipper2-ts"; +import { + multiPolygonToPaths, + polygonToPaths, + polyTreeToGeoJSON, +} from "@turf/internal/clipper2"; /** * Takes {@link Polygon|polygon} or {@link MultiPolygon|multi-polygon} geometries and @@ -50,20 +55,35 @@ function intersect

( properties?: P; } = {} ): Feature | null { - const geoms: polyclip.Geom[] = []; + if (features.features.length < 2) { + throw new Error("Must have at least 2 features"); + } + + const clipper = new Clipper64(); - geomEach(features, (geom) => { - geoms.push(geom.coordinates as polyclip.Geom); + geomEach(features, (geom, idx) => { + if (geom.type === "MultiPolygon") { + if (idx === 0) { + clipper.addSubject(multiPolygonToPaths(geom.coordinates)); + } else { + clipper.addClip(multiPolygonToPaths(geom.coordinates)); + } + } else { + if (idx === 0) { + clipper.addSubject(polygonToPaths(geom.coordinates)); + } else { + clipper.addClip(polygonToPaths(geom.coordinates)); + } + } }); - if (geoms.length < 2) { - throw new Error("Must specify at least 2 geometries"); - } - const intersection = polyclip.intersection(geoms[0], ...geoms.slice(1)); - if (intersection.length === 0) return null; - if (intersection.length === 1) - return polygon(intersection[0], options.properties); - return multiPolygon(intersection, options.properties); + let tree: PolyTree64 = new PolyTree64(); + clipper.execute(ClipType.Intersection, FillRule.EvenOdd, tree); + + // Return the result as Polygon, MultiPolygon, or null as appropriate + const geom = polyTreeToGeoJSON(tree); + if (geom === null) return null; + return feature(geom, options.properties); } export { intersect }; diff --git a/packages/turf-intersect/package.json b/packages/turf-intersect/package.json index c1993216a1..f0e8aae04a 100644 --- a/packages/turf-intersect/package.json +++ b/packages/turf-intersect/package.json @@ -64,9 +64,10 @@ }, "dependencies": { "@turf/helpers": "workspace:*", + "@turf/internal": "workspace:*", "@turf/meta": "workspace:*", "@types/geojson": "^7946.0.10", - "polyclip-ts": "^0.16.8", + "clipper2-ts": "^2.0.1", "tslib": "^2.8.1" } } diff --git a/packages/turf-intersect/test.ts b/packages/turf-intersect/test.ts index a90665e4fb..a570780110 100644 --- a/packages/turf-intersect/test.ts +++ b/packages/turf-intersect/test.ts @@ -51,7 +51,12 @@ test("intersect", (t) => { const fc = featureCollection([polygon1, polygon2]); const result = intersect(fc); - if (result) { + if ( + result && + (result.geometry.type === "Polygon" || + (result.geometry.type === "MultiPolygon" && + result.geometry.coordinates.length > 0)) + ) { // Green Polygon result.properties = { "fill-opacity": 1, fill: "#0F0" }; fc.features.push(result); diff --git a/packages/turf-intersect/test/in/Intersect1.geojson b/packages/turf-intersect/test/in/Intersect1.geojson index b4ce111844..8a8a2e9dcc 100644 --- a/packages/turf-intersect/test/in/Intersect1.geojson +++ b/packages/turf-intersect/test/in/Intersect1.geojson @@ -8,12 +8,12 @@ "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] + [-79.885712, 32.887659], + [-80.097886, 32.927436], + [-80.153504, 32.82825], + [-80.003129, 32.694288], + [-79.893952, 32.755519], + [-79.885712, 32.887659] ] ] } @@ -25,14 +25,14 @@ "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] + [-79.921418, 32.953944], + [-79.974289, 32.836904], + [-79.973603, 32.760716], + [-79.930344, 32.764758], + [-79.937897, 32.741082], + [-79.805375, 32.723176], + [-79.817734, 32.923402], + [-79.921418, 32.953944] ] ] } diff --git a/packages/turf-intersect/test/in/Intersect2.geojson b/packages/turf-intersect/test/in/Intersect2.geojson index 0d7218eef8..cadb53ef33 100644 --- a/packages/turf-intersect/test/in/Intersect2.geojson +++ b/packages/turf-intersect/test/in/Intersect2.geojson @@ -8,15 +8,15 @@ "type": "Polygon", "coordinates": [ [ - [-79.92141723632812, 32.953944317478246], - [-80.068359375, 32.88189375925038], - [-80.01686096191406, 32.87266705436184], - [-79.97360229492188, 32.76071688548088], - [-79.93034362792969, 32.76475877693074], - [-79.93789672851562, 32.74108223150125], - [-79.80537414550781, 32.7231762754146], - [-79.81773376464844, 32.923402043498875], - [-79.92141723632812, 32.953944317478246] + [-79.921418, 32.953944], + [-80.06836, 32.881893], + [-80.016861, 32.872667], + [-79.973603, 32.760716], + [-79.930344, 32.764758], + [-79.937897, 32.741082], + [-79.805375, 32.723176], + [-79.817734, 32.923402], + [-79.921418, 32.953944] ] ] } @@ -28,12 +28,12 @@ "type": "Polygon", "coordinates": [ [ - [-80.10543823242188, 32.94760622243483], - [-80.14389038085938, 32.8149783969858], - [-80.07453918457031, 32.85536439443039], - [-79.99351501464844, 32.84440429734253], - [-79.98184204101562, 32.90495631913751], - [-80.10543823242188, 32.94760622243483] + [-80.105439, 32.947606], + [-80.143891, 32.814978], + [-80.07454, 32.855364], + [-79.993516, 32.844404], + [-79.981843, 32.904956], + [-80.105439, 32.947606] ] ] } diff --git a/packages/turf-intersect/test/in/Intersect3.geojson b/packages/turf-intersect/test/in/Intersect3.geojson new file mode 100644 index 0000000000..0fa4d55ae0 --- /dev/null +++ b/packages/turf-intersect/test/in/Intersect3.geojson @@ -0,0 +1,91 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "coordinates": [ + [ + [ + [-79.885712, 32.88766], + [-80.097885, 32.927437], + [-80.153503, 32.82825], + [-80.003128, 32.694288], + [-79.893951, 32.75552], + [-79.885712, 32.88766] + ], + [ + [-80.033715, 32.875508], + [-79.941087, 32.866098], + [-79.916897, 32.783297], + [-80.01425, 32.754522], + [-80.079736, 32.836853], + [-80.033715, 32.875508] + ] + ], + [ + [ + [-80.046825, 32.846002], + [-80.012242, 32.803534], + [-79.965252, 32.807258], + [-79.964808, 32.835201], + [-80.009581, 32.857916], + [-80.046825, 32.846002] + ], + [ + [-80.002268, 32.845442], + [-79.999388, 32.836876], + [-79.984315, 32.8352], + [-79.997836, 32.829426], + [-79.995398, 32.815456], + [-80.004708, 32.82626], + [-80.017562, 32.820299], + [-80.011136, 32.831103], + [-80.020224, 32.838552], + [-80.00914, 32.837435], + [-80.002268, 32.845442] + ] + ], + [ + [ + [-79.936652, 32.964886], + [-80.041397, 32.98246], + [-80.079302, 32.946468], + [-79.963587, 32.919675], + [-79.936652, 32.964886] + ] + ] + ], + "type": "MultiPolygon" + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "coordinates": [ + [ + [-79.921417, 32.953944], + [-79.994467, 32.83401], + [-79.973602, 32.760717], + [-79.930344, 32.764759], + [-79.937897, 32.741082], + [-79.805374, 32.723176], + [-79.817734, 32.923402], + [-79.921417, 32.953944] + ], + [ + [-79.902742, 32.913654], + [-79.841373, 32.895333], + [-79.837838, 32.793218], + [-79.884445, 32.75204], + [-79.946398, 32.814046], + [-79.902742, 32.913654] + ] + ], + "type": "Polygon" + } + } + ] +} diff --git a/packages/turf-intersect/test/in/armenia.geojson b/packages/turf-intersect/test/in/armenia.geojson index 65ece25ab3..b976db022c 100644 --- a/packages/turf-intersect/test/in/armenia.geojson +++ b/packages/turf-intersect/test/in/armenia.geojson @@ -12,24 +12,24 @@ "coordinates": [ [ [43.582746, 41.092143], - [44.97248, 41.248129], - [45.179496, 40.985354], - [45.560351, 40.81229], - [45.359175, 40.561504], - [45.891907, 40.218476], - [45.610012, 39.899994], - [46.034534, 39.628021], - [46.483499, 39.464155], - [46.50572, 38.770605], - [46.143623, 38.741201], - [45.735379, 39.319719], - [45.739978, 39.473999], - [45.298145, 39.471751], - [45.001987, 39.740004], - [44.79399, 39.713003], - [44.400009, 40.005], - [43.656436, 40.253564], [43.752658, 40.740201], + [43.656436, 40.253564], + [44.400009, 40.005], + [44.79399, 39.713003], + [45.001987, 39.740004], + [45.298145, 39.471751], + [45.739978, 39.473999], + [45.735379, 39.319719], + [46.143623, 38.741201], + [46.50572, 38.770605], + [46.483499, 39.464155], + [46.034534, 39.628021], + [45.610012, 39.899994], + [45.891907, 40.218476], + [45.359175, 40.561504], + [45.560351, 40.81229], + [45.179496, 40.985354], + [44.97248, 41.248129], [43.582746, 41.092143] ] ] @@ -42,11 +42,11 @@ "type": "Polygon", "coordinates": [ [ - [45.1318359375, 40.1452892956766], - [45.1318359375, 43.197167282501276], - [53.3935546875, 43.197167282501276], - [53.3935546875, 40.1452892956766], - [45.1318359375, 40.1452892956766] + [45.131835, 40.145289], + [53.393554, 40.145289], + [53.393554, 43.197167], + [45.131835, 43.197167], + [45.131835, 40.145289] ] ] } diff --git a/packages/turf-intersect/test/in/linestring.geojson b/packages/turf-intersect/test/in/linestring.geojson index 48a9dc22ef..1f346204b9 100644 --- a/packages/turf-intersect/test/in/linestring.geojson +++ b/packages/turf-intersect/test/in/linestring.geojson @@ -8,17 +8,17 @@ "type": "Polygon", "coordinates": [ [ - [4.8618364334106445, 45.784404601286774], - [4.86544132232666, 45.78434474634739], - [4.88217830657959, 45.78745711798122], - [4.886684417724609, 45.78691845071048], - [4.888958930969238, 45.78494329284938], - [4.876770973205566, 45.782100139729486], - [4.874668121337891, 45.77934663219167], - [4.865655899047851, 45.77904732970034], - [4.859733581542969, 45.77976565298041], - [4.860033988952637, 45.78213006841216], - [4.8618364334106445, 45.784404601286774] + [4.861836, 45.784404], + [4.860033, 45.78213], + [4.859733, 45.779765], + [4.865655, 45.779047], + [4.874668, 45.779346], + [4.87677, 45.7821], + [4.888958, 45.784943], + [4.886684, 45.786918], + [4.882178, 45.787457], + [4.865441, 45.784344], + [4.861836, 45.784404] ] ] } @@ -30,14 +30,14 @@ "type": "Polygon", "coordinates": [ [ - [4.86544132232666, 45.78434474634739], - [4.88217830657959, 45.78745711798122], - [4.8838090896606445, 45.79044961914028], - [4.880805015563965, 45.79257419743464], - [4.875955581665039, 45.78808555655138], - [4.869647026062012, 45.78742719215828], - [4.863724708557129, 45.78575132043314], - [4.86544132232666, 45.78434474634739] + [4.865441, 45.784344], + [4.882178, 45.787457], + [4.883809, 45.790449], + [4.880805, 45.792574], + [4.875955, 45.788085], + [4.869647, 45.787427], + [4.863724, 45.785751], + [4.865441, 45.784344] ] ] } diff --git a/packages/turf-intersect/test/in/multilinestring.geojson b/packages/turf-intersect/test/in/multilinestring.geojson index 36caa2b935..d7e20976c8 100644 --- a/packages/turf-intersect/test/in/multilinestring.geojson +++ b/packages/turf-intersect/test/in/multilinestring.geojson @@ -8,17 +8,17 @@ "type": "Polygon", "coordinates": [ [ - [4.8618364334106445, 45.784404601286774], - [4.86544132232666, 45.78434474634739], - [4.88217830657959, 45.78745711798122], - [4.886684417724609, 45.78691845071048], - [4.888958930969238, 45.78494329284938], - [4.876770973205566, 45.782100139729486], - [4.874668121337891, 45.77934663219167], - [4.865655899047851, 45.77904732970034], - [4.859733581542969, 45.77976565298041], - [4.860033988952637, 45.78213006841216], - [4.8618364334106445, 45.784404601286774] + [4.861836, 45.784404], + [4.860033, 45.78213], + [4.859733, 45.779765], + [4.865655, 45.779047], + [4.874668, 45.779346], + [4.87677, 45.7821], + [4.888958, 45.784943], + [4.886684, 45.786918], + [4.882178, 45.787457], + [4.865441, 45.784344], + [4.861836, 45.784404] ] ] } @@ -30,18 +30,18 @@ "type": "Polygon", "coordinates": [ [ - [4.86544132232666, 45.78434474634739], - [4.88217830657959, 45.78745711798122], - [4.8838090896606445, 45.79044961914028], - [4.880805015563965, 45.79257419743464], - [4.875955581665039, 45.78808555655138], - [4.869647026062012, 45.78742719215828], - [4.863724708557129, 45.78575132043314], - [4.860978126525879, 45.78572139369446], - [4.860033988952637, 45.78213006841216], - [4.8618364334106445, 45.784404601286774], - [4.8618364334106445, 45.78503307427041], - [4.86544132232666, 45.78434474634739] + [4.865441, 45.784344], + [4.882178, 45.787457], + [4.883809, 45.790449], + [4.880805, 45.792574], + [4.875955, 45.788085], + [4.869647, 45.787427], + [4.863724, 45.785751], + [4.860978, 45.785721], + [4.860033, 45.78213], + [4.861836, 45.784404], + [4.861836, 45.785033], + [4.865441, 45.784344] ] ] } diff --git a/packages/turf-intersect/test/in/multipoint.geojson b/packages/turf-intersect/test/in/multipoint.geojson index 67cf565379..86e05c28bd 100644 --- a/packages/turf-intersect/test/in/multipoint.geojson +++ b/packages/turf-intersect/test/in/multipoint.geojson @@ -8,13 +8,13 @@ "type": "Polygon", "coordinates": [ [ - [4.845099449157715, 45.77793989651294], - [4.849648475646973, 45.78245928286134], - [4.855012893676758, 45.78446445616189], - [4.859991073608398, 45.784614093068555], - [4.858188629150391, 45.77288134093866], - [4.854154586791992, 45.77249220227275], - [4.845099449157715, 45.77793989651294] + [4.845099, 45.777939], + [4.854154, 45.772492], + [4.858188, 45.772881], + [4.859991, 45.784614], + [4.855012, 45.784464], + [4.849648, 45.782459], + [4.845099, 45.777939] ] ] } @@ -26,12 +26,12 @@ "type": "Polygon", "coordinates": [ [ - [4.845099449157715, 45.77793989651294], - [4.840679168701172, 45.771743851052996], - [4.848017692565918, 45.767133786097716], - [4.854154586791992, 45.77249220227275], - [4.846601486206055, 45.771983324535846], - [4.845099449157715, 45.77793989651294] + [4.845099, 45.777939], + [4.840679, 45.771743], + [4.848017, 45.767133], + [4.854154, 45.772492], + [4.846601, 45.771983], + [4.845099, 45.777939] ] ] } diff --git a/packages/turf-intersect/test/in/multipolygon-input.geojson b/packages/turf-intersect/test/in/multipolygon-input.geojson index 98575779d6..ebc524fd2e 100644 --- a/packages/turf-intersect/test/in/multipolygon-input.geojson +++ b/packages/turf-intersect/test/in/multipolygon-input.geojson @@ -9,22 +9,22 @@ "coordinates": [ [ [ - [2.3273849487304688, 48.87148983809234], - [2.3160552978515625, 48.87307055723444], - [2.3150253295898438, 48.85183958955198], - [2.3493576049804688, 48.845965604118284], - [2.3500442504882812, 48.85613168160397], - [2.3500442504882812, 48.8615527456014], - [2.3273849487304688, 48.87148983809234] + [2.327384, 48.871489], + [2.316055, 48.87307], + [2.315025, 48.851839], + [2.349357, 48.845965], + [2.350044, 48.856131], + [2.350044, 48.861552], + [2.327384, 48.871489] ] ], [ [ - [2.3363113403320312, 48.87690923865779], - [2.3514175415039062, 48.86516646209463], - [2.3596572875976562, 48.873522182101965], - [2.3476409912109375, 48.878489786571116], - [2.3363113403320312, 48.87690923865779] + [2.336311, 48.876909], + [2.351417, 48.865166], + [2.359657, 48.873522], + [2.34764, 48.878489], + [2.336311, 48.876909] ] ] ] @@ -38,20 +38,20 @@ "coordinates": [ [ [ - [2.3256683349609375, 48.87690923865779], - [2.3239517211914062, 48.86787657822752], - [2.3521041870117188, 48.85432452980058], - [2.357940673828125, 48.8615527456014], - [2.3411178588867188, 48.882102279983364], - [2.3256683349609375, 48.87690923865779] + [2.325668, 48.876909], + [2.323951, 48.867876], + [2.352104, 48.854324], + [2.35794, 48.861552], + [2.341117, 48.882102], + [2.325668, 48.876909] ] ], [ [ - [2.362060546875, 48.85229140604385], - [2.3733901977539062, 48.8473212003792], - [2.3733901977539062, 48.854776323867306], - [2.362060546875, 48.85229140604385] + [2.36206, 48.852291], + [2.37339, 48.847321], + [2.37339, 48.854776], + [2.36206, 48.852291] ] ] ] diff --git a/packages/turf-intersect/test/in/no-overlap.geojson b/packages/turf-intersect/test/in/no-overlap.geojson index 917fb86d99..da8948c40f 100644 --- a/packages/turf-intersect/test/in/no-overlap.geojson +++ b/packages/turf-intersect/test/in/no-overlap.geojson @@ -8,11 +8,11 @@ "type": "Polygon", "coordinates": [ [ - [92.6806640625, 53.4357192066942], - [92.6806640625, 53.51418452077113], - [93.0322265625, 53.51418452077113], - [93.0322265625, 53.4357192066942], - [92.6806640625, 53.4357192066942] + [92.680664, 53.435719], + [93.032226, 53.435719], + [93.032226, 53.514184], + [92.680664, 53.514184], + [92.680664, 53.435719] ] ] } @@ -24,11 +24,11 @@ "type": "Polygon", "coordinates": [ [ - [93.47854614257812, 53.628353173374194], - [93.47854614257812, 53.74140157486066], - [93.680419921875, 53.74140157486066], - [93.680419921875, 53.628353173374194], - [93.47854614257812, 53.628353173374194] + [93.478546, 53.628353], + [93.680419, 53.628353], + [93.680419, 53.741401], + [93.478546, 53.741401], + [93.478546, 53.628353] ] ] } diff --git a/packages/turf-intersect/test/in/output-multipolygon.geojson b/packages/turf-intersect/test/in/output-multipolygon.geojson index 92e2aacde1..57699b16f4 100644 --- a/packages/turf-intersect/test/in/output-multipolygon.geojson +++ b/packages/turf-intersect/test/in/output-multipolygon.geojson @@ -8,11 +8,11 @@ "type": "Polygon", "coordinates": [ [ - [129.0234375, -27.371767300523032], - [138.33984375, -27.371767300523032], - [138.33984375, -22.43134015636061], - [129.0234375, -22.43134015636061], - [129.0234375, -27.371767300523032] + [129.023437, -27.371768], + [138.339843, -27.371768], + [138.339843, -22.431341], + [129.023437, -22.431341], + [129.023437, -27.371768] ] ] } @@ -24,18 +24,18 @@ "type": "Polygon", "coordinates": [ [ - [124.23339843749999, -34.921971036163754], - [143.4375, -34.95799531086791], - [143.26171875, -13.154376055418515], - [124.23339843749999, -12.768946439455943], - [124.23339843749999, -34.921971036163754] + [124.233398, -34.921972], + [143.4375, -34.957996], + [143.261718, -13.154377], + [124.233398, -12.768947], + [124.233398, -34.921972] ], [ - [130.2978515625, -29.95493454965612], - [130.2978515625, -18.020527657852327], - [137.2412109375, -18.020527657852327], - [137.2412109375, -29.95493454965612], - [130.2978515625, -29.95493454965612] + [130.297851, -29.954935], + [130.297851, -18.020528], + [137.24121, -18.020528], + [137.24121, -29.954935], + [130.297851, -29.954935] ] ] } diff --git a/packages/turf-intersect/test/in/point.geojson b/packages/turf-intersect/test/in/point.geojson index 5c7f382495..6e711ce62f 100644 --- a/packages/turf-intersect/test/in/point.geojson +++ b/packages/turf-intersect/test/in/point.geojson @@ -8,13 +8,13 @@ "type": "Polygon", "coordinates": [ [ - [4.845099449157715, 45.77793989651294], - [4.849648475646973, 45.78245928286134], - [4.855012893676758, 45.78446445616189], - [4.859991073608398, 45.784614093068555], - [4.858188629150391, 45.77288134093866], - [4.854154586791992, 45.77249220227275], - [4.845099449157715, 45.77793989651294] + [4.845099, 45.777939], + [4.854154, 45.772492], + [4.858188, 45.772881], + [4.859991, 45.784614], + [4.855012, 45.784464], + [4.849648, 45.782459], + [4.845099, 45.777939] ] ] } @@ -26,14 +26,14 @@ "type": "Polygon", "coordinates": [ [ - [4.859991073608398, 45.784614093068555], - [4.86569881439209, 45.78611044004426], - [4.87518310546875, 45.787906003397154], - [4.880547523498535, 45.79251435126729], - [4.883980751037598, 45.7903598464431], - [4.8827362060546875, 45.787906003397154], - [4.864926338195801, 45.78464402040167], - [4.859991073608398, 45.784614093068555] + [4.859991, 45.784614], + [4.864926, 45.784644], + [4.882736, 45.787906], + [4.88398, 45.790359], + [4.880547, 45.792514], + [4.875183, 45.787906], + [4.865698, 45.78611], + [4.859991, 45.784614] ] ] } diff --git a/packages/turf-intersect/test/out/Intersect1.geojson b/packages/turf-intersect/test/out/Intersect1.geojson index 32a2a3f190..62a2873f60 100644 --- a/packages/turf-intersect/test/out/Intersect1.geojson +++ b/packages/turf-intersect/test/out/Intersect1.geojson @@ -11,12 +11,12 @@ "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] + [-79.885712, 32.887659], + [-80.097886, 32.927436], + [-80.153504, 32.82825], + [-80.003129, 32.694288], + [-79.893952, 32.755519], + [-79.885712, 32.887659] ] ] } @@ -31,14 +31,14 @@ "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] + [-79.921418, 32.953944], + [-79.974289, 32.836904], + [-79.973603, 32.760716], + [-79.930344, 32.764758], + [-79.937897, 32.741082], + [-79.805375, 32.723176], + [-79.817734, 32.923402], + [-79.921418, 32.953944] ] ] } @@ -53,15 +53,15 @@ "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] + [-79.893952, 32.755519], + [-79.885712, 32.887659], + [-79.946235, 32.899005], + [-79.974289, 32.836903], + [-79.973603, 32.760716], + [-79.930344, 32.764758], + [-79.937897, 32.741082], + [-79.923227, 32.739099], + [-79.893952, 32.755519] ] ] } diff --git a/packages/turf-intersect/test/out/Intersect2.geojson b/packages/turf-intersect/test/out/Intersect2.geojson index 8755e4c990..067345dfbb 100644 --- a/packages/turf-intersect/test/out/Intersect2.geojson +++ b/packages/turf-intersect/test/out/Intersect2.geojson @@ -11,15 +11,15 @@ "type": "Polygon", "coordinates": [ [ - [-79.92141723632812, 32.953944317478246], - [-80.068359375, 32.88189375925038], - [-80.01686096191406, 32.87266705436184], - [-79.97360229492188, 32.76071688548088], - [-79.93034362792969, 32.76475877693074], - [-79.93789672851562, 32.74108223150125], - [-79.80537414550781, 32.7231762754146], - [-79.81773376464844, 32.923402043498875], - [-79.92141723632812, 32.953944317478246] + [-79.921418, 32.953944], + [-80.06836, 32.881893], + [-80.016861, 32.872667], + [-79.973603, 32.760716], + [-79.930344, 32.764758], + [-79.937897, 32.741082], + [-79.805375, 32.723176], + [-79.817734, 32.923402], + [-79.921418, 32.953944] ] ] } @@ -34,12 +34,12 @@ "type": "Polygon", "coordinates": [ [ - [-80.10543823242188, 32.94760622243483], - [-80.14389038085938, 32.8149783969858], - [-80.07453918457031, 32.85536439443039], - [-79.99351501464844, 32.84440429734253], - [-79.98184204101562, 32.90495631913751], - [-80.10543823242188, 32.94760622243483] + [-80.105439, 32.947606], + [-80.143891, 32.814978], + [-80.07454, 32.855364], + [-79.993516, 32.844404], + [-79.981843, 32.904956], + [-80.105439, 32.947606] ] ] } @@ -54,13 +54,13 @@ "type": "Polygon", "coordinates": [ [ - [-80.068359375, 32.88189375925038], - [-80.01686096191406, 32.87266705436184], - [-80.0066252126598, 32.84617770697059], - [-79.99351501464844, 32.84440429734253], - [-79.98184204101562, 32.90495631913751], - [-80.00501604057509, 32.91295307720083], - [-80.068359375, 32.88189375925038] + [-79.981843, 32.904956], + [-80.005015, 32.912952], + [-80.06836, 32.881892], + [-80.016861, 32.872667], + [-80.006624, 32.846176], + [-79.993516, 32.844403], + [-79.981843, 32.904956] ] ] } diff --git a/packages/turf-intersect/test/out/Intersect3.geojson b/packages/turf-intersect/test/out/Intersect3.geojson new file mode 100644 index 0000000000..418c139273 --- /dev/null +++ b/packages/turf-intersect/test/out/Intersect3.geojson @@ -0,0 +1,145 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "fill-opacity": 0.5, + "fill": "#F00" + }, + "geometry": { + "coordinates": [ + [ + [ + [-79.885712, 32.88766], + [-80.097885, 32.927437], + [-80.153503, 32.82825], + [-80.003128, 32.694288], + [-79.893951, 32.75552], + [-79.885712, 32.88766] + ], + [ + [-80.033715, 32.875508], + [-79.941087, 32.866098], + [-79.916897, 32.783297], + [-80.01425, 32.754522], + [-80.079736, 32.836853], + [-80.033715, 32.875508] + ] + ], + [ + [ + [-80.046825, 32.846002], + [-80.012242, 32.803534], + [-79.965252, 32.807258], + [-79.964808, 32.835201], + [-80.009581, 32.857916], + [-80.046825, 32.846002] + ], + [ + [-80.002268, 32.845442], + [-79.999388, 32.836876], + [-79.984315, 32.8352], + [-79.997836, 32.829426], + [-79.995398, 32.815456], + [-80.004708, 32.82626], + [-80.017562, 32.820299], + [-80.011136, 32.831103], + [-80.020224, 32.838552], + [-80.00914, 32.837435], + [-80.002268, 32.845442] + ] + ], + [ + [ + [-79.936652, 32.964886], + [-80.041397, 32.98246], + [-80.079302, 32.946468], + [-79.963587, 32.919675], + [-79.936652, 32.964886] + ] + ] + ], + "type": "MultiPolygon" + } + }, + { + "type": "Feature", + "properties": { + "fill-opacity": 0.5, + "fill": "#00F" + }, + "geometry": { + "coordinates": [ + [ + [-79.921417, 32.953944], + [-79.994467, 32.83401], + [-79.973602, 32.760717], + [-79.930344, 32.764759], + [-79.937897, 32.741082], + [-79.805374, 32.723176], + [-79.817734, 32.923402], + [-79.921417, 32.953944] + ], + [ + [-79.902742, 32.913654], + [-79.841373, 32.895333], + [-79.837838, 32.793218], + [-79.884445, 32.75204], + [-79.946398, 32.814046], + [-79.902742, 32.913654] + ] + ], + "type": "Polygon" + } + }, + { + "type": "Feature", + "properties": { + "fill-opacity": 1, + "fill": "#0F0" + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [-79.911976, 32.892582], + [-79.953993, 32.900459], + [-79.972951, 32.869335], + [-79.941087, 32.866098], + [-79.934086, 32.842135], + [-79.911976, 32.892582] + ] + ], + [ + [ + [-79.965252, 32.807257], + [-79.964808, 32.8352], + [-79.986911, 32.846414], + [-79.993144, 32.836181], + [-79.984315, 32.8352], + [-79.993668, 32.831205], + [-79.986374, 32.805583], + [-79.965252, 32.807257] + ] + ], + [ + [ + [-79.893951, 32.755519], + [-79.893596, 32.761199], + [-79.917402, 32.785024], + [-79.916897, 32.783296], + [-79.97513, 32.766084], + [-79.973602, 32.760717], + [-79.930344, 32.764758], + [-79.937897, 32.741082], + [-79.923226, 32.739099], + [-79.893951, 32.755519] + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-intersect/test/out/armenia.geojson b/packages/turf-intersect/test/out/armenia.geojson index 8e9228d9da..f19d55de36 100644 --- a/packages/turf-intersect/test/out/armenia.geojson +++ b/packages/turf-intersect/test/out/armenia.geojson @@ -14,24 +14,24 @@ "coordinates": [ [ [43.582746, 41.092143], - [44.97248, 41.248129], - [45.179496, 40.985354], - [45.560351, 40.81229], - [45.359175, 40.561504], - [45.891907, 40.218476], - [45.610012, 39.899994], - [46.034534, 39.628021], - [46.483499, 39.464155], - [46.50572, 38.770605], - [46.143623, 38.741201], - [45.735379, 39.319719], - [45.739978, 39.473999], - [45.298145, 39.471751], - [45.001987, 39.740004], - [44.79399, 39.713003], - [44.400009, 40.005], - [43.656436, 40.253564], [43.752658, 40.740201], + [43.656436, 40.253564], + [44.400009, 40.005], + [44.79399, 39.713003], + [45.001987, 39.740004], + [45.298145, 39.471751], + [45.739978, 39.473999], + [45.735379, 39.319719], + [46.143623, 38.741201], + [46.50572, 38.770605], + [46.483499, 39.464155], + [46.034534, 39.628021], + [45.610012, 39.899994], + [45.891907, 40.218476], + [45.359175, 40.561504], + [45.560351, 40.81229], + [45.179496, 40.985354], + [44.97248, 41.248129], [43.582746, 41.092143] ] ] @@ -47,11 +47,11 @@ "type": "Polygon", "coordinates": [ [ - [45.1318359375, 40.1452892956766], - [45.1318359375, 43.197167282501276], - [53.3935546875, 43.197167282501276], - [53.3935546875, 40.1452892956766], - [45.1318359375, 40.1452892956766] + [45.131835, 40.145289], + [53.393554, 40.145289], + [53.393554, 43.197167], + [45.131835, 43.197167], + [45.131835, 40.145289] ] ] } @@ -66,14 +66,14 @@ "type": "Polygon", "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.131835, 41.045852], + [45.131835, 40.145289], + [45.827128, 40.145289], + [45.891907, 40.218476] ] ] } diff --git a/packages/turf-intersect/test/out/issue-1004.geojson b/packages/turf-intersect/test/out/issue-1004.geojson index 45a42a10e7..f42d49307e 100644 --- a/packages/turf-intersect/test/out/issue-1004.geojson +++ b/packages/turf-intersect/test/out/issue-1004.geojson @@ -132,12 +132,12 @@ "type": "Polygon", "coordinates": [ [ - [-114.757217, 32.619867791666664], - [-114.757213, 32.619753375], - [-114.757213, 32.619926], + [-114.757213, 32.619925], [-114.757215, 32.619925], [-114.757217, 32.619925], - [-114.757217, 32.619867791666664] + [-114.757217, 32.61986], + [-114.757213, 32.61974], + [-114.757213, 32.619925] ] ] } diff --git a/packages/turf-intersect/test/out/issue-1394.geojson b/packages/turf-intersect/test/out/issue-1394.geojson index 5bb4706b78..112b634ad1 100644 --- a/packages/turf-intersect/test/out/issue-1394.geojson +++ b/packages/turf-intersect/test/out/issue-1394.geojson @@ -88,24 +88,6 @@ "fill-opacity": 0.5, "fill": "#00F" } - }, - { - "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [-85.42358073, 41.76885781], - [-85.42357713028528, 41.76878899545362], - [-85.42357713, 41.768789], - [-85.42358073, 41.76885781] - ] - ] - } } ] } diff --git a/packages/turf-intersect/test/out/issue-412.geojson b/packages/turf-intersect/test/out/issue-412.geojson index aa52f6dec6..353979ba8f 100644 --- a/packages/turf-intersect/test/out/issue-412.geojson +++ b/packages/turf-intersect/test/out/issue-412.geojson @@ -47,12 +47,11 @@ "type": "Polygon", "coordinates": [ [ - [11.076136797048882, 9.856269774244707], - [11.076136797048889, 9.856269774244705], - [11.102599853580049, 9.85386305739084], - [11.167525294018608, 9.85386305739084], - [11.168736108831801, 9.855073034114678], - [11.076136797048882, 9.856269774244707] + [11.167526, 9.853863], + [11.168736, 9.855072], + [11.076144, 9.856268], + [11.102596, 9.853863], + [11.167526, 9.853863] ] ] } diff --git a/packages/turf-intersect/test/out/linestring.geojson b/packages/turf-intersect/test/out/linestring.geojson index 4358bc1784..22865fdcc3 100644 --- a/packages/turf-intersect/test/out/linestring.geojson +++ b/packages/turf-intersect/test/out/linestring.geojson @@ -11,17 +11,17 @@ "type": "Polygon", "coordinates": [ [ - [4.8618364334106445, 45.784404601286774], - [4.86544132232666, 45.78434474634739], - [4.88217830657959, 45.78745711798122], - [4.886684417724609, 45.78691845071048], - [4.888958930969238, 45.78494329284938], - [4.876770973205566, 45.782100139729486], - [4.874668121337891, 45.77934663219167], - [4.865655899047851, 45.77904732970034], - [4.859733581542969, 45.77976565298041], - [4.860033988952637, 45.78213006841216], - [4.8618364334106445, 45.784404601286774] + [4.861836, 45.784404], + [4.860033, 45.78213], + [4.859733, 45.779765], + [4.865655, 45.779047], + [4.874668, 45.779346], + [4.87677, 45.7821], + [4.888958, 45.784943], + [4.886684, 45.786918], + [4.882178, 45.787457], + [4.865441, 45.784344], + [4.861836, 45.784404] ] ] } @@ -36,14 +36,14 @@ "type": "Polygon", "coordinates": [ [ - [4.86544132232666, 45.78434474634739], - [4.88217830657959, 45.78745711798122], - [4.8838090896606445, 45.79044961914028], - [4.880805015563965, 45.79257419743464], - [4.875955581665039, 45.78808555655138], - [4.869647026062012, 45.78742719215828], - [4.863724708557129, 45.78575132043314], - [4.86544132232666, 45.78434474634739] + [4.865441, 45.784344], + [4.882178, 45.787457], + [4.883809, 45.790449], + [4.880805, 45.792574], + [4.875955, 45.788085], + [4.869647, 45.787427], + [4.863724, 45.785751], + [4.865441, 45.784344] ] ] } diff --git a/packages/turf-intersect/test/out/multilinestring.geojson b/packages/turf-intersect/test/out/multilinestring.geojson index 4509b4b880..62448073d3 100644 --- a/packages/turf-intersect/test/out/multilinestring.geojson +++ b/packages/turf-intersect/test/out/multilinestring.geojson @@ -11,17 +11,17 @@ "type": "Polygon", "coordinates": [ [ - [4.8618364334106445, 45.784404601286774], - [4.86544132232666, 45.78434474634739], - [4.88217830657959, 45.78745711798122], - [4.886684417724609, 45.78691845071048], - [4.888958930969238, 45.78494329284938], - [4.876770973205566, 45.782100139729486], - [4.874668121337891, 45.77934663219167], - [4.865655899047851, 45.77904732970034], - [4.859733581542969, 45.77976565298041], - [4.860033988952637, 45.78213006841216], - [4.8618364334106445, 45.784404601286774] + [4.861836, 45.784404], + [4.860033, 45.78213], + [4.859733, 45.779765], + [4.865655, 45.779047], + [4.874668, 45.779346], + [4.87677, 45.7821], + [4.888958, 45.784943], + [4.886684, 45.786918], + [4.882178, 45.787457], + [4.865441, 45.784344], + [4.861836, 45.784404] ] ] } @@ -36,18 +36,18 @@ "type": "Polygon", "coordinates": [ [ - [4.86544132232666, 45.78434474634739], - [4.88217830657959, 45.78745711798122], - [4.8838090896606445, 45.79044961914028], - [4.880805015563965, 45.79257419743464], - [4.875955581665039, 45.78808555655138], - [4.869647026062012, 45.78742719215828], - [4.863724708557129, 45.78575132043314], - [4.860978126525879, 45.78572139369446], - [4.860033988952637, 45.78213006841216], - [4.8618364334106445, 45.784404601286774], - [4.8618364334106445, 45.78503307427041], - [4.86544132232666, 45.78434474634739] + [4.865441, 45.784344], + [4.882178, 45.787457], + [4.883809, 45.790449], + [4.880805, 45.792574], + [4.875955, 45.788085], + [4.869647, 45.787427], + [4.863724, 45.785751], + [4.860978, 45.785721], + [4.860033, 45.78213], + [4.861836, 45.784404], + [4.861836, 45.785033], + [4.865441, 45.784344] ] ] } diff --git a/packages/turf-intersect/test/out/multipoint.geojson b/packages/turf-intersect/test/out/multipoint.geojson index fd54684c1d..8e5412d67e 100644 --- a/packages/turf-intersect/test/out/multipoint.geojson +++ b/packages/turf-intersect/test/out/multipoint.geojson @@ -11,13 +11,13 @@ "type": "Polygon", "coordinates": [ [ - [4.845099449157715, 45.77793989651294], - [4.849648475646973, 45.78245928286134], - [4.855012893676758, 45.78446445616189], - [4.859991073608398, 45.784614093068555], - [4.858188629150391, 45.77288134093866], - [4.854154586791992, 45.77249220227275], - [4.845099449157715, 45.77793989651294] + [4.845099, 45.777939], + [4.854154, 45.772492], + [4.858188, 45.772881], + [4.859991, 45.784614], + [4.855012, 45.784464], + [4.849648, 45.782459], + [4.845099, 45.777939] ] ] } @@ -32,12 +32,12 @@ "type": "Polygon", "coordinates": [ [ - [4.845099449157715, 45.77793989651294], - [4.840679168701172, 45.771743851052996], - [4.848017692565918, 45.767133786097716], - [4.854154586791992, 45.77249220227275], - [4.846601486206055, 45.771983324535846], - [4.845099449157715, 45.77793989651294] + [4.845099, 45.777939], + [4.840679, 45.771743], + [4.848017, 45.767133], + [4.854154, 45.772492], + [4.846601, 45.771983], + [4.845099, 45.777939] ] ] } diff --git a/packages/turf-intersect/test/out/multipolygon-input.geojson b/packages/turf-intersect/test/out/multipolygon-input.geojson index 971c29d010..e7135ee1a8 100644 --- a/packages/turf-intersect/test/out/multipolygon-input.geojson +++ b/packages/turf-intersect/test/out/multipolygon-input.geojson @@ -12,22 +12,22 @@ "coordinates": [ [ [ - [2.3273849487304688, 48.87148983809234], - [2.3160552978515625, 48.87307055723444], - [2.3150253295898438, 48.85183958955198], - [2.3493576049804688, 48.845965604118284], - [2.3500442504882812, 48.85613168160397], - [2.3500442504882812, 48.8615527456014], - [2.3273849487304688, 48.87148983809234] + [2.327384, 48.871489], + [2.316055, 48.87307], + [2.315025, 48.851839], + [2.349357, 48.845965], + [2.350044, 48.856131], + [2.350044, 48.861552], + [2.327384, 48.871489] ] ], [ [ - [2.3363113403320312, 48.87690923865779], - [2.3514175415039062, 48.86516646209463], - [2.3596572875976562, 48.873522182101965], - [2.3476409912109375, 48.878489786571116], - [2.3363113403320312, 48.87690923865779] + [2.336311, 48.876909], + [2.351417, 48.865166], + [2.359657, 48.873522], + [2.34764, 48.878489], + [2.336311, 48.876909] ] ] ] @@ -44,20 +44,20 @@ "coordinates": [ [ [ - [2.3256683349609375, 48.87690923865779], - [2.3239517211914062, 48.86787657822752], - [2.3521041870117188, 48.85432452980058], - [2.357940673828125, 48.8615527456014], - [2.3411178588867188, 48.882102279983364], - [2.3256683349609375, 48.87690923865779] + [2.325668, 48.876909], + [2.323951, 48.867876], + [2.352104, 48.854324], + [2.35794, 48.861552], + [2.341117, 48.882102], + [2.325668, 48.876909] ] ], [ [ - [2.362060546875, 48.85229140604385], - [2.3733901977539062, 48.8473212003792], - [2.3733901977539062, 48.854776323867306], - [2.362060546875, 48.85229140604385] + [2.36206, 48.852291], + [2.37339, 48.847321], + [2.37339, 48.854776], + [2.36206, 48.852291] ] ] ] @@ -74,22 +74,22 @@ "coordinates": [ [ [ - [2.3239517211914062, 48.86787657822752], - [2.3499909013050764, 48.85534182435727], - [2.3500442504882812, 48.85613168160397], - [2.3500442504882812, 48.8615527456014], - [2.3273849487304688, 48.87148983809234], - [2.324709348008303, 48.87186313938144], - [2.3239517211914062, 48.86787657822752] + [2.353364, 48.867141], + [2.34444, 48.878042], + [2.336311, 48.876909], + [2.351417, 48.865166], + [2.353364, 48.867141] ] ], [ [ - [2.3363113403320312, 48.87690923865779], - [2.3514175415039062, 48.86516646209463], - [2.353365325175928, 48.86714166070064], - [2.3444407066054644, 48.87804332946407], - [2.3363113403320312, 48.87690923865779] + [2.350044, 48.856131], + [2.350044, 48.861552], + [2.327384, 48.871489], + [2.324708, 48.871862], + [2.323951, 48.867876], + [2.34999, 48.855341], + [2.350044, 48.856131] ] ] ] diff --git a/packages/turf-intersect/test/out/no-overlap.geojson b/packages/turf-intersect/test/out/no-overlap.geojson index 6c6e1918d2..d13608dd51 100644 --- a/packages/turf-intersect/test/out/no-overlap.geojson +++ b/packages/turf-intersect/test/out/no-overlap.geojson @@ -11,11 +11,11 @@ "type": "Polygon", "coordinates": [ [ - [92.6806640625, 53.4357192066942], - [92.6806640625, 53.51418452077113], - [93.0322265625, 53.51418452077113], - [93.0322265625, 53.4357192066942], - [92.6806640625, 53.4357192066942] + [92.680664, 53.435719], + [93.032226, 53.435719], + [93.032226, 53.514184], + [92.680664, 53.514184], + [92.680664, 53.435719] ] ] } @@ -30,11 +30,11 @@ "type": "Polygon", "coordinates": [ [ - [93.47854614257812, 53.628353173374194], - [93.47854614257812, 53.74140157486066], - [93.680419921875, 53.74140157486066], - [93.680419921875, 53.628353173374194], - [93.47854614257812, 53.628353173374194] + [93.478546, 53.628353], + [93.680419, 53.628353], + [93.680419, 53.741401], + [93.478546, 53.741401], + [93.478546, 53.628353] ] ] } diff --git a/packages/turf-intersect/test/out/output-multipolygon.geojson b/packages/turf-intersect/test/out/output-multipolygon.geojson index 4629f4d3ca..fa1692a283 100644 --- a/packages/turf-intersect/test/out/output-multipolygon.geojson +++ b/packages/turf-intersect/test/out/output-multipolygon.geojson @@ -11,11 +11,11 @@ "type": "Polygon", "coordinates": [ [ - [129.0234375, -27.371767300523032], - [138.33984375, -27.371767300523032], - [138.33984375, -22.43134015636061], - [129.0234375, -22.43134015636061], - [129.0234375, -27.371767300523032] + [129.023437, -27.371768], + [138.339843, -27.371768], + [138.339843, -22.431341], + [129.023437, -22.431341], + [129.023437, -27.371768] ] ] } @@ -30,18 +30,18 @@ "type": "Polygon", "coordinates": [ [ - [124.23339843749999, -34.921971036163754], - [143.4375, -34.95799531086791], - [143.26171875, -13.154376055418515], - [124.23339843749999, -12.768946439455943], - [124.23339843749999, -34.921971036163754] + [124.233398, -34.921972], + [143.4375, -34.957996], + [143.261718, -13.154377], + [124.233398, -12.768947], + [124.233398, -34.921972] ], [ - [130.2978515625, -29.95493454965612], - [130.2978515625, -18.020527657852327], - [137.2412109375, -18.020527657852327], - [137.2412109375, -29.95493454965612], - [130.2978515625, -29.95493454965612] + [130.297851, -29.954935], + [130.297851, -18.020528], + [137.24121, -18.020528], + [137.24121, -29.954935], + [130.297851, -29.954935] ] ] } @@ -57,20 +57,20 @@ "coordinates": [ [ [ - [129.0234375, -27.371767300523032], - [130.2978515625, -27.371767300523032], - [130.2978515625, -22.43134015636061], - [129.0234375, -22.43134015636061], - [129.0234375, -27.371767300523032] + [130.297851, -22.431341], + [129.023437, -22.431341], + [129.023437, -27.371768], + [130.297851, -27.371768], + [130.297851, -22.431341] ] ], [ [ - [137.2412109375, -27.371767300523032], - [138.33984375, -27.371767300523032], - [138.33984375, -22.43134015636061], - [137.2412109375, -22.43134015636061], - [137.2412109375, -27.371767300523032] + [138.339843, -22.431341], + [137.24121, -22.431341], + [137.24121, -27.371768], + [138.339843, -27.371768], + [138.339843, -22.431341] ] ] ] diff --git a/packages/turf-intersect/test/out/point.geojson b/packages/turf-intersect/test/out/point.geojson index c3f7c7b9b0..b82a78317e 100644 --- a/packages/turf-intersect/test/out/point.geojson +++ b/packages/turf-intersect/test/out/point.geojson @@ -11,13 +11,13 @@ "type": "Polygon", "coordinates": [ [ - [4.845099449157715, 45.77793989651294], - [4.849648475646973, 45.78245928286134], - [4.855012893676758, 45.78446445616189], - [4.859991073608398, 45.784614093068555], - [4.858188629150391, 45.77288134093866], - [4.854154586791992, 45.77249220227275], - [4.845099449157715, 45.77793989651294] + [4.845099, 45.777939], + [4.854154, 45.772492], + [4.858188, 45.772881], + [4.859991, 45.784614], + [4.855012, 45.784464], + [4.849648, 45.782459], + [4.845099, 45.777939] ] ] } @@ -32,14 +32,14 @@ "type": "Polygon", "coordinates": [ [ - [4.859991073608398, 45.784614093068555], - [4.86569881439209, 45.78611044004426], - [4.87518310546875, 45.787906003397154], - [4.880547523498535, 45.79251435126729], - [4.883980751037598, 45.7903598464431], - [4.8827362060546875, 45.787906003397154], - [4.864926338195801, 45.78464402040167], - [4.859991073608398, 45.784614093068555] + [4.859991, 45.784614], + [4.864926, 45.784644], + [4.882736, 45.787906], + [4.88398, 45.790359], + [4.880547, 45.792514], + [4.875183, 45.787906], + [4.865698, 45.78611], + [4.859991, 45.784614] ] ] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c3a4eb201..0a63460b48 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3273,15 +3273,18 @@ importers: '@turf/helpers': specifier: workspace:* version: link:../turf-helpers + '@turf/internal': + specifier: workspace:* + version: link:../turf-internal '@turf/meta': specifier: workspace:* version: link:../turf-meta '@types/geojson': specifier: ^7946.0.10 version: 7946.0.14 - polyclip-ts: - specifier: ^0.16.8 - version: 0.16.8 + clipper2-ts: + specifier: ^2.0.1 + version: 2.0.1 tslib: specifier: ^2.8.1 version: 2.8.1 From 13bc9fce9595562e8b180de9fcfc47f214ea53c6 Mon Sep 17 00:00:00 2001 From: James Beard Date: Sun, 4 Jan 2026 16:39:58 +1100 Subject: [PATCH 03/14] Retrofitting more compact implementation to union. --- packages/turf-intersect/index.ts | 2 +- packages/turf-union/index.ts | 38 +++++++-------------- packages/turf-union/test/out/union3.geojson | 2 +- 3 files changed, 15 insertions(+), 27 deletions(-) diff --git a/packages/turf-intersect/index.ts b/packages/turf-intersect/index.ts index 74f82f8403..8a76e4d8aa 100644 --- a/packages/turf-intersect/index.ts +++ b/packages/turf-intersect/index.ts @@ -77,7 +77,7 @@ function intersect

( } }); - let tree: PolyTree64 = new PolyTree64(); + const tree: PolyTree64 = new PolyTree64(); clipper.execute(ClipType.Intersection, FillRule.EvenOdd, tree); // Return the result as Polygon, MultiPolygon, or null as appropriate diff --git a/packages/turf-union/index.ts b/packages/turf-union/index.ts index eb5854f87b..54c971cda9 100644 --- a/packages/turf-union/index.ts +++ b/packages/turf-union/index.ts @@ -7,7 +7,7 @@ import { MultiPolygon, GeoJsonProperties, } from "geojson"; -import { Clipper, FillRule, ClipType, PolyTree64, Paths64 } from "clipper2-ts"; +import { FillRule, ClipType, PolyTree64, Clipper64 } from "clipper2-ts"; import { multiPolygonToPaths, polygonToPaths, @@ -66,47 +66,35 @@ function union

( features: FeatureCollection, options: { properties?: P } = {} ): Feature | null { - let subject: Paths64; - let clippers: Paths64[] = []; - if (features.features.length < 2) { throw new Error("Must have at least 2 features"); } + const clipper = new Clipper64(); + geomEach(features, (geom, idx) => { if (geom.type === "MultiPolygon") { if (idx === 0) { - subject = multiPolygonToPaths(geom.coordinates); + clipper.addSubject(multiPolygonToPaths(geom.coordinates)); } else { - clippers.push(multiPolygonToPaths(geom.coordinates)); + clipper.addClip(multiPolygonToPaths(geom.coordinates)); } } else { if (idx === 0) { - subject = polygonToPaths(geom.coordinates); + clipper.addSubject(polygonToPaths(geom.coordinates)); } else { - clippers.push(polygonToPaths(geom.coordinates)); + clipper.addClip(polygonToPaths(geom.coordinates)); } } }); - subject = subject!; - - for (const clipper of clippers) { - subject = Clipper.union(subject, clipper, FillRule.EvenOdd); - } - - // Do one final conversion to PolyTree to better allow handing of holes when - // constructing return Geojson. - let tree: PolyTree64 = new PolyTree64(); - Clipper.booleanOpWithPolyTree( - ClipType.Union, - subject, - [], - tree, - FillRule.EvenOdd - ); + const tree: PolyTree64 = new PolyTree64(); + clipper.execute(ClipType.Union, FillRule.NonZero, tree); - return feature(polyTreeToGeoJSON(tree), options.properties); + // Return the result as Polygon, MultiPolygon, or null as appropriate + const geom = polyTreeToGeoJSON(tree); + if (geom === null) return null; + return feature(geom, options.properties); } export { union }; diff --git a/packages/turf-union/test/out/union3.geojson b/packages/turf-union/test/out/union3.geojson index 5d8b92d34d..25d21f518d 100644 --- a/packages/turf-union/test/out/union3.geojson +++ b/packages/turf-union/test/out/union3.geojson @@ -16,7 +16,7 @@ [-80.153503, 32.828249], [-80.003128, 32.694288], [-79.923226, 32.739099], - [-79.876987, 32.732851], + [-79.876987, 32.732852], [-79.884338, 32.687931], [-79.792328, 32.679841], [-79.632339, 32.804589] From ba8b43e9ceee61701285cc306316719d28b598e9 Mon Sep 17 00:00:00 2001 From: James Beard Date: Sun, 4 Jan 2026 18:47:08 +1100 Subject: [PATCH 04/14] Ported difference to clipper2. Fixed windings of some geojson input test data. Other issue specific test results adjusted. --- packages/turf-difference/index.ts | 46 +++++++---- packages/turf-difference/package.json | 3 +- .../test/in/clip-polygons.geojson | 20 ++--- .../test/in/multi-polygon-input.geojson | 30 +++---- .../test/in/multi-polygon-target.geojson | 40 +++++----- .../test/in/split-polygon.geojson | 20 ++--- .../test/out/clip-polygons.geojson | 34 ++++---- .../test/out/create-hole.geojson | 6 +- .../test/out/issue-#721-inverse.geojson | 36 --------- .../test/out/issue-#721.geojson | 67 +++++++--------- .../test/out/multi-polygon-input.geojson | 66 +++++++-------- .../test/out/multi-polygon-target.geojson | 80 +++++++++---------- .../test/out/split-polygon.geojson | 40 +++++----- pnpm-lock.yaml | 9 ++- 14 files changed, 237 insertions(+), 260 deletions(-) diff --git a/packages/turf-difference/index.ts b/packages/turf-difference/index.ts index e0d2af1950..79706ba18a 100644 --- a/packages/turf-difference/index.ts +++ b/packages/turf-difference/index.ts @@ -1,7 +1,12 @@ import { Polygon, MultiPolygon, Feature, FeatureCollection } from "geojson"; -import * as polyclip from "polyclip-ts"; -import { polygon, multiPolygon } from "@turf/helpers"; +import { feature } from "@turf/helpers"; import { geomEach } from "@turf/meta"; +import { Clipper64, ClipType, FillRule, PolyTree64 } from "clipper2-ts"; +import { + multiPolygonToPaths, + polygonToPaths, + polyTreeToGeoJSON, +} from "@turf/internal/clipper2"; /** * Finds the difference between multiple {@link Polygon|polygons} by clipping the subsequent polygon from the first. @@ -39,22 +44,35 @@ import { geomEach } from "@turf/meta"; function difference( features: FeatureCollection ): Feature | null { - const geoms: Array = []; + if (features.features.length < 2) { + throw new Error("Must have at least 2 features"); + } - geomEach(features, (geom) => { - geoms.push(geom.coordinates as polyclip.Geom); - }); + const clipper = new Clipper64(); - if (geoms.length < 2) { - throw new Error("Must have at least two features"); - } + geomEach(features, (geom, idx) => { + if (geom.type === "MultiPolygon") { + if (idx === 0) { + clipper.addSubject(multiPolygonToPaths(geom.coordinates)); + } else { + clipper.addClip(multiPolygonToPaths(geom.coordinates)); + } + } else { + if (idx === 0) { + clipper.addSubject(polygonToPaths(geom.coordinates)); + } else { + clipper.addClip(polygonToPaths(geom.coordinates)); + } + } + }); - const properties = features.features[0].properties || {}; + const tree: PolyTree64 = new PolyTree64(); + clipper.execute(ClipType.Difference, FillRule.EvenOdd, tree); - const differenced = polyclip.difference(geoms[0], ...geoms.slice(1)); - if (differenced.length === 0) return null; - if (differenced.length === 1) return polygon(differenced[0], properties); - return multiPolygon(differenced, properties); + // Return the result as Polygon, MultiPolygon, or null as appropriate + const geom = polyTreeToGeoJSON(tree); + if (geom === null) return null; + return feature(geom); } export { difference }; diff --git a/packages/turf-difference/package.json b/packages/turf-difference/package.json index ad2d1db2e4..b67d51421a 100644 --- a/packages/turf-difference/package.json +++ b/packages/turf-difference/package.json @@ -62,9 +62,10 @@ }, "dependencies": { "@turf/helpers": "workspace:*", + "@turf/internal": "workspace:*", "@turf/meta": "workspace:*", "@types/geojson": "^7946.0.10", - "polyclip-ts": "^0.16.8", + "clipper2-ts": "^2.0.1", "tslib": "^2.8.1" } } diff --git a/packages/turf-difference/test/in/clip-polygons.geojson b/packages/turf-difference/test/in/clip-polygons.geojson index 492997bc04..9aff678d4c 100644 --- a/packages/turf-difference/test/in/clip-polygons.geojson +++ b/packages/turf-difference/test/in/clip-polygons.geojson @@ -14,11 +14,11 @@ "type": "Polygon", "coordinates": [ [ - [127.705078125, -34.52466147177172], - [139.5703125, -34.52466147177172], - [139.5703125, -15.28418511407642], - [127.705078125, -15.28418511407642], - [127.705078125, -34.52466147177172] + [127.705078, -34.524662], + [139.570312, -34.524662], + [139.570312, -15.284186], + [127.705078, -15.284186], + [127.705078, -34.524662] ] ] } @@ -36,11 +36,11 @@ "type": "Polygon", "coordinates": [ [ - [133.154296875, -29.075375179558346], - [144.228515625, -29.075375179558346], - [144.228515625, -12.983147716796566], - [133.154296875, -12.983147716796566], - [133.154296875, -29.075375179558346] + [133.154296, -29.075376], + [144.228515, -29.075376], + [144.228515, -12.983148], + [133.154296, -12.983148], + [133.154296, -29.075376] ] ] } diff --git a/packages/turf-difference/test/in/multi-polygon-input.geojson b/packages/turf-difference/test/in/multi-polygon-input.geojson index 355bed3682..df347db030 100644 --- a/packages/turf-difference/test/in/multi-polygon-input.geojson +++ b/packages/turf-difference/test/in/multi-polygon-input.geojson @@ -15,20 +15,20 @@ "coordinates": [ [ [ - [123.134765625, -25.562265014427492], - [136.142578125, -25.562265014427492], - [136.142578125, -13.068776734357694], - [123.134765625, -13.068776734357694], - [123.134765625, -25.562265014427492] + [123.134765, -25.562266], + [136.142578, -25.562266], + [136.142578, -13.068777], + [123.134765, -13.068777], + [123.134765, -25.562266] ] ], [ [ - [119.53125, -39.57182223734373], - [134.560546875, -39.57182223734373], - [134.560546875, -28.38173504322308], - [119.53125, -28.38173504322308], - [119.53125, -39.57182223734373] + [119.53125, -39.571823], + [134.560546, -39.571823], + [134.560546, -28.381736], + [119.53125, -28.381736], + [119.53125, -39.571823] ] ] ] @@ -47,11 +47,11 @@ "type": "Polygon", "coordinates": [ [ - [126.298828125, -35.81781315869662], - [131.8359375, -35.81781315869662], - [131.8359375, -18.396230138028812], - [126.298828125, -18.396230138028812], - [126.298828125, -35.81781315869662] + [126.298828, -35.817814], + [131.835937, -35.817814], + [131.835937, -18.396231], + [126.298828, -18.396231], + [126.298828, -35.817814] ] ] } diff --git a/packages/turf-difference/test/in/multi-polygon-target.geojson b/packages/turf-difference/test/in/multi-polygon-target.geojson index 58b82bddff..6202a69ecc 100644 --- a/packages/turf-difference/test/in/multi-polygon-target.geojson +++ b/packages/turf-difference/test/in/multi-polygon-target.geojson @@ -14,18 +14,18 @@ "type": "Polygon", "coordinates": [ [ - [127.66113281249999, -30.713503990354965], - [140.7568359375, -30.713503990354965], - [140.7568359375, -20.2209657795223], - [127.66113281249999, -20.2209657795223], - [127.66113281249999, -30.713503990354965] + [127.661132, -30.713504], + [140.756835, -30.713504], + [140.756835, -20.220966], + [127.661132, -20.220966], + [127.661132, -30.713504] ], [ - [132.38525390625, -27.313213898568247], - [135.1318359375, -27.313213898568247], - [135.1318359375, -24.467150664738988], - [132.38525390625, -24.467150664738988], - [132.38525390625, -27.313213898568247] + [132.385253, -27.313214], + [132.385253, -24.467151], + [135.131835, -24.467151], + [135.131835, -27.313214], + [132.385253, -27.313214] ] ] } @@ -44,20 +44,20 @@ "coordinates": [ [ [ - [128.8916015625, -31.84023266790935], - [130.6494140625, -31.84023266790935], - [130.6494140625, -18.646245142670598], - [128.8916015625, -18.646245142670598], - [128.8916015625, -31.84023266790935] + [128.891601, -31.840233], + [130.649414, -31.840233], + [130.649414, -18.646246], + [128.891601, -18.646246], + [128.891601, -31.840233] ] ], [ [ - [136.23046875, -32.175612478499325], - [138.6474609375, -32.175612478499325], - [138.6474609375, -18.729501999072138], - [136.23046875, -18.729501999072138], - [136.23046875, -32.175612478499325] + [136.230468, -32.175613], + [138.64746, -32.175613], + [138.64746, -18.729502], + [136.230468, -18.729502], + [136.230468, -32.175613] ] ] ] diff --git a/packages/turf-difference/test/in/split-polygon.geojson b/packages/turf-difference/test/in/split-polygon.geojson index 1164d05b27..15930e5b7c 100644 --- a/packages/turf-difference/test/in/split-polygon.geojson +++ b/packages/turf-difference/test/in/split-polygon.geojson @@ -14,11 +14,11 @@ "type": "Polygon", "coordinates": [ [ - [122.51953124999999, -29.22889003019423], - [144.228515625, -29.22889003019423], - [144.228515625, -21.53484700204879], - [122.51953124999999, -21.53484700204879], - [122.51953124999999, -29.22889003019423] + [122.519531, -29.228891], + [144.228515, -29.228891], + [144.228515, -21.534848], + [122.519531, -21.534848], + [122.519531, -29.228891] ] ] } @@ -36,11 +36,11 @@ "type": "Polygon", "coordinates": [ [ - [127.705078125, -34.52466147177172], - [139.5703125, -34.52466147177172], - [139.5703125, -15.28418511407642], - [127.705078125, -15.28418511407642], - [127.705078125, -34.52466147177172] + [127.705078, -34.524662], + [139.570312, -34.524662], + [139.570312, -15.284186], + [127.705078, -15.284186], + [127.705078, -34.524662] ] ] } diff --git a/packages/turf-difference/test/out/clip-polygons.geojson b/packages/turf-difference/test/out/clip-polygons.geojson index a6bedea0b0..73d1fef7ce 100644 --- a/packages/turf-difference/test/out/clip-polygons.geojson +++ b/packages/turf-difference/test/out/clip-polygons.geojson @@ -14,11 +14,11 @@ "type": "Polygon", "coordinates": [ [ - [127.705078125, -34.52466147177172], - [139.5703125, -34.52466147177172], - [139.5703125, -15.28418511407642], - [127.705078125, -15.28418511407642], - [127.705078125, -34.52466147177172] + [127.705078, -34.524662], + [139.570312, -34.524662], + [139.570312, -15.284186], + [127.705078, -15.284186], + [127.705078, -34.524662] ] ] } @@ -36,11 +36,11 @@ "type": "Polygon", "coordinates": [ [ - [133.154296875, -29.075375179558346], - [144.228515625, -29.075375179558346], - [144.228515625, -12.983147716796566], - [133.154296875, -12.983147716796566], - [133.154296875, -29.075375179558346] + [133.154296, -29.075376], + [144.228515, -29.075376], + [144.228515, -12.983148], + [133.154296, -12.983148], + [133.154296, -29.075376] ] ] } @@ -55,13 +55,13 @@ "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] + [139.570312, -29.075376], + [133.154295, -29.075376], + [133.154295, -15.284186], + [127.705078, -15.284186], + [127.705078, -34.524662], + [139.570312, -34.524662], + [139.570312, -29.075376] ] ] } diff --git a/packages/turf-difference/test/out/create-hole.geojson b/packages/turf-difference/test/out/create-hole.geojson index e74d33a70f..5d8a5eac33 100644 --- a/packages/turf-difference/test/out/create-hole.geojson +++ b/packages/turf-difference/test/out/create-hole.geojson @@ -55,11 +55,11 @@ "type": "Polygon", "coordinates": [ [ - [121, -31], - [144, -31], [144, -15], [121, -15], - [121, -31] + [121, -31], + [144, -31], + [144, -15] ], [ [126, -28], diff --git a/packages/turf-difference/test/out/issue-#721-inverse.geojson b/packages/turf-difference/test/out/issue-#721-inverse.geojson index 9bacfc3c01..477c618427 100644 --- a/packages/turf-difference/test/out/issue-#721-inverse.geojson +++ b/packages/turf-difference/test/out/issue-#721-inverse.geojson @@ -92,42 +92,6 @@ ] ] } - }, - { - "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, - "geometry": { - "type": "MultiPolygon", - "coordinates": [ - [ - [ - [-0.6462588068806041, 44.80608667910215], - [-0.6462588068796641, 44.80608667910137], - [-0.6461987, 44.8060367], - [-0.6462588068806041, 44.80608667910215] - ] - ], - [ - [ - [-0.6461042, 44.8059451], - [-0.6461041344154723, 44.805944903377586], - [-0.6461041344154722, 44.805944903377586], - [-0.6461042, 44.8059451] - ] - ], - [ - [ - [-0.6460471709105139, 44.80564743856641], - [-0.6460421, 44.8056729], - [-0.6460471709104708, 44.80564743856663], - [-0.6460471709105139, 44.80564743856641] - ] - ] - ] - } } ] } diff --git a/packages/turf-difference/test/out/issue-#721.geojson b/packages/turf-difference/test/out/issue-#721.geojson index 08606ca524..dba3cb855e 100644 --- a/packages/turf-difference/test/out/issue-#721.geojson +++ b/packages/turf-difference/test/out/issue-#721.geojson @@ -103,47 +103,38 @@ "type": "Polygon", "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.6461073, 44.8053383], - [-0.6460848, 44.8054585], - [-0.6460471709104708, 44.80564743856663], - [-0.6460422277450562, 44.805672561504906], - [-0.6460542976856232, 44.80579530680288], - [-0.646069093721612, 44.80583985137739], - [-0.6460542, 44.8057952], - [-0.6461041344154723, 44.805944903377586], - [-0.6461991369724274, 44.80603699057963], - [-0.6462588068796641, 44.80608667910137], - [-0.6463809, 44.8061882], + [-0.646075, 44.804294], + [-0.645829, 44.804389], + [-0.646016, 44.804794], + [-0.646082, 44.805001], + [-0.646121, 44.805174], + [-0.646107, 44.805338], + [-0.646084, 44.805458], + [-0.646042, 44.805672], + [-0.646054, 44.805795], + [-0.646104, 44.805945], + [-0.646104, 44.805944], + [-0.646199, 44.806036], + [-0.646258, 44.806086], + [-0.64638, 44.806188], [-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] - ], - [ - [-0.6461073, 44.8053383], - [-0.6461158838109077, 44.80524109574131], - [-0.646107941865921, 44.80533857879061], - [-0.646093673696575, 44.80541109474097], - [-0.6461073, 44.8053383] + [-0.646697, 44.806041], + [-0.6467, 44.805996], + [-0.646683, 44.805971], + [-0.646637, 44.805954], + [-0.646592, 44.805912], + [-0.646511, 44.805795], + [-0.646473, 44.805664], + [-0.646504, 44.805555], + [-0.64719, 44.805394], + [-0.647413, 44.805326], + [-0.647229, 44.805048], + [-0.646911, 44.804857], + [-0.646599, 44.804737], + [-0.646284, 44.804219], + [-0.646075, 44.804294] ] ] } diff --git a/packages/turf-difference/test/out/multi-polygon-input.geojson b/packages/turf-difference/test/out/multi-polygon-input.geojson index db250d9044..8f41c4b32d 100644 --- a/packages/turf-difference/test/out/multi-polygon-input.geojson +++ b/packages/turf-difference/test/out/multi-polygon-input.geojson @@ -15,20 +15,20 @@ "coordinates": [ [ [ - [123.134765625, -25.562265014427492], - [136.142578125, -25.562265014427492], - [136.142578125, -13.068776734357694], - [123.134765625, -13.068776734357694], - [123.134765625, -25.562265014427492] + [123.134765, -25.562266], + [136.142578, -25.562266], + [136.142578, -13.068777], + [123.134765, -13.068777], + [123.134765, -25.562266] ] ], [ [ - [119.53125, -39.57182223734373], - [134.560546875, -39.57182223734373], - [134.560546875, -28.38173504322308], - [119.53125, -28.38173504322308], - [119.53125, -39.57182223734373] + [119.53125, -39.571823], + [134.560546, -39.571823], + [134.560546, -28.381736], + [119.53125, -28.381736], + [119.53125, -39.571823] ] ] ] @@ -47,11 +47,11 @@ "type": "Polygon", "coordinates": [ [ - [126.298828125, -35.81781315869662], - [131.8359375, -35.81781315869662], - [131.8359375, -18.396230138028812], - [126.298828125, -18.396230138028812], - [126.298828125, -35.81781315869662] + [126.298828, -35.817814], + [131.835937, -35.817814], + [131.835937, -18.396231], + [126.298828, -18.396231], + [126.298828, -35.817814] ] ] } @@ -67,28 +67,28 @@ "coordinates": [ [ [ - [119.53125, -39.57182223734373], - [134.560546875, -39.57182223734373], - [134.560546875, -28.38173504322308], - [131.8359375, -28.38173504322308], - [131.8359375, -35.81781315869662], - [126.298828125, -35.81781315869662], - [126.298828125, -28.38173504322308], - [119.53125, -28.38173504322308], - [119.53125, -39.57182223734373] + [136.142578, -13.068777], + [123.134765, -13.068777], + [123.134765, -25.562266], + [126.298828, -25.562266], + [126.298828, -18.396231], + [131.835937, -18.396231], + [131.835937, -25.562266], + [136.142578, -25.562266], + [136.142578, -13.068777] ] ], [ [ - [123.134765625, -25.562265014427492], - [126.298828125, -25.562265014427492], - [126.298828125, -18.396230138028812], - [131.8359375, -18.396230138028812], - [131.8359375, -25.562265014427492], - [136.142578125, -25.562265014427492], - [136.142578125, -13.068776734357694], - [123.134765625, -13.068776734357694], - [123.134765625, -25.562265014427492] + [134.560546, -28.381736], + [131.835937, -28.381736], + [131.835937, -35.817814], + [126.298828, -35.817814], + [126.298828, -28.381736], + [119.53125, -28.381736], + [119.53125, -39.571823], + [134.560546, -39.571823], + [134.560546, -28.381736] ] ] ] diff --git a/packages/turf-difference/test/out/multi-polygon-target.geojson b/packages/turf-difference/test/out/multi-polygon-target.geojson index 6d39aedaab..063066d5c3 100644 --- a/packages/turf-difference/test/out/multi-polygon-target.geojson +++ b/packages/turf-difference/test/out/multi-polygon-target.geojson @@ -14,18 +14,18 @@ "type": "Polygon", "coordinates": [ [ - [127.66113281249999, -30.713503990354965], - [140.7568359375, -30.713503990354965], - [140.7568359375, -20.2209657795223], - [127.66113281249999, -20.2209657795223], - [127.66113281249999, -30.713503990354965] + [127.661132, -30.713504], + [140.756835, -30.713504], + [140.756835, -20.220966], + [127.661132, -20.220966], + [127.661132, -30.713504] ], [ - [132.38525390625, -27.313213898568247], - [135.1318359375, -27.313213898568247], - [135.1318359375, -24.467150664738988], - [132.38525390625, -24.467150664738988], - [132.38525390625, -27.313213898568247] + [132.385253, -27.313214], + [132.385253, -24.467151], + [135.131835, -24.467151], + [135.131835, -27.313214], + [132.385253, -27.313214] ] ] } @@ -44,20 +44,20 @@ "coordinates": [ [ [ - [128.8916015625, -31.84023266790935], - [130.6494140625, -31.84023266790935], - [130.6494140625, -18.646245142670598], - [128.8916015625, -18.646245142670598], - [128.8916015625, -31.84023266790935] + [128.891601, -31.840233], + [130.649414, -31.840233], + [130.649414, -18.646246], + [128.891601, -18.646246], + [128.891601, -31.840233] ] ], [ [ - [136.23046875, -32.175612478499325], - [138.6474609375, -32.175612478499325], - [138.6474609375, -18.729501999072138], - [136.23046875, -18.729501999072138], - [136.23046875, -32.175612478499325] + [136.230468, -32.175613], + [138.64746, -32.175613], + [138.64746, -18.729502], + [136.230468, -18.729502], + [136.230468, -32.175613] ] ] ] @@ -74,36 +74,36 @@ "coordinates": [ [ [ - [127.66113281249999, -30.713503990354965], - [128.8916015625, -30.713503990354965], - [128.8916015625, -20.2209657795223], - [127.66113281249999, -20.2209657795223], - [127.66113281249999, -30.713503990354965] + [128.891601, -20.220966], + [127.661132, -20.220966], + [127.661132, -30.713504], + [128.891601, -30.713504], + [128.891601, -20.220966] ] ], [ [ - [130.6494140625, -30.713503990354965], - [136.23046875, -30.713503990354965], - [136.23046875, -20.2209657795223], - [130.6494140625, -20.2209657795223], - [130.6494140625, -30.713503990354965] + [136.230468, -20.220966], + [130.649414, -20.220966], + [130.649414, -30.713504], + [136.230468, -30.713504], + [136.230468, -20.220966] ], [ - [132.38525390625, -27.313213898568247], - [132.38525390625, -24.467150664738988], - [135.1318359375, -24.467150664738988], - [135.1318359375, -27.313213898568247], - [132.38525390625, -27.313213898568247] + [132.385253, -24.467151], + [135.131835, -24.467151], + [135.131835, -27.313214], + [132.385253, -27.313214], + [132.385253, -24.467151] ] ], [ [ - [138.6474609375, -30.713503990354965], - [140.7568359375, -30.713503990354965], - [140.7568359375, -20.2209657795223], - [138.6474609375, -20.2209657795223], - [138.6474609375, -30.713503990354965] + [140.756835, -20.220966], + [138.64746, -20.220966], + [138.64746, -30.713504], + [140.756835, -30.713504], + [140.756835, -20.220966] ] ] ] diff --git a/packages/turf-difference/test/out/split-polygon.geojson b/packages/turf-difference/test/out/split-polygon.geojson index 99da2a61ca..71bc594bc7 100644 --- a/packages/turf-difference/test/out/split-polygon.geojson +++ b/packages/turf-difference/test/out/split-polygon.geojson @@ -14,11 +14,11 @@ "type": "Polygon", "coordinates": [ [ - [122.51953124999999, -29.22889003019423], - [144.228515625, -29.22889003019423], - [144.228515625, -21.53484700204879], - [122.51953124999999, -21.53484700204879], - [122.51953124999999, -29.22889003019423] + [122.519531, -29.228891], + [144.228515, -29.228891], + [144.228515, -21.534848], + [122.519531, -21.534848], + [122.519531, -29.228891] ] ] } @@ -36,11 +36,11 @@ "type": "Polygon", "coordinates": [ [ - [127.705078125, -34.52466147177172], - [139.5703125, -34.52466147177172], - [139.5703125, -15.28418511407642], - [127.705078125, -15.28418511407642], - [127.705078125, -34.52466147177172] + [127.705078, -34.524662], + [139.570312, -34.524662], + [139.570312, -15.284186], + [127.705078, -15.284186], + [127.705078, -34.524662] ] ] } @@ -56,20 +56,20 @@ "coordinates": [ [ [ - [122.51953124999999, -29.22889003019423], - [127.705078125, -29.22889003019423], - [127.705078125, -21.53484700204879], - [122.51953124999999, -21.53484700204879], - [122.51953124999999, -29.22889003019423] + [127.705078, -21.534848], + [122.519531, -21.534848], + [122.519531, -29.228891], + [127.705078, -29.228891], + [127.705078, -21.534848] ] ], [ [ - [139.5703125, -29.22889003019423], - [144.228515625, -29.22889003019423], - [144.228515625, -21.53484700204879], - [139.5703125, -21.53484700204879], - [139.5703125, -29.22889003019423] + [144.228515, -21.534848], + [139.570312, -21.534848], + [139.570312, -29.228891], + [144.228515, -29.228891], + [144.228515, -21.534848] ] ] ] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0a63460b48..fd4a513615 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2493,15 +2493,18 @@ importers: '@turf/helpers': specifier: workspace:* version: link:../turf-helpers + '@turf/internal': + specifier: workspace:* + version: link:../turf-internal '@turf/meta': specifier: workspace:* version: link:../turf-meta '@types/geojson': specifier: ^7946.0.10 version: 7946.0.14 - polyclip-ts: - specifier: ^0.16.8 - version: 0.16.8 + clipper2-ts: + specifier: ^2.0.1 + version: 2.0.1 tslib: specifier: ^2.8.1 version: 2.8.1 From 00c2074b6fb4440058c6bc65bdbc62e4069c47e3 Mon Sep 17 00:00:00 2001 From: James Beard Date: Mon, 5 Jan 2026 13:42:48 +1100 Subject: [PATCH 05/14] Added minimal package setup to @turf/internal to get it building and "linking" to the point @turf/turf could be built. --- packages/turf-internal/LICENSE | 20 +++++++++++++ packages/turf-internal/index.ts | 2 +- packages/turf-internal/package.json | 43 +++++++++++++++++++++++++--- packages/turf-internal/test.ts | 0 packages/turf-internal/tsconfig.json | 3 ++ pnpm-lock.yaml | 4 +++ 6 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 packages/turf-internal/LICENSE create mode 100644 packages/turf-internal/test.ts create mode 100644 packages/turf-internal/tsconfig.json diff --git a/packages/turf-internal/LICENSE b/packages/turf-internal/LICENSE new file mode 100644 index 0000000000..96ce51b76f --- /dev/null +++ b/packages/turf-internal/LICENSE @@ -0,0 +1,20 @@ +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-internal/index.ts b/packages/turf-internal/index.ts index e89e4bea11..200c04487c 100644 --- a/packages/turf-internal/index.ts +++ b/packages/turf-internal/index.ts @@ -1 +1 @@ -export * from "./clipper2"; +export * from "./clipper2/index.js"; diff --git a/packages/turf-internal/package.json b/packages/turf-internal/package.json index 27ab9e3567..293497dbd3 100644 --- a/packages/turf-internal/package.json +++ b/packages/turf-internal/package.json @@ -2,12 +2,47 @@ "name": "@turf/internal", "version": "7.3.1", "private": true, + "description": "Common functionality used across multiple Turf packages.", + "author": "Turf Authors", + "contributors": [ + "James Beard <@smallsaucepan>" + ], + "license": "MIT", + "bugs": { + "url": "https://github.com/Turfjs/turf/issues" + }, + "homepage": "https://github.com/Turfjs/turf", + "repository": { + "type": "git", + "url": "git://github.com/Turfjs/turf.git" + }, + "funding": "https://opencollective.com/turf", "type": "module", - "main": "index.ts", - "types": "index.ts", + "main": "dist/cjs/index.cjs", + "module": "dist/esm/index.js", + "types": "dist/esm/index.d.ts", "exports": { - ".": "./index.ts", - "./clipper2": "./clipper2/index.ts" + "./package.json": "./package.json", + "./clipper2": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/cjs/index.d.cts", + "default": "./dist/cjs/index.cjs" + } + } + }, + "sideEffects": false, + "files": [ + "dist" + ], + "scripts": { + "build": "tsup --config ../../tsup.config.ts" + }, + "devDependencies": { + "tsup": "^8.4.0" }, "dependencies": { "@types/geojson": "^7946.0.10", diff --git a/packages/turf-internal/test.ts b/packages/turf-internal/test.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/turf-internal/tsconfig.json b/packages/turf-internal/tsconfig.json new file mode 100644 index 0000000000..563bf86442 --- /dev/null +++ b/packages/turf-internal/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tsconfig.shared.json" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fd4a513615..87ff7c90a4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3194,6 +3194,10 @@ importers: tslib: specifier: ^2.8.1 version: 2.8.1 + devDependencies: + tsup: + specifier: ^8.4.0 + version: 8.4.0(postcss@8.5.3)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) packages/turf-interpolate: dependencies: From 39035eb524f5643708b149d2f54aed798f406ed3 Mon Sep 17 00:00:00 2001 From: James Beard Date: Tue, 6 Jan 2026 10:16:19 +1100 Subject: [PATCH 06/14] Converted to floating point version of clipper2 (works much better with a non-default precision set). Reverted corrections to incorrect windings in input test to make sure we handle improperly wound geojson. Added runtime checks to force all windings to what clipper2 expects. --- packages/turf-difference/index.ts | 15 +-- .../test/in/clip-polygons.geojson | 20 ++-- .../test/in/multi-polygon-input.geojson | 30 +++--- .../test/in/multi-polygon-target.geojson | 40 ++++---- .../test/in/split-polygon.geojson | 20 ++-- .../test/out/clip-polygons.geojson | 39 ++++---- .../test/out/issue-#721.geojson | 92 +++++++++++-------- .../test/out/multi-polygon-input.geojson | 71 +++++++------- .../test/out/multi-polygon-target.geojson | 85 +++++++++-------- .../test/out/split-polygon.geojson | 45 +++++---- packages/turf-internal/clipper2/index.ts | 80 +++++++++++----- packages/turf-intersect/index.ts | 15 +-- .../turf-intersect/test/in/Intersect1.geojson | 28 +++--- .../turf-intersect/test/in/Intersect2.geojson | 30 +++--- .../turf-intersect/test/in/armenia.geojson | 44 ++++----- .../turf-intersect/test/in/linestring.geojson | 38 ++++---- .../test/in/multilinestring.geojson | 46 +++++----- .../turf-intersect/test/in/multipoint.geojson | 26 +++--- .../test/in/multipolygon-input.geojson | 44 ++++----- .../turf-intersect/test/in/no-overlap.geojson | 20 ++-- .../test/in/output-multipolygon.geojson | 30 +++--- packages/turf-intersect/test/in/point.geojson | 30 +++--- .../test/out/Intersect1.geojson | 61 ++++++------ .../test/out/Intersect2.geojson | 59 +++++------- .../test/out/Intersect3.geojson | 55 +++++------ .../turf-intersect/test/out/armenia.geojson | 68 ++++++-------- .../test/out/issue-1004.geojson | 23 ++--- .../turf-intersect/test/out/issue-412.geojson | 25 ++--- .../test/out/linestring.geojson | 48 +++++----- .../test/out/multilinestring.geojson | 56 +++++------ .../test/out/multipoint.geojson | 36 +++----- .../test/out/multipolygon-input.geojson | 83 ++++++++--------- .../test/out/no-overlap.geojson | 30 +++--- .../test/out/output-multipolygon.geojson | 65 ++++++------- .../turf-intersect/test/out/point.geojson | 40 ++++---- packages/turf-union/index.ts | 15 +-- .../test/in/not-overlapping.geojson | 26 +++--- packages/turf-union/test/in/union1.geojson | 28 +++--- packages/turf-union/test/in/union2.geojson | 52 +++++------ packages/turf-union/test/in/union4.geojson | 18 ++-- .../test/out/not-overlapping.geojson | 26 +++--- packages/turf-union/test/out/union1.geojson | 18 ++-- packages/turf-union/test/out/union2.geojson | 30 +++--- packages/turf-union/test/out/union3.geojson | 16 ++-- packages/turf-union/test/out/union4.geojson | 24 ++--- packages/turf-union/test/out/union5.geojson | 56 +++++------ 46 files changed, 891 insertions(+), 955 deletions(-) diff --git a/packages/turf-difference/index.ts b/packages/turf-difference/index.ts index 79706ba18a..8ef66845ee 100644 --- a/packages/turf-difference/index.ts +++ b/packages/turf-difference/index.ts @@ -1,8 +1,9 @@ import { Polygon, MultiPolygon, Feature, FeatureCollection } from "geojson"; import { feature } from "@turf/helpers"; import { geomEach } from "@turf/meta"; -import { Clipper64, ClipType, FillRule, PolyTree64 } from "clipper2-ts"; +import { ClipperD, ClipType, FillRule, PolyTreeD } from "clipper2-ts"; import { + DEFAULT_PRECISION, multiPolygonToPaths, polygonToPaths, polyTreeToGeoJSON, @@ -48,25 +49,25 @@ function difference( throw new Error("Must have at least 2 features"); } - const clipper = new Clipper64(); + const clipper = new ClipperD(DEFAULT_PRECISION); geomEach(features, (geom, idx) => { if (geom.type === "MultiPolygon") { if (idx === 0) { - clipper.addSubject(multiPolygonToPaths(geom.coordinates)); + clipper.addSubjectPaths(multiPolygonToPaths(geom.coordinates)); } else { - clipper.addClip(multiPolygonToPaths(geom.coordinates)); + clipper.addClipPaths(multiPolygonToPaths(geom.coordinates)); } } else { if (idx === 0) { - clipper.addSubject(polygonToPaths(geom.coordinates)); + clipper.addSubjectPaths(polygonToPaths(geom.coordinates)); } else { - clipper.addClip(polygonToPaths(geom.coordinates)); + clipper.addClipPaths(polygonToPaths(geom.coordinates)); } } }); - const tree: PolyTree64 = new PolyTree64(); + const tree = new PolyTreeD(); clipper.execute(ClipType.Difference, FillRule.EvenOdd, tree); // Return the result as Polygon, MultiPolygon, or null as appropriate diff --git a/packages/turf-difference/test/in/clip-polygons.geojson b/packages/turf-difference/test/in/clip-polygons.geojson index 9aff678d4c..492997bc04 100644 --- a/packages/turf-difference/test/in/clip-polygons.geojson +++ b/packages/turf-difference/test/in/clip-polygons.geojson @@ -14,11 +14,11 @@ "type": "Polygon", "coordinates": [ [ - [127.705078, -34.524662], - [139.570312, -34.524662], - [139.570312, -15.284186], - [127.705078, -15.284186], - [127.705078, -34.524662] + [127.705078125, -34.52466147177172], + [139.5703125, -34.52466147177172], + [139.5703125, -15.28418511407642], + [127.705078125, -15.28418511407642], + [127.705078125, -34.52466147177172] ] ] } @@ -36,11 +36,11 @@ "type": "Polygon", "coordinates": [ [ - [133.154296, -29.075376], - [144.228515, -29.075376], - [144.228515, -12.983148], - [133.154296, -12.983148], - [133.154296, -29.075376] + [133.154296875, -29.075375179558346], + [144.228515625, -29.075375179558346], + [144.228515625, -12.983147716796566], + [133.154296875, -12.983147716796566], + [133.154296875, -29.075375179558346] ] ] } diff --git a/packages/turf-difference/test/in/multi-polygon-input.geojson b/packages/turf-difference/test/in/multi-polygon-input.geojson index df347db030..355bed3682 100644 --- a/packages/turf-difference/test/in/multi-polygon-input.geojson +++ b/packages/turf-difference/test/in/multi-polygon-input.geojson @@ -15,20 +15,20 @@ "coordinates": [ [ [ - [123.134765, -25.562266], - [136.142578, -25.562266], - [136.142578, -13.068777], - [123.134765, -13.068777], - [123.134765, -25.562266] + [123.134765625, -25.562265014427492], + [136.142578125, -25.562265014427492], + [136.142578125, -13.068776734357694], + [123.134765625, -13.068776734357694], + [123.134765625, -25.562265014427492] ] ], [ [ - [119.53125, -39.571823], - [134.560546, -39.571823], - [134.560546, -28.381736], - [119.53125, -28.381736], - [119.53125, -39.571823] + [119.53125, -39.57182223734373], + [134.560546875, -39.57182223734373], + [134.560546875, -28.38173504322308], + [119.53125, -28.38173504322308], + [119.53125, -39.57182223734373] ] ] ] @@ -47,11 +47,11 @@ "type": "Polygon", "coordinates": [ [ - [126.298828, -35.817814], - [131.835937, -35.817814], - [131.835937, -18.396231], - [126.298828, -18.396231], - [126.298828, -35.817814] + [126.298828125, -35.81781315869662], + [131.8359375, -35.81781315869662], + [131.8359375, -18.396230138028812], + [126.298828125, -18.396230138028812], + [126.298828125, -35.81781315869662] ] ] } diff --git a/packages/turf-difference/test/in/multi-polygon-target.geojson b/packages/turf-difference/test/in/multi-polygon-target.geojson index 6202a69ecc..58b82bddff 100644 --- a/packages/turf-difference/test/in/multi-polygon-target.geojson +++ b/packages/turf-difference/test/in/multi-polygon-target.geojson @@ -14,18 +14,18 @@ "type": "Polygon", "coordinates": [ [ - [127.661132, -30.713504], - [140.756835, -30.713504], - [140.756835, -20.220966], - [127.661132, -20.220966], - [127.661132, -30.713504] + [127.66113281249999, -30.713503990354965], + [140.7568359375, -30.713503990354965], + [140.7568359375, -20.2209657795223], + [127.66113281249999, -20.2209657795223], + [127.66113281249999, -30.713503990354965] ], [ - [132.385253, -27.313214], - [132.385253, -24.467151], - [135.131835, -24.467151], - [135.131835, -27.313214], - [132.385253, -27.313214] + [132.38525390625, -27.313213898568247], + [135.1318359375, -27.313213898568247], + [135.1318359375, -24.467150664738988], + [132.38525390625, -24.467150664738988], + [132.38525390625, -27.313213898568247] ] ] } @@ -44,20 +44,20 @@ "coordinates": [ [ [ - [128.891601, -31.840233], - [130.649414, -31.840233], - [130.649414, -18.646246], - [128.891601, -18.646246], - [128.891601, -31.840233] + [128.8916015625, -31.84023266790935], + [130.6494140625, -31.84023266790935], + [130.6494140625, -18.646245142670598], + [128.8916015625, -18.646245142670598], + [128.8916015625, -31.84023266790935] ] ], [ [ - [136.230468, -32.175613], - [138.64746, -32.175613], - [138.64746, -18.729502], - [136.230468, -18.729502], - [136.230468, -32.175613] + [136.23046875, -32.175612478499325], + [138.6474609375, -32.175612478499325], + [138.6474609375, -18.729501999072138], + [136.23046875, -18.729501999072138], + [136.23046875, -32.175612478499325] ] ] ] diff --git a/packages/turf-difference/test/in/split-polygon.geojson b/packages/turf-difference/test/in/split-polygon.geojson index 15930e5b7c..1164d05b27 100644 --- a/packages/turf-difference/test/in/split-polygon.geojson +++ b/packages/turf-difference/test/in/split-polygon.geojson @@ -14,11 +14,11 @@ "type": "Polygon", "coordinates": [ [ - [122.519531, -29.228891], - [144.228515, -29.228891], - [144.228515, -21.534848], - [122.519531, -21.534848], - [122.519531, -29.228891] + [122.51953124999999, -29.22889003019423], + [144.228515625, -29.22889003019423], + [144.228515625, -21.53484700204879], + [122.51953124999999, -21.53484700204879], + [122.51953124999999, -29.22889003019423] ] ] } @@ -36,11 +36,11 @@ "type": "Polygon", "coordinates": [ [ - [127.705078, -34.524662], - [139.570312, -34.524662], - [139.570312, -15.284186], - [127.705078, -15.284186], - [127.705078, -34.524662] + [127.705078125, -34.52466147177172], + [139.5703125, -34.52466147177172], + [139.5703125, -15.28418511407642], + [127.705078125, -15.28418511407642], + [127.705078125, -34.52466147177172] ] ] } diff --git a/packages/turf-difference/test/out/clip-polygons.geojson b/packages/turf-difference/test/out/clip-polygons.geojson index 73d1fef7ce..7af18c6097 100644 --- a/packages/turf-difference/test/out/clip-polygons.geojson +++ b/packages/turf-difference/test/out/clip-polygons.geojson @@ -14,11 +14,11 @@ "type": "Polygon", "coordinates": [ [ - [127.705078, -34.524662], - [139.570312, -34.524662], - [139.570312, -15.284186], - [127.705078, -15.284186], - [127.705078, -34.524662] + [127.705078125, -34.52466147177172], + [139.5703125, -34.52466147177172], + [139.5703125, -15.28418511407642], + [127.705078125, -15.28418511407642], + [127.705078125, -34.52466147177172] ] ] } @@ -36,32 +36,29 @@ "type": "Polygon", "coordinates": [ [ - [133.154296, -29.075376], - [144.228515, -29.075376], - [144.228515, -12.983148], - [133.154296, -12.983148], - [133.154296, -29.075376] + [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" - }, + "properties": { "fill-opacity": 1, "fill": "#0F0" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [139.570312, -29.075376], - [133.154295, -29.075376], - [133.154295, -15.284186], - [127.705078, -15.284186], - [127.705078, -34.524662], - [139.570312, -34.524662], - [139.570312, -29.075376] + [139.5703125, -29.07537518], + [133.15429688, -29.07537518], + [133.15429688, -15.284185110000001], + [127.70507813, -15.284185110000001], + [127.70507813, -34.52466147], + [139.5703125, -34.52466147], + [139.5703125, -29.07537518] ] ] } diff --git a/packages/turf-difference/test/out/issue-#721.geojson b/packages/turf-difference/test/out/issue-#721.geojson index dba3cb855e..ef5bc2c0ad 100644 --- a/packages/turf-difference/test/out/issue-#721.geojson +++ b/packages/turf-difference/test/out/issue-#721.geojson @@ -95,46 +95,64 @@ }, { "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, + "properties": { "fill-opacity": 1, "fill": "#0F0" }, "geometry": { - "type": "Polygon", + "type": "MultiPolygon", "coordinates": [ [ - [-0.646075, 44.804294], - [-0.645829, 44.804389], - [-0.646016, 44.804794], - [-0.646082, 44.805001], - [-0.646121, 44.805174], - [-0.646107, 44.805338], - [-0.646084, 44.805458], - [-0.646042, 44.805672], - [-0.646054, 44.805795], - [-0.646104, 44.805945], - [-0.646104, 44.805944], - [-0.646199, 44.806036], - [-0.646258, 44.806086], - [-0.64638, 44.806188], - [-0.646437, 44.806159], - [-0.64649, 44.80611], - [-0.64662, 44.806065], - [-0.646697, 44.806041], - [-0.6467, 44.805996], - [-0.646683, 44.805971], - [-0.646637, 44.805954], - [-0.646592, 44.805912], - [-0.646511, 44.805795], - [-0.646473, 44.805664], - [-0.646504, 44.805555], - [-0.64719, 44.805394], - [-0.647413, 44.805326], - [-0.647229, 44.805048], - [-0.646911, 44.804857], - [-0.646599, 44.804737], - [-0.646284, 44.804219], - [-0.646075, 44.804294] + [ + [-0.64610413, 44.8059449], + [-0.64619914, 44.80603699], + [-0.64625881, 44.80608668], + [-0.6463809, 44.8061882], + [-0.646437, 44.806159], + [-0.64649, 44.806110000000004], + [-0.64662, 44.806065000000004], + [-0.6466971, 44.806041300000004], + [-0.6467005, 44.8059967], + [-0.6466831000000001, 44.8059719], + [-0.6466376, 44.8059546], + [-0.6465922000000001, 44.805912400000004], + [-0.6465119, 44.8057959], + [-0.6464734, 44.8056645], + [-0.6465049, 44.8055554], + [-0.6471907, 44.8053946], + [-0.6474134, 44.805326], + [-0.6472295, 44.805048400000004], + [-0.6469113, 44.8048572], + [-0.6465997, 44.8047375], + [-0.6462847, 44.8042192], + [-0.6460750000000001, 44.8042943], + [-0.645829, 44.8043891], + [-0.6460168000000001, 44.8047948], + [-0.6460827, 44.8050017], + [-0.6461218, 44.8051741], + [-0.6461158300000001, 44.8052416], + [-0.64610794, 44.805338580000004], + [-0.6460936700000001, 44.80541109], + [-0.6460848, 44.8054585], + [-0.64604712, 44.80564768], + [-0.64604223, 44.80567256], + [-0.6460543, 44.80579531], + [-0.64606909, 44.80583985], + [-0.64610413, 44.8059449] + ] + ], + [ + [ + [-0.6461073, 44.8053383], + [-0.64611588, 44.8052411], + [-0.6461158300000001, 44.8052416], + [-0.6461073, 44.8053383] + ] + ], + [ + [ + [-0.6460421000000001, 44.8056729], + [-0.64604717, 44.80564744], + [-0.64604712, 44.80564768], + [-0.6460421000000001, 44.8056729] + ] ] ] } diff --git a/packages/turf-difference/test/out/multi-polygon-input.geojson b/packages/turf-difference/test/out/multi-polygon-input.geojson index 8f41c4b32d..55f90acaa8 100644 --- a/packages/turf-difference/test/out/multi-polygon-input.geojson +++ b/packages/turf-difference/test/out/multi-polygon-input.geojson @@ -15,20 +15,20 @@ "coordinates": [ [ [ - [123.134765, -25.562266], - [136.142578, -25.562266], - [136.142578, -13.068777], - [123.134765, -13.068777], - [123.134765, -25.562266] + [123.134765625, -25.562265014427492], + [136.142578125, -25.562265014427492], + [136.142578125, -13.068776734357694], + [123.134765625, -13.068776734357694], + [123.134765625, -25.562265014427492] ] ], [ [ - [119.53125, -39.571823], - [134.560546, -39.571823], - [134.560546, -28.381736], - [119.53125, -28.381736], - [119.53125, -39.571823] + [119.53125, -39.57182223734373], + [134.560546875, -39.57182223734373], + [134.560546875, -28.38173504322308], + [119.53125, -28.38173504322308], + [119.53125, -39.57182223734373] ] ] ] @@ -47,48 +47,45 @@ "type": "Polygon", "coordinates": [ [ - [126.298828, -35.817814], - [131.835937, -35.817814], - [131.835937, -18.396231], - [126.298828, -18.396231], - [126.298828, -35.817814] + [126.298828125, -35.81781315869662], + [131.8359375, -35.81781315869662], + [131.8359375, -18.396230138028812], + [126.298828125, -18.396230138028812], + [126.298828125, -35.81781315869662] ] ] } }, { "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, + "properties": { "fill-opacity": 1, "fill": "#0F0" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ - [136.142578, -13.068777], - [123.134765, -13.068777], - [123.134765, -25.562266], - [126.298828, -25.562266], - [126.298828, -18.396231], - [131.835937, -18.396231], - [131.835937, -25.562266], - [136.142578, -25.562266], - [136.142578, -13.068777] + [136.14257813, -13.06877673], + [123.13476563, -13.06877673], + [123.13476563, -25.56226501], + [126.29882813, -25.56226501], + [126.29882813, -18.39623014], + [131.8359375, -18.39623014], + [131.8359375, -25.56226501], + [136.14257813, -25.56226501], + [136.14257813, -13.06877673] ] ], [ [ - [134.560546, -28.381736], - [131.835937, -28.381736], - [131.835937, -35.817814], - [126.298828, -35.817814], - [126.298828, -28.381736], - [119.53125, -28.381736], - [119.53125, -39.571823], - [134.560546, -39.571823], - [134.560546, -28.381736] + [134.56054688, -28.381735040000002], + [131.8359375, -28.381735040000002], + [131.8359375, -35.81781316], + [126.29882813, -35.81781316], + [126.29882813, -28.381735040000002], + [119.53125, -28.381735040000002], + [119.53125, -39.57182224], + [134.56054688, -39.57182224], + [134.56054688, -28.381735040000002] ] ] ] diff --git a/packages/turf-difference/test/out/multi-polygon-target.geojson b/packages/turf-difference/test/out/multi-polygon-target.geojson index 063066d5c3..4a6f0b2acb 100644 --- a/packages/turf-difference/test/out/multi-polygon-target.geojson +++ b/packages/turf-difference/test/out/multi-polygon-target.geojson @@ -14,18 +14,18 @@ "type": "Polygon", "coordinates": [ [ - [127.661132, -30.713504], - [140.756835, -30.713504], - [140.756835, -20.220966], - [127.661132, -20.220966], - [127.661132, -30.713504] + [127.66113281249999, -30.713503990354965], + [140.7568359375, -30.713503990354965], + [140.7568359375, -20.2209657795223], + [127.66113281249999, -20.2209657795223], + [127.66113281249999, -30.713503990354965] ], [ - [132.385253, -27.313214], - [132.385253, -24.467151], - [135.131835, -24.467151], - [135.131835, -27.313214], - [132.385253, -27.313214] + [132.38525390625, -27.313213898568247], + [135.1318359375, -27.313213898568247], + [135.1318359375, -24.467150664738988], + [132.38525390625, -24.467150664738988], + [132.38525390625, -27.313213898568247] ] ] } @@ -44,20 +44,20 @@ "coordinates": [ [ [ - [128.891601, -31.840233], - [130.649414, -31.840233], - [130.649414, -18.646246], - [128.891601, -18.646246], - [128.891601, -31.840233] + [128.8916015625, -31.84023266790935], + [130.6494140625, -31.84023266790935], + [130.6494140625, -18.646245142670598], + [128.8916015625, -18.646245142670598], + [128.8916015625, -31.84023266790935] ] ], [ [ - [136.230468, -32.175613], - [138.64746, -32.175613], - [138.64746, -18.729502], - [136.230468, -18.729502], - [136.230468, -32.175613] + [136.23046875, -32.175612478499325], + [138.6474609375, -32.175612478499325], + [138.6474609375, -18.729501999072138], + [136.23046875, -18.729501999072138], + [136.23046875, -32.175612478499325] ] ] ] @@ -65,45 +65,42 @@ }, { "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, + "properties": { "fill-opacity": 1, "fill": "#0F0" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ - [128.891601, -20.220966], - [127.661132, -20.220966], - [127.661132, -30.713504], - [128.891601, -30.713504], - [128.891601, -20.220966] + [128.89160156, -20.22096578], + [127.66113281, -20.22096578], + [127.66113281, -30.71350399], + [128.89160156, -30.71350399], + [128.89160156, -20.22096578] ] ], [ [ - [136.230468, -20.220966], - [130.649414, -20.220966], - [130.649414, -30.713504], - [136.230468, -30.713504], - [136.230468, -20.220966] + [136.23046875, -20.22096578], + [130.64941406, -20.22096578], + [130.64941406, -30.71350399], + [136.23046875, -30.71350399], + [136.23046875, -20.22096578] ], [ - [132.385253, -24.467151], - [135.131835, -24.467151], - [135.131835, -27.313214], - [132.385253, -27.313214], - [132.385253, -24.467151] + [132.38525391, -24.46715066], + [135.13183594, -24.46715066], + [135.13183594, -27.3132139], + [132.38525391, -27.3132139], + [132.38525391, -24.46715066] ] ], [ [ - [140.756835, -20.220966], - [138.64746, -20.220966], - [138.64746, -30.713504], - [140.756835, -30.713504], - [140.756835, -20.220966] + [140.75683594, -20.22096578], + [138.64746094, -20.22096578], + [138.64746094, -30.71350399], + [140.75683594, -30.71350399], + [140.75683594, -20.22096578] ] ] ] diff --git a/packages/turf-difference/test/out/split-polygon.geojson b/packages/turf-difference/test/out/split-polygon.geojson index 71bc594bc7..fd91c76b09 100644 --- a/packages/turf-difference/test/out/split-polygon.geojson +++ b/packages/turf-difference/test/out/split-polygon.geojson @@ -14,11 +14,11 @@ "type": "Polygon", "coordinates": [ [ - [122.519531, -29.228891], - [144.228515, -29.228891], - [144.228515, -21.534848], - [122.519531, -21.534848], - [122.519531, -29.228891] + [122.51953124999999, -29.22889003019423], + [144.228515625, -29.22889003019423], + [144.228515625, -21.53484700204879], + [122.51953124999999, -21.53484700204879], + [122.51953124999999, -29.22889003019423] ] ] } @@ -36,40 +36,37 @@ "type": "Polygon", "coordinates": [ [ - [127.705078, -34.524662], - [139.570312, -34.524662], - [139.570312, -15.284186], - [127.705078, -15.284186], - [127.705078, -34.524662] + [127.705078125, -34.52466147177172], + [139.5703125, -34.52466147177172], + [139.5703125, -15.28418511407642], + [127.705078125, -15.28418511407642], + [127.705078125, -34.52466147177172] ] ] } }, { "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, + "properties": { "fill-opacity": 1, "fill": "#0F0" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ - [127.705078, -21.534848], - [122.519531, -21.534848], - [122.519531, -29.228891], - [127.705078, -29.228891], - [127.705078, -21.534848] + [127.70507813, -21.534847], + [122.51953125, -21.534847], + [122.51953125, -29.228890030000002], + [127.70507813, -29.228890030000002], + [127.70507813, -21.534847] ] ], [ [ - [144.228515, -21.534848], - [139.570312, -21.534848], - [139.570312, -29.228891], - [144.228515, -29.228891], - [144.228515, -21.534848] + [144.22851563, -21.534847], + [139.5703125, -21.534847], + [139.5703125, -29.228890030000002], + [144.22851563, -29.228890030000002], + [144.22851563, -21.534847] ] ] ] diff --git a/packages/turf-internal/clipper2/index.ts b/packages/turf-internal/clipper2/index.ts index edf648b2d4..158a95cd6f 100644 --- a/packages/turf-internal/clipper2/index.ts +++ b/packages/turf-internal/clipper2/index.ts @@ -1,15 +1,13 @@ -import { PolyTree64, Path64, Paths64, PolyPath64 } from "clipper2-ts"; +import { PolyPathD, PathD, PathsD, PolyTreeD, areaD } from "clipper2-ts"; import { Polygon, MultiPolygon, Position } from "geojson"; -// Multiplier applied to lat lng before passing to clipper2. Implies -// calculations are limited to 6 decimal places. -const INT_MULT = 1_000_000; +const DEFAULT_PRECISION = 8; /** * Converts a multipolygon to a flattened array of clipper2 paths. */ -function multiPolygonToPaths(coords: Position[][][]): Paths64 { - const paths: Paths64 = []; +function multiPolygonToPaths(coords: Position[][][]): PathsD { + const paths: PathsD = []; for (const polygon of coords) { paths.push(...polygonToPaths(polygon)); @@ -21,32 +19,59 @@ function multiPolygonToPaths(coords: Position[][][]): Paths64 { /** * Converts a polygon to a flattened array of clipper2 paths. */ -function polygonToPaths(coords: Position[][]): Paths64 { - const paths: Paths64 = []; +function polygonToPaths(coords: Position[][]): PathsD { + const paths: PathsD = []; - for (const ring of coords) { - paths.push(ringToPath(ring)); + for (const [idx, ring] of coords.entries()) { + // Defensive checking against incorrectly wound Geojson polygons. + const checkedRing = + idx === 0 + ? enforceOuterRing(ringToPath(ring)) + : enforceInnerRing(ringToPath(ring)); + + paths.push(checkedRing); } return paths; } /** - * Converts a ring to a clipper2 paths. + * Make sure this ring is wound as an outer ring, according to clipper2 + * expectations. That is, clockwise. + */ +function enforceOuterRing(path: PathD): PathD { + if (areaD(path) < 0) { + // Leave original array untouched. + return [...path].reverse(); + } + + return path; +} + +/** + * Make sure this ring is wound as an inner ring, according to clipper2 + * expectations. That is, counter clockwise. + */ +function enforceInnerRing(path: PathD): PathD { + if (areaD(path) > 0) { + // Leave original array untouched. + return [...path].reverse(); + } + + return path; +} + +/** + * Converts a ring to a clipper2 path. */ -function ringToPath(ring: Position[]): Path64 { - return ring.map(([x, y]) => ({ - x: Math.trunc(x * INT_MULT), - y: Math.trunc(y * INT_MULT), - })); +function ringToPath(ring: Position[]): PathD { + return ring.map(([x, y]) => ({ x, y })); } /** * Construct the output Geojson based on a clipper2 tree. The tree is useful for propertly handing holes. */ -function polyTreeToGeoJSON( - polyTree: PolyTree64 -): Polygon | MultiPolygon | null { +function polyTreeToGeoJSON(polyTree: PolyTreeD): Polygon | MultiPolygon | null { const polygons: Position[][][] = []; // Process each top-level polygon (outer contours) @@ -79,11 +104,11 @@ function polyTreeToGeoJSON( }; } -function processPolyPath(polyPath: PolyPath64): Position[][] { +function processPolyPath(polyPath: PolyPathD): Position[][] { const rings: Position[][] = []; // Add the outer ring (contour) - const outerRing = pathToCoordinates(polyPath.polygon); + const outerRing = pathToCoordinates(polyPath.poly); if (outerRing.length > 0) { rings.push(outerRing); } @@ -92,7 +117,7 @@ function processPolyPath(polyPath: PolyPath64): Position[][] { for (let i = 0; i < polyPath.count; i++) { const child = polyPath.child(i); if (child && child.isHole) { - const holeRing = pathToCoordinates(child.polygon); + const holeRing = pathToCoordinates(child.poly); if (holeRing.length > 0) { rings.push(holeRing); } @@ -108,7 +133,7 @@ function processPolyPath(polyPath: PolyPath64): Position[][] { /** * Converts a clipper2 integer path to an array of Geojson Positions. */ -function pathToCoordinates(path: Path64 | null): Position[] { +function pathToCoordinates(path: PathD | null): Position[] { const coords: Position[] = []; if (!path || typeof path.length !== "number") { @@ -117,7 +142,7 @@ function pathToCoordinates(path: Path64 | null): Position[] { for (let i = 0; i < path.length; i++) { const pt = path[i]; - coords.push([Number(pt.x) / INT_MULT, Number(pt.y) / INT_MULT]); + coords.push([pt.x, pt.y]); } // GeoJSON requires the first and last coordinates to be identical (closed ring) @@ -132,4 +157,9 @@ function pathToCoordinates(path: Path64 | null): Position[] { return coords; } -export { multiPolygonToPaths, polygonToPaths, polyTreeToGeoJSON }; +export { + multiPolygonToPaths, + polygonToPaths, + polyTreeToGeoJSON, + DEFAULT_PRECISION, +}; diff --git a/packages/turf-intersect/index.ts b/packages/turf-intersect/index.ts index 8a76e4d8aa..f1268069ab 100644 --- a/packages/turf-intersect/index.ts +++ b/packages/turf-intersect/index.ts @@ -7,8 +7,9 @@ import { } from "geojson"; import { feature } from "@turf/helpers"; import { geomEach } from "@turf/meta"; -import { FillRule, ClipType, PolyTree64, Clipper64 } from "clipper2-ts"; +import { FillRule, ClipType, PolyTreeD, ClipperD } from "clipper2-ts"; import { + DEFAULT_PRECISION, multiPolygonToPaths, polygonToPaths, polyTreeToGeoJSON, @@ -59,25 +60,25 @@ function intersect

( throw new Error("Must have at least 2 features"); } - const clipper = new Clipper64(); + const clipper = new ClipperD(DEFAULT_PRECISION); geomEach(features, (geom, idx) => { if (geom.type === "MultiPolygon") { if (idx === 0) { - clipper.addSubject(multiPolygonToPaths(geom.coordinates)); + clipper.addSubjectPaths(multiPolygonToPaths(geom.coordinates)); } else { - clipper.addClip(multiPolygonToPaths(geom.coordinates)); + clipper.addClipPaths(multiPolygonToPaths(geom.coordinates)); } } else { if (idx === 0) { - clipper.addSubject(polygonToPaths(geom.coordinates)); + clipper.addSubjectPaths(polygonToPaths(geom.coordinates)); } else { - clipper.addClip(polygonToPaths(geom.coordinates)); + clipper.addClipPaths(polygonToPaths(geom.coordinates)); } } }); - const tree: PolyTree64 = new PolyTree64(); + const tree = new PolyTreeD(); clipper.execute(ClipType.Intersection, FillRule.EvenOdd, tree); // Return the result as Polygon, MultiPolygon, or null as appropriate diff --git a/packages/turf-intersect/test/in/Intersect1.geojson b/packages/turf-intersect/test/in/Intersect1.geojson index 8a8a2e9dcc..b4ce111844 100644 --- a/packages/turf-intersect/test/in/Intersect1.geojson +++ b/packages/turf-intersect/test/in/Intersect1.geojson @@ -8,12 +8,12 @@ "type": "Polygon", "coordinates": [ [ - [-79.885712, 32.887659], - [-80.097886, 32.927436], - [-80.153504, 32.82825], - [-80.003129, 32.694288], - [-79.893952, 32.755519], - [-79.885712, 32.887659] + [-79.88571166992188, 32.887659962078956], + [-80.09788513183594, 32.927436533285565], + [-80.15350341796875, 32.82825010814964], + [-80.00312805175781, 32.69428812316933], + [-79.89395141601562, 32.75551989829049], + [-79.88571166992188, 32.887659962078956] ] ] } @@ -25,14 +25,14 @@ "type": "Polygon", "coordinates": [ [ - [-79.921418, 32.953944], - [-79.974289, 32.836904], - [-79.973603, 32.760716], - [-79.930344, 32.764758], - [-79.937897, 32.741082], - [-79.805375, 32.723176], - [-79.817734, 32.923402], - [-79.921418, 32.953944] + [-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] ] ] } diff --git a/packages/turf-intersect/test/in/Intersect2.geojson b/packages/turf-intersect/test/in/Intersect2.geojson index cadb53ef33..0d7218eef8 100644 --- a/packages/turf-intersect/test/in/Intersect2.geojson +++ b/packages/turf-intersect/test/in/Intersect2.geojson @@ -8,15 +8,15 @@ "type": "Polygon", "coordinates": [ [ - [-79.921418, 32.953944], - [-80.06836, 32.881893], - [-80.016861, 32.872667], - [-79.973603, 32.760716], - [-79.930344, 32.764758], - [-79.937897, 32.741082], - [-79.805375, 32.723176], - [-79.817734, 32.923402], - [-79.921418, 32.953944] + [-79.92141723632812, 32.953944317478246], + [-80.068359375, 32.88189375925038], + [-80.01686096191406, 32.87266705436184], + [-79.97360229492188, 32.76071688548088], + [-79.93034362792969, 32.76475877693074], + [-79.93789672851562, 32.74108223150125], + [-79.80537414550781, 32.7231762754146], + [-79.81773376464844, 32.923402043498875], + [-79.92141723632812, 32.953944317478246] ] ] } @@ -28,12 +28,12 @@ "type": "Polygon", "coordinates": [ [ - [-80.105439, 32.947606], - [-80.143891, 32.814978], - [-80.07454, 32.855364], - [-79.993516, 32.844404], - [-79.981843, 32.904956], - [-80.105439, 32.947606] + [-80.10543823242188, 32.94760622243483], + [-80.14389038085938, 32.8149783969858], + [-80.07453918457031, 32.85536439443039], + [-79.99351501464844, 32.84440429734253], + [-79.98184204101562, 32.90495631913751], + [-80.10543823242188, 32.94760622243483] ] ] } diff --git a/packages/turf-intersect/test/in/armenia.geojson b/packages/turf-intersect/test/in/armenia.geojson index b976db022c..65ece25ab3 100644 --- a/packages/turf-intersect/test/in/armenia.geojson +++ b/packages/turf-intersect/test/in/armenia.geojson @@ -12,24 +12,24 @@ "coordinates": [ [ [43.582746, 41.092143], - [43.752658, 40.740201], - [43.656436, 40.253564], - [44.400009, 40.005], - [44.79399, 39.713003], - [45.001987, 39.740004], - [45.298145, 39.471751], - [45.739978, 39.473999], - [45.735379, 39.319719], - [46.143623, 38.741201], - [46.50572, 38.770605], - [46.483499, 39.464155], - [46.034534, 39.628021], - [45.610012, 39.899994], - [45.891907, 40.218476], - [45.359175, 40.561504], - [45.560351, 40.81229], - [45.179496, 40.985354], [44.97248, 41.248129], + [45.179496, 40.985354], + [45.560351, 40.81229], + [45.359175, 40.561504], + [45.891907, 40.218476], + [45.610012, 39.899994], + [46.034534, 39.628021], + [46.483499, 39.464155], + [46.50572, 38.770605], + [46.143623, 38.741201], + [45.735379, 39.319719], + [45.739978, 39.473999], + [45.298145, 39.471751], + [45.001987, 39.740004], + [44.79399, 39.713003], + [44.400009, 40.005], + [43.656436, 40.253564], + [43.752658, 40.740201], [43.582746, 41.092143] ] ] @@ -42,11 +42,11 @@ "type": "Polygon", "coordinates": [ [ - [45.131835, 40.145289], - [53.393554, 40.145289], - [53.393554, 43.197167], - [45.131835, 43.197167], - [45.131835, 40.145289] + [45.1318359375, 40.1452892956766], + [45.1318359375, 43.197167282501276], + [53.3935546875, 43.197167282501276], + [53.3935546875, 40.1452892956766], + [45.1318359375, 40.1452892956766] ] ] } diff --git a/packages/turf-intersect/test/in/linestring.geojson b/packages/turf-intersect/test/in/linestring.geojson index 1f346204b9..48a9dc22ef 100644 --- a/packages/turf-intersect/test/in/linestring.geojson +++ b/packages/turf-intersect/test/in/linestring.geojson @@ -8,17 +8,17 @@ "type": "Polygon", "coordinates": [ [ - [4.861836, 45.784404], - [4.860033, 45.78213], - [4.859733, 45.779765], - [4.865655, 45.779047], - [4.874668, 45.779346], - [4.87677, 45.7821], - [4.888958, 45.784943], - [4.886684, 45.786918], - [4.882178, 45.787457], - [4.865441, 45.784344], - [4.861836, 45.784404] + [4.8618364334106445, 45.784404601286774], + [4.86544132232666, 45.78434474634739], + [4.88217830657959, 45.78745711798122], + [4.886684417724609, 45.78691845071048], + [4.888958930969238, 45.78494329284938], + [4.876770973205566, 45.782100139729486], + [4.874668121337891, 45.77934663219167], + [4.865655899047851, 45.77904732970034], + [4.859733581542969, 45.77976565298041], + [4.860033988952637, 45.78213006841216], + [4.8618364334106445, 45.784404601286774] ] ] } @@ -30,14 +30,14 @@ "type": "Polygon", "coordinates": [ [ - [4.865441, 45.784344], - [4.882178, 45.787457], - [4.883809, 45.790449], - [4.880805, 45.792574], - [4.875955, 45.788085], - [4.869647, 45.787427], - [4.863724, 45.785751], - [4.865441, 45.784344] + [4.86544132232666, 45.78434474634739], + [4.88217830657959, 45.78745711798122], + [4.8838090896606445, 45.79044961914028], + [4.880805015563965, 45.79257419743464], + [4.875955581665039, 45.78808555655138], + [4.869647026062012, 45.78742719215828], + [4.863724708557129, 45.78575132043314], + [4.86544132232666, 45.78434474634739] ] ] } diff --git a/packages/turf-intersect/test/in/multilinestring.geojson b/packages/turf-intersect/test/in/multilinestring.geojson index d7e20976c8..36caa2b935 100644 --- a/packages/turf-intersect/test/in/multilinestring.geojson +++ b/packages/turf-intersect/test/in/multilinestring.geojson @@ -8,17 +8,17 @@ "type": "Polygon", "coordinates": [ [ - [4.861836, 45.784404], - [4.860033, 45.78213], - [4.859733, 45.779765], - [4.865655, 45.779047], - [4.874668, 45.779346], - [4.87677, 45.7821], - [4.888958, 45.784943], - [4.886684, 45.786918], - [4.882178, 45.787457], - [4.865441, 45.784344], - [4.861836, 45.784404] + [4.8618364334106445, 45.784404601286774], + [4.86544132232666, 45.78434474634739], + [4.88217830657959, 45.78745711798122], + [4.886684417724609, 45.78691845071048], + [4.888958930969238, 45.78494329284938], + [4.876770973205566, 45.782100139729486], + [4.874668121337891, 45.77934663219167], + [4.865655899047851, 45.77904732970034], + [4.859733581542969, 45.77976565298041], + [4.860033988952637, 45.78213006841216], + [4.8618364334106445, 45.784404601286774] ] ] } @@ -30,18 +30,18 @@ "type": "Polygon", "coordinates": [ [ - [4.865441, 45.784344], - [4.882178, 45.787457], - [4.883809, 45.790449], - [4.880805, 45.792574], - [4.875955, 45.788085], - [4.869647, 45.787427], - [4.863724, 45.785751], - [4.860978, 45.785721], - [4.860033, 45.78213], - [4.861836, 45.784404], - [4.861836, 45.785033], - [4.865441, 45.784344] + [4.86544132232666, 45.78434474634739], + [4.88217830657959, 45.78745711798122], + [4.8838090896606445, 45.79044961914028], + [4.880805015563965, 45.79257419743464], + [4.875955581665039, 45.78808555655138], + [4.869647026062012, 45.78742719215828], + [4.863724708557129, 45.78575132043314], + [4.860978126525879, 45.78572139369446], + [4.860033988952637, 45.78213006841216], + [4.8618364334106445, 45.784404601286774], + [4.8618364334106445, 45.78503307427041], + [4.86544132232666, 45.78434474634739] ] ] } diff --git a/packages/turf-intersect/test/in/multipoint.geojson b/packages/turf-intersect/test/in/multipoint.geojson index 86e05c28bd..67cf565379 100644 --- a/packages/turf-intersect/test/in/multipoint.geojson +++ b/packages/turf-intersect/test/in/multipoint.geojson @@ -8,13 +8,13 @@ "type": "Polygon", "coordinates": [ [ - [4.845099, 45.777939], - [4.854154, 45.772492], - [4.858188, 45.772881], - [4.859991, 45.784614], - [4.855012, 45.784464], - [4.849648, 45.782459], - [4.845099, 45.777939] + [4.845099449157715, 45.77793989651294], + [4.849648475646973, 45.78245928286134], + [4.855012893676758, 45.78446445616189], + [4.859991073608398, 45.784614093068555], + [4.858188629150391, 45.77288134093866], + [4.854154586791992, 45.77249220227275], + [4.845099449157715, 45.77793989651294] ] ] } @@ -26,12 +26,12 @@ "type": "Polygon", "coordinates": [ [ - [4.845099, 45.777939], - [4.840679, 45.771743], - [4.848017, 45.767133], - [4.854154, 45.772492], - [4.846601, 45.771983], - [4.845099, 45.777939] + [4.845099449157715, 45.77793989651294], + [4.840679168701172, 45.771743851052996], + [4.848017692565918, 45.767133786097716], + [4.854154586791992, 45.77249220227275], + [4.846601486206055, 45.771983324535846], + [4.845099449157715, 45.77793989651294] ] ] } diff --git a/packages/turf-intersect/test/in/multipolygon-input.geojson b/packages/turf-intersect/test/in/multipolygon-input.geojson index ebc524fd2e..98575779d6 100644 --- a/packages/turf-intersect/test/in/multipolygon-input.geojson +++ b/packages/turf-intersect/test/in/multipolygon-input.geojson @@ -9,22 +9,22 @@ "coordinates": [ [ [ - [2.327384, 48.871489], - [2.316055, 48.87307], - [2.315025, 48.851839], - [2.349357, 48.845965], - [2.350044, 48.856131], - [2.350044, 48.861552], - [2.327384, 48.871489] + [2.3273849487304688, 48.87148983809234], + [2.3160552978515625, 48.87307055723444], + [2.3150253295898438, 48.85183958955198], + [2.3493576049804688, 48.845965604118284], + [2.3500442504882812, 48.85613168160397], + [2.3500442504882812, 48.8615527456014], + [2.3273849487304688, 48.87148983809234] ] ], [ [ - [2.336311, 48.876909], - [2.351417, 48.865166], - [2.359657, 48.873522], - [2.34764, 48.878489], - [2.336311, 48.876909] + [2.3363113403320312, 48.87690923865779], + [2.3514175415039062, 48.86516646209463], + [2.3596572875976562, 48.873522182101965], + [2.3476409912109375, 48.878489786571116], + [2.3363113403320312, 48.87690923865779] ] ] ] @@ -38,20 +38,20 @@ "coordinates": [ [ [ - [2.325668, 48.876909], - [2.323951, 48.867876], - [2.352104, 48.854324], - [2.35794, 48.861552], - [2.341117, 48.882102], - [2.325668, 48.876909] + [2.3256683349609375, 48.87690923865779], + [2.3239517211914062, 48.86787657822752], + [2.3521041870117188, 48.85432452980058], + [2.357940673828125, 48.8615527456014], + [2.3411178588867188, 48.882102279983364], + [2.3256683349609375, 48.87690923865779] ] ], [ [ - [2.36206, 48.852291], - [2.37339, 48.847321], - [2.37339, 48.854776], - [2.36206, 48.852291] + [2.362060546875, 48.85229140604385], + [2.3733901977539062, 48.8473212003792], + [2.3733901977539062, 48.854776323867306], + [2.362060546875, 48.85229140604385] ] ] ] diff --git a/packages/turf-intersect/test/in/no-overlap.geojson b/packages/turf-intersect/test/in/no-overlap.geojson index da8948c40f..917fb86d99 100644 --- a/packages/turf-intersect/test/in/no-overlap.geojson +++ b/packages/turf-intersect/test/in/no-overlap.geojson @@ -8,11 +8,11 @@ "type": "Polygon", "coordinates": [ [ - [92.680664, 53.435719], - [93.032226, 53.435719], - [93.032226, 53.514184], - [92.680664, 53.514184], - [92.680664, 53.435719] + [92.6806640625, 53.4357192066942], + [92.6806640625, 53.51418452077113], + [93.0322265625, 53.51418452077113], + [93.0322265625, 53.4357192066942], + [92.6806640625, 53.4357192066942] ] ] } @@ -24,11 +24,11 @@ "type": "Polygon", "coordinates": [ [ - [93.478546, 53.628353], - [93.680419, 53.628353], - [93.680419, 53.741401], - [93.478546, 53.741401], - [93.478546, 53.628353] + [93.47854614257812, 53.628353173374194], + [93.47854614257812, 53.74140157486066], + [93.680419921875, 53.74140157486066], + [93.680419921875, 53.628353173374194], + [93.47854614257812, 53.628353173374194] ] ] } diff --git a/packages/turf-intersect/test/in/output-multipolygon.geojson b/packages/turf-intersect/test/in/output-multipolygon.geojson index 57699b16f4..92e2aacde1 100644 --- a/packages/turf-intersect/test/in/output-multipolygon.geojson +++ b/packages/turf-intersect/test/in/output-multipolygon.geojson @@ -8,11 +8,11 @@ "type": "Polygon", "coordinates": [ [ - [129.023437, -27.371768], - [138.339843, -27.371768], - [138.339843, -22.431341], - [129.023437, -22.431341], - [129.023437, -27.371768] + [129.0234375, -27.371767300523032], + [138.33984375, -27.371767300523032], + [138.33984375, -22.43134015636061], + [129.0234375, -22.43134015636061], + [129.0234375, -27.371767300523032] ] ] } @@ -24,18 +24,18 @@ "type": "Polygon", "coordinates": [ [ - [124.233398, -34.921972], - [143.4375, -34.957996], - [143.261718, -13.154377], - [124.233398, -12.768947], - [124.233398, -34.921972] + [124.23339843749999, -34.921971036163754], + [143.4375, -34.95799531086791], + [143.26171875, -13.154376055418515], + [124.23339843749999, -12.768946439455943], + [124.23339843749999, -34.921971036163754] ], [ - [130.297851, -29.954935], - [130.297851, -18.020528], - [137.24121, -18.020528], - [137.24121, -29.954935], - [130.297851, -29.954935] + [130.2978515625, -29.95493454965612], + [130.2978515625, -18.020527657852327], + [137.2412109375, -18.020527657852327], + [137.2412109375, -29.95493454965612], + [130.2978515625, -29.95493454965612] ] ] } diff --git a/packages/turf-intersect/test/in/point.geojson b/packages/turf-intersect/test/in/point.geojson index 6e711ce62f..5c7f382495 100644 --- a/packages/turf-intersect/test/in/point.geojson +++ b/packages/turf-intersect/test/in/point.geojson @@ -8,13 +8,13 @@ "type": "Polygon", "coordinates": [ [ - [4.845099, 45.777939], - [4.854154, 45.772492], - [4.858188, 45.772881], - [4.859991, 45.784614], - [4.855012, 45.784464], - [4.849648, 45.782459], - [4.845099, 45.777939] + [4.845099449157715, 45.77793989651294], + [4.849648475646973, 45.78245928286134], + [4.855012893676758, 45.78446445616189], + [4.859991073608398, 45.784614093068555], + [4.858188629150391, 45.77288134093866], + [4.854154586791992, 45.77249220227275], + [4.845099449157715, 45.77793989651294] ] ] } @@ -26,14 +26,14 @@ "type": "Polygon", "coordinates": [ [ - [4.859991, 45.784614], - [4.864926, 45.784644], - [4.882736, 45.787906], - [4.88398, 45.790359], - [4.880547, 45.792514], - [4.875183, 45.787906], - [4.865698, 45.78611], - [4.859991, 45.784614] + [4.859991073608398, 45.784614093068555], + [4.86569881439209, 45.78611044004426], + [4.87518310546875, 45.787906003397154], + [4.880547523498535, 45.79251435126729], + [4.883980751037598, 45.7903598464431], + [4.8827362060546875, 45.787906003397154], + [4.864926338195801, 45.78464402040167], + [4.859991073608398, 45.784614093068555] ] ] } diff --git a/packages/turf-intersect/test/out/Intersect1.geojson b/packages/turf-intersect/test/out/Intersect1.geojson index 62a2873f60..c5a89dc3de 100644 --- a/packages/turf-intersect/test/out/Intersect1.geojson +++ b/packages/turf-intersect/test/out/Intersect1.geojson @@ -3,65 +3,56 @@ "features": [ { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#F00" - }, + "properties": { "fill-opacity": 0.5, "fill": "#F00" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [-79.885712, 32.887659], - [-80.097886, 32.927436], - [-80.153504, 32.82825], - [-80.003129, 32.694288], - [-79.893952, 32.755519], - [-79.885712, 32.887659] + [-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" - }, + "properties": { "fill-opacity": 0.5, "fill": "#00F" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [-79.921418, 32.953944], - [-79.974289, 32.836904], - [-79.973603, 32.760716], - [-79.930344, 32.764758], - [-79.937897, 32.741082], - [-79.805375, 32.723176], - [-79.817734, 32.923402], - [-79.921418, 32.953944] + [-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" - }, + "properties": { "fill-opacity": 1, "fill": "#0F0" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [-79.893952, 32.755519], - [-79.885712, 32.887659], - [-79.946235, 32.899005], - [-79.974289, 32.836903], - [-79.973603, 32.760716], - [-79.930344, 32.764758], - [-79.937897, 32.741082], - [-79.923227, 32.739099], - [-79.893952, 32.755519] + [-79.89395142000001, 32.7555199], + [-79.88571167, 32.88765996], + [-79.94623496, 32.89900637], + [-79.97428894000001, 32.8369045], + [-79.97360229, 32.76071689], + [-79.93034363, 32.76475878], + [-79.93789673, 32.74108223], + [-79.9232278, 32.73910022], + [-79.89395142000001, 32.7555199] ] ] } diff --git a/packages/turf-intersect/test/out/Intersect2.geojson b/packages/turf-intersect/test/out/Intersect2.geojson index 067345dfbb..b31e1b33cc 100644 --- a/packages/turf-intersect/test/out/Intersect2.geojson +++ b/packages/turf-intersect/test/out/Intersect2.geojson @@ -3,64 +3,55 @@ "features": [ { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#F00" - }, + "properties": { "fill-opacity": 0.5, "fill": "#F00" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [-79.921418, 32.953944], - [-80.06836, 32.881893], - [-80.016861, 32.872667], - [-79.973603, 32.760716], - [-79.930344, 32.764758], - [-79.937897, 32.741082], - [-79.805375, 32.723176], - [-79.817734, 32.923402], - [-79.921418, 32.953944] + [-79.92141723632812, 32.953944317478246], + [-80.068359375, 32.88189375925038], + [-80.01686096191406, 32.87266705436184], + [-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": 0.5, - "fill": "#00F" - }, + "properties": { "fill-opacity": 0.5, "fill": "#00F" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [-80.105439, 32.947606], - [-80.143891, 32.814978], - [-80.07454, 32.855364], - [-79.993516, 32.844404], - [-79.981843, 32.904956], - [-80.105439, 32.947606] + [-80.10543823242188, 32.94760622243483], + [-80.14389038085938, 32.8149783969858], + [-80.07453918457031, 32.85536439443039], + [-79.99351501464844, 32.84440429734253], + [-79.98184204101562, 32.90495631913751], + [-80.10543823242188, 32.94760622243483] ] ] } }, { "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, + "properties": { "fill-opacity": 1, "fill": "#0F0" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [-79.981843, 32.904956], - [-80.005015, 32.912952], - [-80.06836, 32.881892], - [-80.016861, 32.872667], - [-80.006624, 32.846176], - [-79.993516, 32.844403], - [-79.981843, 32.904956] + [-79.98184204, 32.904956320000004], + [-80.00501604, 32.91295307], + [-80.06835937, 32.881893760000004], + [-80.01686096, 32.872667050000004], + [-80.00662521, 32.8461777], + [-79.99351501, 32.8444043], + [-79.98184204, 32.904956320000004] ] ] } diff --git a/packages/turf-intersect/test/out/Intersect3.geojson b/packages/turf-intersect/test/out/Intersect3.geojson index 418c139273..a6ec49cc5b 100644 --- a/packages/turf-intersect/test/out/Intersect3.geojson +++ b/packages/turf-intersect/test/out/Intersect3.geojson @@ -3,10 +3,7 @@ "features": [ { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#F00" - }, + "properties": { "fill-opacity": 0.5, "fill": "#F00" }, "geometry": { "coordinates": [ [ @@ -65,10 +62,7 @@ }, { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#00F" - }, + "properties": { "fill-opacity": 0.5, "fill": "#00F" }, "geometry": { "coordinates": [ [ @@ -95,47 +89,44 @@ }, { "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, + "properties": { "fill-opacity": 1, "fill": "#0F0" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ - [-79.911976, 32.892582], - [-79.953993, 32.900459], - [-79.972951, 32.869335], + [-79.91197654, 32.89258392], + [-79.95399275, 32.90046089], + [-79.97295104, 32.86933504], [-79.941087, 32.866098], - [-79.934086, 32.842135], - [-79.911976, 32.892582] + [-79.93408666, 32.84213624], + [-79.91197654, 32.89258392] ] ], [ [ - [-79.965252, 32.807257], - [-79.964808, 32.8352], - [-79.986911, 32.846414], - [-79.993144, 32.836181], + [-79.965252, 32.807258], + [-79.964808, 32.835201], + [-79.98691138, 32.84641486], + [-79.99314422, 32.83618174], [-79.984315, 32.8352], - [-79.993668, 32.831205], - [-79.986374, 32.805583], - [-79.965252, 32.807257] + [-79.99366865, 32.83120562], + [-79.9863747, 32.805584], + [-79.965252, 32.807258] ] ], [ [ - [-79.893951, 32.755519], - [-79.893596, 32.761199], - [-79.917402, 32.785024], - [-79.916897, 32.783296], - [-79.97513, 32.766084], + [-79.893951, 32.755520000000004], + [-79.89359686, 32.76119969], + [-79.91740183, 32.78502503], + [-79.916897, 32.783297], + [-79.9751301, 32.76608481], [-79.973602, 32.760717], - [-79.930344, 32.764758], + [-79.930344, 32.764759], [-79.937897, 32.741082], - [-79.923226, 32.739099], - [-79.893951, 32.755519] + [-79.92322798000001, 32.73909997], + [-79.893951, 32.755520000000004] ] ] ] diff --git a/packages/turf-intersect/test/out/armenia.geojson b/packages/turf-intersect/test/out/armenia.geojson index f19d55de36..78aadf9f12 100644 --- a/packages/turf-intersect/test/out/armenia.geojson +++ b/packages/turf-intersect/test/out/armenia.geojson @@ -4,34 +4,30 @@ { "type": "Feature", "id": "ARM", - "properties": { - "name": "Armenia", - "fill-opacity": 0.5, - "fill": "#F00" - }, + "properties": { "name": "Armenia", "fill-opacity": 0.5, "fill": "#F00" }, "geometry": { "type": "Polygon", "coordinates": [ [ [43.582746, 41.092143], - [43.752658, 40.740201], - [43.656436, 40.253564], - [44.400009, 40.005], - [44.79399, 39.713003], - [45.001987, 39.740004], - [45.298145, 39.471751], - [45.739978, 39.473999], - [45.735379, 39.319719], - [46.143623, 38.741201], - [46.50572, 38.770605], - [46.483499, 39.464155], - [46.034534, 39.628021], - [45.610012, 39.899994], - [45.891907, 40.218476], - [45.359175, 40.561504], - [45.560351, 40.81229], - [45.179496, 40.985354], [44.97248, 41.248129], + [45.179496, 40.985354], + [45.560351, 40.81229], + [45.359175, 40.561504], + [45.891907, 40.218476], + [45.610012, 39.899994], + [46.034534, 39.628021], + [46.483499, 39.464155], + [46.50572, 38.770605], + [46.143623, 38.741201], + [45.735379, 39.319719], + [45.739978, 39.473999], + [45.298145, 39.471751], + [45.001987, 39.740004], + [44.79399, 39.713003], + [44.400009, 40.005], + [43.656436, 40.253564], + [43.752658, 40.740201], [43.582746, 41.092143] ] ] @@ -39,40 +35,34 @@ }, { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#00F" - }, + "properties": { "fill-opacity": 0.5, "fill": "#00F" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [45.131835, 40.145289], - [53.393554, 40.145289], - [53.393554, 43.197167], - [45.131835, 43.197167], - [45.131835, 40.145289] + [45.1318359375, 40.1452892956766], + [45.1318359375, 43.197167282501276], + [53.3935546875, 43.197167282501276], + [53.3935546875, 40.1452892956766], + [45.1318359375, 40.1452892956766] ] ] } }, { "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, + "properties": { "fill-opacity": 1, "fill": "#0F0" }, "geometry": { "type": "Polygon", "coordinates": [ [ [45.891907, 40.218476], [45.359175, 40.561504], - [45.560351, 40.81229], + [45.560351000000004, 40.812290000000004], [45.179496, 40.985354], - [45.131835, 41.045852], - [45.131835, 40.145289], - [45.827128, 40.145289], + [45.13183594, 41.04585112], + [45.13183594, 40.1452893], + [45.827127940000004, 40.1452893], [45.891907, 40.218476] ] ] diff --git a/packages/turf-intersect/test/out/issue-1004.geojson b/packages/turf-intersect/test/out/issue-1004.geojson index f42d49307e..8ed90bbbb2 100644 --- a/packages/turf-intersect/test/out/issue-1004.geojson +++ b/packages/turf-intersect/test/out/issue-1004.geojson @@ -3,10 +3,7 @@ "features": [ { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#F00" - }, + "properties": { "fill-opacity": 0.5, "fill": "#F00" }, "geometry": { "type": "Polygon", "coordinates": [ @@ -22,10 +19,7 @@ }, { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#00F" - }, + "properties": { "fill-opacity": 0.5, "fill": "#00F" }, "geometry": { "type": "Polygon", "coordinates": [ @@ -124,20 +118,17 @@ }, { "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, + "properties": { "fill-opacity": 1, "fill": "#0F0" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [-114.757213, 32.619925], + [-114.75721300000001, 32.619926], [-114.757215, 32.619925], [-114.757217, 32.619925], - [-114.757217, 32.61986], - [-114.757213, 32.61974], - [-114.757213, 32.619925] + [-114.757217, 32.61986779], + [-114.75721300000001, 32.61975337], + [-114.75721300000001, 32.619926] ] ] } diff --git a/packages/turf-intersect/test/out/issue-412.geojson b/packages/turf-intersect/test/out/issue-412.geojson index 353979ba8f..afa271f7fb 100644 --- a/packages/turf-intersect/test/out/issue-412.geojson +++ b/packages/turf-intersect/test/out/issue-412.geojson @@ -14,10 +14,7 @@ ] ] }, - "properties": { - "fill-opacity": 0.5, - "fill": "#F00" - } + "properties": { "fill-opacity": 0.5, "fill": "#F00" } }, { "type": "Feature", @@ -32,26 +29,20 @@ ] ] }, - "properties": { - "fill-opacity": 0.5, - "fill": "#00F" - } + "properties": { "fill-opacity": 0.5, "fill": "#00F" } }, { "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, + "properties": { "fill-opacity": 1, "fill": "#0F0" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [11.167526, 9.853863], - [11.168736, 9.855072], - [11.076144, 9.856268], - [11.102596, 9.853863], - [11.167526, 9.853863] + [11.168736110000001, 9.85507303], + [11.07613686, 9.85626976], + [11.10259984, 9.85386306], + [11.1675253, 9.85386306], + [11.168736110000001, 9.85507303] ] ] } diff --git a/packages/turf-intersect/test/out/linestring.geojson b/packages/turf-intersect/test/out/linestring.geojson index 22865fdcc3..9eadf1e412 100644 --- a/packages/turf-intersect/test/out/linestring.geojson +++ b/packages/turf-intersect/test/out/linestring.geojson @@ -3,47 +3,41 @@ "features": [ { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#F00" - }, + "properties": { "fill-opacity": 0.5, "fill": "#F00" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [4.861836, 45.784404], - [4.860033, 45.78213], - [4.859733, 45.779765], - [4.865655, 45.779047], - [4.874668, 45.779346], - [4.87677, 45.7821], - [4.888958, 45.784943], - [4.886684, 45.786918], - [4.882178, 45.787457], - [4.865441, 45.784344], - [4.861836, 45.784404] + [4.8618364334106445, 45.784404601286774], + [4.86544132232666, 45.78434474634739], + [4.88217830657959, 45.78745711798122], + [4.886684417724609, 45.78691845071048], + [4.888958930969238, 45.78494329284938], + [4.876770973205566, 45.782100139729486], + [4.874668121337891, 45.77934663219167], + [4.865655899047851, 45.77904732970034], + [4.859733581542969, 45.77976565298041], + [4.860033988952637, 45.78213006841216], + [4.8618364334106445, 45.784404601286774] ] ] } }, { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#00F" - }, + "properties": { "fill-opacity": 0.5, "fill": "#00F" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [4.865441, 45.784344], - [4.882178, 45.787457], - [4.883809, 45.790449], - [4.880805, 45.792574], - [4.875955, 45.788085], - [4.869647, 45.787427], - [4.863724, 45.785751], - [4.865441, 45.784344] + [4.86544132232666, 45.78434474634739], + [4.88217830657959, 45.78745711798122], + [4.8838090896606445, 45.79044961914028], + [4.880805015563965, 45.79257419743464], + [4.875955581665039, 45.78808555655138], + [4.869647026062012, 45.78742719215828], + [4.863724708557129, 45.78575132043314], + [4.86544132232666, 45.78434474634739] ] ] } diff --git a/packages/turf-intersect/test/out/multilinestring.geojson b/packages/turf-intersect/test/out/multilinestring.geojson index 62448073d3..91006c9489 100644 --- a/packages/turf-intersect/test/out/multilinestring.geojson +++ b/packages/turf-intersect/test/out/multilinestring.geojson @@ -3,51 +3,45 @@ "features": [ { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#F00" - }, + "properties": { "fill-opacity": 0.5, "fill": "#F00" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [4.861836, 45.784404], - [4.860033, 45.78213], - [4.859733, 45.779765], - [4.865655, 45.779047], - [4.874668, 45.779346], - [4.87677, 45.7821], - [4.888958, 45.784943], - [4.886684, 45.786918], - [4.882178, 45.787457], - [4.865441, 45.784344], - [4.861836, 45.784404] + [4.8618364334106445, 45.784404601286774], + [4.86544132232666, 45.78434474634739], + [4.88217830657959, 45.78745711798122], + [4.886684417724609, 45.78691845071048], + [4.888958930969238, 45.78494329284938], + [4.876770973205566, 45.782100139729486], + [4.874668121337891, 45.77934663219167], + [4.865655899047851, 45.77904732970034], + [4.859733581542969, 45.77976565298041], + [4.860033988952637, 45.78213006841216], + [4.8618364334106445, 45.784404601286774] ] ] } }, { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#00F" - }, + "properties": { "fill-opacity": 0.5, "fill": "#00F" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [4.865441, 45.784344], - [4.882178, 45.787457], - [4.883809, 45.790449], - [4.880805, 45.792574], - [4.875955, 45.788085], - [4.869647, 45.787427], - [4.863724, 45.785751], - [4.860978, 45.785721], - [4.860033, 45.78213], - [4.861836, 45.784404], - [4.861836, 45.785033], - [4.865441, 45.784344] + [4.86544132232666, 45.78434474634739], + [4.88217830657959, 45.78745711798122], + [4.8838090896606445, 45.79044961914028], + [4.880805015563965, 45.79257419743464], + [4.875955581665039, 45.78808555655138], + [4.869647026062012, 45.78742719215828], + [4.863724708557129, 45.78575132043314], + [4.860978126525879, 45.78572139369446], + [4.860033988952637, 45.78213006841216], + [4.8618364334106445, 45.784404601286774], + [4.8618364334106445, 45.78503307427041], + [4.86544132232666, 45.78434474634739] ] ] } diff --git a/packages/turf-intersect/test/out/multipoint.geojson b/packages/turf-intersect/test/out/multipoint.geojson index 8e5412d67e..02c9487141 100644 --- a/packages/turf-intersect/test/out/multipoint.geojson +++ b/packages/turf-intersect/test/out/multipoint.geojson @@ -3,41 +3,35 @@ "features": [ { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#F00" - }, + "properties": { "fill-opacity": 0.5, "fill": "#F00" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [4.845099, 45.777939], - [4.854154, 45.772492], - [4.858188, 45.772881], - [4.859991, 45.784614], - [4.855012, 45.784464], - [4.849648, 45.782459], - [4.845099, 45.777939] + [4.845099449157715, 45.77793989651294], + [4.849648475646973, 45.78245928286134], + [4.855012893676758, 45.78446445616189], + [4.859991073608398, 45.784614093068555], + [4.858188629150391, 45.77288134093866], + [4.854154586791992, 45.77249220227275], + [4.845099449157715, 45.77793989651294] ] ] } }, { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#00F" - }, + "properties": { "fill-opacity": 0.5, "fill": "#00F" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [4.845099, 45.777939], - [4.840679, 45.771743], - [4.848017, 45.767133], - [4.854154, 45.772492], - [4.846601, 45.771983], - [4.845099, 45.777939] + [4.845099449157715, 45.77793989651294], + [4.840679168701172, 45.771743851052996], + [4.848017692565918, 45.767133786097716], + [4.854154586791992, 45.77249220227275], + [4.846601486206055, 45.771983324535846], + [4.845099449157715, 45.77793989651294] ] ] } diff --git a/packages/turf-intersect/test/out/multipolygon-input.geojson b/packages/turf-intersect/test/out/multipolygon-input.geojson index e7135ee1a8..9e4705dcec 100644 --- a/packages/turf-intersect/test/out/multipolygon-input.geojson +++ b/packages/turf-intersect/test/out/multipolygon-input.geojson @@ -3,31 +3,28 @@ "features": [ { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#F00" - }, + "properties": { "fill-opacity": 0.5, "fill": "#F00" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ - [2.327384, 48.871489], - [2.316055, 48.87307], - [2.315025, 48.851839], - [2.349357, 48.845965], - [2.350044, 48.856131], - [2.350044, 48.861552], - [2.327384, 48.871489] + [2.3273849487304688, 48.87148983809234], + [2.3160552978515625, 48.87307055723444], + [2.3150253295898438, 48.85183958955198], + [2.3493576049804688, 48.845965604118284], + [2.3500442504882812, 48.85613168160397], + [2.3500442504882812, 48.8615527456014], + [2.3273849487304688, 48.87148983809234] ] ], [ [ - [2.336311, 48.876909], - [2.351417, 48.865166], - [2.359657, 48.873522], - [2.34764, 48.878489], - [2.336311, 48.876909] + [2.3363113403320312, 48.87690923865779], + [2.3514175415039062, 48.86516646209463], + [2.3596572875976562, 48.873522182101965], + [2.3476409912109375, 48.878489786571116], + [2.3363113403320312, 48.87690923865779] ] ] ] @@ -35,29 +32,26 @@ }, { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#00F" - }, + "properties": { "fill-opacity": 0.5, "fill": "#00F" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ - [2.325668, 48.876909], - [2.323951, 48.867876], - [2.352104, 48.854324], - [2.35794, 48.861552], - [2.341117, 48.882102], - [2.325668, 48.876909] + [2.3256683349609375, 48.87690923865779], + [2.3239517211914062, 48.86787657822752], + [2.3521041870117188, 48.85432452980058], + [2.357940673828125, 48.8615527456014], + [2.3411178588867188, 48.882102279983364], + [2.3256683349609375, 48.87690923865779] ] ], [ [ - [2.36206, 48.852291], - [2.37339, 48.847321], - [2.37339, 48.854776], - [2.36206, 48.852291] + [2.362060546875, 48.85229140604385], + [2.3733901977539062, 48.8473212003792], + [2.3733901977539062, 48.854776323867306], + [2.362060546875, 48.85229140604385] ] ] ] @@ -65,31 +59,28 @@ }, { "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, + "properties": { "fill-opacity": 1, "fill": "#0F0" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ - [2.353364, 48.867141], - [2.34444, 48.878042], - [2.336311, 48.876909], - [2.351417, 48.865166], - [2.353364, 48.867141] + [2.35336532, 48.86714165], + [2.3444407000000003, 48.878043330000004], + [2.33631134, 48.87690924], + [2.35141754, 48.86516646], + [2.35336532, 48.86714165] ] ], [ [ - [2.350044, 48.856131], - [2.350044, 48.861552], - [2.327384, 48.871489], - [2.324708, 48.871862], - [2.323951, 48.867876], - [2.34999, 48.855341], - [2.350044, 48.856131] + [2.35004425, 48.856131680000004], + [2.35004425, 48.86155275], + [2.32738495, 48.87148984], + [2.32470934, 48.87186314], + [2.32395172, 48.86787658], + [2.3499909, 48.85534182], + [2.35004425, 48.856131680000004] ] ] ] diff --git a/packages/turf-intersect/test/out/no-overlap.geojson b/packages/turf-intersect/test/out/no-overlap.geojson index d13608dd51..9870084d42 100644 --- a/packages/turf-intersect/test/out/no-overlap.geojson +++ b/packages/turf-intersect/test/out/no-overlap.geojson @@ -3,38 +3,32 @@ "features": [ { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#F00" - }, + "properties": { "fill-opacity": 0.5, "fill": "#F00" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [92.680664, 53.435719], - [93.032226, 53.435719], - [93.032226, 53.514184], - [92.680664, 53.514184], - [92.680664, 53.435719] + [92.6806640625, 53.4357192066942], + [92.6806640625, 53.51418452077113], + [93.0322265625, 53.51418452077113], + [93.0322265625, 53.4357192066942], + [92.6806640625, 53.4357192066942] ] ] } }, { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#00F" - }, + "properties": { "fill-opacity": 0.5, "fill": "#00F" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [93.478546, 53.628353], - [93.680419, 53.628353], - [93.680419, 53.741401], - [93.478546, 53.741401], - [93.478546, 53.628353] + [93.47854614257812, 53.628353173374194], + [93.47854614257812, 53.74140157486066], + [93.680419921875, 53.74140157486066], + [93.680419921875, 53.628353173374194], + [93.47854614257812, 53.628353173374194] ] ] } diff --git a/packages/turf-intersect/test/out/output-multipolygon.geojson b/packages/turf-intersect/test/out/output-multipolygon.geojson index fa1692a283..5123cd34e9 100644 --- a/packages/turf-intersect/test/out/output-multipolygon.geojson +++ b/packages/turf-intersect/test/out/output-multipolygon.geojson @@ -3,74 +3,65 @@ "features": [ { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#F00" - }, + "properties": { "fill-opacity": 0.5, "fill": "#F00" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [129.023437, -27.371768], - [138.339843, -27.371768], - [138.339843, -22.431341], - [129.023437, -22.431341], - [129.023437, -27.371768] + [129.0234375, -27.371767300523032], + [138.33984375, -27.371767300523032], + [138.33984375, -22.43134015636061], + [129.0234375, -22.43134015636061], + [129.0234375, -27.371767300523032] ] ] } }, { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#00F" - }, + "properties": { "fill-opacity": 0.5, "fill": "#00F" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [124.233398, -34.921972], - [143.4375, -34.957996], - [143.261718, -13.154377], - [124.233398, -12.768947], - [124.233398, -34.921972] + [124.23339843749999, -34.921971036163754], + [143.4375, -34.95799531086791], + [143.26171875, -13.154376055418515], + [124.23339843749999, -12.768946439455943], + [124.23339843749999, -34.921971036163754] ], [ - [130.297851, -29.954935], - [130.297851, -18.020528], - [137.24121, -18.020528], - [137.24121, -29.954935], - [130.297851, -29.954935] + [130.2978515625, -29.95493454965612], + [130.2978515625, -18.020527657852327], + [137.2412109375, -18.020527657852327], + [137.2412109375, -29.95493454965612], + [130.2978515625, -29.95493454965612] ] ] } }, { "type": "Feature", - "properties": { - "fill-opacity": 1, - "fill": "#0F0" - }, + "properties": { "fill-opacity": 1, "fill": "#0F0" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ - [130.297851, -22.431341], - [129.023437, -22.431341], - [129.023437, -27.371768], - [130.297851, -27.371768], - [130.297851, -22.431341] + [130.29785156, -22.43134016], + [129.0234375, -22.43134016], + [129.0234375, -27.371767300000002], + [130.29785156, -27.371767300000002], + [130.29785156, -22.43134016] ] ], [ [ - [138.339843, -22.431341], - [137.24121, -22.431341], - [137.24121, -27.371768], - [138.339843, -27.371768], - [138.339843, -22.431341] + [138.33984375, -22.43134016], + [137.24121094, -22.43134016], + [137.24121094, -27.371767300000002], + [138.33984375, -27.371767300000002], + [138.33984375, -22.43134016] ] ] ] diff --git a/packages/turf-intersect/test/out/point.geojson b/packages/turf-intersect/test/out/point.geojson index b82a78317e..74f3632784 100644 --- a/packages/turf-intersect/test/out/point.geojson +++ b/packages/turf-intersect/test/out/point.geojson @@ -3,43 +3,37 @@ "features": [ { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#F00" - }, + "properties": { "fill-opacity": 0.5, "fill": "#F00" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [4.845099, 45.777939], - [4.854154, 45.772492], - [4.858188, 45.772881], - [4.859991, 45.784614], - [4.855012, 45.784464], - [4.849648, 45.782459], - [4.845099, 45.777939] + [4.845099449157715, 45.77793989651294], + [4.849648475646973, 45.78245928286134], + [4.855012893676758, 45.78446445616189], + [4.859991073608398, 45.784614093068555], + [4.858188629150391, 45.77288134093866], + [4.854154586791992, 45.77249220227275], + [4.845099449157715, 45.77793989651294] ] ] } }, { "type": "Feature", - "properties": { - "fill-opacity": 0.5, - "fill": "#00F" - }, + "properties": { "fill-opacity": 0.5, "fill": "#00F" }, "geometry": { "type": "Polygon", "coordinates": [ [ - [4.859991, 45.784614], - [4.864926, 45.784644], - [4.882736, 45.787906], - [4.88398, 45.790359], - [4.880547, 45.792514], - [4.875183, 45.787906], - [4.865698, 45.78611], - [4.859991, 45.784614] + [4.859991073608398, 45.784614093068555], + [4.86569881439209, 45.78611044004426], + [4.87518310546875, 45.787906003397154], + [4.880547523498535, 45.79251435126729], + [4.883980751037598, 45.7903598464431], + [4.8827362060546875, 45.787906003397154], + [4.864926338195801, 45.78464402040167], + [4.859991073608398, 45.784614093068555] ] ] } diff --git a/packages/turf-union/index.ts b/packages/turf-union/index.ts index 54c971cda9..bf71b226ff 100644 --- a/packages/turf-union/index.ts +++ b/packages/turf-union/index.ts @@ -7,8 +7,9 @@ import { MultiPolygon, GeoJsonProperties, } from "geojson"; -import { FillRule, ClipType, PolyTree64, Clipper64 } from "clipper2-ts"; +import { FillRule, ClipType, PolyTreeD, ClipperD } from "clipper2-ts"; import { + DEFAULT_PRECISION, multiPolygonToPaths, polygonToPaths, polyTreeToGeoJSON, @@ -70,25 +71,25 @@ function union

( throw new Error("Must have at least 2 features"); } - const clipper = new Clipper64(); + const clipper = new ClipperD(DEFAULT_PRECISION); geomEach(features, (geom, idx) => { if (geom.type === "MultiPolygon") { if (idx === 0) { - clipper.addSubject(multiPolygonToPaths(geom.coordinates)); + clipper.addSubjectPaths(multiPolygonToPaths(geom.coordinates)); } else { - clipper.addClip(multiPolygonToPaths(geom.coordinates)); + clipper.addClipPaths(multiPolygonToPaths(geom.coordinates)); } } else { if (idx === 0) { - clipper.addSubject(polygonToPaths(geom.coordinates)); + clipper.addSubjectPaths(polygonToPaths(geom.coordinates)); } else { - clipper.addClip(polygonToPaths(geom.coordinates)); + clipper.addClipPaths(polygonToPaths(geom.coordinates)); } } }); - const tree: PolyTree64 = new PolyTree64(); + const tree = new PolyTreeD(); clipper.execute(ClipType.Union, FillRule.NonZero, tree); // Return the result as Polygon, MultiPolygon, or null as appropriate diff --git a/packages/turf-union/test/in/not-overlapping.geojson b/packages/turf-union/test/in/not-overlapping.geojson index 5b4209cd7c..e98d104a76 100644 --- a/packages/turf-union/test/in/not-overlapping.geojson +++ b/packages/turf-union/test/in/not-overlapping.geojson @@ -8,12 +8,12 @@ "type": "Polygon", "coordinates": [ [ - [-79.885711, 32.887659], - [-80.097885, 32.927436], - [-80.153503, 32.82825], - [-80.003128, 32.694288], - [-79.893951, 32.755519], - [-79.885711, 32.887659] + [-79.88571166992188, 32.887659962078956], + [-80.09788513183594, 32.927436533285565], + [-80.15350341796875, 32.82825010814964], + [-80.00312805175781, 32.69428812316933], + [-79.89395141601562, 32.75551989829049], + [-79.88571166992188, 32.887659962078956] ] ] } @@ -25,13 +25,13 @@ "type": "Polygon", "coordinates": [ [ - [-79.856185, 32.859978], - [-79.884338, 32.687931], - [-79.792327, 32.67984], - [-79.632339, 32.80459], - [-79.648818, 32.915908], - [-79.789581, 32.913603], - [-79.856185, 32.859978] + [-79.85618591308594, 32.85997876713845], + [-79.78958129882812, 32.913603231028915], + [-79.64881896972656, 32.915908931564864], + [-79.63233947753906, 32.804590457442565], + [-79.79232788085938, 32.679840539897484], + [-79.88433837890625, 32.687931474529464], + [-79.85618591308594, 32.85997876713845] ] ] } diff --git a/packages/turf-union/test/in/union1.geojson b/packages/turf-union/test/in/union1.geojson index 937d0986b9..b4ce111844 100644 --- a/packages/turf-union/test/in/union1.geojson +++ b/packages/turf-union/test/in/union1.geojson @@ -8,12 +8,12 @@ "type": "Polygon", "coordinates": [ [ - [-79.885712, 32.88766], - [-80.097885, 32.927437], - [-80.153503, 32.82825], - [-80.003128, 32.694288], - [-79.893951, 32.75552], - [-79.885712, 32.88766] + [-79.88571166992188, 32.887659962078956], + [-80.09788513183594, 32.927436533285565], + [-80.15350341796875, 32.82825010814964], + [-80.00312805175781, 32.69428812316933], + [-79.89395141601562, 32.75551989829049], + [-79.88571166992188, 32.887659962078956] ] ] } @@ -25,14 +25,14 @@ "type": "Polygon", "coordinates": [ [ - [-79.921417, 32.953944], - [-79.974289, 32.836905], - [-79.973602, 32.760717], - [-79.930344, 32.764759], - [-79.937897, 32.741082], - [-79.805374, 32.723176], - [-79.817734, 32.923402], - [-79.921417, 32.953944] + [-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] ] ] } diff --git a/packages/turf-union/test/in/union2.geojson b/packages/turf-union/test/in/union2.geojson index 6ad73a5682..ff33ee9c99 100644 --- a/packages/turf-union/test/in/union2.geojson +++ b/packages/turf-union/test/in/union2.geojson @@ -8,14 +8,14 @@ "type": "Polygon", "coordinates": [ [ - [-79.921417, 32.953944], - [-79.974289, 32.836905], - [-79.973602, 32.760717], - [-79.930344, 32.764759], - [-79.937897, 32.741082], - [-79.805374, 32.723176], - [-79.817734, 32.923402], - [-79.921417, 32.953944] + [-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] ] ] } @@ -27,12 +27,12 @@ "type": "Polygon", "coordinates": [ [ - [-80.105438, 32.947606], - [-80.14389, 32.814978], - [-80.074539, 32.855364], - [-79.993515, 32.844404], - [-79.981842, 32.904956], - [-80.105438, 32.947606] + [-80.10543823242188, 32.94760622243483], + [-80.14389038085938, 32.8149783969858], + [-80.07453918457031, 32.85536439443039], + [-79.99351501464844, 32.84440429734253], + [-79.98184204101562, 32.90495631913751], + [-80.10543823242188, 32.94760622243483] ] ] } @@ -44,12 +44,12 @@ "type": "Polygon", "coordinates": [ [ - [-79.920044, 32.937234], - [-80.031281, 32.936658], - [-79.990082, 32.772265], - [-79.902191, 32.843251], - [-79.966049, 32.874974], - [-79.920044, 32.937234] + [-79.9200439453125, 32.9372338139709], + [-80.03128051757812, 32.936657533381286], + [-79.99008178710938, 32.77226465992344], + [-79.90219116210938, 32.8432505241666], + [-79.96604919433594, 32.87497382061986], + [-79.9200439453125, 32.9372338139709] ] ] } @@ -61,12 +61,12 @@ "type": "Polygon", "coordinates": [ [ - [-79.950256, 32.970076], - [-80.001755, 32.732419], - [-79.84726, 32.75321], - [-79.82048, 32.848442], - [-79.854813, 32.923402], - [-79.950256, 32.970076] + [-79.95025634765625, 32.97007559940924], + [-80.00175476074217, 32.732418508353746], + [-79.84725952148438, 32.753210028851896], + [-79.82048034667969, 32.848442385344136], + [-79.85481262207031, 32.923402043498875], + [-79.95025634765625, 32.97007559940924] ] ] } diff --git a/packages/turf-union/test/in/union4.geojson b/packages/turf-union/test/in/union4.geojson index b42a98b0d3..bbefadf686 100644 --- a/packages/turf-union/test/in/union4.geojson +++ b/packages/turf-union/test/in/union4.geojson @@ -12,12 +12,12 @@ [-75.728, 45.331], [-75.719, 45.328], [-75.71, 45.331], - [-75.707454, 45.334818], + [-75.70745454545455, 45.33481818181818], [-75.702, 45.333], [-75.693, 45.336], [-75.689, 45.342], [-75.693, 45.349], - [-75.694451, 45.349322], + [-75.69445161290322, 45.34932258064516], [-75.692, 45.353], [-75.696, 45.36], [-75.705, 45.362], @@ -25,7 +25,7 @@ [-75.717, 45.353], [-75.714, 45.347], [-75.71244, 45.34648], - [-75.713422, 45.34476], + [-75.71342253521127, 45.344760563380284], [-75.719, 45.346], [-75.728, 45.344], [-75.732, 45.337] @@ -41,13 +41,13 @@ "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.706, 45.337], + [-75.71, 45.331], + [-75.719, 45.328], + [-75.728, 45.331], + [-75.732, 45.337], + [-75.728, 45.344], [-75.719, 45.346] ] ] diff --git a/packages/turf-union/test/out/not-overlapping.geojson b/packages/turf-union/test/out/not-overlapping.geojson index f57e507b3f..e27e248439 100644 --- a/packages/turf-union/test/out/not-overlapping.geojson +++ b/packages/turf-union/test/out/not-overlapping.geojson @@ -6,23 +6,23 @@ "coordinates": [ [ [ - [-79.893951, 32.755519], - [-79.885711, 32.887659], - [-80.097885, 32.927436], - [-80.153503, 32.828249], - [-80.003128, 32.694288], - [-79.893951, 32.755519] + [-79.89395142000001, 32.7555199], + [-79.88571167, 32.88765996], + [-80.09788513000001, 32.92743653], + [-80.15350342, 32.82825011], + [-80.00312805, 32.69428812], + [-79.89395142000001, 32.7555199] ] ], [ [ - [-79.632339, 32.804589], - [-79.648818, 32.915908], - [-79.789581, 32.913603], - [-79.856185, 32.859977], - [-79.884338, 32.687931], - [-79.792327, 32.67984], - [-79.632339, 32.804589] + [-79.63233948, 32.80459046], + [-79.64881897000001, 32.91590893], + [-79.7895813, 32.91360323], + [-79.85618591000001, 32.85997877], + [-79.88433838, 32.68793147], + [-79.79232788, 32.67984054], + [-79.63233948, 32.80459046] ] ] ] diff --git a/packages/turf-union/test/out/union1.geojson b/packages/turf-union/test/out/union1.geojson index 69d10e896b..950688740e 100644 --- a/packages/turf-union/test/out/union1.geojson +++ b/packages/turf-union/test/out/union1.geojson @@ -5,15 +5,15 @@ "type": "Polygon", "coordinates": [ [ - [-79.923226, 32.739099], - [-79.805374, 32.723176], - [-79.817734, 32.923402], - [-79.921417, 32.953944], - [-79.946235, 32.899005], - [-80.097885, 32.927436], - [-80.153503, 32.828249], - [-80.003128, 32.694288], - [-79.923226, 32.739099] + [-79.9232278, 32.73910022], + [-79.80537415, 32.723176280000004], + [-79.81773376, 32.92340204], + [-79.92141724, 32.95394432], + [-79.94623496, 32.89900637], + [-80.09788513000001, 32.92743653], + [-80.15350342, 32.82825011], + [-80.00312805, 32.69428812], + [-79.9232278, 32.73910022] ] ] } diff --git a/packages/turf-union/test/out/union2.geojson b/packages/turf-union/test/out/union2.geojson index 5160bbd69a..1f4f75dd45 100644 --- a/packages/turf-union/test/out/union2.geojson +++ b/packages/turf-union/test/out/union2.geojson @@ -5,21 +5,21 @@ "type": "Polygon", "coordinates": [ [ - [-79.817734, 32.923402], - [-79.910982, 32.95087], - [-79.950256, 32.970076], - [-79.957414, 32.937039], - [-80.031281, 32.936658], - [-80.027264, 32.92063], - [-80.105438, 32.947606], - [-80.14389, 32.814978], - [-80.074539, 32.855364], - [-80.008674, 32.846453], - [-79.991711, 32.778766], - [-80.001755, 32.732419], - [-79.937639, 32.741047], - [-79.805374, 32.723176], - [-79.817734, 32.923402] + [-79.81773376, 32.92340204], + [-79.91098505000001, 32.95087128], + [-79.95025635, 32.9700756], + [-79.95741485, 32.9370402], + [-80.03128052, 32.93665753], + [-80.02726390000001, 32.92063024], + [-80.10543823, 32.94760622], + [-80.14389038, 32.8149784], + [-80.07453918, 32.85536439], + [-80.00867472, 32.84645494], + [-79.99171138, 32.77876712], + [-80.00175476, 32.73241851], + [-79.93763757, 32.74104721], + [-79.80537415, 32.723176280000004], + [-79.81773376, 32.92340204] ] ] } diff --git a/packages/turf-union/test/out/union3.geojson b/packages/turf-union/test/out/union3.geojson index 25d21f518d..72bdf2a0fb 100644 --- a/packages/turf-union/test/out/union3.geojson +++ b/packages/turf-union/test/out/union3.geojson @@ -5,21 +5,21 @@ "type": "Polygon", "coordinates": [ [ - [-79.632339, 32.804589], + [-79.632339, 32.80459], [-79.648819, 32.915909], [-79.789581, 32.913603], - [-79.815824, 32.892473], + [-79.8158248, 32.89247398], [-79.817734, 32.923402], [-79.921417, 32.953944], - [-79.946235, 32.899005], - [-80.097885, 32.927436], - [-80.153503, 32.828249], + [-79.94623485, 32.899006480000004], + [-80.097885, 32.927437], + [-80.153503, 32.828250000000004], [-80.003128, 32.694288], - [-79.923226, 32.739099], - [-79.876987, 32.732852], + [-79.92322798000001, 32.73909997], + [-79.8769876, 32.73285215], [-79.884338, 32.687931], [-79.792328, 32.679841], - [-79.632339, 32.804589] + [-79.632339, 32.80459] ] ] } diff --git a/packages/turf-union/test/out/union4.geojson b/packages/turf-union/test/out/union4.geojson index 4a7728bc7b..cc4fbe58f8 100644 --- a/packages/turf-union/test/out/union4.geojson +++ b/packages/turf-union/test/out/union4.geojson @@ -5,27 +5,27 @@ "type": "Polygon", "coordinates": [ [ - [-75.71, 45.331], - [-75.707454, 45.334818], + [-75.71000000000001, 45.331], + [-75.70745455000001, 45.33481818], [-75.702, 45.333], [-75.693, 45.336], - [-75.689, 45.342], - [-75.693, 45.349], - [-75.694451, 45.349322], - [-75.692, 45.353], + [-75.68900000000001, 45.342], + [-75.693, 45.349000000000004], + [-75.69445161, 45.34932258], + [-75.69200000000001, 45.353], [-75.696, 45.36], [-75.705, 45.362], [-75.714, 45.36], [-75.717, 45.353], [-75.714, 45.347], [-75.71244, 45.34648], - [-75.713421, 45.34476], - [-75.719, 45.346], - [-75.728, 45.344], + [-75.71342253, 45.34476056], + [-75.71900000000001, 45.346000000000004], + [-75.72800000000001, 45.344], [-75.732, 45.337], - [-75.728, 45.331], - [-75.719, 45.328], - [-75.71, 45.331] + [-75.72800000000001, 45.331], + [-75.71900000000001, 45.328], + [-75.71000000000001, 45.331] ] ] } diff --git a/packages/turf-union/test/out/union5.geojson b/packages/turf-union/test/out/union5.geojson index d89b81d984..71c63fe283 100644 --- a/packages/turf-union/test/out/union5.geojson +++ b/packages/turf-union/test/out/union5.geojson @@ -9,65 +9,65 @@ [-79.936652, 32.964886], [-80.041397, 32.98246], [-80.079302, 32.946468], - [-79.963587, 32.919674], + [-79.963587, 32.919675], [-79.936652, 32.964886] ] ], [ [ - [-79.923226, 32.739099], + [-79.92322798000001, 32.73909997], [-79.805374, 32.723176], [-79.817734, 32.923402], [-79.921417, 32.953944], - [-79.953993, 32.900459], - [-80.097885, 32.927436], - [-80.153503, 32.828249], + [-79.95399275, 32.90046089], + [-80.097885, 32.927437], + [-80.153503, 32.828250000000004], [-80.003128, 32.694288], - [-79.923226, 32.739099] + [-79.92322798000001, 32.73909997] ], [ - [-79.893596, 32.761199], - [-79.885712, 32.887659], - [-79.911976, 32.892582], + [-79.89359686, 32.76119969], + [-79.885712, 32.887660000000004], + [-79.91197654, 32.89258392], [-79.902742, 32.913654], [-79.841373, 32.895333], [-79.837838, 32.793218], [-79.884445, 32.75204], - [-79.893596, 32.761199] + [-79.89359686, 32.76119969] ], [ - [-80.079736, 32.836852], + [-80.079736, 32.836853], [-80.033715, 32.875508], - [-79.972951, 32.869335], - [-79.986911, 32.846414], + [-79.97295104, 32.86933504], + [-79.98691138, 32.84641486], [-80.009581, 32.857916], [-80.046825, 32.846002], [-80.012242, 32.803534], - [-79.986374, 32.805583], - [-79.97513, 32.766084], + [-79.9863747, 32.805584], + [-79.9751301, 32.76608481], [-80.01425, 32.754522], - [-80.079736, 32.836852] + [-80.079736, 32.836853] ], [ - [-80.004708, 32.826259], + [-80.00470800000001, 32.82626], [-80.017562, 32.820299], - [-80.011136, 32.831103], + [-80.01113600000001, 32.831103], [-80.020224, 32.838552], [-80.00914, 32.837435], [-80.002268, 32.845442], - [-79.999388, 32.836875], - [-79.993144, 32.836181], + [-79.999388, 32.836876000000004], + [-79.99314422, 32.83618174], [-79.994467, 32.83401], - [-79.993668, 32.831205], - [-79.997836, 32.829425], - [-79.995398, 32.815455], - [-80.004708, 32.826259] + [-79.99366865, 32.83120562], + [-79.997836, 32.829426], + [-79.99539800000001, 32.815456], + [-80.00470800000001, 32.82626] ], [ - [-79.946398, 32.814045], - [-79.934086, 32.842135], - [-79.917402, 32.785024], - [-79.946398, 32.814045] + [-79.946398, 32.814046], + [-79.93408666, 32.84213624], + [-79.91740183, 32.78502503], + [-79.946398, 32.814046] ] ] ] From 495bc0db9c9695186da6737c8288588ff50567c6 Mon Sep 17 00:00:00 2001 From: James Beard Date: Fri, 9 Jan 2026 14:03:07 +1100 Subject: [PATCH 07/14] Babel plugin to fix a few bigint replacements the third party transform misses. Trying to get away with a minimal internal package e.g. don't have an aggregating "export all" index.ts. Hence a custom tsup to cater for submodule only importing. --- .../babel-plugin-bigint-patch/index.ts | 45 +++++++++++++++++++ packages/turf-internal/index.ts | 1 - packages/turf-internal/package.json | 26 +++++++---- packages/turf-internal/tsup.config.ts | 31 +++++++++++++ 4 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 packages/turf-internal/babel-plugin-bigint-patch/index.ts delete mode 100644 packages/turf-internal/index.ts create mode 100644 packages/turf-internal/tsup.config.ts diff --git a/packages/turf-internal/babel-plugin-bigint-patch/index.ts b/packages/turf-internal/babel-plugin-bigint-patch/index.ts new file mode 100644 index 0000000000..fa8d6c7cbb --- /dev/null +++ b/packages/turf-internal/babel-plugin-bigint-patch/index.ts @@ -0,0 +1,45 @@ +import { PluginObj } from "@babel/core"; + +export default function replaceNumberWithJSBIToNumber(): PluginObj { + return { + name: "replace-number-with-jsbi-toNumber", + visitor: { + CallExpression(path) { + if (!path.get("callee").isIdentifier({ name: "Number" })) return; + + const arg = path.get("arguments")[0]; + if (!arg) return; + + let shouldReplace = false; + + // Number(InternalClipper.MaxInt64 / 4n); + // to + // JSBI.toNumber(JSBI.divide(InternalClipper.MaxInt64, JSBI.BigInt("4"))); + if ( + arg.isBinaryExpression({ operator: "/" }) && + arg.get("left").isMemberExpression() && + arg.get("left.object").isIdentifier({ name: "InternalClipper" }) && + arg.get("left.property").isIdentifier({ name: "MaxInt64" }) && + arg.get("right").isBigIntLiteral() + ) { + shouldReplace = true; + } + + // InternalClipper.Invalid64 = Number(InternalClipper.MaxInt64); + // to + // InternalClipper.Invalid64 = JSBI.toNumber(InternalClipper.MaxInt64); + if ( + arg.isMemberExpression() && + arg.get("object").isIdentifier({ name: "InternalClipper" }) && + arg.get("property").isIdentifier({ name: "MaxInt64" }) + ) { + shouldReplace = true; + } + + if (!shouldReplace) return; + + path.get("callee").replaceWithSourceString("JSBI.toNumber"); + }, + }, + }; +} diff --git a/packages/turf-internal/index.ts b/packages/turf-internal/index.ts deleted file mode 100644 index 200c04487c..0000000000 --- a/packages/turf-internal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./clipper2/index.js"; diff --git a/packages/turf-internal/package.json b/packages/turf-internal/package.json index 293497dbd3..7591ee23ae 100644 --- a/packages/turf-internal/package.json +++ b/packages/turf-internal/package.json @@ -18,19 +18,26 @@ }, "funding": "https://opencollective.com/turf", "type": "module", - "main": "dist/cjs/index.cjs", - "module": "dist/esm/index.js", - "types": "dist/esm/index.d.ts", "exports": { "./package.json": "./package.json", "./clipper2": { "import": { - "types": "./dist/esm/index.d.ts", - "default": "./dist/esm/index.js" + "types": "./dist/esm/clipper2.d.ts", + "default": "./dist/esm/clipper2.js" }, "require": { - "types": "./dist/cjs/index.d.cts", - "default": "./dist/cjs/index.cjs" + "types": "./dist/cjs/clipper2.d.cts", + "default": "./dist/cjs/clipper2.cjs" + } + }, + "./babel-plugin-bigint-patch": { + "import": { + "types": "./dist/esm/babel-plugin-bigint-patch.d.ts", + "default": "./dist/esm/babel-plugin-bigint-patch.js" + }, + "require": { + "types": "./dist/cjs/babel-plugin-bigint-patch.d.cts", + "default": "./dist/cjs/babel-plugin-bigint-patch.cjs" } } }, @@ -39,9 +46,12 @@ "dist" ], "scripts": { - "build": "tsup --config ../../tsup.config.ts" + "build": "tsup" }, "devDependencies": { + "@babel/core": "^7.26.10", + "@babel/types": "^7.26.10", + "@types/babel__core": "^7.20.5", "tsup": "^8.4.0" }, "dependencies": { diff --git a/packages/turf-internal/tsup.config.ts b/packages/turf-internal/tsup.config.ts new file mode 100644 index 0000000000..9748c873db --- /dev/null +++ b/packages/turf-internal/tsup.config.ts @@ -0,0 +1,31 @@ +import { defineConfig, type Options } from "tsup"; + +const baseOptions: Options = { + clean: true, + dts: true, + entry: { + clipper2: "clipper2/index.ts", + "babel-plugin-bigint-patch": "babel-plugin-bigint-patch/index.ts", + }, + minify: false, + skipNodeModulesBundle: true, + sourcemap: true, + target: "es2017", + tsconfig: "./tsconfig.json", + // treeshake: true, causes "chunk.default" warning, breaks CJS exports? + cjsInterop: true, + splitting: true, +}; + +export default [ + defineConfig({ + ...baseOptions, + outDir: "dist/cjs", + format: "cjs", + }), + defineConfig({ + ...baseOptions, + outDir: "dist/esm", + format: "esm", + }), +]; From fc80ef3cfe48ccd3762b16d978a3bc7216075c40 Mon Sep 17 00:00:00 2001 From: James Beard Date: Fri, 9 Jan 2026 21:53:09 +1100 Subject: [PATCH 08/14] Relocating turf-internal to just internal. This indicates it's not a published package, and avoid having to add an exception case to packages/turf/test.ts to skip that directory. --- packages/{turf-internal => internal}/LICENSE | 0 packages/{turf-internal => internal}/README.md | 0 .../babel-plugin-bigint-patch/index.ts | 0 packages/{turf-internal => internal}/clipper2/index.ts | 0 packages/{turf-internal => internal}/package.json | 0 packages/{turf-internal => internal}/test.ts | 0 packages/{turf-internal => internal}/tsconfig.json | 0 packages/{turf-internal => internal}/tsup.config.ts | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename packages/{turf-internal => internal}/LICENSE (100%) rename packages/{turf-internal => internal}/README.md (100%) rename packages/{turf-internal => internal}/babel-plugin-bigint-patch/index.ts (100%) rename packages/{turf-internal => internal}/clipper2/index.ts (100%) rename packages/{turf-internal => internal}/package.json (100%) rename packages/{turf-internal => internal}/test.ts (100%) rename packages/{turf-internal => internal}/tsconfig.json (100%) rename packages/{turf-internal => internal}/tsup.config.ts (100%) diff --git a/packages/turf-internal/LICENSE b/packages/internal/LICENSE similarity index 100% rename from packages/turf-internal/LICENSE rename to packages/internal/LICENSE diff --git a/packages/turf-internal/README.md b/packages/internal/README.md similarity index 100% rename from packages/turf-internal/README.md rename to packages/internal/README.md diff --git a/packages/turf-internal/babel-plugin-bigint-patch/index.ts b/packages/internal/babel-plugin-bigint-patch/index.ts similarity index 100% rename from packages/turf-internal/babel-plugin-bigint-patch/index.ts rename to packages/internal/babel-plugin-bigint-patch/index.ts diff --git a/packages/turf-internal/clipper2/index.ts b/packages/internal/clipper2/index.ts similarity index 100% rename from packages/turf-internal/clipper2/index.ts rename to packages/internal/clipper2/index.ts diff --git a/packages/turf-internal/package.json b/packages/internal/package.json similarity index 100% rename from packages/turf-internal/package.json rename to packages/internal/package.json diff --git a/packages/turf-internal/test.ts b/packages/internal/test.ts similarity index 100% rename from packages/turf-internal/test.ts rename to packages/internal/test.ts diff --git a/packages/turf-internal/tsconfig.json b/packages/internal/tsconfig.json similarity index 100% rename from packages/turf-internal/tsconfig.json rename to packages/internal/tsconfig.json diff --git a/packages/turf-internal/tsup.config.ts b/packages/internal/tsup.config.ts similarity index 100% rename from packages/turf-internal/tsup.config.ts rename to packages/internal/tsup.config.ts From 6b45ae313b53bccaeefd9ef2b57046053b73acc7 Mon Sep 17 00:00:00 2001 From: James Beard Date: Sat, 10 Jan 2026 10:12:32 +1100 Subject: [PATCH 09/14] Updated rollup config with custom transform to es5 to make allowances for BigInt / JSBI handling. --- packages/turf/babel.config.json | 3 +- packages/turf/package.json | 4 + packages/turf/rollup.config.js | 52 +++++++++- pnpm-lock.yaml | 167 +++++++++++++++++++++++++++----- 4 files changed, 196 insertions(+), 30 deletions(-) diff --git a/packages/turf/babel.config.json b/packages/turf/babel.config.json index f77b82335c..f3139a97db 100644 --- a/packages/turf/babel.config.json +++ b/packages/turf/babel.config.json @@ -3,7 +3,8 @@ [ "@babel/preset-env", { - "targets": "> 0.25%, last 2 versions, fully supports es5, not dead" + "targets": "> 0.25%, last 2 versions, fully supports es5, not dead", + "modules": false } ] ] diff --git a/packages/turf/package.json b/packages/turf/package.json index 891c4d060f..196b947a8e 100644 --- a/packages/turf/package.json +++ b/packages/turf/package.json @@ -76,14 +76,18 @@ "devDependencies": { "@babel/core": "^7.26.10", "@babel/preset-env": "^7.26.9", + "@rollup/plugin-alias": "^6.0.0", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.3", "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-terser": "^0.4.4", + "@turf/internal": "workspace:*", "@types/tape": "^5.8.1", + "babel-plugin-transform-bigint-to-jsbi": "^1.0.3", "camelcase": "^8.0.0", "documentation": "^14.0.3", "glob": "^11.1.0", + "jsbi": "^4.3.2", "rollup": "^4.40.1", "rollup-plugin-polyfill-node": "^0.13.0", "tape": "^5.9.0", diff --git a/packages/turf/rollup.config.js b/packages/turf/rollup.config.js index 7932c14b6f..fbb88871c2 100644 --- a/packages/turf/rollup.config.js +++ b/packages/turf/rollup.config.js @@ -1,9 +1,15 @@ -import { babel } from "@rollup/plugin-babel"; +import * as babelCore from "@babel/core"; import { readFileSync } from "fs"; +import alias from "@rollup/plugin-alias"; import commonjs from "@rollup/plugin-commonjs"; import nodePolyfills from "rollup-plugin-polyfill-node"; import nodeResolve from "@rollup/plugin-node-resolve"; import terser from "@rollup/plugin-terser"; +import { fileURLToPath } from "url"; +import { dirname, resolve } from "path"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); const pckg = JSON.parse(readFileSync("./package.json", "utf-8")); const input = "index.ts"; @@ -13,10 +19,50 @@ export default [ input, output: [{ file: pckg.browser, format: "umd", name: "turf" }], plugins: [ - commonjs(), + alias({ + entries: [ + { + // Otherwise tries to require('jsbi/dist/jsbi.mjs') in output. + find: "jsbi/dist/jsbi.mjs", + replacement: resolve(__dirname, "node_modules/jsbi/dist/jsbi.mjs"), + }, + ], + }), nodeResolve(), + commonjs(), + { + name: "transform-all-to-es5", + transform(code, id) { + // Skip commonjs synthetic modules. + if (id.includes("?commonjs")) { + return null; + } + + console.log("Transforming to ES5:", id); + + // Don't apply bigint transforms to jsbi itself, but still transform + // it. + const plugins = id.includes("jsbi") + ? [] + : [ + // Transform most JS 2020 native BigInt to JSBI library + "babel-plugin-transform-bigint-to-jsbi", + // Convert straglers the above misses e.g. Number() + "@turf/internal/babel-plugin-bigint-patch", + ]; + + const result = babelCore.transformSync(code, { + filename: id, + plugins, + }); + + return { + code: result.code, + map: result.map, + }; + }, + }, nodePolyfills(), - babel({ babelHelpers: "bundled" }), terser(), ], }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 87ff7c90a4..338d00212b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -108,6 +108,31 @@ importers: specifier: ^0.3.0 version: 0.3.0 + packages/internal: + dependencies: + '@types/geojson': + specifier: ^7946.0.10 + version: 7946.0.14 + clipper2-ts: + specifier: ^2.0.1 + version: 2.0.1 + tslib: + specifier: ^2.8.1 + version: 2.8.1 + devDependencies: + '@babel/core': + specifier: ^7.26.10 + version: 7.26.10 + '@babel/types': + specifier: ^7.26.10 + version: 7.27.0 + '@types/babel__core': + specifier: ^7.20.5 + version: 7.20.5 + tsup: + specifier: ^8.4.0 + version: 8.4.0(postcss@8.5.3)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) + packages/turf: dependencies: '@turf/along': @@ -462,9 +487,12 @@ importers: '@babel/preset-env': specifier: ^7.26.9 version: 7.26.9(@babel/core@7.26.10) + '@rollup/plugin-alias': + specifier: ^6.0.0 + version: 6.0.0(rollup@4.40.1) '@rollup/plugin-babel': specifier: ^6.0.4 - version: 6.0.4(@babel/core@7.26.10)(rollup@4.40.1) + version: 6.0.4(@babel/core@7.26.10)(@types/babel__core@7.20.5)(rollup@4.40.1) '@rollup/plugin-commonjs': specifier: ^28.0.3 version: 28.0.3(rollup@4.40.1) @@ -474,9 +502,15 @@ importers: '@rollup/plugin-terser': specifier: ^0.4.4 version: 0.4.4(rollup@4.40.1) + '@turf/internal': + specifier: workspace:* + version: link:../internal '@types/tape': specifier: ^5.8.1 version: 5.8.1 + babel-plugin-transform-bigint-to-jsbi: + specifier: ^1.0.3 + version: 1.0.3(@babel/core@7.26.10)(@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.10)) camelcase: specifier: ^8.0.0 version: 8.0.0 @@ -486,6 +520,9 @@ importers: glob: specifier: ^11.1.0 version: 11.1.0 + jsbi: + specifier: ^4.3.2 + version: 4.3.2 rollup: specifier: ^4.40.1 version: 4.40.1 @@ -2495,7 +2532,7 @@ importers: version: link:../turf-helpers '@turf/internal': specifier: workspace:* - version: link:../turf-internal + version: link:../internal '@turf/meta': specifier: workspace:* version: link:../turf-meta @@ -3183,22 +3220,6 @@ importers: specifier: ^6.0.0 version: 6.0.0 - packages/turf-internal: - dependencies: - '@types/geojson': - specifier: ^7946.0.10 - version: 7946.0.14 - clipper2-ts: - specifier: ^2.0.1 - version: 2.0.1 - tslib: - specifier: ^2.8.1 - version: 2.8.1 - devDependencies: - tsup: - specifier: ^8.4.0 - version: 8.4.0(postcss@8.5.3)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) - packages/turf-interpolate: dependencies: '@turf/bbox': @@ -3282,7 +3303,7 @@ importers: version: link:../turf-helpers '@turf/internal': specifier: workspace:* - version: link:../turf-internal + version: link:../internal '@turf/meta': specifier: workspace:* version: link:../turf-meta @@ -6165,7 +6186,7 @@ importers: version: link:../turf-helpers '@turf/internal': specifier: workspace:* - version: link:../turf-internal + version: link:../internal '@turf/meta': specifier: workspace:* version: link:../turf-meta @@ -6420,10 +6441,18 @@ packages: resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.9': resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.25.9': resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} @@ -6482,6 +6511,11 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-import-assertions@7.26.0': resolution: {integrity: sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==} engines: {node: '>=6.9.0'} @@ -6835,6 +6869,10 @@ packages: resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==} engines: {node: '>=6.9.0'} + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + '@colors/colors@1.6.0': resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} engines: {node: '>=0.1.90'} @@ -7564,6 +7602,15 @@ packages: resolution: {integrity: sha512-nRqvPYO8xUVdgy/KhJuaCrWlVT/4uZr97Mpbuizsa6CmvtCQf3NuYnVvOOrpYiKUJcZYtEvm84OooJ8+lJytMQ==} engines: {node: '>=14.6'} + '@rollup/plugin-alias@6.0.0': + resolution: {integrity: sha512-tPCzJOtS7uuVZd+xPhoy5W4vThe6KWXNmsFCNktaAh5RTqcLiSfT4huPQIXkgJ6YCOjJHvecOAzQxLFhPxKr+g==} + engines: {node: '>=20.19.0'} + peerDependencies: + rollup: '>=4.0.0' + peerDependenciesMeta: + rollup: + optional: true + '@rollup/plugin-babel@6.0.4': resolution: {integrity: sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==} engines: {node: '>=14.0.0'} @@ -7779,6 +7826,18 @@ packages: '@tybys/wasm-util@0.9.0': resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/benchmark@2.1.5': resolution: {integrity: sha512-cKio2eFB3v7qmKcvIHLUMw/dIx/8bhWPuzpzRT4unCPRTD8VdA9Zb0afxpcxOqR4PixRS7yT42FqGS8BYL8g1w==} @@ -8117,6 +8176,12 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + babel-plugin-transform-bigint-to-jsbi@1.0.3: + resolution: {integrity: sha512-6O9dFuJSJYUziMd4OE4o/11kW2HBCC5qmF/liddDs/+pmm6iEB5BIlNQgiowjGokOR5ne7ynSi9MZt6uGPmusg==} + peerDependencies: + '@babel/core': ^7.17.2 + '@babel/plugin-syntax-bigint': ^7.8.3 + bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} @@ -9729,6 +9794,9 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true + jsbi@4.3.2: + resolution: {integrity: sha512-9fqMSQbhJykSeii05nxKl4m6Eqn2P6rOlYiS+C5Dr/HPIU/7yZxu5qzbs40tgaFORiw2Amd0mirjxatXYMkIew==} + jsesc@3.0.2: resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} engines: {node: '>=6'} @@ -11890,7 +11958,7 @@ snapshots: '@babel/parser': 7.26.2 '@babel/template': 7.27.0 '@babel/traverse': 7.25.9 - '@babel/types': 7.26.0 + '@babel/types': 7.27.0 convert-source-map: 2.0.0 debug: 4.4.0 gensync: 1.0.0-beta.2 @@ -11922,7 +11990,7 @@ snapshots: '@babel/generator@7.26.2': dependencies: '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 + '@babel/types': 7.27.0 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.0.2 @@ -11988,7 +12056,7 @@ snapshots: '@babel/helper-module-imports@7.25.9': dependencies: '@babel/traverse': 7.25.9 - '@babel/types': 7.26.0 + '@babel/types': 7.27.0 transitivePeerDependencies: - supports-color @@ -12043,8 +12111,12 @@ snapshots: '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-string-parser@7.27.1': {} + '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-option@7.25.9': {} '@babel/helper-wrap-function@7.25.9': @@ -12062,7 +12134,7 @@ snapshots: '@babel/parser@7.26.2': dependencies: - '@babel/types': 7.26.0 + '@babel/types': 7.27.0 '@babel/parser@7.27.0': dependencies: @@ -12107,6 +12179,11 @@ snapshots: dependencies: '@babel/core': 7.26.10 + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.10)': + dependencies: + '@babel/core': 7.26.10 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 @@ -12540,7 +12617,7 @@ snapshots: '@babel/generator': 7.26.2 '@babel/parser': 7.26.2 '@babel/template': 7.27.0 - '@babel/types': 7.26.0 + '@babel/types': 7.27.0 debug: 4.4.0 globals: 11.12.0 transitivePeerDependencies: @@ -12568,6 +12645,11 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@colors/colors@1.6.0': {} '@dabh/diagnostics@2.0.3': @@ -13386,12 +13468,17 @@ snapshots: write-file-atomic: 5.0.1 write-yaml-file: 4.2.0 - '@rollup/plugin-babel@6.0.4(@babel/core@7.26.10)(rollup@4.40.1)': + '@rollup/plugin-alias@6.0.0(rollup@4.40.1)': + optionalDependencies: + rollup: 4.40.1 + + '@rollup/plugin-babel@6.0.4(@babel/core@7.26.10)(@types/babel__core@7.20.5)(rollup@4.40.1)': dependencies: '@babel/core': 7.26.10 '@babel/helper-module-imports': 7.25.9 '@rollup/pluginutils': 5.1.3(rollup@4.40.1) optionalDependencies: + '@types/babel__core': 7.20.5 rollup: 4.40.1 transitivePeerDependencies: - supports-color @@ -13563,6 +13650,27 @@ snapshots: dependencies: tslib: 2.8.1 + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.27.0 + '@babel/types': 7.27.0 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.27.0 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.27.0 + '@babel/types': 7.27.0 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.28.5 + '@types/benchmark@2.1.5': {} '@types/concaveman@1.1.6': {} @@ -13952,6 +14060,11 @@ snapshots: transitivePeerDependencies: - supports-color + babel-plugin-transform-bigint-to-jsbi@1.0.3(@babel/core@7.26.10)(@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.10)): + dependencies: + '@babel/core': 7.26.10 + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.26.10) + bail@2.0.2: {} balanced-match@1.0.2: {} @@ -15753,6 +15866,8 @@ snapshots: dependencies: argparse: 2.0.1 + jsbi@4.3.2: {} + jsesc@3.0.2: {} jsesc@3.1.0: {} From f9641d3ea43eb3cb0d68baa96cba48464b55744d Mon Sep 17 00:00:00 2001 From: James Beard Date: Sat, 10 Jan 2026 10:20:44 +1100 Subject: [PATCH 10/14] Missed reverting turf-union union3 test back to full input precision. --- packages/turf-union/test/in/union3.geojson | 42 ++++++++++----------- packages/turf-union/test/out/union3.geojson | 30 +++++++-------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/packages/turf-union/test/in/union3.geojson b/packages/turf-union/test/in/union3.geojson index b78bec2153..aa4e7059d6 100644 --- a/packages/turf-union/test/in/union3.geojson +++ b/packages/turf-union/test/in/union3.geojson @@ -8,12 +8,12 @@ "type": "Polygon", "coordinates": [ [ - [-79.885712, 32.88766], - [-80.097885, 32.927437], - [-80.153503, 32.82825], - [-80.003128, 32.694288], - [-79.893951, 32.75552], - [-79.885712, 32.88766] + [-79.88571166992188, 32.887659962078956], + [-80.09788513183594, 32.927436533285565], + [-80.15350341796875, 32.82825010814964], + [-80.00312805175781, 32.69428812316933], + [-79.89395141601562, 32.75551989829049], + [-79.88571166992188, 32.887659962078956] ] ] } @@ -25,14 +25,14 @@ "type": "Polygon", "coordinates": [ [ - [-79.921417, 32.953944], - [-79.974289, 32.836905], - [-79.973602, 32.760717], - [-79.930344, 32.764759], - [-79.937897, 32.741082], - [-79.805374, 32.723176], - [-79.817734, 32.923402], - [-79.921417, 32.953944] + [-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] ] ] } @@ -44,13 +44,13 @@ "type": "Polygon", "coordinates": [ [ - [-79.856186, 32.859979], - [-79.884338, 32.687931], - [-79.792328, 32.679841], - [-79.632339, 32.80459], - [-79.648819, 32.915909], - [-79.789581, 32.913603], - [-79.856186, 32.859979] + [-79.85618591308594, 32.85997876713845], + [-79.78958129882812, 32.913603231028915], + [-79.64881896972656, 32.915908931564864], + [-79.63233947753906, 32.804590457442565], + [-79.79232788085938, 32.679840539897484], + [-79.88433837890625, 32.687931474529464], + [-79.85618591308594, 32.85997876713845] ] ] } diff --git a/packages/turf-union/test/out/union3.geojson b/packages/turf-union/test/out/union3.geojson index 72bdf2a0fb..35bb726a1c 100644 --- a/packages/turf-union/test/out/union3.geojson +++ b/packages/turf-union/test/out/union3.geojson @@ -5,21 +5,21 @@ "type": "Polygon", "coordinates": [ [ - [-79.632339, 32.80459], - [-79.648819, 32.915909], - [-79.789581, 32.913603], - [-79.8158248, 32.89247398], - [-79.817734, 32.923402], - [-79.921417, 32.953944], - [-79.94623485, 32.899006480000004], - [-80.097885, 32.927437], - [-80.153503, 32.828250000000004], - [-80.003128, 32.694288], - [-79.92322798000001, 32.73909997], - [-79.8769876, 32.73285215], - [-79.884338, 32.687931], - [-79.792328, 32.679841], - [-79.632339, 32.80459] + [-79.63233948, 32.80459046], + [-79.64881897000001, 32.91590893], + [-79.7895813, 32.91360323], + [-79.81582464, 32.89247428], + [-79.81773376, 32.92340204], + [-79.92141724, 32.95394432], + [-79.94623496, 32.89900637], + [-80.09788513000001, 32.92743653], + [-80.15350342, 32.82825011], + [-80.00312805, 32.69428812], + [-79.9232278, 32.73910022], + [-79.87698786, 32.73285245], + [-79.88433838, 32.68793147], + [-79.79232788, 32.67984054], + [-79.63233948, 32.80459046] ] ] } From 61fe36684ddb97d7d589a8b850df913c9fdd473b Mon Sep 17 00:00:00 2001 From: James Beard Date: Sat, 17 Jan 2026 12:49:37 +1100 Subject: [PATCH 11/14] Fixed clipper2 util that wasn't processing nested polygons properly, and added some more challenging related tests. --- packages/internal/clipper2/index.ts | 78 +++-- packages/turf-difference/index.ts | 4 +- packages/turf-difference/test.ts | 5 +- .../test/in/islands-multiple.geojson | 146 +++++++++ .../turf-difference/test/in/islands.geojson | 67 +++++ .../test/out/islands-multiple.geojson | 278 ++++++++++++++++++ .../turf-difference/test/out/islands.geojson | 117 ++++++++ packages/turf-intersect/index.ts | 4 +- packages/turf-union/index.ts | 4 +- 9 files changed, 667 insertions(+), 36 deletions(-) create mode 100644 packages/turf-difference/test/in/islands-multiple.geojson create mode 100644 packages/turf-difference/test/in/islands.geojson create mode 100644 packages/turf-difference/test/out/islands-multiple.geojson create mode 100644 packages/turf-difference/test/out/islands.geojson diff --git a/packages/internal/clipper2/index.ts b/packages/internal/clipper2/index.ts index 158a95cd6f..33a79676cb 100644 --- a/packages/internal/clipper2/index.ts +++ b/packages/internal/clipper2/index.ts @@ -1,7 +1,13 @@ import { PolyPathD, PathD, PathsD, PolyTreeD, areaD } from "clipper2-ts"; import { Polygon, MultiPolygon, Position } from "geojson"; -const DEFAULT_PRECISION = 8; +/* + * Clipper2 scaling factor used when converting between decimal and integer + * values for internal clipper2 calculations. + * For Turf's purposes defaults to 8 decimal places retained, which is approx + * 1mm if using decimal degrees at the equator. + */ +const TURF_CLIPPER2_SCALE_FACTOR = 8; /** * Converts a multipolygon to a flattened array of clipper2 paths. @@ -69,20 +75,18 @@ function ringToPath(ring: Position[]): PathD { } /** - * Construct the output Geojson based on a clipper2 tree. The tree is useful for propertly handing holes. + * Construct the output Geojson based on a clipper2 tree. The tree is useful + * for propertly handing holes. + * + * @param polyTree hierarchy of outer and inner contours found by clipper2 */ function polyTreeToGeoJSON(polyTree: PolyTreeD): Polygon | MultiPolygon | null { const polygons: Position[][][] = []; - // Process each top-level polygon (outer contours) + // Process each top-level polygon (initally all outer contours) for (let i = 0; i < polyTree.count; i++) { const child = polyTree.child(i); - if (child && !child.isHole) { - const polygon = processPolyPath(child); - if (polygon.length > 0) { - polygons.push(polygon); - } - } + processPolyPath(child, polygons); } if (polygons.length === 0) { @@ -104,36 +108,54 @@ function polyTreeToGeoJSON(polyTree: PolyTreeD): Polygon | MultiPolygon | null { }; } -function processPolyPath(polyPath: PolyPathD): Position[][] { - const rings: Position[][] = []; +/** + * Processes a polyPath. Depending on whether the path denotes an outer ring or a hole, will add a polygon to the list of polygons. + * Recurses to children of this polyPath in turn. + * + * @param polyPath outer or inner contour of a polygon to process + * @param polygons array of completed polygons that this function may add to + */ +function processPolyPath(polyPath: PolyPathD, polygons: Position[][][]) { + // Don't look closely at holes during recursion ... + if (!polyPath.isHole) { + const rings: Position[][] = []; + // Add the outer ring. + const outerRing = pathToCoordinates(polyPath.poly); + if (outerRing.length > 0) { + rings.push(outerRing); + } - // Add the outer ring (contour) - const outerRing = pathToCoordinates(polyPath.poly); - if (outerRing.length > 0) { - rings.push(outerRing); - } + // ... instead add holes here. + // Add any holes (direct children are the holes). Do this now rather than + // during recursion given we already have the outer ring handy. + for (let i = 0; i < polyPath.count; i++) { + const child = polyPath.child(i); - // Add any holes (children are the holes) - for (let i = 0; i < polyPath.count; i++) { - const child = polyPath.child(i); - if (child && child.isHole) { const holeRing = pathToCoordinates(child.poly); if (holeRing.length > 0) { rings.push(holeRing); } - - // Expectation is pools within islands within lakes within continents ... - // are handled as multipolygons. So further recursion is not required. } + polygons.push(rings); } - return rings; + // Now recurse into each child to handle nested levels. + for (let i = 0; i < polyPath.count; i++) { + processPolyPath(polyPath.child(i), polygons); + } } /** - * Converts a clipper2 integer path to an array of Geojson Positions. + * Converts a clipper2 path to an array of Geojson Positions. + * Automatically closes the path unless overridden e.g. for a lineString. + * + * @param path clipper2 path to convert to Positions + * @param [closeIt=true] close the path by making sure first and last positions are equal */ -function pathToCoordinates(path: PathD | null): Position[] { +function pathToCoordinates( + path: PathD | null, + closeIt: boolean = true +): Position[] { const coords: Position[] = []; if (!path || typeof path.length !== "number") { @@ -146,7 +168,7 @@ function pathToCoordinates(path: PathD | null): Position[] { } // GeoJSON requires the first and last coordinates to be identical (closed ring) - if (coords.length > 0) { + if (coords.length > 0 && closeIt) { const first = coords[0]; const last = coords[coords.length - 1]; if (first[0] !== last[0] || first[1] !== last[1]) { @@ -161,5 +183,5 @@ export { multiPolygonToPaths, polygonToPaths, polyTreeToGeoJSON, - DEFAULT_PRECISION, + TURF_CLIPPER2_SCALE_FACTOR, }; diff --git a/packages/turf-difference/index.ts b/packages/turf-difference/index.ts index 8ef66845ee..2e8169737d 100644 --- a/packages/turf-difference/index.ts +++ b/packages/turf-difference/index.ts @@ -3,7 +3,7 @@ import { feature } from "@turf/helpers"; import { geomEach } from "@turf/meta"; import { ClipperD, ClipType, FillRule, PolyTreeD } from "clipper2-ts"; import { - DEFAULT_PRECISION, + TURF_CLIPPER2_SCALE_FACTOR, multiPolygonToPaths, polygonToPaths, polyTreeToGeoJSON, @@ -49,7 +49,7 @@ function difference( throw new Error("Must have at least 2 features"); } - const clipper = new ClipperD(DEFAULT_PRECISION); + const clipper = new ClipperD(TURF_CLIPPER2_SCALE_FACTOR); geomEach(features, (geom, idx) => { if (geom.type === "MultiPolygon") { diff --git a/packages/turf-difference/test.ts b/packages/turf-difference/test.ts index 6b1a15b1d8..699b776440 100644 --- a/packages/turf-difference/test.ts +++ b/packages/turf-difference/test.ts @@ -17,7 +17,8 @@ const directories = { test("turf-difference", (t) => { glob.sync(directories.in + "*.geojson").forEach((filepath) => { const { name, base } = path.parse(filepath); - const [polygon1, polygon2] = loadJsonFileSync(filepath).features; + const [polygon1, polygon2, ...polygon3] = + loadJsonFileSync(filepath).features; if (name.includes("skip")) return t.skip(name); @@ -32,7 +33,7 @@ test("turf-difference", (t) => { fill: "#00F", }); - const results = featureCollection([polygon1, polygon2]); + const results = featureCollection([polygon1, polygon2, ...polygon3]); const result = difference(results); if (result) { diff --git a/packages/turf-difference/test/in/islands-multiple.geojson b/packages/turf-difference/test/in/islands-multiple.geojson new file mode 100644 index 0000000000..8aa79d1fb8 --- /dev/null +++ b/packages/turf-difference/test/in/islands-multiple.geojson @@ -0,0 +1,146 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "coordinates": [ + [ + [100.341829, 21.707513], + [99.946218, 18.265736], + [104.497972, 18.103249], + [104.507178, 21.699765], + [100.341829, 21.707513] + ] + ], + "type": "Polygon" + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [103.987606, 21.227485], + [100.921818, 21.235346], + [100.574542, 18.952871], + [104.123395, 18.527677], + [103.987606, 21.227485] + ], + [ + [101.495625, 19.485559], + [101.602049, 20.579957], + [103.014364, 20.515371], + [103.490307, 19.967501], + [102.75797, 19.36418], + [101.495625, 19.485559] + ] + ], + [ + [ + [103.20384, 19.959388], + [102.697848, 20.315749], + [101.792497, 20.382879], + [101.679461, 19.748293], + [102.631796, 19.6454], + [103.20384, 19.959388] + ], + [ + [101.857201, 19.836747], + [101.887131, 20.172541], + [102.608327, 20.146421], + [102.519141, 19.806948], + [101.857201, 19.836747] + ], + [ + [102.710175, 20.145995], + [103.016792, 19.96959], + [102.716091, 19.807209], + [102.710175, 20.145995] + ] + ], + [ + [ + [102.467324, 19.906336], + [102.483859, 20.007542], + [102.433872, 20.091891], + [102.30271, 20.114574], + [102.198807, 20.067657], + [102.154763, 20.120171], + [102.022812, 20.12187], + [101.932984, 20.056346], + [101.931027, 19.956909], + [101.982923, 19.894882], + [102.104859, 19.885437], + [102.160847, 19.930535], + [102.204835, 19.855339], + [102.380026, 19.846195], + [102.467324, 19.906336] + ], + [ + [102.016567, 19.965037], + [102.007976, 20.016831], + [102.025106, 20.050394], + [102.081247, 20.059202], + [102.12169, 20.041848], + [102.145916, 20.014495], + [102.130554, 19.961962], + [102.070892, 19.951353], + [102.016567, 19.965037] + ], + [ + [102.247885, 19.88569], + [102.218625, 19.938108], + [102.233982, 20.014125], + [102.299533, 20.055184], + [102.375656, 20.044778], + [102.423278, 19.993367], + [102.405766, 19.911304], + [102.346589, 19.879453], + [102.247885, 19.88569] + ] + ], + [ + [ + [102.113123, 20.010395], + [102.104508, 20.025803], + [102.084663, 20.009513], + [102.096753, 19.999083], + [102.113123, 20.010395] + ] + ], + [ + [ + [102.068298, 20.00723], + [102.054491, 20.025105], + [102.039792, 20.010625], + [102.051026, 19.998426], + [102.068298, 20.00723] + ] + ], + [ + [ + [102.325155, 19.913375], + [102.329922, 19.94424], + [102.366693, 19.950325], + [102.362254, 19.981083], + [102.323385, 19.979151], + [102.323375, 20.014048], + [102.297362, 20.010017], + [102.292975, 19.975096], + [102.257956, 19.977134], + [102.255539, 19.952425], + [102.297063, 19.948326], + [102.294479, 19.913356], + [102.325155, 19.913375] + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-difference/test/in/islands.geojson b/packages/turf-difference/test/in/islands.geojson new file mode 100644 index 0000000000..b8b66a4484 --- /dev/null +++ b/packages/turf-difference/test/in/islands.geojson @@ -0,0 +1,67 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "coordinates": [ + [ + [-56.262408, 3.517085], + [-56.262408, -4.571427], + [-46.193645, -4.571427], + [-46.193645, 3.517085], + [-56.262408, 3.517085] + ] + ], + "type": "Polygon" + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "coordinates": [ + [ + [-51.241521, 2.506449], + [-54.474222, -0.594385], + [-51.263364, -3.802459], + [-47.768553, -0.616227], + [-51.241521, 2.506449] + ], + [ + [-51.307049, 1.371305], + [-48.926209, -0.703591], + [-51.219679, -2.73393], + [-53.27288, -0.528861], + [-51.307049, 1.371305] + ] + ], + "type": "Polygon" + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "coordinates": [ + [ + [-51.962326, 0.257464], + [-51.962326, -1.533443], + [-50.324133, -1.533443], + [-50.324133, 0.257464], + [-51.962326, 0.257464] + ], + [ + [-51.711136, 0.04996], + [-50.55348, 0.04996], + [-50.55348, -1.249574], + [-51.711136, -1.249574], + [-51.711136, 0.04996] + ] + ], + "type": "Polygon" + } + } + ] +} diff --git a/packages/turf-difference/test/out/islands-multiple.geojson b/packages/turf-difference/test/out/islands-multiple.geojson new file mode 100644 index 0000000000..37796b5249 --- /dev/null +++ b/packages/turf-difference/test/out/islands-multiple.geojson @@ -0,0 +1,278 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { "fill-opacity": 0.5, "fill": "#F00" }, + "geometry": { + "coordinates": [ + [ + [100.341829, 21.707513], + [99.946218, 18.265736], + [104.497972, 18.103249], + [104.507178, 21.699765], + [100.341829, 21.707513] + ] + ], + "type": "Polygon" + } + }, + { + "type": "Feature", + "properties": { "fill-opacity": 0.5, "fill": "#00F" }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [103.987606, 21.227485], + [100.921818, 21.235346], + [100.574542, 18.952871], + [104.123395, 18.527677], + [103.987606, 21.227485] + ], + [ + [101.495625, 19.485559], + [101.602049, 20.579957], + [103.014364, 20.515371], + [103.490307, 19.967501], + [102.75797, 19.36418], + [101.495625, 19.485559] + ] + ], + [ + [ + [103.20384, 19.959388], + [102.697848, 20.315749], + [101.792497, 20.382879], + [101.679461, 19.748293], + [102.631796, 19.6454], + [103.20384, 19.959388] + ], + [ + [101.857201, 19.836747], + [101.887131, 20.172541], + [102.608327, 20.146421], + [102.519141, 19.806948], + [101.857201, 19.836747] + ], + [ + [102.710175, 20.145995], + [103.016792, 19.96959], + [102.716091, 19.807209], + [102.710175, 20.145995] + ] + ], + [ + [ + [102.467324, 19.906336], + [102.483859, 20.007542], + [102.433872, 20.091891], + [102.30271, 20.114574], + [102.198807, 20.067657], + [102.154763, 20.120171], + [102.022812, 20.12187], + [101.932984, 20.056346], + [101.931027, 19.956909], + [101.982923, 19.894882], + [102.104859, 19.885437], + [102.160847, 19.930535], + [102.204835, 19.855339], + [102.380026, 19.846195], + [102.467324, 19.906336] + ], + [ + [102.016567, 19.965037], + [102.007976, 20.016831], + [102.025106, 20.050394], + [102.081247, 20.059202], + [102.12169, 20.041848], + [102.145916, 20.014495], + [102.130554, 19.961962], + [102.070892, 19.951353], + [102.016567, 19.965037] + ], + [ + [102.247885, 19.88569], + [102.218625, 19.938108], + [102.233982, 20.014125], + [102.299533, 20.055184], + [102.375656, 20.044778], + [102.423278, 19.993367], + [102.405766, 19.911304], + [102.346589, 19.879453], + [102.247885, 19.88569] + ] + ], + [ + [ + [102.113123, 20.010395], + [102.104508, 20.025803], + [102.084663, 20.009513], + [102.096753, 19.999083], + [102.113123, 20.010395] + ] + ], + [ + [ + [102.068298, 20.00723], + [102.054491, 20.025105], + [102.039792, 20.010625], + [102.051026, 19.998426], + [102.068298, 20.00723] + ] + ], + [ + [ + [102.325155, 19.913375], + [102.329922, 19.94424], + [102.366693, 19.950325], + [102.362254, 19.981083], + [102.323385, 19.979151], + [102.323375, 20.014048], + [102.297362, 20.010017], + [102.292975, 19.975096], + [102.257956, 19.977134], + [102.255539, 19.952425], + [102.297063, 19.948326], + [102.294479, 19.913356], + [102.325155, 19.913375] + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { "fill-opacity": 1, "fill": "#0F0" }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [104.507178, 21.699765], + [100.341829, 21.707513], + [99.946218, 18.265736], + [104.497972, 18.103249], + [104.507178, 21.699765] + ], + [ + [100.57454200000001, 18.952871000000002], + [100.921818, 21.235346], + [103.987606, 21.227485], + [104.123395, 18.527677], + [100.57454200000001, 18.952871000000002] + ] + ], + [ + [ + [103.490307, 19.967501000000002], + [103.014364, 20.515371000000002], + [101.60204900000001, 20.579957], + [101.495625, 19.485559000000002], + [102.75797, 19.36418], + [103.490307, 19.967501000000002] + ], + [ + [101.679461, 19.748293], + [101.792497, 20.382879], + [102.69784800000001, 20.315749], + [103.20384, 19.959388], + [102.63179600000001, 19.6454], + [101.679461, 19.748293] + ] + ], + [ + [ + [102.608327, 20.146421], + [101.887131, 20.172541], + [101.857201, 19.836747], + [102.519141, 19.806948000000002], + [102.608327, 20.146421] + ], + [ + [102.204835, 19.855339], + [102.160847, 19.930535], + [102.104859, 19.885437], + [101.982923, 19.894882], + [101.931027, 19.956909], + [101.932984, 20.056346], + [102.022812, 20.12187], + [102.154763, 20.120171], + [102.198807, 20.067657], + [102.30271, 20.114574], + [102.43387200000001, 20.091891], + [102.483859, 20.007542], + [102.467324, 19.906336], + [102.380026, 19.846195], + [102.204835, 19.855339] + ] + ], + [ + [ + [102.130554, 19.961962], + [102.145916, 20.014495], + [102.12169, 20.041848], + [102.081247, 20.059202], + [102.02510600000001, 20.050394], + [102.007976, 20.016831], + [102.01656700000001, 19.965037], + [102.070892, 19.951353], + [102.130554, 19.961962] + ], + [ + [102.084663, 20.009513000000002], + [102.104508, 20.025803], + [102.113123, 20.010395], + [102.096753, 19.999083], + [102.084663, 20.009513000000002] + ], + [ + [102.039792, 20.010625], + [102.054491, 20.025105], + [102.068298, 20.00723], + [102.05102600000001, 19.998426000000002], + [102.039792, 20.010625] + ] + ], + [ + [ + [102.405766, 19.911304], + [102.423278, 19.993367], + [102.375656, 20.044778], + [102.299533, 20.055184], + [102.233982, 20.014125], + [102.218625, 19.938108], + [102.247885, 19.88569], + [102.34658900000001, 19.879453], + [102.405766, 19.911304] + ], + [ + [102.29706300000001, 19.948326], + [102.255539, 19.952425], + [102.25795600000001, 19.977134], + [102.292975, 19.975096], + [102.297362, 20.010017], + [102.323375, 20.014048], + [102.323385, 19.979151], + [102.36225400000001, 19.981083], + [102.366693, 19.950325], + [102.329922, 19.94424], + [102.325155, 19.913375000000002], + [102.294479, 19.913356], + [102.29706300000001, 19.948326] + ] + ], + [ + [ + [103.016792, 19.96959], + [102.710175, 20.145995], + [102.716091, 19.807209], + [103.016792, 19.96959] + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-difference/test/out/islands.geojson b/packages/turf-difference/test/out/islands.geojson new file mode 100644 index 0000000000..20bb6327fc --- /dev/null +++ b/packages/turf-difference/test/out/islands.geojson @@ -0,0 +1,117 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { "fill-opacity": 0.5, "fill": "#F00" }, + "geometry": { + "coordinates": [ + [ + [-56.262408, 3.517085], + [-56.262408, -4.571427], + [-46.193645, -4.571427], + [-46.193645, 3.517085], + [-56.262408, 3.517085] + ] + ], + "type": "Polygon" + } + }, + { + "type": "Feature", + "properties": { "fill-opacity": 0.5, "fill": "#00F" }, + "geometry": { + "coordinates": [ + [ + [-51.241521, 2.506449], + [-54.474222, -0.594385], + [-51.263364, -3.802459], + [-47.768553, -0.616227], + [-51.241521, 2.506449] + ], + [ + [-51.307049, 1.371305], + [-48.926209, -0.703591], + [-51.219679, -2.73393], + [-53.27288, -0.528861], + [-51.307049, 1.371305] + ] + ], + "type": "Polygon" + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "coordinates": [ + [ + [-51.962326, 0.257464], + [-51.962326, -1.533443], + [-50.324133, -1.533443], + [-50.324133, 0.257464], + [-51.962326, 0.257464] + ], + [ + [-51.711136, 0.04996], + [-50.55348, 0.04996], + [-50.55348, -1.249574], + [-51.711136, -1.249574], + [-51.711136, 0.04996] + ] + ], + "type": "Polygon" + } + }, + { + "type": "Feature", + "properties": { "fill-opacity": 1, "fill": "#0F0" }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [-46.193645000000004, 3.5170850000000002], + [-56.262408, 3.5170850000000002], + [-56.262408, -4.571427], + [-46.193645000000004, -4.571427], + [-46.193645000000004, 3.5170850000000002] + ], + [ + [-54.474222000000005, -0.594385], + [-51.241521, 2.506449], + [-47.768553000000004, -0.616227], + [-51.263364, -3.8024590000000003], + [-54.474222000000005, -0.594385] + ] + ], + [ + [ + [-48.926209, -0.703591], + [-51.307049, 1.371305], + [-53.27288, -0.528861], + [-51.219679, -2.73393], + [-48.926209, -0.703591] + ], + [ + [-51.962326000000004, -1.5334430000000001], + [-51.962326000000004, 0.257464], + [-50.324133, 0.257464], + [-50.324133, -1.5334430000000001], + [-51.962326000000004, -1.5334430000000001] + ] + ], + [ + [ + [-50.55348, -1.249574], + [-50.55348, 0.049960000000000004], + [-51.711136, 0.049960000000000004], + [-51.711136, -1.249574], + [-50.55348, -1.249574] + ] + ] + ] + } + } + ] +} diff --git a/packages/turf-intersect/index.ts b/packages/turf-intersect/index.ts index f1268069ab..a2667490d9 100644 --- a/packages/turf-intersect/index.ts +++ b/packages/turf-intersect/index.ts @@ -9,7 +9,7 @@ import { feature } from "@turf/helpers"; import { geomEach } from "@turf/meta"; import { FillRule, ClipType, PolyTreeD, ClipperD } from "clipper2-ts"; import { - DEFAULT_PRECISION, + TURF_CLIPPER2_SCALE_FACTOR, multiPolygonToPaths, polygonToPaths, polyTreeToGeoJSON, @@ -60,7 +60,7 @@ function intersect

( throw new Error("Must have at least 2 features"); } - const clipper = new ClipperD(DEFAULT_PRECISION); + const clipper = new ClipperD(TURF_CLIPPER2_SCALE_FACTOR); geomEach(features, (geom, idx) => { if (geom.type === "MultiPolygon") { diff --git a/packages/turf-union/index.ts b/packages/turf-union/index.ts index bf71b226ff..6618ae0a3f 100644 --- a/packages/turf-union/index.ts +++ b/packages/turf-union/index.ts @@ -9,7 +9,7 @@ import { } from "geojson"; import { FillRule, ClipType, PolyTreeD, ClipperD } from "clipper2-ts"; import { - DEFAULT_PRECISION, + TURF_CLIPPER2_SCALE_FACTOR, multiPolygonToPaths, polygonToPaths, polyTreeToGeoJSON, @@ -71,7 +71,7 @@ function union

( throw new Error("Must have at least 2 features"); } - const clipper = new ClipperD(DEFAULT_PRECISION); + const clipper = new ClipperD(TURF_CLIPPER2_SCALE_FACTOR); geomEach(features, (geom, idx) => { if (geom.type === "MultiPolygon") { From 08b2034cd9ed371488d7d9785bf7d3d81fab9f5e Mon Sep 17 00:00:00 2001 From: James Beard Date: Sat, 17 Jan 2026 16:06:59 +1100 Subject: [PATCH 12/14] Rolling back changes to @turf/turf babel setup, instead favouring a patch approach to address bigint syntax in clipper2-ts. --- .../babel-plugin-bigint-patch/index.ts | 45 ---------- packages/internal/package.json | 21 ++--- packages/internal/test.ts | 16 ++++ packages/internal/tsup.config.ts | 1 - packages/turf/babel.config.json | 3 +- packages/turf/package.json | 3 - packages/turf/rollup.config.js | 52 +---------- patches/clipper2-ts.patch | 90 +++++++++++++++++++ pnpm-lock.yaml | 67 ++++---------- pnpm-workspace.yaml | 4 +- 10 files changed, 141 insertions(+), 161 deletions(-) delete mode 100644 packages/internal/babel-plugin-bigint-patch/index.ts create mode 100644 patches/clipper2-ts.patch diff --git a/packages/internal/babel-plugin-bigint-patch/index.ts b/packages/internal/babel-plugin-bigint-patch/index.ts deleted file mode 100644 index fa8d6c7cbb..0000000000 --- a/packages/internal/babel-plugin-bigint-patch/index.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { PluginObj } from "@babel/core"; - -export default function replaceNumberWithJSBIToNumber(): PluginObj { - return { - name: "replace-number-with-jsbi-toNumber", - visitor: { - CallExpression(path) { - if (!path.get("callee").isIdentifier({ name: "Number" })) return; - - const arg = path.get("arguments")[0]; - if (!arg) return; - - let shouldReplace = false; - - // Number(InternalClipper.MaxInt64 / 4n); - // to - // JSBI.toNumber(JSBI.divide(InternalClipper.MaxInt64, JSBI.BigInt("4"))); - if ( - arg.isBinaryExpression({ operator: "/" }) && - arg.get("left").isMemberExpression() && - arg.get("left.object").isIdentifier({ name: "InternalClipper" }) && - arg.get("left.property").isIdentifier({ name: "MaxInt64" }) && - arg.get("right").isBigIntLiteral() - ) { - shouldReplace = true; - } - - // InternalClipper.Invalid64 = Number(InternalClipper.MaxInt64); - // to - // InternalClipper.Invalid64 = JSBI.toNumber(InternalClipper.MaxInt64); - if ( - arg.isMemberExpression() && - arg.get("object").isIdentifier({ name: "InternalClipper" }) && - arg.get("property").isIdentifier({ name: "MaxInt64" }) - ) { - shouldReplace = true; - } - - if (!shouldReplace) return; - - path.get("callee").replaceWithSourceString("JSBI.toNumber"); - }, - }, - }; -} diff --git a/packages/internal/package.json b/packages/internal/package.json index 7591ee23ae..989713b88c 100644 --- a/packages/internal/package.json +++ b/packages/internal/package.json @@ -1,7 +1,6 @@ { "name": "@turf/internal", "version": "7.3.1", - "private": true, "description": "Common functionality used across multiple Turf packages.", "author": "Turf Authors", "contributors": [ @@ -17,6 +16,9 @@ "url": "git://github.com/Turfjs/turf.git" }, "funding": "https://opencollective.com/turf", + "publishConfig": { + "access": "public" + }, "type": "module", "exports": { "./package.json": "./package.json", @@ -29,16 +31,6 @@ "types": "./dist/cjs/clipper2.d.cts", "default": "./dist/cjs/clipper2.cjs" } - }, - "./babel-plugin-bigint-patch": { - "import": { - "types": "./dist/esm/babel-plugin-bigint-patch.d.ts", - "default": "./dist/esm/babel-plugin-bigint-patch.js" - }, - "require": { - "types": "./dist/cjs/babel-plugin-bigint-patch.d.cts", - "default": "./dist/cjs/babel-plugin-bigint-patch.cjs" - } } }, "sideEffects": false, @@ -46,17 +38,22 @@ "dist" ], "scripts": { - "build": "tsup" + "build": "tsup", + "test": "pnpm run /test:.*/", + "test:tape": "tsx test.ts" }, "devDependencies": { "@babel/core": "^7.26.10", "@babel/types": "^7.26.10", "@types/babel__core": "^7.20.5", + "@types/tape": "^5.8.1", + "tape": "^5.9.0", "tsup": "^8.4.0" }, "dependencies": { "@types/geojson": "^7946.0.10", "clipper2-ts": "^2.0.1", + "jsbi": "^4.3.2", "tslib": "^2.8.1" } } diff --git a/packages/internal/test.ts b/packages/internal/test.ts index e69de29bb2..2495e34a92 100644 --- a/packages/internal/test.ts +++ b/packages/internal/test.ts @@ -0,0 +1,16 @@ +import test from "tape"; +import { FillRule, ClipType, PolyTreeD, ClipperD } from "clipper2-ts"; +import { + TURF_CLIPPER2_SCALE_FACTOR, + multiPolygonToPaths, + polygonToPaths, + polyTreeToGeoJSON, +} from "./clipper2/index.js"; + +test("clipper2", (t) => { + const clipper = new ClipperD(TURF_CLIPPER2_SCALE_FACTOR); + + clipper.clear(); + + t.end(); +}); diff --git a/packages/internal/tsup.config.ts b/packages/internal/tsup.config.ts index 9748c873db..c0b977eb94 100644 --- a/packages/internal/tsup.config.ts +++ b/packages/internal/tsup.config.ts @@ -5,7 +5,6 @@ const baseOptions: Options = { dts: true, entry: { clipper2: "clipper2/index.ts", - "babel-plugin-bigint-patch": "babel-plugin-bigint-patch/index.ts", }, minify: false, skipNodeModulesBundle: true, diff --git a/packages/turf/babel.config.json b/packages/turf/babel.config.json index f3139a97db..f77b82335c 100644 --- a/packages/turf/babel.config.json +++ b/packages/turf/babel.config.json @@ -3,8 +3,7 @@ [ "@babel/preset-env", { - "targets": "> 0.25%, last 2 versions, fully supports es5, not dead", - "modules": false + "targets": "> 0.25%, last 2 versions, fully supports es5, not dead" } ] ] diff --git a/packages/turf/package.json b/packages/turf/package.json index 196b947a8e..ff38321967 100644 --- a/packages/turf/package.json +++ b/packages/turf/package.json @@ -76,18 +76,15 @@ "devDependencies": { "@babel/core": "^7.26.10", "@babel/preset-env": "^7.26.9", - "@rollup/plugin-alias": "^6.0.0", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.3", "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-terser": "^0.4.4", "@turf/internal": "workspace:*", "@types/tape": "^5.8.1", - "babel-plugin-transform-bigint-to-jsbi": "^1.0.3", "camelcase": "^8.0.0", "documentation": "^14.0.3", "glob": "^11.1.0", - "jsbi": "^4.3.2", "rollup": "^4.40.1", "rollup-plugin-polyfill-node": "^0.13.0", "tape": "^5.9.0", diff --git a/packages/turf/rollup.config.js b/packages/turf/rollup.config.js index fbb88871c2..7932c14b6f 100644 --- a/packages/turf/rollup.config.js +++ b/packages/turf/rollup.config.js @@ -1,15 +1,9 @@ -import * as babelCore from "@babel/core"; +import { babel } from "@rollup/plugin-babel"; import { readFileSync } from "fs"; -import alias from "@rollup/plugin-alias"; import commonjs from "@rollup/plugin-commonjs"; import nodePolyfills from "rollup-plugin-polyfill-node"; import nodeResolve from "@rollup/plugin-node-resolve"; import terser from "@rollup/plugin-terser"; -import { fileURLToPath } from "url"; -import { dirname, resolve } from "path"; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); const pckg = JSON.parse(readFileSync("./package.json", "utf-8")); const input = "index.ts"; @@ -19,50 +13,10 @@ export default [ input, output: [{ file: pckg.browser, format: "umd", name: "turf" }], plugins: [ - alias({ - entries: [ - { - // Otherwise tries to require('jsbi/dist/jsbi.mjs') in output. - find: "jsbi/dist/jsbi.mjs", - replacement: resolve(__dirname, "node_modules/jsbi/dist/jsbi.mjs"), - }, - ], - }), - nodeResolve(), commonjs(), - { - name: "transform-all-to-es5", - transform(code, id) { - // Skip commonjs synthetic modules. - if (id.includes("?commonjs")) { - return null; - } - - console.log("Transforming to ES5:", id); - - // Don't apply bigint transforms to jsbi itself, but still transform - // it. - const plugins = id.includes("jsbi") - ? [] - : [ - // Transform most JS 2020 native BigInt to JSBI library - "babel-plugin-transform-bigint-to-jsbi", - // Convert straglers the above misses e.g. Number() - "@turf/internal/babel-plugin-bigint-patch", - ]; - - const result = babelCore.transformSync(code, { - filename: id, - plugins, - }); - - return { - code: result.code, - map: result.map, - }; - }, - }, + nodeResolve(), nodePolyfills(), + babel({ babelHelpers: "bundled" }), terser(), ], }, diff --git a/patches/clipper2-ts.patch b/patches/clipper2-ts.patch new file mode 100644 index 0000000000..320c8d0d94 --- /dev/null +++ b/patches/clipper2-ts.patch @@ -0,0 +1,90 @@ +diff --git a/dist/Core.js b/dist/Core.js +index f54c7a922c38d7eab2c6a6e1c8277c12f843b111..9eedff6ff2f016c5b5f7a34da132e45437167c20 100644 +--- a/dist/Core.js ++++ b/dist/Core.js +@@ -6,6 +6,9 @@ + * Purpose : Core structures and functions for the Clipper Library * + * License : https://www.boost.org/LICENSE_1_0.txt * + *******************************************************************************/ ++ ++import JSBI from "jsbi"; ++ + // Note: all clipping operations except for Difference are commutative. + export var ClipType; + (function (ClipType) { +@@ -39,11 +42,11 @@ export var PointInPolygonResult; + })(PointInPolygonResult || (PointInPolygonResult = {})); + export var InternalClipper; + (function (InternalClipper) { +- InternalClipper.MaxInt64 = 9223372036854775807n; +- InternalClipper.MaxCoord = Number(InternalClipper.MaxInt64 / 4n); ++ InternalClipper.MaxInt64 = JSBI.BigInt("9223372036854775807"); ++ InternalClipper.MaxCoord = JSBI.toNumber(JSBI.divide(InternalClipper.MaxInt64, JSBI.BigInt(4))); + InternalClipper.max_coord = InternalClipper.MaxCoord; + InternalClipper.min_coord = -InternalClipper.MaxCoord; +- InternalClipper.Invalid64 = Number(InternalClipper.MaxInt64); ++ InternalClipper.Invalid64 = JSBI.toNumber(InternalClipper.MaxInt64); + InternalClipper.floatingPointTolerance = 1E-12; + InternalClipper.defaultMinimumEdgeLength = 0.1; + function crossProduct(pt1, pt2, pt3) { +@@ -77,15 +80,15 @@ export var InternalClipper; + } + if (signAB === 0) + return 0; // both 0 because signs equal +- const bigA = BigInt(a); +- const bigB = BigInt(b); +- const bigC = BigInt(c); +- const bigD = BigInt(d); +- const prod1 = bigA * bigB; +- const prod2 = bigC * bigD; +- if (prod1 === prod2) ++ const bigA = JSBI.BigInt(a); ++ const bigB = JSBI.BigInt(b); ++ const bigC = JSBI.BigInt(c); ++ const bigD = JSBI.BigInt(d); ++ const prod1 = JSBI.multiply(bigA, bigB); ++ const prod2 = JSBI.multiply(bigC, bigD); ++ if (JSBI.equal(prod1, prod2)) + return 0; +- return (prod1 > prod2) ? 1 : -1; ++ return (JSBI.greaterThen(prod1, prod2)) ? 1 : -1; + } + InternalClipper.crossProductSign = crossProductSign; + function checkPrecision(precision) { +@@ -104,13 +107,13 @@ export var InternalClipper; + InternalClipper.triSign = triSign; + function multiplyUInt64(a, b) { + // Fix: a and b might be larger than 2^32, so don't use >>> 0 +- const aBig = BigInt(a); +- const bBig = BigInt(b); +- const res = aBig * bBig; ++ const aBig = JSBI.BigInt(a); ++ const bBig = JSBI.BigInt(b); ++ const res = JSBI.multiply(aBig, bBig); + return { +- lo64: Number(res & 0xffffffffffffffffn), +- hi64: Number(res >> 64n) +- }; ++ lo64: JSBI.toNumber(JSBI.bitwiseAnd(res, JSBI.BigInt("0xffffffffffffffffn"))), ++ hi64: JSBI.toNumber(JSBI.signedRightShift(res, JSBI.BigInt(64))), ++ } + } + InternalClipper.multiplyUInt64 = multiplyUInt64; + // returns true if (and only if) a * b == c * d +@@ -133,11 +136,11 @@ export var InternalClipper; + return false; + if (signAb === 0) + return true; +- const bigA = BigInt(absA); +- const bigB = BigInt(absB); +- const bigC = BigInt(absC); +- const bigD = BigInt(absD); +- return (bigA * bigB) === (bigC * bigD); ++ const bigA = JSBI.BigInt(absA); ++ const bigB = JSBI.BigInt(absB); ++ const bigC = JSBI.BigInt(absC); ++ const bigD = JSBI.BigInt(absD); ++ return JSBI.equal(JSBI.multiply(bigA, bigB), JSBI.multiply(bigC, bigD)); + } + InternalClipper.productsAreEqual = productsAreEqual; + function isCollinear(pt1, sharedPt, pt2) { \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 338d00212b..63eb6d74f8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,11 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +patchedDependencies: + clipper2-ts: + hash: 997913062feeb1de5fd5261beeb64bd3c36ed793014e98af5d790ee1eed2e846 + path: patches/clipper2-ts.patch + importers: .: @@ -115,7 +120,10 @@ importers: version: 7946.0.14 clipper2-ts: specifier: ^2.0.1 - version: 2.0.1 + version: 2.0.1(patch_hash=997913062feeb1de5fd5261beeb64bd3c36ed793014e98af5d790ee1eed2e846) + jsbi: + specifier: ^4.3.2 + version: 4.3.2 tslib: specifier: ^2.8.1 version: 2.8.1 @@ -129,6 +137,12 @@ importers: '@types/babel__core': specifier: ^7.20.5 version: 7.20.5 + '@types/tape': + specifier: ^5.8.1 + version: 5.8.1 + tape: + specifier: ^5.9.0 + version: 5.9.0 tsup: specifier: ^8.4.0 version: 8.4.0(postcss@8.5.3)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) @@ -487,9 +501,6 @@ importers: '@babel/preset-env': specifier: ^7.26.9 version: 7.26.9(@babel/core@7.26.10) - '@rollup/plugin-alias': - specifier: ^6.0.0 - version: 6.0.0(rollup@4.40.1) '@rollup/plugin-babel': specifier: ^6.0.4 version: 6.0.4(@babel/core@7.26.10)(@types/babel__core@7.20.5)(rollup@4.40.1) @@ -508,9 +519,6 @@ importers: '@types/tape': specifier: ^5.8.1 version: 5.8.1 - babel-plugin-transform-bigint-to-jsbi: - specifier: ^1.0.3 - version: 1.0.3(@babel/core@7.26.10)(@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.10)) camelcase: specifier: ^8.0.0 version: 8.0.0 @@ -520,9 +528,6 @@ importers: glob: specifier: ^11.1.0 version: 11.1.0 - jsbi: - specifier: ^4.3.2 - version: 4.3.2 rollup: specifier: ^4.40.1 version: 4.40.1 @@ -2541,7 +2546,7 @@ importers: version: 7946.0.14 clipper2-ts: specifier: ^2.0.1 - version: 2.0.1 + version: 2.0.1(patch_hash=997913062feeb1de5fd5261beeb64bd3c36ed793014e98af5d790ee1eed2e846) tslib: specifier: ^2.8.1 version: 2.8.1 @@ -3312,7 +3317,7 @@ importers: version: 7946.0.14 clipper2-ts: specifier: ^2.0.1 - version: 2.0.1 + version: 2.0.1(patch_hash=997913062feeb1de5fd5261beeb64bd3c36ed793014e98af5d790ee1eed2e846) tslib: specifier: ^2.8.1 version: 2.8.1 @@ -6195,7 +6200,7 @@ importers: version: 7946.0.14 clipper2-ts: specifier: ^2.0.1 - version: 2.0.1 + version: 2.0.1(patch_hash=997913062feeb1de5fd5261beeb64bd3c36ed793014e98af5d790ee1eed2e846) tslib: specifier: ^2.8.1 version: 2.8.1 @@ -6511,11 +6516,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-bigint@7.8.3': - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-import-assertions@7.26.0': resolution: {integrity: sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==} engines: {node: '>=6.9.0'} @@ -7602,15 +7602,6 @@ packages: resolution: {integrity: sha512-nRqvPYO8xUVdgy/KhJuaCrWlVT/4uZr97Mpbuizsa6CmvtCQf3NuYnVvOOrpYiKUJcZYtEvm84OooJ8+lJytMQ==} engines: {node: '>=14.6'} - '@rollup/plugin-alias@6.0.0': - resolution: {integrity: sha512-tPCzJOtS7uuVZd+xPhoy5W4vThe6KWXNmsFCNktaAh5RTqcLiSfT4huPQIXkgJ6YCOjJHvecOAzQxLFhPxKr+g==} - engines: {node: '>=20.19.0'} - peerDependencies: - rollup: '>=4.0.0' - peerDependenciesMeta: - rollup: - optional: true - '@rollup/plugin-babel@6.0.4': resolution: {integrity: sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==} engines: {node: '>=14.0.0'} @@ -8176,12 +8167,6 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-transform-bigint-to-jsbi@1.0.3: - resolution: {integrity: sha512-6O9dFuJSJYUziMd4OE4o/11kW2HBCC5qmF/liddDs/+pmm6iEB5BIlNQgiowjGokOR5ne7ynSi9MZt6uGPmusg==} - peerDependencies: - '@babel/core': ^7.17.2 - '@babel/plugin-syntax-bigint': ^7.8.3 - bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} @@ -12179,11 +12164,6 @@ snapshots: dependencies: '@babel/core': 7.26.10 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.10)': - dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 @@ -13468,10 +13448,6 @@ snapshots: write-file-atomic: 5.0.1 write-yaml-file: 4.2.0 - '@rollup/plugin-alias@6.0.0(rollup@4.40.1)': - optionalDependencies: - rollup: 4.40.1 - '@rollup/plugin-babel@6.0.4(@babel/core@7.26.10)(@types/babel__core@7.20.5)(rollup@4.40.1)': dependencies: '@babel/core': 7.26.10 @@ -14060,11 +14036,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-transform-bigint-to-jsbi@1.0.3(@babel/core@7.26.10)(@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.10)): - dependencies: - '@babel/core': 7.26.10 - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.26.10) - bail@2.0.2: {} balanced-match@1.0.2: {} @@ -14274,7 +14245,7 @@ snapshots: cli-width@4.1.0: {} - clipper2-ts@2.0.1: {} + clipper2-ts@2.0.1(patch_hash=997913062feeb1de5fd5261beeb64bd3c36ed793014e98af5d790ee1eed2e846): {} cliui@7.0.4: dependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index dee51e928d..5eed33654d 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,2 +1,4 @@ packages: - - "packages/*" + - packages/* +patchedDependencies: + clipper2-ts: patches/clipper2-ts.patch From 5032695581588a5b0137516008c2a177732ca3c0 Mon Sep 17 00:00:00 2001 From: James Beard Date: Sat, 17 Jan 2026 17:02:48 +1100 Subject: [PATCH 13/14] Couple of suggested coding / performance changes. --- packages/internal/clipper2/index.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/internal/clipper2/index.ts b/packages/internal/clipper2/index.ts index 33a79676cb..1e9cc5360d 100644 --- a/packages/internal/clipper2/index.ts +++ b/packages/internal/clipper2/index.ts @@ -16,7 +16,9 @@ function multiPolygonToPaths(coords: Position[][][]): PathsD { const paths: PathsD = []; for (const polygon of coords) { - paths.push(...polygonToPaths(polygon)); + for (const ring of polygonToPaths(polygon)) { + paths.push(ring); + } } return paths; @@ -47,8 +49,7 @@ function polygonToPaths(coords: Position[][]): PathsD { */ function enforceOuterRing(path: PathD): PathD { if (areaD(path) < 0) { - // Leave original array untouched. - return [...path].reverse(); + return path.reverse(); } return path; From b4e0728b876988d412b8401ff737cb4ed2f2ed72 Mon Sep 17 00:00:00 2001 From: James Beard Date: Sat, 17 Jan 2026 17:22:21 +1100 Subject: [PATCH 14/14] Rejigging new internal package so nx recognises its source files as a build dependency. --- nx.json | 6 +++++- packages/internal/{ => src}/clipper2/index.ts | 0 packages/internal/test.ts | 2 +- packages/internal/tsup.config.ts | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) rename packages/internal/{ => src}/clipper2/index.ts (100%) diff --git a/nx.json b/nx.json index e6ced2dd5d..c5a0b0452c 100644 --- a/nx.json +++ b/nx.json @@ -6,7 +6,11 @@ "{projectRoot}/package.json", "{projectRoot}/tsconfig.json" ], - "sources": ["{projectRoot}/index.{js,ts}", "{projectRoot}/lib/**"] + "sources": [ + "{projectRoot}/index.{js,ts}", + "{projectRoot}/lib/**", + "{projectRoot}/src/**" + ] }, "targetDefaults": { "build": { diff --git a/packages/internal/clipper2/index.ts b/packages/internal/src/clipper2/index.ts similarity index 100% rename from packages/internal/clipper2/index.ts rename to packages/internal/src/clipper2/index.ts diff --git a/packages/internal/test.ts b/packages/internal/test.ts index 2495e34a92..54b7b3fd2e 100644 --- a/packages/internal/test.ts +++ b/packages/internal/test.ts @@ -5,7 +5,7 @@ import { multiPolygonToPaths, polygonToPaths, polyTreeToGeoJSON, -} from "./clipper2/index.js"; +} from "./src/clipper2/index.js"; test("clipper2", (t) => { const clipper = new ClipperD(TURF_CLIPPER2_SCALE_FACTOR); diff --git a/packages/internal/tsup.config.ts b/packages/internal/tsup.config.ts index c0b977eb94..0634185024 100644 --- a/packages/internal/tsup.config.ts +++ b/packages/internal/tsup.config.ts @@ -4,7 +4,7 @@ const baseOptions: Options = { clean: true, dts: true, entry: { - clipper2: "clipper2/index.ts", + clipper2: "src/clipper2/index.ts", }, minify: false, skipNodeModulesBundle: true,