/** * 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); }
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; }
/** * Takes a reference point and a list of {@link Point} geometries and returns the point from the * set point list closest to the reference. This calculation is geodesic. * * @param targetPoint the reference point * @param points set list of points to run against the input point * @return the closest point in the set to the reference point * @since 3.0.0 */ @NonNull public static Point nearestPoint(@NonNull Point targetPoint, @NonNull List<Point> points) { if (points.isEmpty()) { return targetPoint; } Point nearestPoint = points.get(0); double minDist = Double.POSITIVE_INFINITY; for (Point point : points) { double distanceToPoint = TurfMeasurement.distance(targetPoint, point); if (distanceToPoint < minDist) { nearestPoint = point; minDist = distanceToPoint; } } return nearestPoint; } }
/** * 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); }
travelled += distance(coords.get(i), coords.get(i + 1), units);
@Test public void testDistance() throws TurfException { Point pt1 = Point.fromLngLat(-75.343, 39.984); Point pt2 = Point.fromLngLat(-75.534, 39.123); // Common cases assertEquals(60.37218405837491, TurfMeasurement.distance(pt1, pt2, TurfConstants.UNIT_MILES), DELTA); assertEquals(52.461979624130436, TurfMeasurement.distance(pt1, pt2, TurfConstants.UNIT_NAUTICAL_MILES), DELTA); assertEquals(97.15957803131901, TurfMeasurement.distance(pt1, pt2, TurfConstants.UNIT_KILOMETERS), DELTA); assertEquals(0.015245501024842149, TurfMeasurement.distance(pt1, pt2, TurfConstants.UNIT_RADIANS), DELTA); assertEquals(0.8735028650863799, TurfMeasurement.distance(pt1, pt2, TurfConstants.UNIT_DEGREES), DELTA); // This also works assertEquals(97.15957803131901, TurfMeasurement.distance(pt1, pt2, TurfConstants.UNIT_KILOMETERS), DELTA); // Default is kilometers assertEquals(97.15957803131901, TurfMeasurement.distance(pt1, pt2), DELTA); // Bad units not possible }
travelled += TurfMeasurement.distance(coords.get(i), coords.get(i + 1), 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 testMidpointVericalFromEquator() throws TurfException { Point pt1 = Point.fromLngLat(0, 0); Point pt2 = Point.fromLngLat(0, 10); 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 testMidpointHorizontalEquator() 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); }
@Test public void testMidpointDiagonalForwardOverEquator() throws TurfException { Point pt1 = Point.fromLngLat(-5, -1); Point pt2 = Point.fromLngLat(5, 10); 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 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); }
@Test public void testMidpointLongDistance() throws TurfException { Point pt1 = Point.fromLngLat(22.5, 21.94304553343818); Point pt2 = Point.fromLngLat(92.10937499999999, 46.800059446787316); 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 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); }
@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); }
@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); } }
Feature stop = Feature.fromGeometry(coords.get(i + 1)); start.addNumberProperty("dist", TurfMeasurement.distance( pt, (Point) start.geometry(), TurfConstants.UNIT_MILES)); stop.addNumberProperty("dist", TurfMeasurement.distance( pt, (Point) stop.geometry(), TurfConstants.UNIT_MILES)); intersectPt = Feature.fromGeometry( Point.fromLngLat(intersect.horizontalIntersection(), intersect.verticalIntersection())); intersectPt.addNumberProperty("dist", TurfMeasurement.distance(pt, (Point) intersectPt.geometry(), TurfConstants.UNIT_MILES));