mirror of
https://github.com/Turfjs/turf.git
synced 2025-12-08 20:26:16 +00:00
Reduce bundle size of apps that import @turf/helpers (#2623)
* Remove GeojsonEquality library from turf-helpers/lib/ in favour of the third party geojson-equality-ts (which is essentially a copy of the code we're removing from turf-helpers/lib/). This allows us to remove the dependency on deep-equal which was causing an unintended increase in bundle size for users of turf-helpers. Updated boolean-equal and boolean-overlap to use geojson-equality-ts directly. * Removing keepNames from tsup config. --------- Co-authored-by: Tim Welch <tim.j.welch@gmail.com>
This commit is contained in:
parent
36167829d9
commit
0ce6ecca05
@ -1,5 +1,5 @@
|
||||
import { Feature, Geometry } from "geojson";
|
||||
import { GeojsonEquality } from "@turf/helpers";
|
||||
import { geojsonEquality } from "geojson-equality-ts";
|
||||
import { cleanCoords } from "@turf/clean-coords";
|
||||
import { getGeom } from "@turf/invariant";
|
||||
|
||||
@ -45,8 +45,9 @@ function booleanEqual(
|
||||
const type2 = getGeom(feature2).type;
|
||||
if (type1 !== type2) return false;
|
||||
|
||||
const equality = new GeojsonEquality({ precision: precision });
|
||||
return equality.compare(cleanCoords(feature1), cleanCoords(feature2));
|
||||
return geojsonEquality(cleanCoords(feature1), cleanCoords(feature2), {
|
||||
precision,
|
||||
});
|
||||
}
|
||||
|
||||
export { booleanEqual };
|
||||
|
||||
@ -74,6 +74,7 @@
|
||||
"@turf/clean-coords": "workspace:^",
|
||||
"@turf/helpers": "workspace:^",
|
||||
"@turf/invariant": "workspace:^",
|
||||
"geojson-equality-ts": "^1.0.2",
|
||||
"tslib": "^2.6.2"
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import { segmentEach } from "@turf/meta";
|
||||
import { getGeom } from "@turf/invariant";
|
||||
import { lineOverlap } from "@turf/line-overlap";
|
||||
import { lineIntersect } from "@turf/line-intersect";
|
||||
import { GeojsonEquality } from "@turf/helpers";
|
||||
import { geojsonEquality } from "geojson-equality-ts";
|
||||
|
||||
/**
|
||||
* Compares two geometries of the same dimension and returns true if their intersection set results in a geometry
|
||||
@ -49,8 +49,8 @@ function booleanOverlap(
|
||||
if (type1 === "Point") throw new Error("Point geometry not supported");
|
||||
|
||||
// features must be not equal
|
||||
const equality = new GeojsonEquality({ precision: 6 });
|
||||
if (equality.compare(feature1 as any, feature2 as any)) return false;
|
||||
if (geojsonEquality(feature1 as any, feature2 as any, { precision: 6 }))
|
||||
return false;
|
||||
|
||||
let overlap = 0;
|
||||
|
||||
|
||||
@ -75,6 +75,7 @@
|
||||
"@turf/line-intersect": "workspace:^",
|
||||
"@turf/line-overlap": "workspace:^",
|
||||
"@turf/meta": "workspace:^",
|
||||
"geojson-equality-ts": "^1.0.2",
|
||||
"tslib": "^2.6.2"
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,6 @@ import {
|
||||
|
||||
import { Id } from "./lib/geojson.js";
|
||||
export * from "./lib/geojson.js";
|
||||
export * from "./lib/geojson-equality.js";
|
||||
|
||||
// TurfJS Combined Types
|
||||
export type Coord = Feature<Point> | Point | Position;
|
||||
|
||||
@ -1,198 +0,0 @@
|
||||
import {
|
||||
Feature,
|
||||
LineString,
|
||||
Position,
|
||||
GeoJSON,
|
||||
Point,
|
||||
Polygon,
|
||||
GeometryCollection,
|
||||
FeatureCollection,
|
||||
MultiLineString,
|
||||
MultiPoint,
|
||||
MultiPolygon,
|
||||
} from "geojson";
|
||||
import equal from "deep-equal";
|
||||
|
||||
/**
|
||||
|
||||
* GeoJSON equality checking utility.
|
||||
* Adapted from https://github.com/geosquare/geojson-equality
|
||||
*
|
||||
* @memberof helpers
|
||||
* @type {Class}
|
||||
*/
|
||||
export class GeojsonEquality {
|
||||
private precision: number;
|
||||
private direction = false;
|
||||
private compareProperties = true;
|
||||
|
||||
constructor(opts?: {
|
||||
precision?: number;
|
||||
direction?: boolean;
|
||||
compareProperties?: boolean;
|
||||
}) {
|
||||
this.precision = 10 ** -(opts?.precision ?? 17);
|
||||
this.direction = opts?.direction ?? false;
|
||||
this.compareProperties = opts?.compareProperties ?? true;
|
||||
}
|
||||
|
||||
compare(g1: GeoJSON, g2: GeoJSON): boolean {
|
||||
if (g1.type !== g2.type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sameLength(g1, g2)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (g1.type) {
|
||||
case "Point":
|
||||
return this.compareCoord(g1.coordinates, (g2 as Point).coordinates);
|
||||
case "LineString":
|
||||
return this.compareLine(g1.coordinates, (g2 as LineString).coordinates);
|
||||
case "Polygon":
|
||||
return this.comparePolygon(g1, g2 as Polygon);
|
||||
case "GeometryCollection":
|
||||
return this.compareGeometryCollection(g1, g2 as GeometryCollection);
|
||||
case "Feature":
|
||||
return this.compareFeature(g1, g2 as Feature);
|
||||
case "FeatureCollection":
|
||||
return this.compareFeatureCollection(g1, g2 as FeatureCollection);
|
||||
default:
|
||||
if (g1.type.startsWith("Multi")) {
|
||||
const g1s = explode(g1);
|
||||
const g2s = explode(
|
||||
g2 as MultiLineString | MultiPoint | MultiPolygon
|
||||
);
|
||||
return g1s.every((g1part) =>
|
||||
g2s.some((g2part) => this.compare(g1part as any, g2part as any))
|
||||
);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private compareCoord(c1: Position, c2: Position) {
|
||||
return (
|
||||
c1.length === c2.length &&
|
||||
c1.every((c, i) => Math.abs(c - c2[i]) < this.precision)
|
||||
);
|
||||
}
|
||||
|
||||
private compareLine(
|
||||
path1: Position[],
|
||||
path2: Position[],
|
||||
ind = 0,
|
||||
isPoly = false
|
||||
): boolean {
|
||||
if (!sameLength(path1, path2)) {
|
||||
return false;
|
||||
}
|
||||
const p1 = path1;
|
||||
let p2 = path2;
|
||||
if (isPoly && !this.compareCoord(p1[0], p2[0])) {
|
||||
// fix start index of both to same point
|
||||
const startIndex = this.fixStartIndex(p2, p1);
|
||||
if (!startIndex) {
|
||||
return false;
|
||||
} else {
|
||||
p2 = startIndex;
|
||||
}
|
||||
}
|
||||
// for linestring ind =0 and for polygon ind =1
|
||||
const sameDirection = this.compareCoord(p1[ind], p2[ind]);
|
||||
if (this.direction || sameDirection) {
|
||||
return this.comparePath(p1, p2);
|
||||
} else {
|
||||
if (this.compareCoord(p1[ind], p2[p2.length - (1 + ind)])) {
|
||||
return this.comparePath(p1.slice().reverse(), p2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private fixStartIndex(sourcePath: Position[], targetPath: Position[]) {
|
||||
//make sourcePath first point same as of targetPath
|
||||
let correctPath,
|
||||
ind = -1;
|
||||
for (let i = 0; i < sourcePath.length; i++) {
|
||||
if (this.compareCoord(sourcePath[i], targetPath[0])) {
|
||||
ind = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ind >= 0) {
|
||||
correctPath = ([] as Position[]).concat(
|
||||
sourcePath.slice(ind, sourcePath.length),
|
||||
sourcePath.slice(1, ind + 1)
|
||||
);
|
||||
}
|
||||
return correctPath;
|
||||
}
|
||||
|
||||
private comparePath(p1: Position[], p2: Position[]) {
|
||||
return p1.every((c, i) => this.compareCoord(c, p2[i]));
|
||||
}
|
||||
|
||||
private comparePolygon(g1: Polygon, g2: Polygon) {
|
||||
if (this.compareLine(g1.coordinates[0], g2.coordinates[0], 1, true)) {
|
||||
const holes1 = g1.coordinates.slice(1, g1.coordinates.length);
|
||||
const holes2 = g2.coordinates.slice(1, g2.coordinates.length);
|
||||
return holes1.every((h1) =>
|
||||
holes2.some((h2) => this.compareLine(h1, h2, 1, true))
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private compareGeometryCollection(
|
||||
g1: GeometryCollection,
|
||||
g2: GeometryCollection
|
||||
) {
|
||||
return (
|
||||
sameLength(g1.geometries, g2.geometries) &&
|
||||
this.compareBBox(g1, g2) &&
|
||||
g1.geometries.every((g, i) => this.compare(g, g2.geometries[i]))
|
||||
);
|
||||
}
|
||||
|
||||
private compareFeature(g1: Feature, g2: Feature) {
|
||||
return (
|
||||
g1.id === g2.id &&
|
||||
(this.compareProperties ? equal(g1.properties, g2.properties) : true) &&
|
||||
this.compareBBox(g1, g2) &&
|
||||
this.compare(g1.geometry, g2.geometry)
|
||||
);
|
||||
}
|
||||
|
||||
private compareFeatureCollection(
|
||||
g1: FeatureCollection,
|
||||
g2: FeatureCollection
|
||||
) {
|
||||
return (
|
||||
sameLength(g1.features, g2.features) &&
|
||||
this.compareBBox(g1, g2) &&
|
||||
g1.features.every((f, i) => this.compare(f, g2.features[i]))
|
||||
);
|
||||
}
|
||||
|
||||
private compareBBox(g1: GeoJSON, g2: GeoJSON): boolean {
|
||||
return (
|
||||
Boolean(!g1.bbox && !g2.bbox) ||
|
||||
(g1.bbox && g2.bbox ? this.compareCoord(g1.bbox, g2.bbox) : false)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function sameLength(g1: any, g2: any) {
|
||||
return g1.coordinates
|
||||
? g1.coordinates.length === g2.coordinates.length
|
||||
: g1.length === g2.length;
|
||||
}
|
||||
|
||||
function explode(g: MultiLineString | MultiPoint | MultiPolygon) {
|
||||
return g.coordinates.map((part) => ({
|
||||
type: g.type.replace("Multi", ""),
|
||||
coordinates: part,
|
||||
}));
|
||||
}
|
||||
@ -59,7 +59,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/benchmark": "^2.1.5",
|
||||
"@types/deep-equal": "^1.0.4",
|
||||
"@types/tape": "^4.2.32",
|
||||
"benchmark": "^2.1.4",
|
||||
"npm-run-all": "^4.1.5",
|
||||
@ -69,7 +68,6 @@
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"deep-equal": "^2.2.3",
|
||||
"tslib": "^2.6.2"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
22
pnpm-lock.yaml
generated
22
pnpm-lock.yaml
generated
@ -1146,6 +1146,9 @@ importers:
|
||||
'@turf/invariant':
|
||||
specifier: workspace:^
|
||||
version: link:../turf-invariant
|
||||
geojson-equality-ts:
|
||||
specifier: ^1.0.2
|
||||
version: 1.0.2
|
||||
tslib:
|
||||
specifier: ^2.6.2
|
||||
version: 2.6.2
|
||||
@ -1251,6 +1254,9 @@ importers:
|
||||
'@turf/meta':
|
||||
specifier: workspace:^
|
||||
version: link:../turf-meta
|
||||
geojson-equality-ts:
|
||||
specifier: ^1.0.2
|
||||
version: 1.0.2
|
||||
tslib:
|
||||
specifier: ^2.6.2
|
||||
version: 2.6.2
|
||||
@ -3154,9 +3160,6 @@ importers:
|
||||
|
||||
packages/turf-helpers:
|
||||
dependencies:
|
||||
deep-equal:
|
||||
specifier: ^2.2.3
|
||||
version: 2.2.3
|
||||
tslib:
|
||||
specifier: ^2.6.2
|
||||
version: 2.6.2
|
||||
@ -3164,9 +3167,6 @@ importers:
|
||||
'@types/benchmark':
|
||||
specifier: ^2.1.5
|
||||
version: 2.1.5
|
||||
'@types/deep-equal':
|
||||
specifier: ^1.0.4
|
||||
version: 1.0.4
|
||||
'@types/tape':
|
||||
specifier: ^4.2.32
|
||||
version: 4.13.4
|
||||
@ -9064,6 +9064,10 @@ packages:
|
||||
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
|
||||
dev: true
|
||||
|
||||
/@types/geojson@7946.0.14:
|
||||
resolution: {integrity: sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==}
|
||||
dev: false
|
||||
|
||||
/@types/geojson@7946.0.8:
|
||||
resolution: {integrity: sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==}
|
||||
|
||||
@ -12086,6 +12090,12 @@ packages:
|
||||
engines: {node: '>=6.9.0'}
|
||||
dev: true
|
||||
|
||||
/geojson-equality-ts@1.0.2:
|
||||
resolution: {integrity: sha512-h3Ryq+0mCSN/7yLs0eDgrZhvc9af23o/QuC4aTiuuzP/MRCtd6mf5rLsLRY44jX0RPUfM8c4GqERQmlUxPGPoQ==}
|
||||
dependencies:
|
||||
'@types/geojson': 7946.0.14
|
||||
dev: false
|
||||
|
||||
/geojson-polygon-self-intersections@1.2.1:
|
||||
resolution: {integrity: sha512-/QM1b5u2d172qQVO//9CGRa49jEmclKEsYOQmWP9ooEjj63tBM51m2805xsbxkzlEELQ2REgTf700gUhhlegxA==}
|
||||
dependencies:
|
||||
|
||||
@ -9,7 +9,6 @@ const baseOptions: Options = {
|
||||
sourcemap: true,
|
||||
target: "es2017",
|
||||
tsconfig: "./tsconfig.json",
|
||||
keepNames: true,
|
||||
// treeshake: true, causes "chunk.default" warning, breaks CJS exports?
|
||||
cjsInterop: true,
|
||||
splitting: true,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user