Skip to content

Commit 3847436

Browse files
ivovandongenCameron Mace
authored andcommitted
[turf] add bbox for arbitrary geometries (#769)
1 parent 642b039 commit 3847436

3 files changed

Lines changed: 108 additions & 8 deletions

File tree

services-turf/src/main/java/com/mapbox/turf/TurfMeasurement.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
import android.support.annotation.FloatRange;
44
import android.support.annotation.NonNull;
55

6+
import com.mapbox.geojson.Geometry;
7+
import com.mapbox.geojson.GeometryCollection;
68
import com.mapbox.geojson.LineString;
79
import com.mapbox.geojson.MultiLineString;
810
import com.mapbox.geojson.MultiPoint;
911
import com.mapbox.geojson.Point;
1012
import com.mapbox.geojson.Polygon;
1113
import com.mapbox.geojson.MultiPolygon;
1214

15+
import java.util.ArrayList;
1316
import java.util.List;
1417

1518
/**
@@ -333,6 +336,42 @@ public static double[] bbox(MultiPolygon multiPolygon) {
333336
return bboxCalculator(resultCoords);
334337
}
335338

339+
/**
340+
* Takes an arbitrary {@link Geometry} and calculates a bounding box.
341+
*
342+
* @param geometry a {@link Geometry} object
343+
* @return a double array defining the bounding box in this order {@code [minX, minY, maxX, maxY]}
344+
* @since 2.0.0
345+
*/
346+
public static double[] bbox(Geometry geometry) {
347+
if (geometry instanceof Point) {
348+
return bbox((Point) geometry);
349+
} else if (geometry instanceof MultiPoint) {
350+
return bbox((MultiPoint) geometry);
351+
} else if (geometry instanceof LineString) {
352+
return bbox((LineString) geometry);
353+
} else if (geometry instanceof MultiLineString) {
354+
return bbox((MultiLineString) geometry);
355+
} else if (geometry instanceof Polygon) {
356+
return bbox((Polygon) geometry);
357+
} else if (geometry instanceof MultiPolygon) {
358+
return bbox((MultiPolygon) geometry);
359+
} else if (geometry instanceof GeometryCollection) {
360+
List<Point> points = new ArrayList<>();
361+
for (Geometry geo : ((GeometryCollection) geometry).geometries()) {
362+
// recursive
363+
double[] bbox = bbox(geo);
364+
points.add(Point.fromLngLat(bbox[0], bbox[1]));
365+
points.add(Point.fromLngLat(bbox[2], bbox[1]));
366+
points.add(Point.fromLngLat(bbox[2], bbox[3]));
367+
points.add(Point.fromLngLat(bbox[0], bbox[3]));
368+
}
369+
return TurfMeasurement.bbox(MultiPoint.fromLngLats(points));
370+
} else {
371+
throw new RuntimeException(("Unknown geometry class: " + geometry.getClass()));
372+
}
373+
}
374+
336375
private static double[] bboxCalculator(List<Point> resultCoords) {
337376
double[] bbox = new double[4];
338377

services-turf/src/test/java/com/mapbox/turf/TurfMeasurementTest.java

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
package com.mapbox.turf;
22

3-
import static org.junit.Assert.assertEquals;
4-
import static org.junit.Assert.assertNotEquals;
5-
import static org.junit.Assert.assertNotNull;
6-
import static org.junit.Assert.assertTrue;
7-
8-
import com.mapbox.geojson.Feature;
9-
import com.mapbox.geojson.MultiLineString;
103
import com.mapbox.core.TestUtils;
4+
import com.mapbox.geojson.Feature;
115
import com.mapbox.geojson.FeatureCollection;
12-
import com.mapbox.geojson.Polygon;
6+
import com.mapbox.geojson.Geometry;
7+
import com.mapbox.geojson.GeometryCollection;
138
import com.mapbox.geojson.LineString;
9+
import com.mapbox.geojson.MultiLineString;
10+
import com.mapbox.geojson.MultiPoint;
1411
import com.mapbox.geojson.MultiPolygon;
1512
import com.mapbox.geojson.Point;
13+
import com.mapbox.geojson.Polygon;
1614

1715
import org.junit.Assert;
1816
import org.junit.Rule;
@@ -23,13 +21,19 @@
2321
import java.util.ArrayList;
2422
import java.util.List;
2523

24+
import static org.junit.Assert.assertArrayEquals;
25+
import static org.junit.Assert.assertEquals;
26+
import static org.junit.Assert.assertNotEquals;
27+
import static org.junit.Assert.assertNotNull;
28+
2629
public class TurfMeasurementTest extends TestUtils {
2730

2831
private static final String LINE_DISTANCE_ROUTE_ONE = "turf-line-distance/route1.geojson";
2932
private static final String LINE_DISTANCE_ROUTE_TWO = "turf-line-distance/route2.geojson";
3033
private static final String LINE_DISTANCE_POLYGON = "turf-line-distance/polygon.geojson";
3134
private static final String TURF_ALONG_DC_LINE = "turf-along/dc-line.geojson";
3235
private static final String TURF_BBOX_POINT = "turf-bbox/point.geojson";
36+
private static final String TURF_BBOX_MULTI_POINT = "turf-bbox/multipoint.geojson";
3337
private static final String TURF_BBOX_LINESTRING = "turf-bbox/linestring.geojson";
3438
private static final String TURF_BBOX_POLYGON = "turf-bbox/polygon.geojson";
3539
private static final String TURF_BBOX_MULTILINESTRING = "turf-bbox/multilinestring.geojson";
@@ -301,4 +305,40 @@ public void bboxFromMultiPolygon() throws IOException, TurfException {
301305
assertEquals(103, bbox[2], DELTA);
302306
assertEquals(3, bbox[3], DELTA);
303307
}
308+
309+
@Test
310+
public void bboxFromGeometry() throws IOException, TurfException {
311+
Geometry geometry = MultiPolygon.fromJson(loadJsonFixture(TURF_BBOX_MULTIPOLYGON));
312+
double[] bbox = TurfMeasurement.bbox(geometry);
313+
314+
assertEquals(4, bbox.length);
315+
assertEquals(100, bbox[0], DELTA);
316+
assertEquals(0, bbox[1], DELTA);
317+
assertEquals(103, bbox[2], DELTA);
318+
assertEquals(3, bbox[3], DELTA);
319+
}
320+
321+
@Test
322+
public void bboxFromGeometryCollection() throws IOException, TurfException {
323+
// Check that geometry collection and direct bbox are equal
324+
MultiPolygon multiPolygon = MultiPolygon.fromJson(loadJsonFixture(TURF_BBOX_MULTIPOLYGON));
325+
assertArrayEquals(TurfMeasurement.bbox(multiPolygon), TurfMeasurement.bbox(GeometryCollection.fromGeometry(multiPolygon)), DELTA);
326+
327+
// Check all geometry types
328+
List<Geometry> geometries = new ArrayList<>();
329+
geometries.add(Feature.fromJson(loadJsonFixture(TURF_BBOX_POINT)).geometry());
330+
geometries.add(MultiPoint.fromJson(loadJsonFixture(TURF_BBOX_MULTI_POINT)));
331+
geometries.add(LineString.fromJson(loadJsonFixture(TURF_BBOX_LINESTRING)));
332+
geometries.add(MultiLineString.fromJson(loadJsonFixture(TURF_BBOX_MULTILINESTRING)));
333+
geometries.add(Feature.fromJson(loadJsonFixture(TURF_BBOX_POLYGON)).geometry());
334+
geometries.add(MultiPolygon.fromJson(loadJsonFixture(TURF_BBOX_MULTIPOLYGON)));
335+
geometries.add(GeometryCollection.fromGeometry(Point.fromLngLat(-1., -1.)));
336+
double[] bbox = TurfMeasurement.bbox(GeometryCollection.fromGeometries(geometries));
337+
338+
assertEquals(4, bbox.length);
339+
assertEquals(-1, bbox[0], DELTA);
340+
assertEquals(-10, bbox[1], DELTA);
341+
assertEquals(130, bbox[2], DELTA);
342+
assertEquals(4, bbox[3], DELTA);
343+
}
304344
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"type": "MultiPoint",
3+
"coordinates": [
4+
[
5+
102,
6+
-10
7+
],
8+
[
9+
103,
10+
1
11+
],
12+
[
13+
104,
14+
0
15+
],
16+
[
17+
130,
18+
4
19+
]
20+
]
21+
}

0 commit comments

Comments
 (0)