ST_Distance(a, b) — minimum distance in meters between two geometries. Point-to-point: haversine (exact great-circle). All others: find minimum coordinate-space distance, convert to meters.
(a: &Geometry, b: &Geometry)
| 20 | /// Point-to-point: haversine (exact great-circle). |
| 21 | /// All others: find minimum coordinate-space distance, convert to meters. |
| 22 | pub fn st_distance(a: &Geometry, b: &Geometry) -> f64 { |
| 23 | match (a, b) { |
| 24 | // Point–Point: haversine (exact). |
| 25 | (Geometry::Point { coordinates: ca }, Geometry::Point { coordinates: cb }) => { |
| 26 | haversine_distance(ca[0], ca[1], cb[0], cb[1]) |
| 27 | } |
| 28 | |
| 29 | // Point–LineString or reverse. |
| 30 | (Geometry::Point { coordinates: pt }, Geometry::LineString { coordinates: line }) |
| 31 | | (Geometry::LineString { coordinates: line }, Geometry::Point { coordinates: pt }) => { |
| 32 | point_to_linestring_distance(*pt, line) |
| 33 | } |
| 34 | |
| 35 | // Point–Polygon or reverse. |
| 36 | (Geometry::Point { coordinates: pt }, Geometry::Polygon { coordinates: rings }) |
| 37 | | (Geometry::Polygon { coordinates: rings }, Geometry::Point { coordinates: pt }) => { |
| 38 | point_to_polygon_distance(*pt, rings) |
| 39 | } |
| 40 | |
| 41 | // LineString–LineString. |
| 42 | (Geometry::LineString { coordinates: la }, Geometry::LineString { coordinates: lb }) => { |
| 43 | linestring_to_linestring_distance(la, lb) |
| 44 | } |
| 45 | |
| 46 | // LineString–Polygon or reverse. |
| 47 | (Geometry::LineString { coordinates: line }, Geometry::Polygon { coordinates: rings }) |
| 48 | | (Geometry::Polygon { coordinates: rings }, Geometry::LineString { coordinates: line }) => { |
| 49 | linestring_to_polygon_distance(line, rings) |
| 50 | } |
| 51 | |
| 52 | // Polygon–Polygon. |
| 53 | (Geometry::Polygon { coordinates: ra }, Geometry::Polygon { coordinates: rb }) => { |
| 54 | polygon_to_polygon_distance(ra, rb) |
| 55 | } |
| 56 | |
| 57 | // Multi* types: minimum distance among all component pairs. |
| 58 | (Geometry::MultiPoint { coordinates }, other) |
| 59 | | (other, Geometry::MultiPoint { coordinates }) => coordinates |
| 60 | .iter() |
| 61 | .map(|pt| st_distance(&Geometry::Point { coordinates: *pt }, other)) |
| 62 | .fold(f64::INFINITY, f64::min), |
| 63 | |
| 64 | (Geometry::MultiLineString { coordinates }, other) |
| 65 | | (other, Geometry::MultiLineString { coordinates }) => coordinates |
| 66 | .iter() |
| 67 | .map(|ls| { |
| 68 | st_distance( |
| 69 | &Geometry::LineString { |
| 70 | coordinates: ls.clone(), |
| 71 | }, |
| 72 | other, |
| 73 | ) |
| 74 | }) |
| 75 | .fold(f64::INFINITY, f64::min), |
| 76 | |
| 77 | (Geometry::MultiPolygon { coordinates }, other) |
| 78 | | (other, Geometry::MultiPolygon { coordinates }) => coordinates |
| 79 | .iter() |