Skip to content

Commit

Permalink
Converted turf-transform-rotate to Typescript (#2651)
Browse files Browse the repository at this point in the history
* Converting turf-transform-rotate to Typescript. Avoiding in house type AllGeoJSON.
  • Loading branch information
smallsaucepan authored Jul 23, 2024
1 parent 19d2aa9 commit 8cb62b6
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 40 deletions.
8 changes: 4 additions & 4 deletions packages/turf-transform-rotate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ Rotates any geojson Feature or Geometry of a specified angle, around its `centro
### Examples

```javascript
var poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]);
var options = {pivot: [0, 25]};
var rotatedPoly = turf.transformRotate(poly, 10, options);
const poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]);
const options = {pivot: [0, 25]};
const rotatedPoly = turf.transformRotate(poly, 10, options);

//addToMap
var addToMap = [poly, rotatedPoly];
const addToMap = [poly, rotatedPoly];
rotatedPoly.properties = {stroke: '#F00', 'stroke-width': 4};
```

Expand Down
7 changes: 4 additions & 3 deletions packages/turf-transform-rotate/bench.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Feature } from "geojson";
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
import { loadJsonFileSync } from "load-json-file";
import Benchmark from "benchmark";
import Benchmark, { Event } from "benchmark";
import { transformRotate as rotate } from "./index.js";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
Expand All @@ -11,7 +12,7 @@ const directory = path.join(__dirname, "test", "in") + path.sep;
const fixtures = fs.readdirSync(directory).map((filename) => {
return {
name: path.parse(filename).name,
geojson: loadJsonFileSync(directory + filename),
geojson: loadJsonFileSync(directory + filename) as Feature,
};
});

Expand Down Expand Up @@ -54,4 +55,4 @@ for (const { name, geojson } of fixtures) {
suite.add(name, () => rotate(geojson, angle, { pivot, mutate: true }));
}

suite.on("cycle", (e) => console.log(String(e.target))).run();
suite.on("cycle", (e: Event) => console.log(String(e.target))).run();
16 changes: 0 additions & 16 deletions packages/turf-transform-rotate/index.d.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { GeoJSON, GeometryCollection } from "geojson";
import { centroid } from "@turf/centroid";
import { rhumbBearing } from "@turf/rhumb-bearing";
import { rhumbDistance } from "@turf/rhumb-distance";
import { rhumbDestination } from "@turf/rhumb-destination";
import { clone } from "@turf/clone";
import { coordEach } from "@turf/meta";
import { getCoords } from "@turf/invariant";
import { isObject } from "@turf/helpers";
import { isObject, Coord } from "@turf/helpers";

/**
* Rotates any geojson Feature or Geometry of a specified angle, around its `centroid` or a given `pivot` point.
Expand All @@ -18,20 +19,27 @@ import { isObject } from "@turf/helpers";
* @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true)
* @returns {GeoJSON} the rotated GeoJSON feature
* @example
* var poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]);
* var options = {pivot: [0, 25]};
* var rotatedPoly = turf.transformRotate(poly, 10, options);
* const poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]);
* const options = {pivot: [0, 25]};
* const rotatedPoly = turf.transformRotate(poly, 10, options);
*
* //addToMap
* var addToMap = [poly, rotatedPoly];
* const addToMap = [poly, rotatedPoly];
* rotatedPoly.properties = {stroke: '#F00', 'stroke-width': 4};
*/
function transformRotate(geojson, angle, options) {
function transformRotate<T extends GeoJSON | GeometryCollection>(
geojson: T,
angle: number,
options?: {
pivot?: Coord;
mutate?: boolean;
}
): T {
// Optional parameters
options = options || {};
if (!isObject(options)) throw new Error("options is invalid");
var pivot = options.pivot;
var mutate = options.mutate;
const pivot = options.pivot;
const mutate = options.mutate;

// Input validation
if (!geojson) throw new Error("geojson is required");
Expand All @@ -42,17 +50,19 @@ function transformRotate(geojson, angle, options) {
if (angle === 0) return geojson;

// Use centroid of GeoJSON if pivot is not provided
if (!pivot) pivot = centroid(geojson);
const pivotCoord = pivot ?? centroid(geojson);

// Clone geojson to avoid side effects
if (mutate === false || mutate === undefined) geojson = clone(geojson);

// Rotate each coordinate
coordEach(geojson, function (pointCoords) {
var initialAngle = rhumbBearing(pivot, pointCoords);
var finalAngle = initialAngle + angle;
var distance = rhumbDistance(pivot, pointCoords);
var newCoords = getCoords(rhumbDestination(pivot, distance, finalAngle));
const initialAngle = rhumbBearing(pivotCoord, pointCoords);
const finalAngle = initialAngle + angle;
const distance = rhumbDistance(pivotCoord, pointCoords);
const newCoords = getCoords(
rhumbDestination(pivotCoord, distance, finalAngle)
);
pointCoords[0] = newCoords[0];
pointCoords[1] = newCoords[1];
});
Expand Down
5 changes: 4 additions & 1 deletion packages/turf-transform-rotate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"tape": "^5.7.2",
"tsup": "^8.0.1",
"tsx": "^4.6.2",
"typescript": "^5.2.2",
"write-json-file": "^5.0.0"
},
"dependencies": {
Expand All @@ -75,6 +76,8 @@
"@turf/meta": "workspace:^",
"@turf/rhumb-bearing": "workspace:^",
"@turf/rhumb-destination": "workspace:^",
"@turf/rhumb-distance": "workspace:^"
"@turf/rhumb-distance": "workspace:^",
"@types/geojson": "7946.0.8",
"tslib": "^2.6.2"
}
}
15 changes: 12 additions & 3 deletions packages/turf-transform-rotate/test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Feature, GeoJSON, GeometryCollection } from "geojson";
import fs from "fs";
import test from "tape";
import path from "path";
Expand All @@ -12,6 +13,7 @@ import {
lineString,
featureCollection,
geometryCollection,
Coord,
} from "@turf/helpers";
import { transformRotate as rotate } from "./index.js";

Expand All @@ -26,7 +28,7 @@ const fixtures = fs.readdirSync(directories.in).map((filename) => {
return {
filename,
name: path.parse(filename).name,
geojson: loadJsonFileSync(directories.in + filename),
geojson: loadJsonFileSync(directories.in + filename) as Feature,
};
});

Expand Down Expand Up @@ -55,9 +57,12 @@ test("rotate -- throws", (t) => {
[12, 15],
]);

// @ts-expect-error testing JS runtime for mis-typed option
t.throws(() => rotate(null, 100), /geojson is required/, "missing geojson");
// @ts-expect-error testing JS runtime for mis-typed option
t.throws(() => rotate(line, null), /angle is required/, "missing angle");
t.throws(
// @ts-expect-error testing JS runtime for mis-typed option
() => rotate(line, 56, { pivot: "notApoint" }),
/coord must be GeoJSON Point or an Array of numbers/,
"coord must be GeoJSON Point or an Array of numbers"
Expand Down Expand Up @@ -116,7 +121,10 @@ test("rotate -- geometry support", (t) => {
});

// style result
function colorize(geojson) {
function colorize(geojson: Feature) {
// We are going to add some properties, so make sure properties attribute is
// present.
geojson.properties = geojson.properties ?? {};
if (
geojson.geometry.type === "Point" ||
geojson.geometry.type === "MultiPoint"
Expand All @@ -130,9 +138,10 @@ function colorize(geojson) {
return geojson;
}

function makePivot(pivot, geojson) {
function makePivot(pivot: Coord, geojson: GeoJSON | GeometryCollection) {
if (!pivot) {
const pt = centroid(geojson);
pt.properties = pt.properties ?? {};
pt.properties["marker-symbol"] = "circle";
return pt;
}
Expand Down
9 changes: 9 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8cb62b6

Please sign in to comment.