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()) { 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[0], bbox[3])); return TurfMeasurement.bbox(MultiPoint.fromLngLats(points)); } else { throw new RuntimeException(("Unknown geometry class: " + geometry.getClass()));
/** * Takes two {@link Point}s and returns a point midway between them. The midpoint is calculated * geodesically, meaning the curvature of the earth is taken into account. * * @param from first point used for calculating the midpoint * @param to second point used for calculating the midpoint * @return a {@link Point} midway between point1 and point2 * @see <a href="http://turfjs.org/docs/#midpoint">Turf Midpoint documentation</a> * @since 1.3.0 */ public static Point midpoint(@NonNull Point from, @NonNull Point to) { double dist = distance(from, to, TurfConstants.UNIT_MILES); double heading = bearing(from, to); return destination(from, dist / 2, heading, TurfConstants.UNIT_MILES); }
/** * Takes a {@link LineString} and measures its length in the specified units. * * @param lineString geometry to measure * @param units one of the units found inside {@link TurfConstants.TurfUnitCriteria} * @return length of the input line in the units specified * @see <a href="http://turfjs.org/docs/#linedistance">Turf Line Distance documentation</a> * @since 1.2.0 */ public static double length(@NonNull LineString lineString, @NonNull @TurfConstants.TurfUnitCriteria String units) { List<Point> coordinates = lineString.coordinates(); return length(coordinates, units); }
@Test public void testMidpointDiagonalBackOverEquator() throws TurfException { Point pt1 = Point.fromLngLat(-1, 10); Point pt2 = Point.fromLngLat(1, -1); Point mid = TurfMeasurement.midpoint(pt1, pt2); assertEquals(TurfMeasurement.distance(pt1, mid, TurfConstants.UNIT_MILES), TurfMeasurement.distance(pt2, mid, TurfConstants.UNIT_MILES), DELTA); }
@Test public void testTurfPointOnLinePointsOnTopOfLine() throws TurfException { List<Point> line = new ArrayList<>(); line.add(Point.fromLngLat(-0.10919809341430663, 51.52204224896724)); line.add(Point.fromLngLat(-0.10923027992248535, 51.521942114455435)); line.add(Point.fromLngLat(-0.10916590690612793, 51.52186200668747)); line.add(Point.fromLngLat(-0.10904788970947266, 51.52177522311313)); line.add(Point.fromLngLat(-0.10886549949645996, 51.521601655468345)); line.add(Point.fromLngLat(-0.10874748229980469, 51.52138135712038)); line.add(Point.fromLngLat(-0.10855436325073242, 51.5206870765674)); line.add(Point.fromLngLat(-0.10843634605407713, 51.52027984939518)); line.add(Point.fromLngLat(-0.10839343070983887, 51.519952729849024)); line.add(Point.fromLngLat(-0.10817885398864746, 51.51957887606202)); line.add(Point.fromLngLat(-0.10814666748046874, 51.51928513164789)); line.add(Point.fromLngLat(-0.10789990425109863, 51.518624199789016)); line.add(Point.fromLngLat(-0.10759949684143065, 51.51778299991493)); double dist = TurfMeasurement.length(LineString.fromLngLats(line), TurfConstants.UNIT_MILES); double increment = dist / 10; for (int i = 0; i < 10; i++) { Point pt = TurfMeasurement.along( LineString.fromLngLats(line), increment * i, TurfConstants.UNIT_MILES); Feature snappedFeature = TurfMisc.nearestPointOnLine(pt, line); Point snapped = (Point) snappedFeature.geometry(); double shift = TurfMeasurement.distance(pt, snapped, TurfConstants.UNIT_MILES); // pt did not shift far assertTrue(shift < 0.000001); } }
@Test public void testTurfPointOnLinePointAlongLine() throws TurfException { List<Point> line = new ArrayList<>(); line.add(Point.fromLngLat(-122.45717525482178, 37.7200330638563)); line.add(Point.fromLngLat(-122.45717525482178, 37.718242366859215)); Point pt = TurfMeasurement.along( LineString.fromLngLats(line), 0.019, TurfConstants.UNIT_MILES); Feature snappedFeature = TurfMisc.nearestPointOnLine(pt, line); Point snapped = (Point) snappedFeature.geometry(); double shift = TurfMeasurement.distance(pt, snapped, TurfConstants.UNIT_MILES); // pt did not shift far assertTrue(shift < 0.00001); }
/** * Calculates the distance between two points in kilometers. This uses the Haversine formula to * account for global curvature. * * @param point1 first point used for calculating the bearing * @param point2 second point used for calculating the bearing * @return distance between the two points in kilometers * @see <a href="http://turfjs.org/docs/#distance">Turf distance documentation</a> * @since 1.2.0 */ public static double distance(@NonNull Point point1, @NonNull Point point2) { return distance(point1, point2, TurfConstants.UNIT_DEFAULT); }
/** * Takes a {@link Point} and calculates the circle polygon given a radius in degrees, radians, * miles, or kilometers; and steps for precision. * * @param center a {@link Point} which the circle will center around * @param radius the radius of the circle * @param steps number of steps which make up the circle parameter * @param units one of the units found inside {@link TurfConstants.TurfUnitCriteria} * @return a {@link Polygon} which represents the newly created circle * @since 3.0.0 */ public static Polygon circle(@NonNull Point center, double radius, int steps, @TurfConstants.TurfUnitCriteria String units) { List<Point> coordinates = new ArrayList<>(); for (int i = 0; i < steps; i++) { coordinates.add(TurfMeasurement.destination(center, radius, i * 360d / steps, units)); } coordinates.add(coordinates.get(0)); List<List<Point>> coordinate = new ArrayList<>(); coordinate.add(coordinates); return Polygon.fromLngLats(coordinate); } }
@Test public void turfAlong_returnsZeroWhenRouteIsPoint() throws Exception { List<Point> coords = new ArrayList<>(); coords.add(Point.fromLngLat(1.0, 1.0)); LineString lineString = LineString.fromLngLats(coords); Point point = TurfMeasurement.along(lineString, 0, TurfConstants.UNIT_METERS); assertEquals(1.0, point.latitude(), DELTA); assertEquals(1.0, point.longitude(), DELTA); }
@Test public void testBearing() { Point pt1 = Point.fromLngLat(-75.4, 39.4); Point pt2 = Point.fromLngLat(-75.534, 39.123); assertNotEquals(TurfMeasurement.bearing(pt1, pt2), 0, DELTA); }
/** * Takes a set of features, calculates the bbox of all input features, and returns a bounding box. * * @param lineString a {@link LineString} 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(@NonNull LineString lineString) { List<Point> resultCoords = TurfMeta.coordAll(lineString); return bboxCalculator(resultCoords); }
@Test public void testMidpointPositionToPoint() throws TurfException { Point pt1 = Point.fromLngLat(0, 0); Point pt2 = Point.fromLngLat(10, 0); Point mid = TurfMeasurement.midpoint(pt1, pt2); assertEquals(TurfMeasurement.distance(pt1, mid, TurfConstants.UNIT_MILES), TurfMeasurement.distance(pt2, mid, TurfConstants.UNIT_MILES), DELTA); }
private static double length(List<Point> coords, String units) { double travelled = 0; Point prevCoords = coords.get(0); Point curCoords; for (int i = 1; i < coords.size(); i++) { curCoords = coords.get(i); travelled += distance(prevCoords, curCoords, units); prevCoords = curCoords; } return travelled; }
@Test public void testDestination() throws TurfException { Point pt1 = Point.fromLngLat(-75.0, 39.0); double dist = 100; double bear = 180; assertNotNull(TurfMeasurement.destination(pt1, dist, bear, TurfConstants.UNIT_KILOMETERS)); }
@Test public void testLineSliceAlongRoute2() throws IOException, TurfException { Feature route2 = Feature.fromJson(loadJsonFixture(LINE_SLICE_ALONG_ROUTE_TWO)); LineString lineStringRoute2 = (LineString)route2.geometry(); double start = 25; double stop = 50; Point start_point = TurfMeasurement.along(lineStringRoute2, start, TurfConstants.UNIT_MILES); Point end_point = TurfMeasurement.along(lineStringRoute2, stop, TurfConstants.UNIT_MILES); LineString sliced = TurfMisc.lineSliceAlong(route2, start, stop, TurfConstants.UNIT_MILES); assertEquals(sliced.coordinates().get(0).coordinates(), start_point.coordinates()); assertEquals(sliced.coordinates().get(sliced.coordinates().size() - 1).coordinates(), end_point.coordinates()); }
/** * Takes a set of features, calculates the bbox of all input features, and returns a bounding box. * * @param multiPoint a {@link MultiPoint} 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(@NonNull MultiPoint multiPoint) { List<Point> resultCoords = TurfMeta.coordAll(multiPoint); return bboxCalculator(resultCoords); }
return coords.get(i); } else { double direction = bearing(coords.get(i), coords.get(i - 1)) - 180; return destination(coords.get(i), overshot, direction, units); travelled += distance(coords.get(i), coords.get(i + 1), units);
@Test public void testMidpointVericalToEquator() throws TurfException { Point pt1 = Point.fromLngLat(0, 10); Point pt2 = Point.fromLngLat(0, 0); Point mid = TurfMeasurement.midpoint(pt1, pt2); assertEquals(TurfMeasurement.distance(pt1, mid, TurfConstants.UNIT_MILES), TurfMeasurement.distance(pt2, mid, TurfConstants.UNIT_MILES), DELTA); }
/** * Takes a {@link MultiLineString} and measures its length in the specified units. * * @param multiLineString geometry to measure * @param units one of the units found inside {@link TurfConstants.TurfUnitCriteria} * @return length of the input lines combined, in the units specified * @see <a href="http://turfjs.org/docs/#linedistance">Turf Line Distance documentation</a> * @since 1.2.0 */ public static double length(@NonNull MultiLineString multiLineString, @NonNull @TurfConstants.TurfUnitCriteria String units) { double len = 0; for (List<Point> points : multiLineString.coordinates()) { len += length(points, units); } return len; }
@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); } }