From 3642e4e063ffafc5a7f79d937a5b75660e080789 Mon Sep 17 00:00:00 2001 From: hadrien Date: Tue, 17 Dec 2024 14:50:59 +0100 Subject: [PATCH 1/2] feat [transform-translate] lets the user decide whether to keep the geometric properties of the feature given as input or to run the translation point by point. --- packages/turf-transform-translate/index.ts | 117 ++++++++- .../turf-transform-translate/package.json | 7 + packages/turf-transform-translate/test.ts | 44 +++- .../test/in/circle.geojson | 79 ++++++ .../test/out/circle.geojson | 246 ++++++++++++++++++ .../test/out/line.geojson | 27 ++ .../test/out/multiLine.geojson | 24 ++ .../test/out/multiPoint.geojson | 19 ++ .../test/out/multiPolygon.geojson | 127 +++++++++ .../test/out/no-motion.geojson | 45 ++++ .../test/out/point.geojson | 14 + .../test/out/polygon-fiji.geojson | 43 +++ .../test/out/polygon-resolute-bay.geojson | 42 +++ .../test/out/polygon-with-hole.geojson | 62 +++++ .../test/out/polygon.geojson | 20 ++ .../test/out/z-translation.geojson | 24 ++ pnpm-lock.yaml | 21 ++ 17 files changed, 946 insertions(+), 15 deletions(-) create mode 100644 packages/turf-transform-translate/test/in/circle.geojson create mode 100644 packages/turf-transform-translate/test/out/circle.geojson diff --git a/packages/turf-transform-translate/index.ts b/packages/turf-transform-translate/index.ts index ef20f16136..e53aa8df6c 100644 --- a/packages/turf-transform-translate/index.ts +++ b/packages/turf-transform-translate/index.ts @@ -1,9 +1,13 @@ -import { GeoJSON, GeometryCollection } from "geojson"; -import { coordEach } from "@turf/meta"; +import { FeatureCollection, GeoJSON, GeometryCollection } from "geojson"; +import { coordEach, featureEach } from "@turf/meta"; import { isObject, Units } from "@turf/helpers"; import { getCoords } from "@turf/invariant"; import { clone } from "@turf/clone"; import { rhumbDestination } from "@turf/rhumb-destination"; +import { bearing } from "@turf/bearing"; +import { centroid } from "@turf/centroid"; +import { destination } from "@turf/destination"; +import { distance } from "@turf/distance"; /** * Moves any geojson Feature or Geometry of a specified distance along a Rhumb Line @@ -17,6 +21,7 @@ import { rhumbDestination } from "@turf/rhumb-destination"; * @param {Units} [options.units='kilometers'] in which `distance` will be express; miles, kilometers, degrees, or radians * @param {number} [options.zTranslation=0] length of the vertical motion, same unit of distance * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true) + * @param {boolean} [options.aroundCenter=false] when set to true, for each feature the center is translated and the geometry reconstructed around it. Otherwise, points are independently translated. * @returns {GeoJSON|GeometryCollection} the translated GeoJSON object * @example * var poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]); @@ -34,6 +39,7 @@ function transformTranslate( units?: Units; zTranslation?: number; mutate?: boolean; + aroundCenter?: boolean; } ): T { // Optional parameters @@ -42,6 +48,7 @@ function transformTranslate( var units = options.units; var zTranslation = options.zTranslation; var mutate = options.mutate; + var aroundCenter = options.aroundCenter; // Input validation if (!geojson) throw new Error("geojson is required"); @@ -66,17 +73,105 @@ function transformTranslate( // Clone geojson to avoid side effects if (mutate === false || mutate === undefined) geojson = clone(geojson); - // Translate each coordinate - coordEach(geojson, function (pointCoords) { - var newCoords = getCoords( - rhumbDestination(pointCoords, distance, direction, { units: units }) + if (aroundCenter === false || aroundCenter === undefined) { + // Translate each coordinate + coordEach(geojson, function (pointCoords) { + var newCoords = getCoords( + rhumbDestination(pointCoords, distance, direction, { units: units }) + ); + pointCoords[0] = newCoords[0]; + pointCoords[1] = newCoords[1]; + if (zTranslation && pointCoords.length === 3) + pointCoords[2] += zTranslation; + }); + } else { + /// Translate each feature using its center + if (geojson.type === "FeatureCollection") { + featureEach(geojson, function (feature, index) { + // The type guard above is not recognised in the callback so we have to + // cast to accept responsibility. + (geojson as FeatureCollection).features[index] = + translateAroundCentroid( + feature, + distance, + direction, + zTranslation, + units + ); + }); + } else { + geojson = translateAroundCentroid( + geojson, + distance, + direction, + zTranslation, + units + ); + } + } + + return geojson; +} + +/** + * Translate Feature/Geometry + * + * @private + * @param {GeoJSON|GeometryCollection} feature feature or geometry collection to translate + * @param {number} distance of translation greater than 0 + * @param {number} direction of translation + * @param {number} zTranslation + * @param {Units} units in which the distance is expressed + * @returns {GeoJSON|GeometryCollection} translated GeoJSON Feature/Geometry + */ +function translateAroundCentroid( + feature: T, + distanceTranslation: number, + directionTranslation: number, + zTranslation?: number, + units?: Units +): T { + if ( + distanceTranslation === undefined || + distanceTranslation === null || + isNaN(distanceTranslation) + ) + throw new Error("distance is required"); + if (distanceTranslation < 0) + throw new Error("distance should be greater than 0"); + if ( + directionTranslation === undefined || + directionTranslation === null || + isNaN(directionTranslation) + ) + throw new Error("direction is required"); + zTranslation = zTranslation !== undefined ? zTranslation : 0; + + if (distanceTranslation === 0) return feature; + + const featureCentroid = centroid(feature); + const newCentroid = getCoords( + rhumbDestination( + featureCentroid, + distanceTranslation, + directionTranslation, + { units: units } + ) + ); + + // Scale each coordinate + coordEach(feature, function (coord) { + const originalDistance = distance(featureCentroid, coord); + const originalBearing = bearing(featureCentroid, coord); + const newCoord = getCoords( + destination(newCentroid, originalDistance, originalBearing) ); - pointCoords[0] = newCoords[0]; - pointCoords[1] = newCoords[1]; - if (zTranslation && pointCoords.length === 3) - pointCoords[2] += zTranslation; + coord[0] = newCoord[0]; + coord[1] = newCoord[1]; + if (zTranslation && coord.length === 3) coord[2] += zTranslation; }); - return geojson; + + return feature; } export { transformTranslate }; diff --git a/packages/turf-transform-translate/package.json b/packages/turf-transform-translate/package.json index 56a069ca37..e2d034c56e 100644 --- a/packages/turf-transform-translate/package.json +++ b/packages/turf-transform-translate/package.json @@ -58,6 +58,9 @@ "test:types": "tsc --esModuleInterop --module node16 --moduleResolution node16 --noEmit --strict types.ts" }, "devDependencies": { + "@turf/area": "workspace:^", + "@turf/circle": "workspace:^", + "@turf/intersect": "workspace:^", "@turf/truncate": "workspace:^", "@types/benchmark": "^2.1.5", "@types/tape": "^4.13.4", @@ -71,7 +74,11 @@ "write-json-file": "^5.0.0" }, "dependencies": { + "@turf/bearing": "workspace:^", + "@turf/centroid": "workspace:^", "@turf/clone": "workspace:^", + "@turf/destination": "workspace:^", + "@turf/distance": "workspace:^", "@turf/helpers": "workspace:^", "@turf/invariant": "workspace:^", "@turf/meta": "workspace:^", diff --git a/packages/turf-transform-translate/test.ts b/packages/turf-transform-translate/test.ts index ebc9a491a9..f0cfa248b8 100644 --- a/packages/turf-transform-translate/test.ts +++ b/packages/turf-transform-translate/test.ts @@ -5,6 +5,9 @@ import path from "path"; import { fileURLToPath } from "url"; import { loadJsonFileSync } from "load-json-file"; import { writeJsonFileSync } from "write-json-file"; +import { area } from "@turf/area"; +import { circle } from "@turf/circle"; +import { intersect } from "@turf/intersect"; import { truncate } from "@turf/truncate"; import { point, @@ -37,8 +40,17 @@ test("translate", (t) => { units, zTranslation, }); + const translatedAroundCenter = translate(geojson, distance, direction, { + units, + zTranslation, + aroundCenter: true, + }); const result = featureCollection([ - colorize(truncate(translated, { precision: 6, coordinates: 3 })), + colorize(truncate(translated, { precision: 6, coordinates: 3 }), "#F00"), + colorize( + truncate(translatedAroundCenter, { precision: 6, coordinates: 3 }), + "#00F" + ), geojson, ]); @@ -135,19 +147,43 @@ test("rotate -- geometry support", (t) => { t.end(); }); +test("turf-translate -- circle consistency", (t) => { + const circleCenter = point([0, 60]); + const circleCenterTranslated = translate(circleCenter, 1000, 30); + const circleOrigin = circle(circleCenter, 1000); + const circleTranslated = translate(circleOrigin, 1000, 30, { + aroundCenter: true, + }); + const circleReconstructed = circle(circleCenterTranslated, 1000); + + const intersectionGeom = intersect( + featureCollection([circleTranslated, circleReconstructed]) + ); + const areaIntersection = + intersectionGeom != null ? area(intersectionGeom.geometry) : 0; + const areaCircle = + circleTranslated != null ? area(circleTranslated.geometry) : 0; + t.true( + Math.abs(areaIntersection - areaCircle) / areaCircle < 0.01, + "both areas are equal" + ); + t.end(); +}); + // style result -function colorize(geojson: Feature) { +function colorize(geojson: Feature, color?) { // We are going to add some properties, so make sure properties attribute is // present. + color = color || "#F00"; geojson.properties = geojson.properties ?? {}; if ( geojson.geometry.type === "Point" || geojson.geometry.type === "MultiPoint" ) { - geojson.properties["marker-color"] = "#F00"; + geojson.properties["marker-color"] = color; geojson.properties["marker-symbol"] = "star"; } else { - geojson.properties["stroke"] = "#F00"; + geojson.properties["stroke"] = color; geojson.properties["stroke-width"] = 4; } return geojson; diff --git a/packages/turf-transform-translate/test/in/circle.geojson b/packages/turf-transform-translate/test/in/circle.geojson new file mode 100644 index 0000000000..c8ebf25f1a --- /dev/null +++ b/packages/turf-transform-translate/test/in/circle.geojson @@ -0,0 +1,79 @@ +{ + "type": "Feature", + "properties": { + "direction": 30, + "distance": 1000 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [0, 68.99320363724537], + [-2.4429584198737904, 68.93313263109376], + [-4.827615673717056, 68.75446551386186], + [-7.099933947678443, 68.46170890478926], + [-9.213648021302797, 68.06196358356087], + [-11.132504186336082, 67.56439307389124], + [-12.831074422570252, 66.97961850084515], + [-14.294324293079713, 66.31912548486699], + [-15.516311969170072, 65.59474542818991], + [-16.49844020508527, 64.81824400722547], + [-17.247616061432137, 64.00102375186508], + [-17.7745577051021, 63.153930055547875], + [-18.0923735451161, 62.28714117393077], + [-18.2154519279803, 61.41012065685274], + [-18.158645231502856, 60.53161254825021], + [-17.93670515509441, 59.65966336278071], + [-17.56391759236705, 58.80165885845095], + [-17.053887726029547, 57.96436721224244], + [-16.419433163873737, 57.1539830832056], + [-15.672551513843027, 56.37616919405936], + [-14.824436921265958, 55.636093578844374], + [-13.885526976991425, 54.938461667547514], + [-12.865566866929816, 54.2875430393439], + [-11.773681779319768, 53.687193081741135], + [-10.618451635896449, 53.1408700250564], + [-9.407984404938373, 52.65164793888436], + [-8.149985801204723, 52.222226319863246], + [-6.85182425431596, 51.85493689498236], + [-5.520590767778858, 51.55174822927353], + [-4.16315379565268, 51.31426867194753], + [-2.786209605013719, 51.14374810765571], + [-1.3963288207704132, 51.041078903744776], + [-1.7431403842134502e-15, 51.00679636275462], + [1.39632882077041, 51.041078903744776], + [2.7862096050137155, 51.14374810765571], + [4.163153795652676, 51.31426867194753], + [5.520590767778848, 51.55174822927353], + [6.8518242543159555, 51.85493689498236], + [8.149985801204727, 52.222226319863246], + [9.40798440493837, 52.65164793888436], + [10.618451635896443, 53.140870025056394], + [11.773681779319771, 53.687193081741135], + [12.865566866929806, 54.287543039343895], + [13.885526976991414, 54.9384616675475], + [14.824436921265967, 55.63609357884438], + [15.672551513843027, 56.37616919405936], + [16.419433163873734, 57.1539830832056], + [17.053887726029547, 57.96436721224244], + [17.56391759236705, 58.80165885845095], + [17.93670515509441, 59.65966336278071], + [18.158645231502856, 60.53161254825021], + [18.2154519279803, 61.41012065685273], + [18.0923735451161, 62.28714117393077], + [17.7745577051021, 63.153930055547875], + [17.247616061432137, 64.00102375186508], + [16.49844020508527, 64.81824400722547], + [15.516311969170077, 65.59474542818991], + [14.294324293079722, 66.31912548486699], + [12.831074422570252, 66.97961850084515], + [11.132504186336087, 67.56439307389124], + [9.213648021302793, 68.06196358356087], + [7.099933947678468, 68.46170890478926], + [4.827615673717068, 68.75446551386186], + [2.442958419873788, 68.93313263109376], + [0, 68.99320363724537] + ] + ] + } +} diff --git a/packages/turf-transform-translate/test/out/circle.geojson b/packages/turf-transform-translate/test/out/circle.geojson new file mode 100644 index 0000000000..77c2b01241 --- /dev/null +++ b/packages/turf-transform-translate/test/out/circle.geojson @@ -0,0 +1,246 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "direction": 30, + "distance": 1000, + "stroke": "#F00", + "stroke-width": 4 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [15.549908, 76.781546], + [13.052231, 76.721475], + [10.50722, 76.542808], + [7.979655, 76.250052], + [5.531681, 75.850306], + [3.218208, 75.352736], + [1.083763, 74.767961], + [-0.838912, 74.107468], + [-2.528702, 73.383088], + [-3.974855, 72.606587], + [-5.17513, 71.789367], + [-6.133792, 70.942273], + [-6.859734, 70.075484], + [-7.36489, 69.198463], + [-7.662972, 68.319955], + [-7.768536, 67.448006], + [-7.696317, 66.590002], + [-7.460789, 65.75271], + [-7.075883, 64.942326], + [-6.554836, 64.164512], + [-5.910123, 63.424436], + [-5.153442, 62.726804], + [-4.295743, 62.075886], + [-3.347272, 61.475536], + [-2.31763, 60.929213], + [-1.215844, 60.439991], + [-0.050426, 60.010569], + [1.170561, 59.64328], + [2.439439, 59.340091], + [3.748867, 59.102611], + [5.091779, 58.932091], + [6.461345, 58.829422], + [7.850919, 58.795139], + [9.254003, 58.829422], + [10.664198, 58.932091], + [12.075174, 59.102611], + [13.480621, 59.340091], + [14.874209, 59.64328], + [16.249546, 60.010569], + [17.600125, 60.439991], + [18.919273, 60.929213], + [20.200092, 61.475536], + [21.43539, 62.075886], + [22.617612, 62.726804], + [23.738751, 63.424436], + [24.790267, 64.164512], + [25.762984, 64.942326], + [26.646986, 65.75271], + [27.431518, 66.590002], + [28.104875, 67.448006], + [28.654319, 68.319955], + [29.066014, 69.198463], + [29.325013, 70.075484], + [29.415324, 70.942273], + [29.320102, 71.789367], + [29.022025, 72.606587], + [28.503922, 73.383088], + [27.749736, 74.107468], + [26.745912, 74.767961], + [25.483217, 75.352736], + [23.958977, 75.850306], + [22.179523, 76.250052], + [20.162452, 76.542808], + [17.938147, 76.721475], + [15.549908, 76.781546] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "direction": 30, + "distance": 1000, + "stroke": "#00F", + "stroke-width": 4 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [10.069457, 76.781546], + [6.247666, 76.710436], + [2.563212, 76.499985], + [-0.864101, 76.158392], + [-3.944273, 75.698011], + [-6.6216, 75.133831], + [-8.872197, 74.481994], + [-10.697389, 73.758617], + [-12.115877, 72.978997], + [-13.156682, 72.157185], + [-13.853699, 71.30582], + [-14.241983, 70.436134], + [-14.355451, 69.55805], + [-14.225634, 68.680328], + [-13.881132, 67.810708], + [-13.347481, 66.956053], + [-12.647288, 66.122475], + [-11.800469, 65.315437], + [-10.824549, 64.539842], + [-9.734972, 63.800103], + [-8.545386, 63.100197], + [-7.267914, 62.443714], + [-5.913388, 61.833886], + [-4.491555, 61.273615], + [-3.011255, 60.765493], + [-1.480579, 60.311818], + [0.093004, 59.9146], + [1.702529, 59.575576], + [3.341438, 59.296205], + [5.003494, 59.077683], + [6.682706, 58.920934], + [8.37326, 58.826621], + [10.069457, 58.795139], + [11.765653, 58.826621], + [13.456207, 58.920934], + [15.135419, 59.077683], + [16.797475, 59.296205], + [18.436384, 59.575576], + [20.045909, 59.9146], + [21.619492, 60.311818], + [23.150168, 60.765493], + [24.630468, 61.273615], + [26.052301, 61.833886], + [27.406827, 62.443714], + [28.684299, 63.100197], + [29.873885, 63.800103], + [30.963462, 64.539842], + [31.939382, 65.315437], + [32.786201, 66.122475], + [33.486394, 66.956053], + [34.020045, 67.810708], + [34.364547, 68.680328], + [34.494364, 69.55805], + [34.380896, 70.436134], + [33.992612, 71.30582], + [33.295595, 72.157185], + [32.25479, 72.978997], + [30.836302, 73.758617], + [29.01111, 74.481994], + [26.760513, 75.133831], + [24.083186, 75.698011], + [21.003014, 76.158392], + [17.575701, 76.499985], + [13.891247, 76.710436], + [10.069457, 76.781546] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "direction": 30, + "distance": 1000 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [0, 68.99320363724537], + [-2.4429584198737904, 68.93313263109376], + [-4.827615673717056, 68.75446551386186], + [-7.099933947678443, 68.46170890478926], + [-9.213648021302797, 68.06196358356087], + [-11.132504186336082, 67.56439307389124], + [-12.831074422570252, 66.97961850084515], + [-14.294324293079713, 66.31912548486699], + [-15.516311969170072, 65.59474542818991], + [-16.49844020508527, 64.81824400722547], + [-17.247616061432137, 64.00102375186508], + [-17.7745577051021, 63.153930055547875], + [-18.0923735451161, 62.28714117393077], + [-18.2154519279803, 61.41012065685274], + [-18.158645231502856, 60.53161254825021], + [-17.93670515509441, 59.65966336278071], + [-17.56391759236705, 58.80165885845095], + [-17.053887726029547, 57.96436721224244], + [-16.419433163873737, 57.1539830832056], + [-15.672551513843027, 56.37616919405936], + [-14.824436921265958, 55.636093578844374], + [-13.885526976991425, 54.938461667547514], + [-12.865566866929816, 54.2875430393439], + [-11.773681779319768, 53.687193081741135], + [-10.618451635896449, 53.1408700250564], + [-9.407984404938373, 52.65164793888436], + [-8.149985801204723, 52.222226319863246], + [-6.85182425431596, 51.85493689498236], + [-5.520590767778858, 51.55174822927353], + [-4.16315379565268, 51.31426867194753], + [-2.786209605013719, 51.14374810765571], + [-1.3963288207704132, 51.041078903744776], + [-1.7431403842134502e-15, 51.00679636275462], + [1.39632882077041, 51.041078903744776], + [2.7862096050137155, 51.14374810765571], + [4.163153795652676, 51.31426867194753], + [5.520590767778848, 51.55174822927353], + [6.8518242543159555, 51.85493689498236], + [8.149985801204727, 52.222226319863246], + [9.40798440493837, 52.65164793888436], + [10.618451635896443, 53.140870025056394], + [11.773681779319771, 53.687193081741135], + [12.865566866929806, 54.287543039343895], + [13.885526976991414, 54.9384616675475], + [14.824436921265967, 55.63609357884438], + [15.672551513843027, 56.37616919405936], + [16.419433163873734, 57.1539830832056], + [17.053887726029547, 57.96436721224244], + [17.56391759236705, 58.80165885845095], + [17.93670515509441, 59.65966336278071], + [18.158645231502856, 60.53161254825021], + [18.2154519279803, 61.41012065685273], + [18.0923735451161, 62.28714117393077], + [17.7745577051021, 63.153930055547875], + [17.247616061432137, 64.00102375186508], + [16.49844020508527, 64.81824400722547], + [15.516311969170077, 65.59474542818991], + [14.294324293079722, 66.31912548486699], + [12.831074422570252, 66.97961850084515], + [11.132504186336087, 67.56439307389124], + [9.213648021302793, 68.06196358356087], + [7.099933947678468, 68.46170890478926], + [4.827615673717068, 68.75446551386186], + [2.442958419873788, 68.93313263109376], + [0, 68.99320363724537] + ] + ] + } + } + ] +} diff --git a/packages/turf-transform-translate/test/out/line.geojson b/packages/turf-transform-translate/test/out/line.geojson index d36ccc2a0f..d03d66e3a0 100644 --- a/packages/turf-transform-translate/test/out/line.geojson +++ b/packages/turf-transform-translate/test/out/line.geojson @@ -28,6 +28,33 @@ ] } }, + { + "type": "Feature", + "properties": { + "distance": 3, + "units": "miles", + "direction": 175, + "stroke": "#00F", + "stroke-width": 4 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.264629, 44.44125], + [11.273549, 44.445414], + [11.277666, 44.463046], + [11.292075, 44.480183], + [11.31163, 44.481896], + [11.331184, 44.489728], + [11.352455, 44.487036], + [11.378871, 44.475532], + [11.386418, 44.466229], + [11.386761, 44.460352], + [11.39774, 44.448598], + [11.412149, 44.44223] + ] + } + }, { "type": "Feature", "properties": { diff --git a/packages/turf-transform-translate/test/out/multiLine.geojson b/packages/turf-transform-translate/test/out/multiLine.geojson index aaf9bcdba3..85097889e9 100644 --- a/packages/turf-transform-translate/test/out/multiLine.geojson +++ b/packages/turf-transform-translate/test/out/multiLine.geojson @@ -25,6 +25,30 @@ ] } }, + { + "type": "Feature", + "properties": { + "distance": 13.45, + "direction": 0, + "stroke": "#00F", + "stroke-width": 4 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [-99.200073, 19.220958], + [-99.1, 19.290959], + [-98.999927, 19.220958] + ], + [ + [-99.200074, 19.280958], + [-99.1, 19.350959], + [-98.999926, 19.280958] + ] + ] + } + }, { "type": "Feature", "properties": { diff --git a/packages/turf-transform-translate/test/out/multiPoint.geojson b/packages/turf-transform-translate/test/out/multiPoint.geojson index b1136b215a..889eff39fb 100644 --- a/packages/turf-transform-translate/test/out/multiPoint.geojson +++ b/packages/turf-transform-translate/test/out/multiPoint.geojson @@ -20,6 +20,25 @@ ] } }, + { + "type": "Feature", + "properties": { + "distance": -10, + "units": "miles", + "direction": 90, + "marker-color": "#00F", + "marker-symbol": "star" + }, + "geometry": { + "type": "MultiPoint", + "coordinates": [ + [99.855263, 0], + [100.855263, 1], + [101.005263, -0.86], + [99.655263, 1.8] + ] + } + }, { "type": "Feature", "properties": { diff --git a/packages/turf-transform-translate/test/out/multiPolygon.geojson b/packages/turf-transform-translate/test/out/multiPolygon.geojson index 1a3a0e29da..23dbd1f330 100644 --- a/packages/turf-transform-translate/test/out/multiPolygon.geojson +++ b/packages/turf-transform-translate/test/out/multiPolygon.geojson @@ -128,6 +128,133 @@ ] } }, + { + "type": "Feature", + "properties": { + "distance": 40, + "units": "miles", + "direction": -35, + "stroke": "#00F", + "stroke-width": 4 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [-81.225812, -33.277454], + [-81.215223, -33.289154], + [-81.218804, -33.302426], + [-81.18311, -33.337796], + [-81.165012, -33.341928], + [-81.14948, -33.331227], + [-81.145226, -33.291848], + [-81.163337, -33.249173], + [-81.19475, -33.250038], + [-81.225812, -33.277454] + ] + ], + [ + [ + [-79.277172, -33.13153], + [-79.285367, -33.138964], + [-79.278539, -33.156117], + [-79.292539, -33.17098], + [-79.302783, -33.172981], + [-79.307222, -33.170123], + [-79.314051, -33.171837], + [-79.320539, -33.177839], + [-79.321904, -33.180697], + [-79.329075, -33.183269], + [-79.338977, -33.193555], + [-79.334539, -33.196699], + [-79.337612, -33.200127], + [-79.340685, -33.198698], + [-79.347514, -33.202698], + [-79.340002, -33.208127], + [-79.334198, -33.208984], + [-79.336929, -33.204413], + [-79.33727, -33.201556], + [-79.331807, -33.19727], + [-79.322929, -33.196985], + [-79.320198, -33.190984], + [-79.322929, -33.187555], + [-79.31371, -33.181554], + [-79.306539, -33.188699], + [-79.303466, -33.186127], + [-79.30449, -33.182983], + [-79.298344, -33.178411], + [-79.291174, -33.185841], + [-79.283662, -33.181841], + [-79.273418, -33.170695], + [-79.264881, -33.170981], + [-79.260102, -33.191272], + [-79.227322, -33.186701], + [-79.183618, -33.205275], + [-79.168935, -33.196418], + [-79.176787, -33.187846], + [-79.178836, -33.181273], + [-79.190103, -33.167268], + [-79.21298, -33.16641], + [-79.216736, -33.170126], + [-79.230053, -33.166695], + [-79.229711, -33.157262], + [-79.247466, -33.144397], + [-79.248149, -33.139251], + [-79.262148, -33.13296], + [-79.277172, -33.13153] + ] + ], + [ + [ + [-79.350332, -33.221053], + [-79.354002, -33.225837], + [-79.350844, -33.227408], + [-79.349393, -33.226052], + [-79.347344, -33.22698], + [-79.348454, -33.228836], + [-79.349478, -33.228622], + [-79.350503, -33.230336], + [-79.346832, -33.23362], + [-79.348198, -33.23512], + [-79.341796, -33.239547], + [-79.337955, -33.239404], + [-79.336503, -33.240332], + [-79.337528, -33.242117], + [-79.335394, -33.24076], + [-79.33565, -33.239261], + [-79.333601, -33.240689], + [-79.332918, -33.239333], + [-79.329589, -33.239333], + [-79.323614, -33.240975], + [-79.322675, -33.240546], + [-79.323699, -33.239547], + [-79.325918, -33.238762], + [-79.328821, -33.238619], + [-79.328821, -33.237476], + [-79.330016, -33.235477], + [-79.332747, -33.235763], + [-79.335052, -33.233692], + [-79.336674, -33.234049], + [-79.33804, -33.232193], + [-79.339918, -33.231978], + [-79.338979, -33.230836], + [-79.340174, -33.229979], + [-79.339149, -33.228408], + [-79.340856, -33.223695], + [-79.341966, -33.223195], + [-79.344442, -33.225123], + [-79.348027, -33.223766], + [-79.348539, -33.222267], + [-79.347941, -33.221696], + [-79.34888, -33.22091], + [-79.349649, -33.221553], + [-79.350332, -33.221053] + ] + ] + ] + } + }, { "type": "Feature", "properties": { diff --git a/packages/turf-transform-translate/test/out/no-motion.geojson b/packages/turf-transform-translate/test/out/no-motion.geojson index 32db60744b..d6b72f6e94 100644 --- a/packages/turf-transform-translate/test/out/no-motion.geojson +++ b/packages/turf-transform-translate/test/out/no-motion.geojson @@ -46,6 +46,51 @@ ] } }, + { + "type": "Feature", + "properties": { + "distance": 0, + "direction": 45, + "stroke": "#00F", + "stroke-width": 4 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [128.84, -25.76], + [128.18, -25.6], + [127.96, -25.52], + [127.88, -25.52], + [127.7, -25.6], + [127.26, -25.79], + [126.6, -26.11], + [126.16, -26.78], + [126.12, -27.68], + [126.21, -28.42], + [126.69, -29.49], + [127.74, -29.8], + [128.8, -29.72], + [129.41, -29.03], + [129.72, -27.95], + [129.68, -27.21], + [129.33, -26.23], + [128.84, -25.76] + ], + [ + [128.45, -27.44], + [128.32, -26.94], + [127.7, -26.82], + [127.35, -27.05], + [127.17, -27.8], + [127.57, -28.22], + [128.1, -28.42], + [128.49, -27.8], + [128.45, -27.44] + ] + ] + } + }, { "type": "Feature", "properties": { diff --git a/packages/turf-transform-translate/test/out/point.geojson b/packages/turf-transform-translate/test/out/point.geojson index 4670bb8b75..a4bc77e71b 100644 --- a/packages/turf-transform-translate/test/out/point.geojson +++ b/packages/turf-transform-translate/test/out/point.geojson @@ -15,6 +15,20 @@ "coordinates": [-75.407065, 45.636132] } }, + { + "type": "Feature", + "properties": { + "distance": 20, + "units": "miles", + "direction": 45, + "marker-color": "#00F", + "marker-symbol": "star" + }, + "geometry": { + "type": "Point", + "coordinates": [-75.407065, 45.636132] + } + }, { "type": "Feature", "properties": { diff --git a/packages/turf-transform-translate/test/out/polygon-fiji.geojson b/packages/turf-transform-translate/test/out/polygon-fiji.geojson index 51afbbd5e3..cad6545246 100644 --- a/packages/turf-transform-translate/test/out/polygon-fiji.geojson +++ b/packages/turf-transform-translate/test/out/polygon-fiji.geojson @@ -44,6 +44,49 @@ ] } }, + { + "type": "Feature", + "properties": { + "distance": 15, + "units": "miles", + "direction": 100, + "stroke": "#00F", + "stroke-width": 4 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [-179.408566, -16.800163], + [-179.436038, -16.684413], + [-179.50197, -16.615983], + [-179.771187, -16.679153], + [-179.947002, -16.973658], + [-179.914036, -17.094483], + [-179.710748, -17.047212], + [-179.408566, -16.800163] + ] + ], + [ + [ + [-179.842613, -16.547531], + [-179.567904, -16.131016], + [-179.870086, -16.072953], + [-180.485437, -16.115184], + [-181.408471, -16.563322], + [-181.441441, -16.87378], + [-181.276616, -17.104979], + [-180.996408, -17.104982], + [-180.727188, -16.994676], + [-180.370061, -16.952638], + [-179.968979, -16.905332], + [-179.842613, -16.547531] + ] + ] + ] + } + }, { "type": "Feature", "properties": { diff --git a/packages/turf-transform-translate/test/out/polygon-resolute-bay.geojson b/packages/turf-transform-translate/test/out/polygon-resolute-bay.geojson index 213990c8fb..47036283a9 100644 --- a/packages/turf-transform-translate/test/out/polygon-resolute-bay.geojson +++ b/packages/turf-transform-translate/test/out/polygon-resolute-bay.geojson @@ -43,6 +43,48 @@ ] } }, + { + "type": "Feature", + "properties": { + "distance": 15, + "units": "miles", + "direction": 45, + "stroke": "#00F", + "stroke-width": 4 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [-94.577286, 75.763039], + [-95.443091, 75.581689], + [-95.908983, 75.313929], + [-96.053097, 75.189606], + [-95.131844, 74.958156], + [-94.310741, 74.819339], + [-93.711637, 74.775694], + [-92.879519, 74.816394], + [-92.823856, 75.021358], + [-92.901376, 75.192486], + [-92.945529, 75.459574], + [-93.555916, 75.6754], + [-93.844534, 75.76304], + [-94.222013, 75.790322], + [-94.577286, 75.763039] + ], + [ + [-94.51062, 75.554057], + [-95.071085, 75.38276], + [-95.021007, 75.164119], + [-94.044451, 74.99413], + [-93.417523, 74.991244], + [-93.406241, 75.332262], + [-93.983348, 75.523567], + [-94.51062, 75.554057] + ] + ] + } + }, { "type": "Feature", "properties": { diff --git a/packages/turf-transform-translate/test/out/polygon-with-hole.geojson b/packages/turf-transform-translate/test/out/polygon-with-hole.geojson index b29ad47044..5c06d84bc6 100644 --- a/packages/turf-transform-translate/test/out/polygon-with-hole.geojson +++ b/packages/turf-transform-translate/test/out/polygon-with-hole.geojson @@ -63,6 +63,68 @@ ] } }, + { + "type": "Feature", + "properties": { + "distance": 15, + "direction": -195, + "name": "Bled Lake", + "area": "1.45", + "area-unit": "km2", + "volume": "0.0257", + "volume-unit": "km3", + "picture": "https://en.wikipedia.org/wiki/Lake_Bled#/media/File:Lake_Bled_from_the_Mountain.jpg", + "stroke": "#00F", + "stroke-width": 4 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [14.137466, 46.237862], + [14.136138, 46.236737], + [14.136609, 46.236145], + [14.134297, 46.233361], + [14.132499, 46.232413], + [14.133355, 46.231258], + [14.135325, 46.231584], + [14.135282, 46.229866], + [14.136138, 46.228652], + [14.140377, 46.228001], + [14.141447, 46.228267], + [14.142303, 46.229067], + [14.143802, 46.229659], + [14.148683, 46.229481], + [14.149796, 46.229926], + [14.14941, 46.231851], + [14.156817, 46.234694], + [14.159086, 46.238099], + [14.156774, 46.239284], + [14.15382, 46.239077], + [14.150481, 46.238247], + [14.147869, 46.237862], + [14.146114, 46.237714], + [14.144958, 46.237033], + [14.14316, 46.236944], + [14.137466, 46.237862] + ], + [ + [14.140366, 46.232784], + [14.140024, 46.23231], + [14.140088, 46.231725], + [14.140452, 46.231273], + [14.140655, 46.231244], + [14.140762, 46.231303], + [14.140826, 46.231421], + [14.14104, 46.231732], + [14.141126, 46.232088], + [14.141073, 46.232302], + [14.140473, 46.232761], + [14.140366, 46.232784] + ] + ] + } + }, { "type": "Feature", "properties": { diff --git a/packages/turf-transform-translate/test/out/polygon.geojson b/packages/turf-transform-translate/test/out/polygon.geojson index dcc37c1d84..72771a8aae 100644 --- a/packages/turf-transform-translate/test/out/polygon.geojson +++ b/packages/turf-transform-translate/test/out/polygon.geojson @@ -21,6 +21,26 @@ ] } }, + { + "type": "Feature", + "properties": { + "direction": 70, + "distance": 300, + "stroke": "#00F", + "stroke-width": 4 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [2.923008, 29.92219], + [6.45499, 29.922438], + [5.446431, 32.922722], + [2.923008, 29.92219] + ] + ] + } + }, { "type": "Feature", "properties": { diff --git a/packages/turf-transform-translate/test/out/z-translation.geojson b/packages/turf-transform-translate/test/out/z-translation.geojson index c85920a457..8f0d7e86b0 100644 --- a/packages/turf-transform-translate/test/out/z-translation.geojson +++ b/packages/turf-transform-translate/test/out/z-translation.geojson @@ -25,6 +25,30 @@ ] } }, + { + "type": "Feature", + "properties": { + "distance": 120, + "units": "miles", + "direction": 165, + "zTranslation": 15, + "stroke": "#00F", + "stroke-width": 4 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [121.896083, -25.557737, 25], + [125.992335, -29.166271, 26], + [130.18447, -27.236726, 27], + [129.776416, -23.740417, 28], + [125.417422, -22.063039, 29], + [121.896083, -25.557737, 25] + ] + ] + } + }, { "type": "Feature", "properties": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3ab4e90963..efe1f85dd2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6252,9 +6252,21 @@ importers: packages/turf-transform-translate: dependencies: + '@turf/bearing': + specifier: workspace:^ + version: link:../turf-bearing + '@turf/centroid': + specifier: workspace:^ + version: link:../turf-centroid '@turf/clone': specifier: workspace:^ version: link:../turf-clone + '@turf/destination': + specifier: workspace:^ + version: link:../turf-destination + '@turf/distance': + specifier: workspace:^ + version: link:../turf-distance '@turf/helpers': specifier: workspace:^ version: link:../turf-helpers @@ -6274,6 +6286,15 @@ importers: specifier: ^2.8.1 version: 2.8.1 devDependencies: + '@turf/area': + specifier: workspace:^ + version: link:../turf-area + '@turf/circle': + specifier: workspace:^ + version: link:../turf-circle + '@turf/intersect': + specifier: workspace:^ + version: link:../turf-intersect '@turf/truncate': specifier: workspace:^ version: link:../turf-truncate From 1f9ef052963b2b3fef93b0959f6ee730afe0d6f6 Mon Sep 17 00:00:00 2001 From: hadrien Date: Tue, 17 Dec 2024 14:53:38 +0100 Subject: [PATCH 2/2] updates doc --- packages/turf-transform-translate/README.md | 1 + packages/turf-transform-translate/index.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/turf-transform-translate/README.md b/packages/turf-transform-translate/README.md index 846ebc0bc1..6d1f340839 100644 --- a/packages/turf-transform-translate/README.md +++ b/packages/turf-transform-translate/README.md @@ -17,6 +17,7 @@ on the provided direction angle. * `options.units` **Units** in which `distance` will be express; miles, kilometers, degrees, or radians (optional, default `'kilometers'`) * `options.zTranslation` **[number][3]** length of the vertical motion, same unit of distance (optional, default `0`) * `options.mutate` **[boolean][5]** allows GeoJSON input to be mutated (significant performance increase if true) (optional, default `false`) + * `options.aroundCenter` **[boolean][5]** when set to true, for each feature the center is translated and the geometry reconstructed around it. Otherwise, points are independently translated. (optional, default `false`) ### Examples diff --git a/packages/turf-transform-translate/index.ts b/packages/turf-transform-translate/index.ts index e53aa8df6c..4d7f7120b6 100644 --- a/packages/turf-transform-translate/index.ts +++ b/packages/turf-transform-translate/index.ts @@ -118,8 +118,8 @@ function transformTranslate( * * @private * @param {GeoJSON|GeometryCollection} feature feature or geometry collection to translate - * @param {number} distance of translation greater than 0 - * @param {number} direction of translation + * @param {number} distanceTranslation of translation greater than 0 + * @param {number} directionTranslation of translation * @param {number} zTranslation * @param {Units} units in which the distance is expressed * @returns {GeoJSON|GeometryCollection} translated GeoJSON Feature/Geometry