1- use crate :: block_definitions:: WATER ;
21use crate :: clipping:: clip_water_ring_to_bbox;
2+ use crate :: floodfill_cache:: RoadMaskBitmap ;
3+ use crate :: water_depth:: { carve_water_column, BigWaterField } ;
34use crate :: {
45 coordinate_system:: cartesian:: { XZBBox , XZPoint } ,
56 osm_parser:: { ProcessedMemberRole , ProcessedNode , ProcessedRelation , ProcessedWay } ,
@@ -10,20 +11,24 @@ pub fn generate_water_area_from_way(
1011 editor : & mut WorldEditor ,
1112 element : & ProcessedWay ,
1213 _xzbbox : & XZBBox ,
14+ bwf : & BigWaterField ,
15+ road_mask : & RoadMaskBitmap ,
1316) {
1417 let outers = [ element. nodes . clone ( ) ] ;
1518 if !verify_closed_rings ( & outers) {
1619 println ! ( "Skipping way {} due to invalid polygon" , element. id) ;
1720 return ;
1821 }
1922
20- generate_water_areas ( editor, & outers, & [ ] ) ;
23+ generate_water_areas ( editor, & outers, & [ ] , bwf , road_mask ) ;
2124}
2225
2326pub fn generate_water_areas_from_relation (
2427 editor : & mut WorldEditor ,
2528 element : & ProcessedRelation ,
2629 xzbbox : & XZBBox ,
30+ bwf : & BigWaterField ,
31+ road_mask : & RoadMaskBitmap ,
2732) {
2833 // Check if this is a water relation (either with water tag or natural=water)
2934 let is_water = element. tags . contains_key ( "water" )
@@ -116,13 +121,15 @@ pub fn generate_water_areas_from_relation(
116121 return ;
117122 }
118123
119- generate_water_areas ( editor, & outers, & inners) ;
124+ generate_water_areas ( editor, & outers, & inners, bwf , road_mask ) ;
120125}
121126
122127fn generate_water_areas (
123128 editor : & mut WorldEditor ,
124129 outers : & [ Vec < ProcessedNode > ] ,
125130 inners : & [ Vec < ProcessedNode > ] ,
131+ bwf : & BigWaterField ,
132+ road_mask : & RoadMaskBitmap ,
126133) {
127134 // Calculate polygon bounding box to limit fill area
128135 let mut poly_min_x = i32:: MAX ;
@@ -161,7 +168,9 @@ fn generate_water_areas(
161168 . map ( |x| x. iter ( ) . map ( |y| y. xz ( ) ) . collect :: < Vec < _ > > ( ) )
162169 . collect ( ) ;
163170
164- scanline_fill_water ( min_x, min_z, max_x, max_z, & outers_xz, & inners_xz, editor) ;
171+ scanline_fill_water (
172+ min_x, min_z, max_x, max_z, & outers_xz, & inners_xz, editor, bwf, road_mask,
173+ ) ;
165174}
166175
167176/// Verifies all rings are properly closed (first node matches last).
@@ -391,6 +400,8 @@ fn scanline_fill_water(
391400 outers : & [ Vec < XZPoint > ] ,
392401 inners : & [ Vec < XZPoint > ] ,
393402 editor : & mut WorldEditor ,
403+ bwf : & BigWaterField ,
404+ road_mask : & RoadMaskBitmap ,
394405) {
395406 // Collect edges per outer ring so we can union their spans correctly,
396407 // even if multiple outer rings happen to overlap (invalid OSM, but
@@ -427,14 +438,18 @@ fn scanline_fill_water(
427438
428439 for ( start, end) in fill_spans {
429440 for x in start..=end {
441+ // Keep road/bridge surfaces (carve would overwrite them).
442+ if road_mask. contains ( x, z) {
443+ continue ;
444+ }
430445 let water_y = editor. get_water_level ( x, z) ;
431446 let ground_y = editor. get_ground_level ( x, z) ;
432- // Only place water where terrain is at or below the water
433- // surface — skip hillside blocks where the polygon extends
434- // above the actual waterline.
435- if ground_y <= water_y {
436- editor. set_block_absolute ( WATER , x, water_y, z, None , None ) ;
447+ // Skip hillside blocks the polygon claims above the waterline.
448+ if ground_y > water_y {
449+ continue ;
437450 }
451+ // depth_at gives the carved depth (0 without land-cover water data).
452+ carve_water_column ( editor, x, z, water_y, bwf. depth_at ( x, z) ) ;
438453 }
439454 }
440455 }
0 commit comments