Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bbox for arbitrary geometries #769

Merged
merged 3 commits into from
Mar 29, 2018
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
39 changes: 39 additions & 0 deletions services-turf/src/main/java/com/mapbox/turf/TurfMeasurement.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;

import com.mapbox.geojson.Geometry;
import com.mapbox.geojson.GeometryCollection;
import com.mapbox.geojson.LineString;
import com.mapbox.geojson.MultiLineString;
import com.mapbox.geojson.MultiPoint;
import com.mapbox.geojson.Point;
import com.mapbox.geojson.Polygon;
import com.mapbox.geojson.MultiPolygon;

import java.util.ArrayList;
import java.util.List;

/**
Expand Down Expand Up @@ -333,6 +336,42 @@ public static double[] bbox(MultiPolygon multiPolygon) {
return bboxCalculator(resultCoords);
}

/**
* Takes an arbitrary {@link Geometry} and calculates a bounding box.
*
* @param geometry a {@link Geometry} object
* @return a double array defining the bounding box in this order {@code [minX, minY, maxX, maxY]}
* @since 2.0.0
*/
public static double[] bbox(Geometry geometry) {
if (geometry instanceof Point) {
return bbox((Point) geometry);
} else if (geometry instanceof MultiPoint) {
return bbox((MultiPoint) geometry);
} else if (geometry instanceof LineString) {
return bbox((LineString) geometry);
} else if (geometry instanceof MultiLineString) {
return bbox((MultiLineString) geometry);
} else if (geometry instanceof Polygon) {
return bbox((Polygon) geometry);
} else if (geometry instanceof MultiPolygon) {
return bbox((MultiPolygon) geometry);
} else if (geometry instanceof GeometryCollection) {
List<Point> points = new ArrayList<>();
for (Geometry geo : ((GeometryCollection) geometry).geometries()) {
// recursive
double[] bbox = bbox(geo);
points.add(Point.fromLngLat(bbox[0], bbox[1]));
points.add(Point.fromLngLat(bbox[2], bbox[1]));
points.add(Point.fromLngLat(bbox[2], bbox[3]));
points.add(Point.fromLngLat(bbox[0], bbox[3]));
}
return TurfMeasurement.bbox(MultiPoint.fromLngLats(points));
} else {
throw new RuntimeException(("Unknown geometry class: " + geometry.getClass()));
}
}

private static double[] bboxCalculator(List<Point> resultCoords) {
double[] bbox = new double[4];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package com.mapbox.turf;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import com.mapbox.geojson.Feature;
import com.mapbox.geojson.MultiLineString;
import com.mapbox.core.TestUtils;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.FeatureCollection;
import com.mapbox.geojson.Polygon;
import com.mapbox.geojson.Geometry;
import com.mapbox.geojson.GeometryCollection;
import com.mapbox.geojson.LineString;
import com.mapbox.geojson.MultiLineString;
import com.mapbox.geojson.MultiPoint;
import com.mapbox.geojson.MultiPolygon;
import com.mapbox.geojson.Point;
import com.mapbox.geojson.Polygon;

import org.junit.Assert;
import org.junit.Rule;
Expand All @@ -23,13 +21,19 @@
import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;

public class TurfMeasurementTest extends TestUtils {

private static final String LINE_DISTANCE_ROUTE_ONE = "turf-line-distance/route1.geojson";
private static final String LINE_DISTANCE_ROUTE_TWO = "turf-line-distance/route2.geojson";
private static final String LINE_DISTANCE_POLYGON = "turf-line-distance/polygon.geojson";
private static final String TURF_ALONG_DC_LINE = "turf-along/dc-line.geojson";
private static final String TURF_BBOX_POINT = "turf-bbox/point.geojson";
private static final String TURF_BBOX_MULTI_POINT = "turf-bbox/multipoint.geojson";
private static final String TURF_BBOX_LINESTRING = "turf-bbox/linestring.geojson";
private static final String TURF_BBOX_POLYGON = "turf-bbox/polygon.geojson";
private static final String TURF_BBOX_MULTILINESTRING = "turf-bbox/multilinestring.geojson";
Expand Down Expand Up @@ -301,4 +305,40 @@ public void bboxFromMultiPolygon() throws IOException, TurfException {
assertEquals(103, bbox[2], DELTA);
assertEquals(3, bbox[3], DELTA);
}

@Test
public void bboxFromGeometry() throws IOException, TurfException {
Geometry geometry = MultiPolygon.fromJson(loadJsonFixture(TURF_BBOX_MULTIPOLYGON));
double[] bbox = TurfMeasurement.bbox(geometry);

assertEquals(4, bbox.length);
assertEquals(100, bbox[0], DELTA);
assertEquals(0, bbox[1], DELTA);
assertEquals(103, bbox[2], DELTA);
assertEquals(3, bbox[3], DELTA);
}

@Test
public void bboxFromGeometryCollection() throws IOException, TurfException {
// Check that geometry collection and direct bbox are equal
MultiPolygon multiPolygon = MultiPolygon.fromJson(loadJsonFixture(TURF_BBOX_MULTIPOLYGON));
assertArrayEquals(TurfMeasurement.bbox(multiPolygon), TurfMeasurement.bbox(GeometryCollection.fromGeometry(multiPolygon)), DELTA);

// Check all geometry types
List<Geometry> geometries = new ArrayList<>();
geometries.add(Feature.fromJson(loadJsonFixture(TURF_BBOX_POINT)).geometry());
geometries.add(MultiPoint.fromJson(loadJsonFixture(TURF_BBOX_MULTI_POINT)));
geometries.add(LineString.fromJson(loadJsonFixture(TURF_BBOX_LINESTRING)));
geometries.add(MultiLineString.fromJson(loadJsonFixture(TURF_BBOX_MULTILINESTRING)));
geometries.add(Feature.fromJson(loadJsonFixture(TURF_BBOX_POLYGON)).geometry());
geometries.add(MultiPolygon.fromJson(loadJsonFixture(TURF_BBOX_MULTIPOLYGON)));
geometries.add(GeometryCollection.fromGeometry(Point.fromLngLat(-1., -1.)));
double[] bbox = TurfMeasurement.bbox(GeometryCollection.fromGeometries(geometries));

assertEquals(4, bbox.length);
assertEquals(-1, bbox[0], DELTA);
assertEquals(-10, bbox[1], DELTA);
assertEquals(130, bbox[2], DELTA);
assertEquals(4, bbox[3], DELTA);
}
}
21 changes: 21 additions & 0 deletions services-turf/src/test/resources/turf-bbox/multipoint.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"type": "MultiPoint",
"coordinates": [
[
102,
-10
],
[
103,
1
],
[
104,
0
],
[
130,
4
]
]
}