fix more bugs caused by updates, especially using unwrap_geom
This commit is contained in:
parent
1837c49ab8
commit
9618d7304f
9 changed files with 59 additions and 38 deletions
|
@ -22,6 +22,7 @@ from c3nav.editor.views.base import etag_func
|
||||||
from c3nav.mapdata.api import api_etag
|
from c3nav.mapdata.api import api_etag
|
||||||
from c3nav.mapdata.models import Area, MapUpdate, Source
|
from c3nav.mapdata.models import Area, MapUpdate, Source
|
||||||
from c3nav.mapdata.models.geometry.space import POI
|
from c3nav.mapdata.models.geometry.space import POI
|
||||||
|
from c3nav.mapdata.utils.geometry import unwrap_geom
|
||||||
from c3nav.mapdata.utils.user import can_access_editor
|
from c3nav.mapdata.utils.user import can_access_editor
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ class EditorViewSet(EditorViewSetMixin, ViewSet):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_level_geometries(level):
|
def _get_level_geometries(level):
|
||||||
buildings = level.buildings.all()
|
buildings = level.buildings.all()
|
||||||
buildings_geom = unary_union([building.geometry.wrapped_geom for building in buildings])
|
buildings_geom = unary_union([unwrap_geom(building.geometry) for building in buildings])
|
||||||
spaces = {space.pk: space for space in level.spaces.all()}
|
spaces = {space.pk: space for space in level.spaces.all()}
|
||||||
holes_geom = []
|
holes_geom = []
|
||||||
for space in spaces.values():
|
for space in spaces.values():
|
||||||
|
@ -77,9 +78,9 @@ class EditorViewSet(EditorViewSetMixin, ViewSet):
|
||||||
space.geometry = space.geometry.difference(buildings_geom)
|
space.geometry = space.geometry.difference(buildings_geom)
|
||||||
columns = [column.geometry for column in space.columns.all()]
|
columns = [column.geometry for column in space.columns.all()]
|
||||||
if columns:
|
if columns:
|
||||||
columns_geom = unary_union([column.geometry.wrapped_geom for column in space.columns.all()])
|
columns_geom = unary_union([unwrap_geom(column.geometry) for column in space.columns.all()])
|
||||||
space.geometry = space.geometry.difference(columns_geom)
|
space.geometry = space.geometry.difference(columns_geom)
|
||||||
holes = [hole.geometry.wrapped_geom for hole in space.holes.all()]
|
holes = [unwrap_geom(hole.geometry) for hole in space.holes.all()]
|
||||||
if holes:
|
if holes:
|
||||||
space_holes_geom = unary_union(holes)
|
space_holes_geom = unary_union(holes)
|
||||||
holes_geom.append(space_holes_geom.intersection(space.geometry))
|
holes_geom.append(space_holes_geom.intersection(space.geometry))
|
||||||
|
@ -221,7 +222,10 @@ class EditorViewSet(EditorViewSetMixin, ViewSet):
|
||||||
if request.user_permissions.can_access_base_mapdata:
|
if request.user_permissions.can_access_base_mapdata:
|
||||||
doors = [door for door in level.doors.filter(Door.q_for_request(request)).all()
|
doors = [door for door in level.doors.filter(Door.q_for_request(request)).all()
|
||||||
if door.geometry.intersects(space.geometry)]
|
if door.geometry.intersects(space.geometry)]
|
||||||
doors_space_geom = unary_union([door.geometry for door in doors]+[space.geometry])
|
doors_space_geom = unary_union(
|
||||||
|
[unwrap_geom(door.geometry) for door in doors] +
|
||||||
|
[unwrap_geom(space.geometry)]
|
||||||
|
)
|
||||||
|
|
||||||
levels, levels_on_top, levels_under = self._get_levels_pk(request, level.primary_level)
|
levels, levels_on_top, levels_under = self._get_levels_pk(request, level.primary_level)
|
||||||
if level.on_top_of_id is not None:
|
if level.on_top_of_id is not None:
|
||||||
|
|
|
@ -41,7 +41,7 @@ class EditorFormBase(I18nModelFormMixin, ModelForm):
|
||||||
# hide geometry widget
|
# hide geometry widget
|
||||||
self.fields['geometry'].widget = HiddenInput()
|
self.fields['geometry'].widget = HiddenInput()
|
||||||
if not creating:
|
if not creating:
|
||||||
self.initial['geometry'] = json.dumps(mapping(self.instance.geometry), separators=(',', ':'))
|
self.initial['geometry'] = mapping(self.instance.geometry)
|
||||||
|
|
||||||
if self._meta.model.__name__ == 'Source' and self.request.user.is_superuser:
|
if self._meta.model.__name__ == 'Source' and self.request.user.is_superuser:
|
||||||
Source = self.request.changeset.wrap_model('Source')
|
Source = self.request.changeset.wrap_model('Source')
|
||||||
|
|
|
@ -55,6 +55,9 @@ class GeometryField(models.JSONField):
|
||||||
def to_python(self, value):
|
def to_python(self, value):
|
||||||
if value is None or value == '':
|
if value is None or value == '':
|
||||||
return None
|
return None
|
||||||
|
if isinstance(value, str):
|
||||||
|
# todo: this is all too complex, why do we need this?
|
||||||
|
value = json.loads(value)
|
||||||
try:
|
try:
|
||||||
geometry = shape(value)
|
geometry = shape(value)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
|
@ -9,7 +9,7 @@ from shapely.geometry.base import BaseGeometry
|
||||||
from shapely.ops import unary_union
|
from shapely.ops import unary_union
|
||||||
|
|
||||||
from c3nav.mapdata.models.base import SerializableMixin
|
from c3nav.mapdata.models.base import SerializableMixin
|
||||||
from c3nav.mapdata.utils.geometry import assert_multipolygon, good_representative_point, smart_mapping
|
from c3nav.mapdata.utils.geometry import assert_multipolygon, good_representative_point, smart_mapping, unwrap_geom
|
||||||
from c3nav.mapdata.utils.json import format_geojson
|
from c3nav.mapdata.utils.json import format_geojson
|
||||||
|
|
||||||
geometry_affecting_fields = ('height', 'width', 'access_restriction')
|
geometry_affecting_fields = ('height', 'width', 'access_restriction')
|
||||||
|
@ -119,11 +119,11 @@ class GeometryMixin(SerializableMixin):
|
||||||
return True
|
return True
|
||||||
if self.geometry is self.orig_geometry:
|
if self.geometry is self.orig_geometry:
|
||||||
return False
|
return False
|
||||||
if not self.geometry.equals_exact(self.orig_geometry, 0.05):
|
if not self.geometry.equals_exact(unwrap_geom(self.orig_geometry), 0.05):
|
||||||
return True
|
return True
|
||||||
field = self._meta.get_field('geometry')
|
field = self._meta.get_field('geometry')
|
||||||
rounded = field.to_python(field.get_prep_value(self.geometry))
|
rounded = field.to_python(field.get_prep_value(self.geometry))
|
||||||
if not rounded.equals_exact(self.orig_geometry, 0.005):
|
if not rounded.equals_exact(unwrap_geom(self.orig_geometry), 0.005):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ class GeometryMixin(SerializableMixin):
|
||||||
new_geometry = field.get_final_value(self.geometry)
|
new_geometry = field.get_final_value(self.geometry)
|
||||||
if self.orig_geometry is None:
|
if self.orig_geometry is None:
|
||||||
return new_geometry
|
return new_geometry
|
||||||
difference = new_geometry.symmetric_difference(self.orig_geometry)
|
difference = new_geometry.symmetric_difference(unwrap_geom(self.orig_geometry))
|
||||||
if self._meta.get_field('geometry').geomtype in ('polygon', 'multipolygon'):
|
if self._meta.get_field('geometry').geomtype in ('polygon', 'multipolygon'):
|
||||||
difference = unary_union(assert_multipolygon(difference))
|
difference = unary_union(assert_multipolygon(difference))
|
||||||
return difference
|
return difference
|
||||||
|
|
|
@ -26,7 +26,7 @@ from c3nav.mapdata.models.geometry.base import GeometryMixin
|
||||||
from c3nav.mapdata.models.locations import SpecificLocation
|
from c3nav.mapdata.models.locations import SpecificLocation
|
||||||
from c3nav.mapdata.utils.cache.changes import changed_geometries
|
from c3nav.mapdata.utils.cache.changes import changed_geometries
|
||||||
from c3nav.mapdata.utils.geometry import (assert_multilinestring, assert_multipolygon, clean_cut_polygon,
|
from c3nav.mapdata.utils.geometry import (assert_multilinestring, assert_multipolygon, clean_cut_polygon,
|
||||||
cut_polygon_with_line)
|
cut_polygon_with_line, unwrap_geom)
|
||||||
|
|
||||||
|
|
||||||
class LevelGeometryMixin(GeometryMixin):
|
class LevelGeometryMixin(GeometryMixin):
|
||||||
|
@ -222,7 +222,7 @@ class AltitudeArea(LevelGeometryMixin, models.Model):
|
||||||
stairs = []
|
stairs = []
|
||||||
|
|
||||||
# collect all accessible areas on this level
|
# collect all accessible areas on this level
|
||||||
buildings_geom = unary_union(tuple(building.geometry.wrapped_geom for building in level.buildings.all()))
|
buildings_geom = unary_union(tuple(unwrap_geom(building.geometry) for building in level.buildings.all()))
|
||||||
for space in level.spaces.all():
|
for space in level.spaces.all():
|
||||||
spaces[space.pk] = space
|
spaces[space.pk] = space
|
||||||
space.orig_geometry = space.geometry
|
space.orig_geometry = space.geometry
|
||||||
|
@ -271,9 +271,9 @@ class AltitudeArea(LevelGeometryMixin, models.Model):
|
||||||
space_areas.update({space.pk: [] for space in level.spaces.all()})
|
space_areas.update({space.pk: [] for space in level.spaces.all()})
|
||||||
for area in areas:
|
for area in areas:
|
||||||
area.spaces = set()
|
area.spaces = set()
|
||||||
area.geometry_prep = prepared.prep(area.geometry)
|
area.geometry_prep = prepared.prep(unwrap_geom(area.geometry))
|
||||||
for space in level.spaces.all():
|
for space in level.spaces.all():
|
||||||
if area.geometry_prep.intersects(space.geometry):
|
if area.geometry_prep.intersects(unwrap_geom(space.geometry)):
|
||||||
area.spaces.add(space.pk)
|
area.spaces.add(space.pk)
|
||||||
space_areas[space.pk].append(area)
|
space_areas[space.pk].append(area)
|
||||||
|
|
||||||
|
@ -470,9 +470,11 @@ class AltitudeArea(LevelGeometryMixin, models.Model):
|
||||||
for space in level.spaces.all():
|
for space in level.spaces.all():
|
||||||
space.geometry = space.orig_geometry
|
space.geometry = space.orig_geometry
|
||||||
|
|
||||||
buildings_geom = unary_union(tuple(b.geometry.wrapped_geom for b in level.buildings.all()))
|
buildings_geom = unary_union(tuple(unwrap_geom(b.geometry) for b in level.buildings.all()))
|
||||||
doors_geom = unary_union(tuple(d.geometry for d in level.doors.all()))
|
doors_geom = unary_union(tuple(d.geometry for d in level.doors.all()))
|
||||||
space_geom = unary_union(tuple((s.geometry if not s.outside else s.geometry.difference(buildings_geom))
|
space_geom = unary_union(tuple((unwrap_geom(s.geometry)
|
||||||
|
if not s.outside
|
||||||
|
else s.geometry.difference(buildings_geom))
|
||||||
for s in level.spaces.all()))
|
for s in level.spaces.all()))
|
||||||
|
|
||||||
# accessible area on this level is doors + spaces - holes
|
# accessible area on this level is doors + spaces - holes
|
||||||
|
@ -494,7 +496,7 @@ class AltitudeArea(LevelGeometryMixin, models.Model):
|
||||||
space_geom = space.geometry
|
space_geom = space.geometry
|
||||||
if space.outside:
|
if space.outside:
|
||||||
space_geom = space_geom.difference(buildings_geom)
|
space_geom = space_geom.difference(buildings_geom)
|
||||||
space_geom_prep = prepared.prep(space_geom)
|
space_geom_prep = prepared.prep(unwrap_geom(space_geom))
|
||||||
holes_geom = unary_union(tuple(h.geometry for h in space.holes.all()))
|
holes_geom = unary_union(tuple(h.geometry for h in space.holes.all()))
|
||||||
|
|
||||||
# remaining_space means remaining space (=obstacles) that still needs to be added to altitude areas
|
# remaining_space means remaining space (=obstacles) that still needs to be added to altitude areas
|
||||||
|
@ -572,7 +574,7 @@ class AltitudeArea(LevelGeometryMixin, models.Model):
|
||||||
all_candidates = AltitudeArea.objects.select_related('level')
|
all_candidates = AltitudeArea.objects.select_related('level')
|
||||||
for candidate in all_candidates:
|
for candidate in all_candidates:
|
||||||
candidate.area = candidate.geometry.area
|
candidate.area = candidate.geometry.area
|
||||||
candidate.geometry_prep = prepared.prep(candidate.geometry)
|
candidate.geometry_prep = prepared.prep(unwrap_geom(candidate.geometry))
|
||||||
all_candidates = sorted(all_candidates, key=attrgetter('area'), reverse=True)
|
all_candidates = sorted(all_candidates, key=attrgetter('area'), reverse=True)
|
||||||
|
|
||||||
num_modified = 0
|
num_modified = 0
|
||||||
|
@ -606,7 +608,7 @@ class AltitudeArea(LevelGeometryMixin, models.Model):
|
||||||
num_deleted += 1
|
num_deleted += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not field.get_final_value(new_area.geometry).equals_exact(candidate.geometry, 0.00001):
|
if not field.get_final_value(new_area.geometry).equals_exact(unwrap_geom(candidate.geometry), 0.00001):
|
||||||
num_modified += 1
|
num_modified += 1
|
||||||
|
|
||||||
candidate.geometry = new_area.geometry
|
candidate.geometry = new_area.geometry
|
||||||
|
|
|
@ -13,7 +13,7 @@ from c3nav.mapdata.render.geometry.altitudearea import AltitudeAreaGeometries
|
||||||
from c3nav.mapdata.render.geometry.hybrid import HybridGeometry
|
from c3nav.mapdata.render.geometry.hybrid import HybridGeometry
|
||||||
from c3nav.mapdata.render.geometry.mesh import Mesh
|
from c3nav.mapdata.render.geometry.mesh import Mesh
|
||||||
from c3nav.mapdata.utils.cache import AccessRestrictionAffected
|
from c3nav.mapdata.utils.cache import AccessRestrictionAffected
|
||||||
from c3nav.mapdata.utils.geometry import get_rings
|
from c3nav.mapdata.utils.geometry import get_rings, unwrap_geom
|
||||||
from c3nav.mapdata.utils.mesh import triangulate_rings
|
from c3nav.mapdata.utils.mesh import triangulate_rings
|
||||||
|
|
||||||
empty_geometry_collection = GeometryCollection()
|
empty_geometry_collection = GeometryCollection()
|
||||||
|
@ -65,7 +65,7 @@ class LevelGeometries:
|
||||||
@classmethod
|
@classmethod
|
||||||
def build_for_level(cls, level, altitudeareas_above):
|
def build_for_level(cls, level, altitudeareas_above):
|
||||||
geoms = LevelGeometries()
|
geoms = LevelGeometries()
|
||||||
buildings_geom = unary_union([b.geometry.wrapped_geom for b in level.buildings.all()])
|
buildings_geom = unary_union([unwrap_geom(b.geometry) for b in level.buildings.all()])
|
||||||
geoms.buildings = buildings_geom
|
geoms.buildings = buildings_geom
|
||||||
buildings_geom_prep = prepared.prep(buildings_geom)
|
buildings_geom_prep = prepared.prep(buildings_geom)
|
||||||
|
|
||||||
|
@ -89,10 +89,10 @@ class LevelGeometries:
|
||||||
space.holes_geom = empty_geometry_collection
|
space.holes_geom = empty_geometry_collection
|
||||||
space.walkable_geom = space.geometry
|
space.walkable_geom = space.geometry
|
||||||
|
|
||||||
spaces_geom = unary_union([s.geometry for s in level.spaces.all()])
|
spaces_geom = unary_union([unwrap_geom(s.geometry) for s in level.spaces.all()])
|
||||||
doors_geom = unary_union([d.geometry for d in level.doors.all()])
|
doors_geom = unary_union([unwrap_geom(d.geometry) for d in level.doors.all()])
|
||||||
doors_geom = doors_geom.intersection(buildings_geom)
|
doors_geom = doors_geom.intersection(buildings_geom)
|
||||||
walkable_spaces_geom = unary_union([s.walkable_geom for s in level.spaces.all()])
|
walkable_spaces_geom = unary_union([unwrap_geom(s.walkable_geom) for s in level.spaces.all()])
|
||||||
geoms.doors = doors_geom.difference(walkable_spaces_geom)
|
geoms.doors = doors_geom.difference(walkable_spaces_geom)
|
||||||
if level.on_top_of_id is None:
|
if level.on_top_of_id is None:
|
||||||
geoms.holes = unary_union([s.holes_geom for s in level.spaces.all()])
|
geoms.holes = unary_union([s.holes_geom for s in level.spaces.all()])
|
||||||
|
@ -127,7 +127,9 @@ class LevelGeometries:
|
||||||
buffered.difference(buildings_geom)
|
buffered.difference(buildings_geom)
|
||||||
)
|
)
|
||||||
|
|
||||||
colors.setdefault(space.get_color_sorted(), {}).setdefault(access_restriction, []).append(space.geometry)
|
colors.setdefault(space.get_color_sorted(), {}).setdefault(access_restriction, []).append(
|
||||||
|
unwrap_geom(space.geometry)
|
||||||
|
)
|
||||||
|
|
||||||
for area in space.areas.all():
|
for area in space.areas.all():
|
||||||
access_restriction = area.access_restriction_id or space.access_restriction_id
|
access_restriction = area.access_restriction_id or space.access_restriction_id
|
||||||
|
@ -166,7 +168,9 @@ class LevelGeometries:
|
||||||
|
|
||||||
geoms.ramps.extend(ramp.geometry for ramp in space.ramps.all())
|
geoms.ramps.extend(ramp.geometry for ramp in space.ramps.all())
|
||||||
|
|
||||||
heightareas.setdefault(int((space.height or level.default_height)*1000), []).append(space.geometry)
|
heightareas.setdefault(int((space.height or level.default_height)*1000), []).append(
|
||||||
|
unwrap_geom(space.geometry)
|
||||||
|
)
|
||||||
colors.pop(None, None)
|
colors.pop(None, None)
|
||||||
|
|
||||||
# merge ground colors
|
# merge ground colors
|
||||||
|
@ -178,8 +182,8 @@ class LevelGeometries:
|
||||||
|
|
||||||
# add altitudegroup geometries and split ground colors into them
|
# add altitudegroup geometries and split ground colors into them
|
||||||
for altitudearea in level.altitudeareas.all():
|
for altitudearea in level.altitudeareas.all():
|
||||||
altitudearea_prep = prepared.prep(altitudearea.geometry)
|
altitudearea_prep = prepared.prep(unwrap_geom(altitudearea.geometry))
|
||||||
altitudearea_colors = {color: {access_restriction: area.intersection(altitudearea.geometry)
|
altitudearea_colors = {color: {access_restriction: area.intersection(unwrap_geom(altitudearea.geometry))
|
||||||
for access_restriction, area in areas.items()
|
for access_restriction, area in areas.items()
|
||||||
if altitudearea_prep.intersects(area)}
|
if altitudearea_prep.intersects(area)}
|
||||||
for color, areas in colors.items()}
|
for color, areas in colors.items()}
|
||||||
|
|
|
@ -16,7 +16,7 @@ from c3nav.mapdata.models import Level, MapUpdate, Source
|
||||||
from c3nav.mapdata.render.geometry import AltitudeAreaGeometries, LevelGeometries
|
from c3nav.mapdata.render.geometry import AltitudeAreaGeometries, LevelGeometries
|
||||||
from c3nav.mapdata.utils.cache import AccessRestrictionAffected, MapHistory
|
from c3nav.mapdata.utils.cache import AccessRestrictionAffected, MapHistory
|
||||||
from c3nav.mapdata.utils.cache.package import CachePackage
|
from c3nav.mapdata.utils.cache.package import CachePackage
|
||||||
from c3nav.mapdata.utils.geometry import get_rings
|
from c3nav.mapdata.utils.geometry import get_rings, unwrap_geom
|
||||||
|
|
||||||
empty_geometry_collection = GeometryCollection()
|
empty_geometry_collection = GeometryCollection()
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ empty_geometry_collection = GeometryCollection()
|
||||||
class Cropper:
|
class Cropper:
|
||||||
def __init__(self, geometry=None):
|
def __init__(self, geometry=None):
|
||||||
self.geometry = geometry
|
self.geometry = geometry
|
||||||
self.geometry_prep = None if geometry is None else prepared.prep(geometry)
|
self.geometry_prep = None if geometry is None else prepared.prep(unwrap_geom(geometry))
|
||||||
|
|
||||||
def intersection(self, other):
|
def intersection(self, other):
|
||||||
if self.geometry is None:
|
if self.geometry is None:
|
||||||
|
@ -179,7 +179,7 @@ class LevelRenderData:
|
||||||
) if not geom.is_empty)
|
) if not geom.is_empty)
|
||||||
|
|
||||||
for altitudearea in old_geoms.altitudeareas:
|
for altitudearea in old_geoms.altitudeareas:
|
||||||
new_geometry = crop_to.intersection(altitudearea.geometry)
|
new_geometry = crop_to.intersection(unwrap_geom(altitudearea.geometry))
|
||||||
if new_geometry.is_empty:
|
if new_geometry.is_empty:
|
||||||
continue
|
continue
|
||||||
new_geometry_prep = prepared.prep(new_geometry)
|
new_geometry_prep = prepared.prep(new_geometry)
|
||||||
|
|
|
@ -40,10 +40,18 @@ class WrappedGeometry():
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def wrapped_geom(self):
|
def wrapped_geom(self):
|
||||||
if not self.wrapped_geojson['coordinates']:
|
if not self.wrapped_geojson or not self.wrapped_geojson['coordinates']:
|
||||||
return GeometryCollection()
|
return GeometryCollection()
|
||||||
return shapely_shape(self.wrapped_geojson)
|
return shapely_shape(self.wrapped_geojson)
|
||||||
|
|
||||||
|
def __getstate__(self):
|
||||||
|
self.picklable = True
|
||||||
|
# make sure geometry is cached
|
||||||
|
if self.wrapped_geojson:
|
||||||
|
# noinspection PyStatementEffect
|
||||||
|
self.wrapped_geom
|
||||||
|
super().__getstate__()
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
if name in ('__getstate__'):
|
if name in ('__getstate__'):
|
||||||
self.picklable = True
|
self.picklable = True
|
||||||
|
@ -64,8 +72,8 @@ class WrappedGeometry():
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def unwrap_geometry(geometry):
|
def unwrap_geom(geometry):
|
||||||
return getattr(geometry, 'geom', geometry)
|
return geometry.wrapped_geom if isinstance(geometry, WrappedGeometry) else geometry
|
||||||
|
|
||||||
|
|
||||||
def smart_mapping(geometry):
|
def smart_mapping(geometry):
|
||||||
|
|
|
@ -20,7 +20,7 @@ from shapely.ops import unary_union
|
||||||
from c3nav.mapdata.models import AltitudeArea, Area, GraphEdge, Level, LocationGroup, MapUpdate, Space, WayType
|
from c3nav.mapdata.models import AltitudeArea, Area, GraphEdge, Level, LocationGroup, MapUpdate, Space, WayType
|
||||||
from c3nav.mapdata.models.geometry.space import POI, CrossDescription, LeaveDescription
|
from c3nav.mapdata.models.geometry.space import POI, CrossDescription, LeaveDescription
|
||||||
from c3nav.mapdata.models.locations import CustomLocationProxyMixin
|
from c3nav.mapdata.models.locations import CustomLocationProxyMixin
|
||||||
from c3nav.mapdata.utils.geometry import assert_multipolygon, get_rings, good_representative_point
|
from c3nav.mapdata.utils.geometry import assert_multipolygon, get_rings, good_representative_point, unwrap_geom
|
||||||
from c3nav.mapdata.utils.locations import CustomLocation
|
from c3nav.mapdata.utils.locations import CustomLocation
|
||||||
from c3nav.routing.exceptions import LocationUnreachable, NoRouteFound, NotYetRoutable
|
from c3nav.routing.exceptions import LocationUnreachable, NoRouteFound, NotYetRoutable
|
||||||
from c3nav.routing.route import Route
|
from c3nav.routing.route import Route
|
||||||
|
@ -63,7 +63,7 @@ class Router:
|
||||||
restrictions = {}
|
restrictions = {}
|
||||||
nodes = deque()
|
nodes = deque()
|
||||||
for level in levels_query:
|
for level in levels_query:
|
||||||
buildings_geom = unary_union(tuple(building.geometry.wrapped_geom for building in level.buildings.all()))
|
buildings_geom = unary_union(tuple(unwrap_geom(building.geometry) for building in level.buildings.all()))
|
||||||
|
|
||||||
nodes_before_count = len(nodes)
|
nodes_before_count = len(nodes)
|
||||||
|
|
||||||
|
@ -122,9 +122,9 @@ class Router:
|
||||||
space.areas.add(area.pk)
|
space.areas.add(area.pk)
|
||||||
|
|
||||||
for area in level.altitudeareas.all():
|
for area in level.altitudeareas.all():
|
||||||
if not space.geometry_prep.intersects(area.geometry):
|
if not space.geometry_prep.intersects(unwrap_geom(area.geometry)):
|
||||||
continue
|
continue
|
||||||
for subgeom in assert_multipolygon(accessible_geom.intersection(area.geometry)):
|
for subgeom in assert_multipolygon(accessible_geom.intersection(unwrap_geom(area.geometry))):
|
||||||
if subgeom.is_empty:
|
if subgeom.is_empty:
|
||||||
continue
|
continue
|
||||||
area_clear_geom = unary_union(tuple(get_rings(subgeom.difference(obstacles_geom))))
|
area_clear_geom = unary_union(tuple(get_rings(subgeom.difference(obstacles_geom))))
|
||||||
|
@ -511,7 +511,7 @@ class BaseRouterProxy:
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def geometry_prep(self):
|
def geometry_prep(self):
|
||||||
return prepared.prep(self.src.geometry)
|
return prepared.prep(unwrap_geom(self.src.geometry))
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
result = self.__dict__.copy()
|
result = self.__dict__.copy()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue