code wiki / _hdl_build / nx_geo_union.nx

nx_geo_union.nx source

↩ module page · 46 lines · 2251 B

1// nx_geo_union.nx -- LIB: GEO-016 POLYGON UNION + INTERSECTION MEASURE (set algebra on areas). 2// 3// The union of two convex polygons is generally NON-convex, so it is not produced by a single 4// Sutherland-Hodgman clip. Instead we compute the exact set MEASURE by inclusion-exclusion: 5// area(A u B) = area(A) + area(B) - area(A n B) 6// composing GEO-010 (geo_area2, integer-exact shoelace) and GEO-015 (geo_poly_clip, Sutherland-Hodgman 7// intersection). HONEST SCOPE: this returns the union/intersection COVERAGE MEASURE (doubled area in 8// microdeg^2), not the union BOUNDARY polygon -- which is exactly what geofence coverage / overlap 9// scoring needs ("how much of region A is also covered by region B?"). 10// 11// EXCEED ANGLE: every term is integer arithmetic over microdegree coords -> deterministic, no float 12// drift in the inclusion-exclusion (where chained float set-ops accumulate error). geo_iou_permil adds 13// a sovereign Jaccard overlap score (intersection/union, per-mille) for geofence dedup/matching. 14// Convention: polygons = flat [lat0,lon0,...]; the SECOND polygon (b) is the clip and must be CONVEX+CCW. 15// license_tier: ORIGINAL 16import "nx_geo_clip.nx" 17import "nx_geo_area.nx" 18import "nx_syscalls.nx" 19 20// doubled area of A n B (microdeg^2); 0 if they do not overlap. 21func geo_inter_area2(a: *i64, na: i64, b: *i64, nb: i64) -> i64 { 22 let cap: i64 = na + nb + 8 23 let inter: *i64 = sys_mmap(8 * cap * 2) as *i64 24 let ni: i64 = geo_poly_clip(a, na, b, nb, inter) 25 if ni < 3 { return 0 } 26 return geo_area2(inter, ni) 27} 28 29// doubled area of A u B (microdeg^2) via inclusion-exclusion. 30func geo_union_area2(a: *i64, na: i64, b: *i64, nb: i64) -> i64 { 31 let aa: i64 = geo_area2(a, na) 32 let bb: i64 = geo_area2(b, nb) 33 let ai: i64 = geo_inter_area2(a, na, b, nb) 34 return aa + bb - ai 35} 36 37// Jaccard overlap (intersection / union) in per-mille [0,1000]; 0 if union is empty. The sovereign 38// geofence-similarity / dedup score. 39func geo_iou_permil(a: *i64, na: i64, b: *i64, nb: i64) -> i64 { 40 let inter: i64 = geo_inter_area2(a, na, b, nb) 41 let aa: i64 = geo_area2(a, na) 42 let bb: i64 = geo_area2(b, nb) 43 let uni: i64 = aa + bb - inter 44 if uni <= 0 { return 0 } 45 return inter * 1000 / uni 46}