Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions packages/turf-helpers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,18 @@ turf.isObject('foo')

Returns **[boolean][23]** true/false, including false for Arrays and Functions

## removeBbox

Recursively removes bounding boxes from a GeoJSON object.

This function mutates the input GeoJSON object.

### Parameters

* `geojson` **[GeoJSON][24]** GeoJSON object whose bounding boxes should be removed

Returns **void** 

[1]: https://www.thoughtco.com/degree-of-latitude-and-longitude-distance-4070616

[2]: #units
Expand Down Expand Up @@ -615,6 +627,8 @@ Returns **[boolean][23]** true/false, including false for Arrays and Functions

[23]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean

[24]: https://tools.ietf.org/html/rfc7946#section-3

<!-- This file is automatically generated. Please don't edit it directly. If you find an error, edit the source file of the module in question (likely index.js or index.ts), and re-run "yarn docs" from the root of the turf project. -->

---
Expand Down
22 changes: 22 additions & 0 deletions packages/turf-helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Polygon,
Position,
GeoJsonProperties,
GeoJSON,
} from "geojson";

import { Id } from "./lib/geojson.js";
Expand Down Expand Up @@ -877,6 +878,27 @@ export function isObject(input: any): boolean {
return input !== null && typeof input === "object" && !Array.isArray(input);
}

/**
* Recursively removes bounding boxes from a GeoJSON object.
*
* This function mutates the input GeoJSON object.
*
* @function
* @param {GeoJSON} geojson GeoJSON object whose bounding boxes should be removed
* @returns {void}
*/
export function removeBbox(geojson: GeoJSON): void {
delete geojson.bbox;

if (geojson.type === "Feature") {
if (geojson.geometry) removeBbox(geojson.geometry);
} else if (geojson.type === "FeatureCollection") {
geojson.features.forEach(removeBbox);
} else if (geojson.type === "GeometryCollection") {
geojson.geometries.forEach(removeBbox);
}
}

/**
* Validate BBox
*
Expand Down
33 changes: 33 additions & 0 deletions packages/turf-helpers/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
isObject,
isNumber,
earthRadius,
removeBbox,
} from "./index.js";
import * as turf from "./index.js";

Expand All @@ -47,6 +48,38 @@ test("point", (t) => {
t.end();
});

test("removeBbox", (t) => {
const line = lineString(
[
[0, 0],
[1, 1],
],
{ bbox: "property value is preserved" }
);
line.bbox = [0, 0, 1, 1];
line.geometry.bbox = [0, 0, 1, 1];

const collection = geometryCollection([line.geometry]);
collection.bbox = [0, 0, 1, 1];
collection.geometry.bbox = [0, 0, 1, 1];

const input = featureCollection([collection]);
input.bbox = [0, 0, 1, 1];

removeBbox(input);

t.notOk(input.bbox, "removes FeatureCollection bbox");
t.notOk(collection.bbox, "removes Feature bbox");
t.notOk(collection.geometry.bbox, "removes GeometryCollection bbox");
t.notOk(line.geometry.bbox, "removes nested geometry bbox");
t.equal(
line.properties.bbox,
"property value is preserved",
"does not alter feature properties"
);
t.end();
});

test("polygon", (t) => {
const poly = polygon(
[
Expand Down
3 changes: 3 additions & 0 deletions packages/turf-helpers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
point,
polygon,
radiansToLength,
removeBbox,
} from "./index.js";

// Fixtures
Expand Down Expand Up @@ -58,6 +59,8 @@ const multiPoly = multiPolygon([
],
]);

removeBbox(multiPoly);

// radiansToLength & lengthToRadians
radiansToLength(5);
lengthToRadians(10);
Expand Down
3 changes: 2 additions & 1 deletion packages/turf-transform-rotate/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { rhumbDestination } from "@turf/rhumb-destination";
import { clone } from "@turf/clone";
import { coordEach } from "@turf/meta";
import { getCoords } from "@turf/invariant";
import { isObject, Coord } from "@turf/helpers";
import { isObject, removeBbox, Coord } from "@turf/helpers";

/**
* Rotates any geojson Feature or Geometry of a specified angle, around its `centroid` or a given `pivot` point.
Expand Down Expand Up @@ -66,6 +66,7 @@ function transformRotate<T extends GeoJSON | GeometryCollection>(
pointCoords[0] = newCoords[0];
pointCoords[1] = newCoords[1];
});
removeBbox(geojson);
return geojson;
}

Expand Down
50 changes: 50 additions & 0 deletions packages/turf-transform-rotate/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,53 @@ function makePivot(pivot: Coord, geojson: GeoJSON | GeometryCollection) {
}
return point(getCoord(pivot), { "marker-symbol": "circle" });
}

test("rotate -- removes stale bbox values", (t) => {
const input = nestedGeojsonWithBboxes();
const rotated = rotate(input, 45);

t.equal(countBboxes(rotated), 0, "removes bboxes from cloned output");
t.ok(countBboxes(input) > 0, "does not alter input by default");

rotate(input, 45, { mutate: true });
t.equal(countBboxes(input), 0, "removes bboxes from mutated input");
t.end();
});

function nestedGeojsonWithBboxes() {
const geojson = featureCollection([
geometryCollection([
lineString([
[0, 0],
[1, 1],
]).geometry,
]),
]);
addBboxes(geojson);
return geojson;
}

function addBboxes(geojson: GeoJSON | GeometryCollection): void {
geojson.bbox = [0, 0, 1, 1];
if (geojson.type === "Feature" && geojson.geometry) {
addBboxes(geojson.geometry);
} else if (geojson.type === "FeatureCollection") {
geojson.features.forEach(addBboxes);
} else if (geojson.type === "GeometryCollection") {
geojson.geometries.forEach(addBboxes);
}
}

function countBboxes(geojson: GeoJSON | GeometryCollection): number {
let count = geojson.bbox ? 1 : 0;
if (geojson.type === "Feature" && geojson.geometry) {
count += countBboxes(geojson.geometry);
} else if (geojson.type === "FeatureCollection") {
geojson.features.forEach((feature) => (count += countBboxes(feature)));
} else if (geojson.type === "GeometryCollection") {
geojson.geometries.forEach((geometry) => {
count += countBboxes(geometry);
});
}
return count;
}
5 changes: 3 additions & 2 deletions packages/turf-transform-scale/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Corners, Coord } from "@turf/helpers";
import { Corners, Coord, removeBbox } from "@turf/helpers";
import { FeatureCollection, GeoJSON, GeometryCollection } from "geojson";
import { clone } from "@turf/clone";
import { center } from "@turf/center";
Expand Down Expand Up @@ -67,6 +67,7 @@ function transformScale<T extends GeoJSON | GeometryCollection>(
origin
);
});
if (factor !== 1) delete geojson.bbox;
return geojson;
}
// Scale Feature/Geometry
Expand Down Expand Up @@ -108,7 +109,7 @@ function scale<T extends GeoJSON | GeometryCollection>(
if (coord.length === 3) coord[2] *= factor;
});

delete feature.bbox;
removeBbox(feature);

return feature;
}
Expand Down
58 changes: 57 additions & 1 deletion packages/turf-transform-scale/test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { BBox, Feature, FeatureCollection } from "geojson";
import {
BBox,
Feature,
FeatureCollection,
GeoJSON,
GeometryCollection,
} from "geojson";
import fs from "fs";
import test from "tape";
import path from "path";
Expand Down Expand Up @@ -277,6 +283,56 @@ function colorize(geojson: FeatureCollection | Feature) {
return geojson;
}

test("scale -- removes stale bbox values", (t) => {
const input = nestedGeojsonWithBboxes();
const scaled = scale(input, 2, { origin: [0, 0] });

t.equal(countBboxes(scaled), 0, "removes bboxes from cloned output");
t.ok(countBboxes(input) > 0, "does not alter input by default");

scale(input, 2, { origin: [0, 0], mutate: true });
t.equal(countBboxes(input), 0, "removes bboxes from mutated input");
t.end();
});

function nestedGeojsonWithBboxes() {
const geojson = featureCollection([
geometryCollection([
lineString([
[0, 0],
[1, 1],
]).geometry,
]),
]);
addBboxes(geojson);
return geojson;
}

function addBboxes(geojson: GeoJSON | GeometryCollection): void {
geojson.bbox = [0, 0, 1, 1];
if (geojson.type === "Feature" && geojson.geometry) {
addBboxes(geojson.geometry);
} else if (geojson.type === "FeatureCollection") {
geojson.features.forEach(addBboxes);
} else if (geojson.type === "GeometryCollection") {
geojson.geometries.forEach(addBboxes);
}
}

function countBboxes(geojson: GeoJSON | GeometryCollection): number {
let count = geojson.bbox ? 1 : 0;
if (geojson.type === "Feature" && geojson.geometry) {
count += countBboxes(geojson.geometry);
} else if (geojson.type === "FeatureCollection") {
geojson.features.forEach((feature) => (count += countBboxes(feature)));
} else if (geojson.type === "GeometryCollection") {
geojson.geometries.forEach((geometry) => {
count += countBboxes(geometry);
});
}
return count;
}

// define origin, as defined in transform-scale, and style it
function markedOrigin(
geojson: Feature,
Expand Down
3 changes: 2 additions & 1 deletion packages/turf-transform-translate/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { GeoJSON, GeometryCollection } from "geojson";
import { coordEach } from "@turf/meta";
import { isObject, Units } from "@turf/helpers";
import { isObject, removeBbox, Units } from "@turf/helpers";
import { getCoords } from "@turf/invariant";
import { clone } from "@turf/clone";
import { rhumbDestination } from "@turf/rhumb-destination";
Expand Down Expand Up @@ -79,6 +79,7 @@ function transformTranslate<T extends GeoJSON | GeometryCollection>(
if (zTranslation && pointCoords.length === 3)
pointCoords[2] += zTranslation;
});
removeBbox(geojson);
return geojson;
}

Expand Down
52 changes: 51 additions & 1 deletion packages/turf-transform-translate/test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Feature } from "geojson";
import { Feature, GeoJSON, GeometryCollection } from "geojson";
import fs from "fs";
import test from "tape";
import path from "path";
Expand Down Expand Up @@ -152,3 +152,53 @@ function colorize(geojson: Feature) {
}
return geojson;
}

test("translate -- removes stale bbox values", (t) => {
const input = nestedGeojsonWithBboxes();
const translated = translate(input, 10, 45);

t.equal(countBboxes(translated), 0, "removes bboxes from cloned output");
t.ok(countBboxes(input) > 0, "does not alter input by default");

translate(input, 10, 45, { mutate: true });
t.equal(countBboxes(input), 0, "removes bboxes from mutated input");
t.end();
});

function nestedGeojsonWithBboxes() {
const geojson = featureCollection([
geometryCollection([
lineString([
[0, 0],
[1, 1],
]).geometry,
]),
]);
addBboxes(geojson);
return geojson;
}

function addBboxes(geojson: GeoJSON | GeometryCollection): void {
geojson.bbox = [0, 0, 1, 1];
if (geojson.type === "Feature" && geojson.geometry) {
addBboxes(geojson.geometry);
} else if (geojson.type === "FeatureCollection") {
geojson.features.forEach(addBboxes);
} else if (geojson.type === "GeometryCollection") {
geojson.geometries.forEach(addBboxes);
}
}

function countBboxes(geojson: GeoJSON | GeometryCollection): number {
let count = geojson.bbox ? 1 : 0;
if (geojson.type === "Feature" && geojson.geometry) {
count += countBboxes(geojson.geometry);
} else if (geojson.type === "FeatureCollection") {
geojson.features.forEach((feature) => (count += countBboxes(feature)));
} else if (geojson.type === "GeometryCollection") {
geojson.geometries.forEach((geometry) => {
count += countBboxes(geometry);
});
}
return count;
}
Loading