@mytec: iter3.4.0 start
This commit is contained in:
@@ -485,7 +485,16 @@ class CoverageService:
|
||||
)
|
||||
streets = _filter_osm_list_to_bbox(streets, min_lat, min_lon, max_lat, max_lon)
|
||||
water_bodies = _filter_osm_list_to_bbox(water_bodies, min_lat, min_lon, max_lat, max_lon)
|
||||
vegetation_areas = _filter_osm_list_to_bbox(vegetation_areas, min_lat, min_lon, max_lat, max_lon)
|
||||
# Cap vegetation at 5000 — each area requires O(samples × areas)
|
||||
# point-in-polygon checks per grid point. 20k+ areas with dominant
|
||||
# path enabled causes OOM via worker memory explosion.
|
||||
vegetation_areas = _filter_osm_list_to_bbox(
|
||||
vegetation_areas, min_lat, min_lon, max_lat, max_lon,
|
||||
max_count=5000,
|
||||
)
|
||||
|
||||
_clog(f"Filtered OSM data: {len(buildings)} bldgs, {len(streets)} streets, "
|
||||
f"{len(water_bodies)} water, {len(vegetation_areas)} veg")
|
||||
|
||||
# Build spatial index for buildings
|
||||
spatial_idx: Optional[SpatialIndex] = None
|
||||
@@ -650,10 +659,13 @@ class CoverageService:
|
||||
sites: List[SiteParams],
|
||||
settings: CoverageSettings,
|
||||
cancel_token: Optional[CancellationToken] = None,
|
||||
progress_fn: Optional[Callable[[str, float], None]] = None,
|
||||
) -> List[CoveragePoint]:
|
||||
"""
|
||||
Calculate combined coverage from multiple sites
|
||||
Best server (strongest signal) wins at each point
|
||||
|
||||
progress_fn(phase, pct): optional callback for progress updates (0.0-1.0).
|
||||
"""
|
||||
if not sites:
|
||||
return []
|
||||
@@ -661,10 +673,26 @@ class CoverageService:
|
||||
# Apply preset once
|
||||
settings = apply_preset(settings)
|
||||
|
||||
# Per-site progress tracking for averaged overall progress
|
||||
num_sites = len(sites)
|
||||
_site_progress = [0.0] * num_sites
|
||||
|
||||
def _make_site_progress(idx: int):
|
||||
"""Create a progress_fn for one site that reports scaled overall progress."""
|
||||
def _site_fn(phase: str, pct: float, _eta=None):
|
||||
_site_progress[idx] = pct
|
||||
if progress_fn:
|
||||
overall = sum(_site_progress) / num_sites
|
||||
progress_fn(f"Site {idx + 1}/{num_sites}: {phase}", overall)
|
||||
return _site_fn
|
||||
|
||||
# Get all individual coverages
|
||||
all_coverages = await asyncio.gather(*[
|
||||
self.calculate_coverage(site, settings, cancel_token)
|
||||
for site in sites
|
||||
self.calculate_coverage(
|
||||
site, settings, cancel_token,
|
||||
progress_fn=_make_site_progress(i) if progress_fn else None,
|
||||
)
|
||||
for i, site in enumerate(sites)
|
||||
])
|
||||
|
||||
# Combine by best signal
|
||||
@@ -751,7 +779,8 @@ class CoverageService:
|
||||
points = []
|
||||
timing = {"los": 0.0, "buildings": 0.0, "antenna": 0.0,
|
||||
"dominant_path": 0.0, "street_canyon": 0.0,
|
||||
"reflection": 0.0, "vegetation": 0.0}
|
||||
"reflection": 0.0, "vegetation": 0.0,
|
||||
"lod_none": 0, "lod_simplified": 0, "lod_full": 0}
|
||||
total = len(grid)
|
||||
log_interval = max(1, total // 20)
|
||||
|
||||
@@ -901,7 +930,6 @@ class CoverageService:
|
||||
|
||||
# LOD_NONE: skip dominant path entirely for distant points (>3km)
|
||||
if lod == LODLevel.NONE:
|
||||
timing.setdefault("lod_none", 0)
|
||||
timing["lod_none"] += 1
|
||||
else:
|
||||
t0 = time.time()
|
||||
@@ -909,12 +937,10 @@ class CoverageService:
|
||||
# LOD_SIMPLIFIED: limit buildings for mid-range points (1.5-3km)
|
||||
dp_buildings = nearby_buildings
|
||||
if lod == LODLevel.SIMPLIFIED:
|
||||
timing.setdefault("lod_simplified", 0)
|
||||
timing["lod_simplified"] += 1
|
||||
if len(nearby_buildings) > SIMPLIFIED_MAX_BUILDINGS:
|
||||
dp_buildings = nearby_buildings[:SIMPLIFIED_MAX_BUILDINGS]
|
||||
else:
|
||||
timing.setdefault("lod_full", 0)
|
||||
timing["lod_full"] += 1
|
||||
|
||||
# nearby_buildings already filtered via spatial index —
|
||||
|
||||
Reference in New Issue
Block a user