ST_Union(a, b) → Geometry — merge two geometries. For this version, collects into appropriate Multi* type or GeometryCollection. True polygon clipping (Weiler-Atherton) is deferred — this handles the common cases correctly.
(a: &Geometry, b: &Geometry)
| 63 | /// GeometryCollection. True polygon clipping (Weiler-Atherton) is |
| 64 | /// deferred — this handles the common cases correctly. |
| 65 | pub fn st_union(a: &Geometry, b: &Geometry) -> Geometry { |
| 66 | match (a, b) { |
| 67 | // Point + Point → MultiPoint |
| 68 | (Geometry::Point { coordinates: ca }, Geometry::Point { coordinates: cb }) => { |
| 69 | Geometry::MultiPoint { |
| 70 | coordinates: vec![*ca, *cb], |
| 71 | } |
| 72 | } |
| 73 | // LineString + LineString → MultiLineString |
| 74 | (Geometry::LineString { coordinates: la }, Geometry::LineString { coordinates: lb }) => { |
| 75 | Geometry::MultiLineString { |
| 76 | coordinates: vec![la.clone(), lb.clone()], |
| 77 | } |
| 78 | } |
| 79 | // Polygon + Polygon → MultiPolygon |
| 80 | (Geometry::Polygon { coordinates: ra }, Geometry::Polygon { coordinates: rb }) => { |
| 81 | Geometry::MultiPolygon { |
| 82 | coordinates: vec![ra.clone(), rb.clone()], |
| 83 | } |
| 84 | } |
| 85 | // Same-type Multi* + element → extend |
| 86 | (Geometry::MultiPoint { coordinates: pts }, Geometry::Point { coordinates: pt }) => { |
| 87 | let mut coords = pts.clone(); |
| 88 | coords.push(*pt); |
| 89 | Geometry::MultiPoint { |
| 90 | coordinates: coords, |
| 91 | } |
| 92 | } |
| 93 | (Geometry::Point { coordinates: pt }, Geometry::MultiPoint { coordinates: pts }) => { |
| 94 | let mut coords = vec![*pt]; |
| 95 | coords.extend_from_slice(pts); |
| 96 | Geometry::MultiPoint { |
| 97 | coordinates: coords, |
| 98 | } |
| 99 | } |
| 100 | // Everything else → GeometryCollection |
| 101 | _ => Geometry::GeometryCollection { |
| 102 | geometries: vec![a.clone(), b.clone()], |
| 103 | }, |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | // ── Buffer helpers ── |
| 108 |