mapbox-gl-js icon indicating copy to clipboard operation
mapbox-gl-js copied to clipboard

Introduce `distance` expression

Open zmiao opened this issue 3 years ago • 5 comments

This pr introduces a new expression distance, which will return the shortest distance in Meters between the feature and the input geometry data.

['distnace', geoJSON]

distance support all geometry types, i.e. Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon.

Basic evaluation rules for finding the distance:

(1) The distance between two points is the straight line between them. (2) The distance between a point and a line segment is the perpendicular or the closest line endpoint to the point. (3) The distance between two line segments is either the perpendicular from one endpoint of a line segment to the other line segment or the distance between the two closest endpoints from each line segment.

Special cases to consider:

  • The distance between 2 geometry sets is always the same regardless of the geometry being evaluated to (input geometry), and the one being evaluated from (feature geometry).

  • The distance between 2 geometry sets is zero, whenever one geometry set contains or is within the other geometry set.

  • This distance between 2 geometry sets is zero when these two geometry sets intersect, overlap, collide with each other.

  • The distance evaluation for polygon geometry is based on the boundary of the polygon, instead of the centroid.

  • The distance would always be positive or zero.

Steps to find the distance between different geometry combination cases:

  1. Point to Point: use rule (1)
  2. Point to LineString: use rule (2) to calculate each distance between the Point to each line segment of the LineString. Choose the smallest distance.
  3. Point to Polygon: Polygon can be taken as the closet ring of a LineString, use case 2 to calculate the distance. In case Point is within or on the boundary of the polygon, the distance is zero.
  4. LineString to LineString: use rule (2) to calculate the distance between each line segment of the LineString to the other one. Choose the smallest distance. In case two line segment are intersecting with each other, the distance is zero.
  5. LineString to Polygon: use case 4 to calculate the distance between the line segments, choose the smallest distance. In case LineString is crossing, intersecting or within Polygon, the distance is zero.
  6. Polygon to Polygon: use case 4 to calculate the distance between the line segments, choose the smallest distance. In case one Polygon is intersecting or within the other Polygon, the distance is zero.
  7. Multi*/ Single* geometry to Multi*/Single* geometry: choose the smallest distance of each single to single geometry set distance.

One example of using an expression with filter would have the following effects :

'filter': ['<', ['distance','userPosition'], 200]
Screen Shot 2020-03-24 at 5 50 39 PM

Follow-up:

  • Current impl has already introduced a big size burden, so I decided to postpone porting distance expression perf improvements from gl-native.

Launch Checklist

  • [x] briefly describe the changes in this PR
  • [x] include before/after visuals or gifs if this PR includes visual changes
  • [x] write tests for all new functionality
  • [x] document any changes to public APIs
  • [ ] post benchmark scores
  • [x] manually test the debug page
  • [x] tagged @mapbox/map-design-team @mapbox/static-apis if this PR includes style spec API or visual changes
  • [x] apply changelog label ('bug', 'feature', 'docs', etc) or use the label 'skip changelog'
  • [x] add an entry inside this element for inclusion in the mapbox-gl-js changelog: <changelog>Introduce 'distance' expression. </changelog>

zmiao avatar Apr 26 '21 10:04 zmiao

i really love and need this feature. Is there any progress on review?

enersis-pst avatar Sep 24 '21 09:09 enersis-pst

@enersis-pst thank you for your feedback and the reason why we are putting this feature on hold is that the current implementation brings a significant bundle size increase, which is something we want to address before merging it. Screen Shot 2021-09-28 at 9 48 43 PM

zmiao avatar Sep 28 '21 18:09 zmiao

@enersis-pst thank you for your feedback and the reason why we are putting this feature on hold is that the current implementation brings a significant bundle size increase, which is something we want to address before merging it. Screen Shot 2021-09-28 at 9 48 43 PM

@zmiao thanks for the info. Then i will wait :-)

enersis-pst avatar Sep 29 '21 07:09 enersis-pst

@enersis-pst thank you for your feedback and the reason why we are putting this feature on hold is that the current implementation brings a significant bundle size increase, which is something we want to address before merging it. Screen Shot 2021-09-28 at 9 48 43 PM

Does anyone have any ideas for how to address this problem?

awulkan avatar Jan 14 '22 09:01 awulkan

Has it been any advance on this request? It's been inactive for a year now.

markusand avatar Sep 05 '22 16:09 markusand