@turf/clean-coords 7.2.0 → 7.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,8 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});// index.ts
2
2
  var _helpers = require('@turf/helpers');
3
3
  var _invariant = require('@turf/invariant');
4
+ var _booleanpointonline = require('@turf/boolean-point-on-line');
5
+
4
6
  function cleanCoords(geojson, options = {}) {
5
7
  var mutate = typeof options === "object" ? options.mutate : options;
6
8
  if (!geojson) throw new Error("geojson is required");
@@ -58,65 +60,47 @@ function cleanCoords(geojson, options = {}) {
58
60
  }
59
61
  }
60
62
  function cleanLine(line, type) {
61
- var points = _invariant.getCoords.call(void 0, line);
63
+ const points = _invariant.getCoords.call(void 0, line);
62
64
  if (points.length === 2 && !equals(points[0], points[1])) return points;
63
- var newPoints = [];
64
- var secondToLast = points.length - 1;
65
- var newPointsLength = newPoints.length;
66
- newPoints.push(points[0]);
67
- for (var i = 1; i < secondToLast; i++) {
68
- var prevAddedPoint = newPoints[newPoints.length - 1];
69
- if (points[i][0] === prevAddedPoint[0] && points[i][1] === prevAddedPoint[1])
70
- continue;
71
- else {
72
- newPoints.push(points[i]);
73
- newPointsLength = newPoints.length;
74
- if (newPointsLength > 2) {
75
- if (isPointOnLineSegment(
76
- newPoints[newPointsLength - 3],
77
- newPoints[newPointsLength - 1],
78
- newPoints[newPointsLength - 2]
79
- ))
80
- newPoints.splice(newPoints.length - 2, 1);
81
- }
65
+ const newPoints = [];
66
+ let a = 0, b = 1, c = 2;
67
+ newPoints.push(points[a]);
68
+ while (c < points.length) {
69
+ if (_booleanpointonline.booleanPointOnLine.call(void 0, points[b], _helpers.lineString.call(void 0, [points[a], points[c]]))) {
70
+ b = c;
71
+ } else {
72
+ newPoints.push(points[b]);
73
+ a = b;
74
+ b++;
75
+ c = b;
82
76
  }
77
+ c++;
83
78
  }
84
- newPoints.push(points[points.length - 1]);
85
- newPointsLength = newPoints.length;
86
- if ((type === "Polygon" || type === "MultiPolygon") && equals(points[0], points[points.length - 1]) && newPointsLength < 4) {
87
- throw new Error("invalid polygon");
88
- }
89
- if (type === "LineString" && newPointsLength < 3) {
90
- return newPoints;
79
+ newPoints.push(points[b]);
80
+ if (type === "Polygon" || type === "MultiPolygon") {
81
+ if (_booleanpointonline.booleanPointOnLine.call(void 0,
82
+ newPoints[0],
83
+ _helpers.lineString.call(void 0, [newPoints[1], newPoints[newPoints.length - 2]])
84
+ )) {
85
+ newPoints.shift();
86
+ newPoints.pop();
87
+ newPoints.push(newPoints[0]);
88
+ }
89
+ if (newPoints.length < 4) {
90
+ throw new Error("invalid polygon, fewer than 4 points");
91
+ }
92
+ if (!equals(newPoints[0], newPoints[newPoints.length - 1])) {
93
+ throw new Error("invalid polygon, first and last points not equal");
94
+ }
91
95
  }
92
- if (isPointOnLineSegment(
93
- newPoints[newPointsLength - 3],
94
- newPoints[newPointsLength - 1],
95
- newPoints[newPointsLength - 2]
96
- ))
97
- newPoints.splice(newPoints.length - 2, 1);
98
96
  return newPoints;
99
97
  }
100
98
  function equals(pt1, pt2) {
101
99
  return pt1[0] === pt2[0] && pt1[1] === pt2[1];
102
100
  }
103
- function isPointOnLineSegment(start, end, point) {
104
- var x = point[0], y = point[1];
105
- var startX = start[0], startY = start[1];
106
- var endX = end[0], endY = end[1];
107
- var dxc = x - startX;
108
- var dyc = y - startY;
109
- var dxl = endX - startX;
110
- var dyl = endY - startY;
111
- var cross = dxc * dyl - dyc * dxl;
112
- if (cross !== 0) return false;
113
- else if (Math.abs(dxl) >= Math.abs(dyl))
114
- return dxl > 0 ? startX <= x && x <= endX : endX <= x && x <= startX;
115
- else return dyl > 0 ? startY <= y && y <= endY : endY <= y && y <= startY;
116
- }
117
- var turf_clean_coords_default = cleanCoords;
101
+ var index_default = cleanCoords;
118
102
 
119
103
 
120
104
 
121
- exports.cleanCoords = cleanCoords; exports.default = turf_clean_coords_default;
105
+ exports.cleanCoords = cleanCoords; exports.default = index_default;
122
106
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/turf/turf/packages/turf-clean-coords/dist/cjs/index.cjs","../../index.ts"],"names":[],"mappings":"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","file":"/home/runner/work/turf/turf/packages/turf-clean-coords/dist/cjs/index.cjs","sourcesContent":[null,"import { Position } from \"geojson\";\nimport { feature } from \"@turf/helpers\";\nimport { getCoords, getType } from \"@turf/invariant\";\n\n// To-Do => Improve Typescript GeoJSON handling\n\n/**\n * Removes redundant coordinates from any GeoJSON Geometry.\n *\n * @function\n * @param {Geometry|Feature} geojson Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated\n * @returns {Geometry|Feature} the cleaned input Feature/Geometry\n * @example\n * var line = turf.lineString([[0, 0], [0, 2], [0, 5], [0, 8], [0, 8], [0, 10]]);\n * var multiPoint = turf.multiPoint([[0, 0], [0, 0], [2, 2]]);\n *\n * turf.cleanCoords(line).geometry.coordinates;\n * //= [[0, 0], [0, 10]]\n *\n * turf.cleanCoords(multiPoint).geometry.coordinates;\n * //= [[0, 0], [2, 2]]\n */\nfunction cleanCoords(\n geojson: any,\n options: {\n mutate?: boolean;\n } = {}\n) {\n // Backwards compatible with v4.0\n var mutate = typeof options === \"object\" ? options.mutate : options;\n if (!geojson) throw new Error(\"geojson is required\");\n var type = getType(geojson);\n\n // Store new \"clean\" points in this Array\n var newCoords = [];\n\n switch (type) {\n case \"LineString\":\n newCoords = cleanLine(geojson, type);\n break;\n case \"MultiLineString\":\n case \"Polygon\":\n getCoords(geojson).forEach(function (line) {\n newCoords.push(cleanLine(line, type));\n });\n break;\n case \"MultiPolygon\":\n getCoords(geojson).forEach(function (polygons: any) {\n var polyPoints: Position[] = [];\n polygons.forEach(function (ring: Position[]) {\n polyPoints.push(cleanLine(ring, type));\n });\n newCoords.push(polyPoints);\n });\n break;\n case \"Point\":\n return geojson;\n case \"MultiPoint\":\n var existing: Record<string, true> = {};\n getCoords(geojson).forEach(function (coord: any) {\n var key = coord.join(\"-\");\n if (!Object.prototype.hasOwnProperty.call(existing, key)) {\n newCoords.push(coord);\n existing[key] = true;\n }\n });\n break;\n default:\n throw new Error(type + \" geometry not supported\");\n }\n\n // Support input mutation\n if (geojson.coordinates) {\n if (mutate === true) {\n geojson.coordinates = newCoords;\n return geojson;\n }\n return { type: type, coordinates: newCoords };\n } else {\n if (mutate === true) {\n geojson.geometry.coordinates = newCoords;\n return geojson;\n }\n return feature({ type: type, coordinates: newCoords }, geojson.properties, {\n bbox: geojson.bbox,\n id: geojson.id,\n });\n }\n}\n\n/**\n * Clean Coords\n *\n * @private\n * @param {Array<number>|LineString} line Line\n * @param {string} type Type of geometry\n * @returns {Array<number>} Cleaned coordinates\n */\nfunction cleanLine(line: Position[], type: string) {\n var points = getCoords(line);\n // handle \"clean\" segment\n if (points.length === 2 && !equals(points[0], points[1])) return points;\n\n var newPoints = [];\n var secondToLast = points.length - 1;\n var newPointsLength = newPoints.length;\n\n newPoints.push(points[0]);\n for (var i = 1; i < secondToLast; i++) {\n var prevAddedPoint = newPoints[newPoints.length - 1];\n if (\n points[i][0] === prevAddedPoint[0] &&\n points[i][1] === prevAddedPoint[1]\n )\n continue;\n else {\n newPoints.push(points[i]);\n newPointsLength = newPoints.length;\n if (newPointsLength > 2) {\n if (\n isPointOnLineSegment(\n newPoints[newPointsLength - 3],\n newPoints[newPointsLength - 1],\n newPoints[newPointsLength - 2]\n )\n )\n newPoints.splice(newPoints.length - 2, 1);\n }\n }\n }\n newPoints.push(points[points.length - 1]);\n newPointsLength = newPoints.length;\n\n // (Multi)Polygons must have at least 4 points, but a closed LineString with only 3 points is acceptable\n if (\n (type === \"Polygon\" || type === \"MultiPolygon\") &&\n equals(points[0], points[points.length - 1]) &&\n newPointsLength < 4\n ) {\n throw new Error(\"invalid polygon\");\n }\n\n if (type === \"LineString\" && newPointsLength < 3) {\n return newPoints;\n }\n\n if (\n isPointOnLineSegment(\n newPoints[newPointsLength - 3],\n newPoints[newPointsLength - 1],\n newPoints[newPointsLength - 2]\n )\n )\n newPoints.splice(newPoints.length - 2, 1);\n\n return newPoints;\n}\n\n/**\n * Compares two points and returns if they are equals\n *\n * @private\n * @param {Position} pt1 point\n * @param {Position} pt2 point\n * @returns {boolean} true if they are equals\n */\nfunction equals(pt1: Position, pt2: Position) {\n return pt1[0] === pt2[0] && pt1[1] === pt2[1];\n}\n\n/**\n * Returns if `point` is on the segment between `start` and `end`.\n * Borrowed from `@turf/boolean-point-on-line` to speed up the evaluation (instead of using the module as dependency)\n *\n * @private\n * @param {Position} start coord pair of start of line\n * @param {Position} end coord pair of end of line\n * @param {Position} point coord pair of point to check\n * @returns {boolean} true/false\n */\nfunction isPointOnLineSegment(start: Position, end: Position, point: Position) {\n var x = point[0],\n y = point[1];\n var startX = start[0],\n startY = start[1];\n var endX = end[0],\n endY = end[1];\n\n var dxc = x - startX;\n var dyc = y - startY;\n var dxl = endX - startX;\n var dyl = endY - startY;\n var cross = dxc * dyl - dyc * dxl;\n\n if (cross !== 0) return false;\n else if (Math.abs(dxl) >= Math.abs(dyl))\n return dxl > 0 ? startX <= x && x <= endX : endX <= x && x <= startX;\n else return dyl > 0 ? startY <= y && y <= endY : endY <= y && y <= startY;\n}\n\nexport { cleanCoords };\nexport default cleanCoords;\n"]}
1
+ {"version":3,"sources":["/home/runner/work/turf/turf/packages/turf-clean-coords/dist/cjs/index.cjs","../../index.ts"],"names":[],"mappings":"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","file":"/home/runner/work/turf/turf/packages/turf-clean-coords/dist/cjs/index.cjs","sourcesContent":[null,"import { Position } from \"geojson\";\nimport { feature } from \"@turf/helpers\";\nimport { getCoords, getType } from \"@turf/invariant\";\nimport { booleanPointOnLine } from \"@turf/boolean-point-on-line\";\nimport { lineString } from \"@turf/helpers\";\n\n// To-Do => Improve Typescript GeoJSON handling\n\n/**\n * Removes redundant coordinates from any GeoJSON Geometry.\n *\n * @function\n * @param {Geometry|Feature} geojson Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated\n * @returns {Geometry|Feature} the cleaned input Feature/Geometry\n * @example\n * var line = turf.lineString([[0, 0], [0, 2], [0, 5], [0, 8], [0, 8], [0, 10]]);\n * var multiPoint = turf.multiPoint([[0, 0], [0, 0], [2, 2]]);\n *\n * turf.cleanCoords(line).geometry.coordinates;\n * //= [[0, 0], [0, 10]]\n *\n * turf.cleanCoords(multiPoint).geometry.coordinates;\n * //= [[0, 0], [2, 2]]\n */\nfunction cleanCoords(\n geojson: any,\n options: {\n mutate?: boolean;\n } = {}\n) {\n // Backwards compatible with v4.0\n var mutate = typeof options === \"object\" ? options.mutate : options;\n if (!geojson) throw new Error(\"geojson is required\");\n var type = getType(geojson);\n\n // Store new \"clean\" points in this Array\n var newCoords = [];\n\n switch (type) {\n case \"LineString\":\n newCoords = cleanLine(geojson, type);\n break;\n case \"MultiLineString\":\n case \"Polygon\":\n getCoords(geojson).forEach(function (line) {\n newCoords.push(cleanLine(line, type));\n });\n break;\n case \"MultiPolygon\":\n getCoords(geojson).forEach(function (polygons: any) {\n var polyPoints: Position[] = [];\n polygons.forEach(function (ring: Position[]) {\n polyPoints.push(cleanLine(ring, type));\n });\n newCoords.push(polyPoints);\n });\n break;\n case \"Point\":\n return geojson;\n case \"MultiPoint\":\n var existing: Record<string, true> = {};\n getCoords(geojson).forEach(function (coord: any) {\n var key = coord.join(\"-\");\n if (!Object.prototype.hasOwnProperty.call(existing, key)) {\n newCoords.push(coord);\n existing[key] = true;\n }\n });\n break;\n default:\n throw new Error(type + \" geometry not supported\");\n }\n\n // Support input mutation\n if (geojson.coordinates) {\n if (mutate === true) {\n geojson.coordinates = newCoords;\n return geojson;\n }\n return { type: type, coordinates: newCoords };\n } else {\n if (mutate === true) {\n geojson.geometry.coordinates = newCoords;\n return geojson;\n }\n return feature({ type: type, coordinates: newCoords }, geojson.properties, {\n bbox: geojson.bbox,\n id: geojson.id,\n });\n }\n}\n\n/**\n * Clean Coords\n *\n * @private\n * @param {Array<number>|LineString} line Line\n * @param {string} type Type of geometry\n * @returns {Array<number>} Cleaned coordinates\n */\nfunction cleanLine(line: Position[], type: string) {\n const points = getCoords(line);\n // handle \"clean\" segment\n if (points.length === 2 && !equals(points[0], points[1])) return points;\n\n const newPoints = [];\n\n // Segments based approach. With initial segment a-b, keep comparing to a\n // longer segment a-c and as long as b is still on a-c, b is a redundant\n // point.\n let a = 0,\n b = 1,\n c = 2;\n\n // Guaranteed we'll use the first point.\n newPoints.push(points[a]);\n // While there is still room to extend the segment ...\n while (c < points.length) {\n if (booleanPointOnLine(points[b], lineString([points[a], points[c]]))) {\n // b is on a-c, so we can discard point b, and extend a-b to be the same\n // as a-c as the basis for comparison during the next iteration.\n b = c;\n } else {\n // b is NOT on a-c, suggesting a-c is not an extension of a-b. Commit a-b\n // as a necessary segment.\n newPoints.push(points[b]);\n\n // Make our a-b for the next iteration start from the end of the segment\n // that was just locked in i.e. next a-b should be the current b-(b+1).\n a = b;\n b++;\n c = b;\n }\n // Plan to look at the next point during the next iteration.\n c++;\n }\n // No remaining points, so commit the current a-b segment.\n newPoints.push(points[b]);\n\n if (type === \"Polygon\" || type === \"MultiPolygon\") {\n // For polygons need to make sure the start / end point wasn't one of the\n // points that needed to be cleaned.\n // https://github.com/Turfjs/turf/issues/2406\n // For points [a, b, c, ..., z, a]\n // if a is on line b-z, it too can be removed. New array becomes\n // [b, c, ..., z, b]\n if (\n booleanPointOnLine(\n newPoints[0],\n lineString([newPoints[1], newPoints[newPoints.length - 2]])\n )\n ) {\n newPoints.shift(); // Discard starting point.\n newPoints.pop(); // Discard closing point.\n newPoints.push(newPoints[0]); // Duplicate the new closing point to end of array.\n }\n\n // (Multi)Polygons must have at least 4 points and be closed.\n if (newPoints.length < 4) {\n throw new Error(\"invalid polygon, fewer than 4 points\");\n }\n if (!equals(newPoints[0], newPoints[newPoints.length - 1])) {\n throw new Error(\"invalid polygon, first and last points not equal\");\n }\n }\n\n return newPoints;\n}\n\n/**\n * Compares two points and returns if they are equals\n *\n * @private\n * @param {Position} pt1 point\n * @param {Position} pt2 point\n * @returns {boolean} true if they are equals\n */\nfunction equals(pt1: Position, pt2: Position) {\n return pt1[0] === pt2[0] && pt1[1] === pt2[1];\n}\n\nexport { cleanCoords };\nexport default cleanCoords;\n"]}
package/dist/esm/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  // index.ts
2
2
  import { feature } from "@turf/helpers";
3
3
  import { getCoords, getType } from "@turf/invariant";
4
+ import { booleanPointOnLine } from "@turf/boolean-point-on-line";
5
+ import { lineString } from "@turf/helpers";
4
6
  function cleanCoords(geojson, options = {}) {
5
7
  var mutate = typeof options === "object" ? options.mutate : options;
6
8
  if (!geojson) throw new Error("geojson is required");
@@ -58,65 +60,47 @@ function cleanCoords(geojson, options = {}) {
58
60
  }
59
61
  }
60
62
  function cleanLine(line, type) {
61
- var points = getCoords(line);
63
+ const points = getCoords(line);
62
64
  if (points.length === 2 && !equals(points[0], points[1])) return points;
63
- var newPoints = [];
64
- var secondToLast = points.length - 1;
65
- var newPointsLength = newPoints.length;
66
- newPoints.push(points[0]);
67
- for (var i = 1; i < secondToLast; i++) {
68
- var prevAddedPoint = newPoints[newPoints.length - 1];
69
- if (points[i][0] === prevAddedPoint[0] && points[i][1] === prevAddedPoint[1])
70
- continue;
71
- else {
72
- newPoints.push(points[i]);
73
- newPointsLength = newPoints.length;
74
- if (newPointsLength > 2) {
75
- if (isPointOnLineSegment(
76
- newPoints[newPointsLength - 3],
77
- newPoints[newPointsLength - 1],
78
- newPoints[newPointsLength - 2]
79
- ))
80
- newPoints.splice(newPoints.length - 2, 1);
81
- }
65
+ const newPoints = [];
66
+ let a = 0, b = 1, c = 2;
67
+ newPoints.push(points[a]);
68
+ while (c < points.length) {
69
+ if (booleanPointOnLine(points[b], lineString([points[a], points[c]]))) {
70
+ b = c;
71
+ } else {
72
+ newPoints.push(points[b]);
73
+ a = b;
74
+ b++;
75
+ c = b;
82
76
  }
77
+ c++;
83
78
  }
84
- newPoints.push(points[points.length - 1]);
85
- newPointsLength = newPoints.length;
86
- if ((type === "Polygon" || type === "MultiPolygon") && equals(points[0], points[points.length - 1]) && newPointsLength < 4) {
87
- throw new Error("invalid polygon");
88
- }
89
- if (type === "LineString" && newPointsLength < 3) {
90
- return newPoints;
79
+ newPoints.push(points[b]);
80
+ if (type === "Polygon" || type === "MultiPolygon") {
81
+ if (booleanPointOnLine(
82
+ newPoints[0],
83
+ lineString([newPoints[1], newPoints[newPoints.length - 2]])
84
+ )) {
85
+ newPoints.shift();
86
+ newPoints.pop();
87
+ newPoints.push(newPoints[0]);
88
+ }
89
+ if (newPoints.length < 4) {
90
+ throw new Error("invalid polygon, fewer than 4 points");
91
+ }
92
+ if (!equals(newPoints[0], newPoints[newPoints.length - 1])) {
93
+ throw new Error("invalid polygon, first and last points not equal");
94
+ }
91
95
  }
92
- if (isPointOnLineSegment(
93
- newPoints[newPointsLength - 3],
94
- newPoints[newPointsLength - 1],
95
- newPoints[newPointsLength - 2]
96
- ))
97
- newPoints.splice(newPoints.length - 2, 1);
98
96
  return newPoints;
99
97
  }
100
98
  function equals(pt1, pt2) {
101
99
  return pt1[0] === pt2[0] && pt1[1] === pt2[1];
102
100
  }
103
- function isPointOnLineSegment(start, end, point) {
104
- var x = point[0], y = point[1];
105
- var startX = start[0], startY = start[1];
106
- var endX = end[0], endY = end[1];
107
- var dxc = x - startX;
108
- var dyc = y - startY;
109
- var dxl = endX - startX;
110
- var dyl = endY - startY;
111
- var cross = dxc * dyl - dyc * dxl;
112
- if (cross !== 0) return false;
113
- else if (Math.abs(dxl) >= Math.abs(dyl))
114
- return dxl > 0 ? startX <= x && x <= endX : endX <= x && x <= startX;
115
- else return dyl > 0 ? startY <= y && y <= endY : endY <= y && y <= startY;
116
- }
117
- var turf_clean_coords_default = cleanCoords;
101
+ var index_default = cleanCoords;
118
102
  export {
119
103
  cleanCoords,
120
- turf_clean_coords_default as default
104
+ index_default as default
121
105
  };
122
106
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../index.ts"],"sourcesContent":["import { Position } from \"geojson\";\nimport { feature } from \"@turf/helpers\";\nimport { getCoords, getType } from \"@turf/invariant\";\n\n// To-Do => Improve Typescript GeoJSON handling\n\n/**\n * Removes redundant coordinates from any GeoJSON Geometry.\n *\n * @function\n * @param {Geometry|Feature} geojson Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated\n * @returns {Geometry|Feature} the cleaned input Feature/Geometry\n * @example\n * var line = turf.lineString([[0, 0], [0, 2], [0, 5], [0, 8], [0, 8], [0, 10]]);\n * var multiPoint = turf.multiPoint([[0, 0], [0, 0], [2, 2]]);\n *\n * turf.cleanCoords(line).geometry.coordinates;\n * //= [[0, 0], [0, 10]]\n *\n * turf.cleanCoords(multiPoint).geometry.coordinates;\n * //= [[0, 0], [2, 2]]\n */\nfunction cleanCoords(\n geojson: any,\n options: {\n mutate?: boolean;\n } = {}\n) {\n // Backwards compatible with v4.0\n var mutate = typeof options === \"object\" ? options.mutate : options;\n if (!geojson) throw new Error(\"geojson is required\");\n var type = getType(geojson);\n\n // Store new \"clean\" points in this Array\n var newCoords = [];\n\n switch (type) {\n case \"LineString\":\n newCoords = cleanLine(geojson, type);\n break;\n case \"MultiLineString\":\n case \"Polygon\":\n getCoords(geojson).forEach(function (line) {\n newCoords.push(cleanLine(line, type));\n });\n break;\n case \"MultiPolygon\":\n getCoords(geojson).forEach(function (polygons: any) {\n var polyPoints: Position[] = [];\n polygons.forEach(function (ring: Position[]) {\n polyPoints.push(cleanLine(ring, type));\n });\n newCoords.push(polyPoints);\n });\n break;\n case \"Point\":\n return geojson;\n case \"MultiPoint\":\n var existing: Record<string, true> = {};\n getCoords(geojson).forEach(function (coord: any) {\n var key = coord.join(\"-\");\n if (!Object.prototype.hasOwnProperty.call(existing, key)) {\n newCoords.push(coord);\n existing[key] = true;\n }\n });\n break;\n default:\n throw new Error(type + \" geometry not supported\");\n }\n\n // Support input mutation\n if (geojson.coordinates) {\n if (mutate === true) {\n geojson.coordinates = newCoords;\n return geojson;\n }\n return { type: type, coordinates: newCoords };\n } else {\n if (mutate === true) {\n geojson.geometry.coordinates = newCoords;\n return geojson;\n }\n return feature({ type: type, coordinates: newCoords }, geojson.properties, {\n bbox: geojson.bbox,\n id: geojson.id,\n });\n }\n}\n\n/**\n * Clean Coords\n *\n * @private\n * @param {Array<number>|LineString} line Line\n * @param {string} type Type of geometry\n * @returns {Array<number>} Cleaned coordinates\n */\nfunction cleanLine(line: Position[], type: string) {\n var points = getCoords(line);\n // handle \"clean\" segment\n if (points.length === 2 && !equals(points[0], points[1])) return points;\n\n var newPoints = [];\n var secondToLast = points.length - 1;\n var newPointsLength = newPoints.length;\n\n newPoints.push(points[0]);\n for (var i = 1; i < secondToLast; i++) {\n var prevAddedPoint = newPoints[newPoints.length - 1];\n if (\n points[i][0] === prevAddedPoint[0] &&\n points[i][1] === prevAddedPoint[1]\n )\n continue;\n else {\n newPoints.push(points[i]);\n newPointsLength = newPoints.length;\n if (newPointsLength > 2) {\n if (\n isPointOnLineSegment(\n newPoints[newPointsLength - 3],\n newPoints[newPointsLength - 1],\n newPoints[newPointsLength - 2]\n )\n )\n newPoints.splice(newPoints.length - 2, 1);\n }\n }\n }\n newPoints.push(points[points.length - 1]);\n newPointsLength = newPoints.length;\n\n // (Multi)Polygons must have at least 4 points, but a closed LineString with only 3 points is acceptable\n if (\n (type === \"Polygon\" || type === \"MultiPolygon\") &&\n equals(points[0], points[points.length - 1]) &&\n newPointsLength < 4\n ) {\n throw new Error(\"invalid polygon\");\n }\n\n if (type === \"LineString\" && newPointsLength < 3) {\n return newPoints;\n }\n\n if (\n isPointOnLineSegment(\n newPoints[newPointsLength - 3],\n newPoints[newPointsLength - 1],\n newPoints[newPointsLength - 2]\n )\n )\n newPoints.splice(newPoints.length - 2, 1);\n\n return newPoints;\n}\n\n/**\n * Compares two points and returns if they are equals\n *\n * @private\n * @param {Position} pt1 point\n * @param {Position} pt2 point\n * @returns {boolean} true if they are equals\n */\nfunction equals(pt1: Position, pt2: Position) {\n return pt1[0] === pt2[0] && pt1[1] === pt2[1];\n}\n\n/**\n * Returns if `point` is on the segment between `start` and `end`.\n * Borrowed from `@turf/boolean-point-on-line` to speed up the evaluation (instead of using the module as dependency)\n *\n * @private\n * @param {Position} start coord pair of start of line\n * @param {Position} end coord pair of end of line\n * @param {Position} point coord pair of point to check\n * @returns {boolean} true/false\n */\nfunction isPointOnLineSegment(start: Position, end: Position, point: Position) {\n var x = point[0],\n y = point[1];\n var startX = start[0],\n startY = start[1];\n var endX = end[0],\n endY = end[1];\n\n var dxc = x - startX;\n var dyc = y - startY;\n var dxl = endX - startX;\n var dyl = endY - startY;\n var cross = dxc * dyl - dyc * dxl;\n\n if (cross !== 0) return false;\n else if (Math.abs(dxl) >= Math.abs(dyl))\n return dxl > 0 ? startX <= x && x <= endX : endX <= x && x <= startX;\n else return dyl > 0 ? startY <= y && y <= endY : endY <= y && y <= startY;\n}\n\nexport { cleanCoords };\nexport default cleanCoords;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../index.ts"],"sourcesContent":["import { Position } from \"geojson\";\nimport { feature } from \"@turf/helpers\";\nimport { getCoords, getType } from \"@turf/invariant\";\nimport { booleanPointOnLine } from \"@turf/boolean-point-on-line\";\nimport { lineString } from \"@turf/helpers\";\n\n// To-Do => Improve Typescript GeoJSON handling\n\n/**\n * Removes redundant coordinates from any GeoJSON Geometry.\n *\n * @function\n * @param {Geometry|Feature} geojson Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated\n * @returns {Geometry|Feature} the cleaned input Feature/Geometry\n * @example\n * var line = turf.lineString([[0, 0], [0, 2], [0, 5], [0, 8], [0, 8], [0, 10]]);\n * var multiPoint = turf.multiPoint([[0, 0], [0, 0], [2, 2]]);\n *\n * turf.cleanCoords(line).geometry.coordinates;\n * //= [[0, 0], [0, 10]]\n *\n * turf.cleanCoords(multiPoint).geometry.coordinates;\n * //= [[0, 0], [2, 2]]\n */\nfunction cleanCoords(\n geojson: any,\n options: {\n mutate?: boolean;\n } = {}\n) {\n // Backwards compatible with v4.0\n var mutate = typeof options === \"object\" ? options.mutate : options;\n if (!geojson) throw new Error(\"geojson is required\");\n var type = getType(geojson);\n\n // Store new \"clean\" points in this Array\n var newCoords = [];\n\n switch (type) {\n case \"LineString\":\n newCoords = cleanLine(geojson, type);\n break;\n case \"MultiLineString\":\n case \"Polygon\":\n getCoords(geojson).forEach(function (line) {\n newCoords.push(cleanLine(line, type));\n });\n break;\n case \"MultiPolygon\":\n getCoords(geojson).forEach(function (polygons: any) {\n var polyPoints: Position[] = [];\n polygons.forEach(function (ring: Position[]) {\n polyPoints.push(cleanLine(ring, type));\n });\n newCoords.push(polyPoints);\n });\n break;\n case \"Point\":\n return geojson;\n case \"MultiPoint\":\n var existing: Record<string, true> = {};\n getCoords(geojson).forEach(function (coord: any) {\n var key = coord.join(\"-\");\n if (!Object.prototype.hasOwnProperty.call(existing, key)) {\n newCoords.push(coord);\n existing[key] = true;\n }\n });\n break;\n default:\n throw new Error(type + \" geometry not supported\");\n }\n\n // Support input mutation\n if (geojson.coordinates) {\n if (mutate === true) {\n geojson.coordinates = newCoords;\n return geojson;\n }\n return { type: type, coordinates: newCoords };\n } else {\n if (mutate === true) {\n geojson.geometry.coordinates = newCoords;\n return geojson;\n }\n return feature({ type: type, coordinates: newCoords }, geojson.properties, {\n bbox: geojson.bbox,\n id: geojson.id,\n });\n }\n}\n\n/**\n * Clean Coords\n *\n * @private\n * @param {Array<number>|LineString} line Line\n * @param {string} type Type of geometry\n * @returns {Array<number>} Cleaned coordinates\n */\nfunction cleanLine(line: Position[], type: string) {\n const points = getCoords(line);\n // handle \"clean\" segment\n if (points.length === 2 && !equals(points[0], points[1])) return points;\n\n const newPoints = [];\n\n // Segments based approach. With initial segment a-b, keep comparing to a\n // longer segment a-c and as long as b is still on a-c, b is a redundant\n // point.\n let a = 0,\n b = 1,\n c = 2;\n\n // Guaranteed we'll use the first point.\n newPoints.push(points[a]);\n // While there is still room to extend the segment ...\n while (c < points.length) {\n if (booleanPointOnLine(points[b], lineString([points[a], points[c]]))) {\n // b is on a-c, so we can discard point b, and extend a-b to be the same\n // as a-c as the basis for comparison during the next iteration.\n b = c;\n } else {\n // b is NOT on a-c, suggesting a-c is not an extension of a-b. Commit a-b\n // as a necessary segment.\n newPoints.push(points[b]);\n\n // Make our a-b for the next iteration start from the end of the segment\n // that was just locked in i.e. next a-b should be the current b-(b+1).\n a = b;\n b++;\n c = b;\n }\n // Plan to look at the next point during the next iteration.\n c++;\n }\n // No remaining points, so commit the current a-b segment.\n newPoints.push(points[b]);\n\n if (type === \"Polygon\" || type === \"MultiPolygon\") {\n // For polygons need to make sure the start / end point wasn't one of the\n // points that needed to be cleaned.\n // https://github.com/Turfjs/turf/issues/2406\n // For points [a, b, c, ..., z, a]\n // if a is on line b-z, it too can be removed. New array becomes\n // [b, c, ..., z, b]\n if (\n booleanPointOnLine(\n newPoints[0],\n lineString([newPoints[1], newPoints[newPoints.length - 2]])\n )\n ) {\n newPoints.shift(); // Discard starting point.\n newPoints.pop(); // Discard closing point.\n newPoints.push(newPoints[0]); // Duplicate the new closing point to end of array.\n }\n\n // (Multi)Polygons must have at least 4 points and be closed.\n if (newPoints.length < 4) {\n throw new Error(\"invalid polygon, fewer than 4 points\");\n }\n if (!equals(newPoints[0], newPoints[newPoints.length - 1])) {\n throw new Error(\"invalid polygon, first and last points not equal\");\n }\n }\n\n return newPoints;\n}\n\n/**\n * Compares two points and returns if they are equals\n *\n * @private\n * @param {Position} pt1 point\n * @param {Position} pt2 point\n * @returns {boolean} true if they are equals\n */\nfunction equals(pt1: Position, pt2: Position) {\n return pt1[0] === pt2[0] && pt1[1] === pt2[1];\n}\n\nexport { cleanCoords };\nexport default cleanCoords;\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@turf/clean-coords",
3
- "version": "7.2.0",
4
- "description": "turf clean-coords module",
3
+ "version": "7.3.1",
4
+ "description": "Removes redundant coordinates from a GeoJSON Geometry.",
5
5
  "author": "Turf Authors",
6
6
  "contributors": [
7
- "Stefano Borghi <@stebogit>"
7
+ "Stefano Borghi <@stebogit>",
8
+ "James Beard <@smallsaucepan>"
8
9
  ],
9
10
  "license": "MIT",
10
11
  "bugs": {
@@ -49,28 +50,29 @@
49
50
  "bench": "tsx bench.ts",
50
51
  "build": "tsup --config ../../tsup.config.ts",
51
52
  "docs": "tsx ../../scripts/generate-readmes.ts",
52
- "test": "npm-run-all --npm-path npm test:*",
53
+ "test": "pnpm run /test:.*/",
53
54
  "test:tape": "tsx test.ts",
54
55
  "test:types": "tsc --esModuleInterop --module node16 --moduleResolution node16 --noEmit --strict types.ts"
55
56
  },
56
57
  "devDependencies": {
57
- "@turf/truncate": "^7.2.0",
58
+ "@turf/truncate": "7.3.1",
58
59
  "@types/benchmark": "^2.1.5",
59
- "@types/tape": "^4.13.4",
60
+ "@types/tape": "^5.8.1",
60
61
  "benchmark": "^2.1.4",
62
+ "geojson-equality-ts": "^1.0.2",
61
63
  "load-json-file": "^7.0.1",
62
- "npm-run-all": "^4.1.5",
63
64
  "tape": "^5.9.0",
64
- "tsup": "^8.3.5",
65
- "tsx": "^4.19.2",
66
- "typescript": "^5.5.4",
67
- "write-json-file": "^5.0.0"
65
+ "tsup": "^8.4.0",
66
+ "tsx": "^4.19.4",
67
+ "typescript": "^5.8.3",
68
+ "write-json-file": "^6.0.0"
68
69
  },
69
70
  "dependencies": {
70
- "@turf/helpers": "^7.2.0",
71
- "@turf/invariant": "^7.2.0",
71
+ "@turf/boolean-point-on-line": "7.3.1",
72
+ "@turf/helpers": "7.3.1",
73
+ "@turf/invariant": "7.3.1",
72
74
  "@types/geojson": "^7946.0.10",
73
75
  "tslib": "^2.8.1"
74
76
  },
75
- "gitHead": "7b0f0374c4668cd569f8904c71e2ae7d941be867"
77
+ "gitHead": "b7f1b4eafb760431e03955499d8eac9489438219"
76
78
  }