improve locating a bit by using the pointplacementhelper
This commit is contained in:
parent
652223085b
commit
8112abad31
4 changed files with 57 additions and 34 deletions
|
@ -6,7 +6,7 @@ from shapely import distance
|
|||
|
||||
from c3nav.mapdata.models import MapUpdate
|
||||
from c3nav.mapdata.models.geometry.space import RangingBeacon
|
||||
from c3nav.mapdata.utils.importer import PointImportHelper
|
||||
from c3nav.mapdata.utils.placement import PointPlacementHelper
|
||||
from c3nav.mapdata.utils.cache.changes import changed_geometries
|
||||
from c3nav.mapdata.utils.geometry import unwrap_geom
|
||||
|
||||
|
@ -37,7 +37,7 @@ class Command(BaseCommand):
|
|||
MapUpdate.objects.create(type='importnoc')
|
||||
|
||||
def do_import(self, items: dict[str, NocImportItem]):
|
||||
import_helper = PointImportHelper()
|
||||
import_helper = PointPlacementHelper()
|
||||
|
||||
beacons_so_far: dict[str, RangingBeacon] = {
|
||||
**{m.import_tag: m for m in RangingBeacon.objects.filter(import_tag__startswith="noc:",
|
||||
|
|
|
@ -14,7 +14,7 @@ from c3nav.mapdata.models import MapUpdate, Level
|
|||
from c3nav.mapdata.models.geometry.space import RangingBeacon
|
||||
from c3nav.mapdata.utils.cache.changes import changed_geometries
|
||||
from c3nav.mapdata.utils.geometry import unwrap_geom
|
||||
from c3nav.mapdata.utils.importer import PointImportHelper
|
||||
from c3nav.mapdata.utils.placement import PointPlacementHelper
|
||||
|
||||
|
||||
class PocImportItemProperties(BaseModel):
|
||||
|
@ -46,7 +46,7 @@ class Command(BaseCommand):
|
|||
MapUpdate.objects.create(type='importnoc')
|
||||
|
||||
def do_import(self, items: list[PocImportItem]):
|
||||
import_helper = PointImportHelper()
|
||||
import_helper = PointPlacementHelper()
|
||||
|
||||
beacons_so_far: dict[str, RangingBeacon] = {
|
||||
**{m.import_tag: m for m in RangingBeacon.objects.filter(import_tag__startswith="poc:",
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
from typing import Optional
|
||||
|
||||
from shapely import Point, distance
|
||||
from shapely.ops import unary_union, nearest_points
|
||||
|
||||
from c3nav.mapdata.models import Level, Space
|
||||
from c3nav.mapdata.utils.geometry import unwrap_geom
|
||||
from c3nav.routing.router import RouterRestrictionSet
|
||||
|
||||
|
||||
class PointImportHelper:
|
||||
class PointPlacementHelper:
|
||||
def __init__(self):
|
||||
self.spaces_for_level = {}
|
||||
self.levels = tuple(Level.objects.values_list("pk", flat=True))
|
||||
|
@ -14,23 +17,30 @@ class PointImportHelper:
|
|||
for space in Space.objects.select_related('level').prefetch_related('holes'):
|
||||
self.spaces_for_level.setdefault(space.level_id, []).append(space)
|
||||
|
||||
def get_point_and_space(self, level_id: int, point: Point, name: str):
|
||||
def get_point_and_space(self, level_id: int, point: Point, name: Optional[str] = None,
|
||||
restrictions: Optional[RouterRestrictionSet] = None, max_space_distance=1.5):
|
||||
# determine space
|
||||
restricted_spaces = restrictions.spaces if restrictions else ()
|
||||
possible_spaces = [space for space in self.spaces_for_level[level_id]
|
||||
if space.geometry.intersects(point)]
|
||||
if space.pk not in restricted_spaces and space.geometry.intersects(point)]
|
||||
|
||||
if not possible_spaces:
|
||||
possible_spaces = [space for space in self.spaces_for_level[level_id]
|
||||
if distance(unwrap_geom(space.geometry), point) < 1.5]
|
||||
if (space.pk not in restricted_spaces
|
||||
and distance(unwrap_geom(space.geometry), point) < max_space_distance)]
|
||||
if len(possible_spaces) == 1:
|
||||
new_space = possible_spaces[0]
|
||||
the_distance = distance(unwrap_geom(new_space.geometry), point)
|
||||
print(f"SUCCESS: {name} is {the_distance:.02f}m away from {new_space.title}")
|
||||
if name:
|
||||
print(f"SUCCESS: {name} is {the_distance:.02f}m away from {new_space.title}")
|
||||
elif len(possible_spaces) > 1:
|
||||
new_space = min(possible_spaces, key=lambda s: distance(unwrap_geom(s.geometry), point))
|
||||
print(f"WARNING: {name} could be in multiple spaces ({possible_spaces}, picking {new_space}, "
|
||||
f"which is {distance(unwrap_geom(new_space.geometry), point)}m away...")
|
||||
if name:
|
||||
print(f"WARNING: {name} could be in multiple spaces ({possible_spaces}, picking {new_space}, "
|
||||
f"which is {distance(unwrap_geom(new_space.geometry), point)}m away...")
|
||||
else:
|
||||
print(f"ERROR: {name} is not within any space on level {level_id} ({point})")
|
||||
if name:
|
||||
print(f"ERROR: {name} is not within any space on level {level_id} ({point})")
|
||||
return None, None
|
||||
|
||||
# move point into space if needed
|
||||
|
@ -41,9 +51,11 @@ class PointImportHelper:
|
|||
point = nearest_points(new_space_geometry.buffer(-0.05), point)[0]
|
||||
elif len(possible_spaces) == 1:
|
||||
new_space = possible_spaces[0]
|
||||
print(f"SUCCESS: {name} is in {new_space.title}")
|
||||
if name:
|
||||
print(f"SUCCESS: {name} is in {new_space.title}")
|
||||
else:
|
||||
print(f"WARNING: {name} could be in multiple spaces, picking one...")
|
||||
if name:
|
||||
print(f"WARNING: {name} could be in multiple spaces, picking one...")
|
||||
new_space = possible_spaces[0]
|
||||
|
||||
lower_levels = self.lower_levels_for_level[new_space.level_id]
|
||||
|
@ -52,15 +64,18 @@ class PointImportHelper:
|
|||
if not unary_union([unwrap_geom(h.geometry) for h in new_space.holes.all()]).intersects(point):
|
||||
# current selected spacae is fine, that's it
|
||||
break
|
||||
print(f"NOTE: {name} is in a hole, looking lower...")
|
||||
if name:
|
||||
print(f"NOTE: {name} is in a hole, looking lower...")
|
||||
|
||||
# find a lower space
|
||||
possible_spaces = [space for space in self.spaces_for_level[lower_level]
|
||||
if space.geometry.intersects(point)]
|
||||
if space.pk not in restricted_spaces and space.geometry.intersects(point)]
|
||||
if possible_spaces:
|
||||
new_space = possible_spaces[0]
|
||||
print(f"NOTE: {name} moved to lower space {new_space}")
|
||||
if name:
|
||||
print(f"NOTE: {name} moved to lower space {new_space}")
|
||||
else:
|
||||
print(f"WARNING: {name} couldn't find a lower space, still in a hole")
|
||||
if name:
|
||||
print(f"WARNING: {name} couldn't find a lower space, still in a hole")
|
||||
|
||||
return new_space, point
|
Loading…
Add table
Add a link
Reference in a new issue