question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Distance to Polygon / MultiPolygon from Point

See original GitHub issue

Opened new issue as requested by @rowanwins from #252 .

Currently there is no native way to achieve distance to Polygon (and Multi-Polygon) from a point using Turf.

There was a suggestion in the previous issue to use the vertexes and measure the distance to those, but we end up with the following issue:

closest-point-to-polygon

In this image, B is clearly the closest point to the polygon, but using the above algorithm we’d end up with point A.

I’ve come up with the following solution for now:

const distanceKm = pointToLineDistance(point, polygonToLineString(polygon));

if (booleanPointInPolygon(point, polygon)) {
  return  distanceKm * -1;
} else {
  return distanceKm;
}

Using this over an array of Polygons allows me to achieve what I want. (I want to compare the distances of an array of Polygons to a Point and pick out the one which is the closest).

Still need to add support for MultiPolygons (as polygonToLineString doesn’t support them) - but that’s as easy as splitting the geometry’s coordinate array into multiple regular Polygons and finding the shortest distance within that group and choosing the shortest.

Since there is no direct function for Polygons, it makes use of polygonToLineString() to convert them to lines first and run the distance checks on that.

If the point is inside the Polygon, I return the negative value of the distance (how far inside the polygon the point is).

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:8
  • Comments:11 (1 by maintainers)

github_iconTop GitHub Comments

8reactions
pachacamaccommented, Dec 1, 2020

Seems to work nicely. Thank you @lostpebble !

In case someone sees this and just wants to use it in place without having to recompile turf, this version works with turf ~5.1.6:

// Returns distance in meters (negative values for points inside) from a point to the edges of a polygon
function distanceToPolygon({ point, polygon }) {
  if (polygon.type === "Feature") { polygon = polygon.geometry }
  let distance;
  if (polygon.type === "MultiPolygon") {
    distance = polygon.coordinates
      .map(coords => distanceToPolygon({ point, polygon: turf.polygon(coords).geometry }))
      .reduce((smallest, current) => (current < smallest ? current : smallest));
  } else {
    if (polygon.coordinates.length > 1) {
      // Has holes
      const [exteriorDistance, ...interiorDistances] = polygon.coordinates.map(coords =>
        distanceToPolygon({ point, polygon: turf.polygon([coords]).geometry })
      );
      if (exteriorDistance < 0) {
        // point is inside the exterior polygon shape
        const smallestInteriorDistance = interiorDistances.reduce(
          (smallest, current) => (current < smallest ? current : smallest)
        );
        if (smallestInteriorDistance < 0) {
          // point is inside one of the holes (therefore not actually inside this shape)
          distance = smallestInteriorDistance * -1;
        } else {
          // find which is closer, the distance to the hole or the distance to the edge of the exterior, and set that as the inner distance.
          distance = smallestInteriorDistance < exteriorDistance * -1
            ? smallestInteriorDistance * -1
            : exteriorDistance;
        }
      } else {
        distance = exteriorDistance;
      }
    } else {
      // The actual distance operation - on a normal, hole-less polygon (converted to meters)
      distance = turf.pointToLineDistance(point, turf.polygonToLineString(polygon)) * 1000;
      if (turf.booleanPointInPolygon(point, polygon)) {
        distance = distance * -1;
      }
    }
  }
  return distance
}
3reactions
kachkaevcommented, May 12, 2021

Thanks for sharing your code @lostpebble and @pachacamac 🙌 I made a typescript version of the function if anyone would want to copy-paste it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Calculating distance between a Point and a MultiPolygon ...
I'm working in a layer with MultiPolygons and I'm trying to calculate the shortest distance between a MultiPolygon and a point which is ......
Read more >
Distance between a point and a MultiPolygon Geoseries ...
The distance is 60 miles nautic for 1 degree, its an approximation because the calculated distance is an euclidian distance of the orthogonal ......
Read more >
geo_distance_point_to_polygon() - Azure Data Explorer
Calculates the shortest distance between a coordinate and a polygon or a multipolygon on Earth. Syntax. geo_distance_point_to_polygon( longitude ...
Read more >
Spatial manipulation with sf: :CHEAT SHEET - OSF
(i.e. point within polygon) st_equals(x, y, . ... distance to y. Geometry creation ... rows), dim = "XYZ") Creating multi polygon.
Read more >
ee.Geometry.Point.distance - Earth Engine - Google Developers
// Apply the distance method to the Point object. var pointDistance = point.distance({'right' ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found