importnoc: support to place things on staircases
This commit is contained in:
parent
d4154a61b6
commit
237063a840
1 changed files with 31 additions and 4 deletions
|
@ -6,12 +6,12 @@ from django.core.management.base import BaseCommand
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from shapely import distance
|
from shapely import distance
|
||||||
|
|
||||||
from c3nav.mapdata.models import MapUpdate, Space
|
from c3nav.mapdata.models import MapUpdate, Space, Level
|
||||||
from c3nav.mapdata.models.geometry.space import RangingBeacon
|
from c3nav.mapdata.models.geometry.space import RangingBeacon
|
||||||
from c3nav.mapdata.models.report import Report
|
from c3nav.mapdata.models.report import Report
|
||||||
from c3nav.mapdata.utils.cache.changes import changed_geometries
|
from c3nav.mapdata.utils.cache.changes import changed_geometries
|
||||||
from c3nav.mapdata.utils.geometry import unwrap_geom
|
from c3nav.mapdata.utils.geometry import unwrap_geom
|
||||||
from shapely.ops import nearest_points
|
from shapely.ops import nearest_points, unary_union
|
||||||
|
|
||||||
|
|
||||||
class NocImportItem(BaseModel):
|
class NocImportItem(BaseModel):
|
||||||
|
@ -48,9 +48,17 @@ class Command(BaseCommand):
|
||||||
report.save()
|
report.save()
|
||||||
report.notify_reviewers()
|
report.notify_reviewers()
|
||||||
|
|
||||||
|
def _get_space_geom(self, space):
|
||||||
|
return space.geometry.difference(unary_union([unwrap_geom(hole.geometry) for hole in space.holes.all()]))
|
||||||
|
|
||||||
def do_import(self, items: dict[str, NocImportItem]):
|
def do_import(self, items: dict[str, NocImportItem]):
|
||||||
spaces_for_level = {}
|
spaces_for_level = {}
|
||||||
for space in Space.objects.all():
|
levels = tuple(Level.objects.values_list("pk", flat=True))
|
||||||
|
lower_levels_for_level = {pk: levels[:i] for i, pk in enumerate(levels)}
|
||||||
|
|
||||||
|
RangingBeacon.objects.all().delete()
|
||||||
|
|
||||||
|
for space in Space.objects.select_related('level').prefetch_related('holes'):
|
||||||
spaces_for_level.setdefault(space.level_id, []).append(space)
|
spaces_for_level.setdefault(space.level_id, []).append(space)
|
||||||
|
|
||||||
beacons_so_far: dict[str, RangingBeacon] = {
|
beacons_so_far: dict[str, RangingBeacon] = {
|
||||||
|
@ -87,15 +95,34 @@ class Command(BaseCommand):
|
||||||
else:
|
else:
|
||||||
print(f"ERROR: {name} is not within any space (NOC: {(item.lat, item.lng)}, NAV: {new_geometry}")
|
print(f"ERROR: {name} is not within any space (NOC: {(item.lat, item.lng)}, NAV: {new_geometry}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# move point into space if needed
|
||||||
if not space.geometry.intersects(new_geometry):
|
if not space.geometry.intersects(new_geometry):
|
||||||
new_geometry = nearest_points(space.geometry.buffer(-0.05), new_geometry)[0]
|
new_geometry = nearest_points(space.geometry.buffer(-0.05), new_geometry)[0]
|
||||||
if len(possible_spaces) == 1:
|
elif len(possible_spaces) == 1:
|
||||||
new_space = possible_spaces[0]
|
new_space = possible_spaces[0]
|
||||||
print(f"SUCCESS: {name} is in {new_space.title}")
|
print(f"SUCCESS: {name} is in {new_space.title}")
|
||||||
else:
|
else:
|
||||||
print(f"WARNING: {name} could be in multiple spaces, picking one...")
|
print(f"WARNING: {name} could be in multiple spaces, picking one...")
|
||||||
new_space = possible_spaces[0]
|
new_space = possible_spaces[0]
|
||||||
|
|
||||||
|
lower_levels = lower_levels_for_level[new_space.level_id]
|
||||||
|
for lower_level in reversed(lower_levels):
|
||||||
|
# let's go through the lower levels
|
||||||
|
if not unary_union([unwrap_geom(h.geometry) for h in new_space.holes.all()]).intersects(new_geometry):
|
||||||
|
# current selected spacae is fine, that's it
|
||||||
|
break
|
||||||
|
print(f"WARNING: {name} is in a hole, looking lower...")
|
||||||
|
|
||||||
|
# find a lower space
|
||||||
|
possible_spaces = [space for space in spaces_for_level[lower_level]
|
||||||
|
if space.geometry.intersects(new_geometry)]
|
||||||
|
if possible_spaces:
|
||||||
|
new_space = possible_spaces[0]
|
||||||
|
print(f"WARNING: {name} moved to lower space {new_space}")
|
||||||
|
else:
|
||||||
|
print(f"WARNING: {name} couldn't find a lower space, still in a hole")
|
||||||
|
|
||||||
# find existing location
|
# find existing location
|
||||||
result = beacons_so_far.pop(import_tag, None)
|
result = beacons_so_far.pop(import_tag, None)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue