unwrap geometries were necessary to comply with the new shapely api
This commit is contained in:
parent
d27b408acb
commit
1ae1274c2c
6 changed files with 36 additions and 35 deletions
|
@ -229,13 +229,13 @@ class AltitudeArea(LevelGeometryMixin, models.Model):
|
||||||
if space.outside:
|
if space.outside:
|
||||||
space.geometry = space.geometry.difference(buildings_geom)
|
space.geometry = space.geometry.difference(buildings_geom)
|
||||||
space_accessible = space.geometry.difference(
|
space_accessible = space.geometry.difference(
|
||||||
unary_union(tuple(c.geometry for c in space.columns.all() if c.access_restriction_id is None) +
|
unary_union(tuple(unwrap_geom(c.geometry) for c in space.columns.all() if c.access_restriction_id is None) +
|
||||||
tuple(o.geometry for o in space.obstacles.all() if o.altitude == 0) +
|
tuple(unwrap_geom(o.geometry) for o in space.obstacles.all() if o.altitude == 0) +
|
||||||
tuple(o.buffered_geometry for o in space.lineobstacles.all() if o.altitude == 0) +
|
tuple(o.buffered_geometry for o in space.lineobstacles.all() if o.altitude == 0) +
|
||||||
tuple(h.geometry for h in space.holes.all()))
|
tuple(unwrap_geom(h.geometry) for h in space.holes.all()))
|
||||||
)
|
)
|
||||||
|
|
||||||
space_ramps = unary_union(tuple(r.geometry for r in space.ramps.all()))
|
space_ramps = unary_union(tuple(unwrap_geom(r.geometry) for r in space.ramps.all()))
|
||||||
areas.append(space_accessible.difference(space_ramps))
|
areas.append(space_accessible.difference(space_ramps))
|
||||||
for geometry in assert_multipolygon(space_accessible.intersection(space_ramps)):
|
for geometry in assert_multipolygon(space_accessible.intersection(space_ramps)):
|
||||||
ramp = AltitudeArea(geometry=geometry, level=level)
|
ramp = AltitudeArea(geometry=geometry, level=level)
|
||||||
|
@ -244,7 +244,7 @@ class AltitudeArea(LevelGeometryMixin, models.Model):
|
||||||
ramps.append(ramp)
|
ramps.append(ramp)
|
||||||
|
|
||||||
areas = tuple(orient(polygon) for polygon in assert_multipolygon(
|
areas = tuple(orient(polygon) for polygon in assert_multipolygon(
|
||||||
unary_union(areas+list(door.geometry for door in level.doors.all()))
|
unary_union(areas+list(unwrap_geom(door.geometry) for door in level.doors.all()))
|
||||||
))
|
))
|
||||||
|
|
||||||
# collect all stairs on this level
|
# collect all stairs on this level
|
||||||
|
@ -281,7 +281,7 @@ class AltitudeArea(LevelGeometryMixin, models.Model):
|
||||||
for space in level.spaces.all():
|
for space in level.spaces.all():
|
||||||
for altitudemarker in space.altitudemarkers.all():
|
for altitudemarker in space.altitudemarkers.all():
|
||||||
for area in space_areas[space.pk]:
|
for area in space_areas[space.pk]:
|
||||||
if area.geometry_prep.contains(altitudemarker.geometry):
|
if area.geometry_prep.contains(unwrap_geom(altitudemarker.geometry)):
|
||||||
area.altitude = altitudemarker.altitude
|
area.altitude = altitudemarker.altitude
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
@ -471,7 +471,7 @@ class AltitudeArea(LevelGeometryMixin, models.Model):
|
||||||
space.geometry = space.orig_geometry
|
space.geometry = space.orig_geometry
|
||||||
|
|
||||||
buildings_geom = unary_union(tuple(unwrap_geom(b.geometry) 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(unwrap_geom(d.geometry) for d in level.doors.all()))
|
||||||
space_geom = unary_union(tuple((unwrap_geom(s.geometry)
|
space_geom = unary_union(tuple((unwrap_geom(s.geometry)
|
||||||
if not s.outside
|
if not s.outside
|
||||||
else s.geometry.difference(buildings_geom))
|
else s.geometry.difference(buildings_geom))
|
||||||
|
@ -481,7 +481,7 @@ class AltitudeArea(LevelGeometryMixin, models.Model):
|
||||||
accessible_area = unary_union((doors_geom, space_geom))
|
accessible_area = unary_union((doors_geom, space_geom))
|
||||||
for space in level.spaces.all():
|
for space in level.spaces.all():
|
||||||
accessible_area = accessible_area.difference(space.geometry.intersection(
|
accessible_area = accessible_area.difference(space.geometry.intersection(
|
||||||
unary_union(tuple(h.geometry for h in space.holes.all()))
|
unary_union(tuple(unwrap_geom(h.geometry) for h in space.holes.all()))
|
||||||
))
|
))
|
||||||
|
|
||||||
# areas mean altitude areas (including ramps) here
|
# areas mean altitude areas (including ramps) here
|
||||||
|
@ -497,17 +497,17 @@ class AltitudeArea(LevelGeometryMixin, models.Model):
|
||||||
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(unwrap_geom(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(unwrap_geom(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
|
||||||
remaining_space = (
|
remaining_space = (
|
||||||
tuple(o.geometry for o in space.obstacles.all()) +
|
tuple(unwrap_geom(o.geometry) for o in space.obstacles.all()) +
|
||||||
tuple(o.buffered_geometry for o in space.lineobstacles.all())
|
tuple(o.buffered_geometry for o in space.lineobstacles.all())
|
||||||
)
|
)
|
||||||
# make sure to remove everything outside the space the obstacles are in as well as holes
|
# make sure to remove everything outside the space the obstacles are in as well as holes
|
||||||
remaining_space = tuple(g.intersection(space_geom).difference(holes_geom)
|
remaining_space = tuple(g.intersection(unwrap_geom(space_geom)).difference(holes_geom)
|
||||||
for g in remaining_space
|
for g in remaining_space
|
||||||
if space_geom_prep.intersects(g))
|
if space_geom_prep.intersects(unwrap_geom(g)))
|
||||||
# we need this to be a list of simple normal polygons
|
# we need this to be a list of simple normal polygons
|
||||||
remaining_space = tuple(chain(*(
|
remaining_space = tuple(chain(*(
|
||||||
assert_multipolygon(g) for g in remaining_space if not g.is_empty
|
assert_multipolygon(g) for g in remaining_space if not g.is_empty
|
||||||
|
@ -597,9 +597,9 @@ class AltitudeArea(LevelGeometryMixin, models.Model):
|
||||||
potential_areas = [area for area in potential_areas
|
potential_areas = [area for area in potential_areas
|
||||||
if (candidate.altitude, candidate.altitude2) in ((area.altitude, area.altitude2),
|
if (candidate.altitude, candidate.altitude2) in ((area.altitude, area.altitude2),
|
||||||
(area.altitude2, area.altitude))]
|
(area.altitude2, area.altitude))]
|
||||||
potential_areas = [(area, area.geometry.intersection(candidate.geometry).area)
|
potential_areas = [(area, area.geometry.intersection(unwrap_geom(candidate.geometry)).area)
|
||||||
for area in potential_areas
|
for area in potential_areas
|
||||||
if candidate.geometry_prep.intersects(area.geometry)]
|
if candidate.geometry_prep.intersects(unwrap_geom(area.geometry))]
|
||||||
if potential_areas:
|
if potential_areas:
|
||||||
new_area = max(potential_areas, key=itemgetter(1))[0]
|
new_area = max(potential_areas, key=itemgetter(1))[0]
|
||||||
|
|
||||||
|
|
|
@ -78,11 +78,11 @@ class LevelGeometries:
|
||||||
if columns:
|
if columns:
|
||||||
subtract.extend(columns)
|
subtract.extend(columns)
|
||||||
if subtract:
|
if subtract:
|
||||||
space.geometry = space.geometry.difference(unary_union(subtract))
|
space.geometry = space.geometry.difference(unary_union([unwrap_geom(geom) for geom in subtract]))
|
||||||
|
|
||||||
holes = tuple(h.geometry for h in space.holes.all())
|
holes = tuple(h.geometry for h in space.holes.all())
|
||||||
if holes:
|
if holes:
|
||||||
space.holes_geom = unary_union([h.geometry for h in space.holes.all()])
|
space.holes_geom = unary_union([unwrap_geom(h.geometry) for h in space.holes.all()])
|
||||||
space.walkable_geom = space.geometry.difference(space.holes_geom)
|
space.walkable_geom = space.geometry.difference(space.holes_geom)
|
||||||
space.holes_geom = space.geometry.intersection(space.holes_geom)
|
space.holes_geom = space.geometry.intersection(space.holes_geom)
|
||||||
else:
|
else:
|
||||||
|
@ -110,7 +110,7 @@ class LevelGeometries:
|
||||||
heightareas = {}
|
heightareas = {}
|
||||||
for space in level.spaces.all():
|
for space in level.spaces.all():
|
||||||
buffered = space.geometry.buffer(0.01).union(unary_union(
|
buffered = space.geometry.buffer(0.01).union(unary_union(
|
||||||
tuple(door.geometry for door in level.doors.all() if door.geometry.intersects(space.geometry))
|
tuple(unwrap_geom(door.geometry) for door in level.doors.all() if door.geometry.intersects(unwrap_geom(space.geometry)))
|
||||||
).difference(walkable_spaces_geom))
|
).difference(walkable_spaces_geom))
|
||||||
intersects = buildings_geom_prep.intersects(buffered)
|
intersects = buildings_geom_prep.intersects(buffered)
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ class LevelGeometries:
|
||||||
|
|
||||||
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
|
||||||
area.geometry = area.geometry.intersection(space.walkable_geom)
|
area.geometry = area.geometry.intersection(unwrap_geom(space.walkable_geom))
|
||||||
if access_restriction is not None:
|
if access_restriction is not None:
|
||||||
access_restriction_affected.setdefault(access_restriction, []).append(area.geometry)
|
access_restriction_affected.setdefault(access_restriction, []).append(area.geometry)
|
||||||
colors.setdefault(area.get_color_sorted(), {}).setdefault(access_restriction, []).append(area.geometry)
|
colors.setdefault(area.get_color_sorted(), {}).setdefault(access_restriction, []).append(area.geometry)
|
||||||
|
@ -142,7 +142,7 @@ class LevelGeometries:
|
||||||
access_restriction = column.access_restriction_id
|
access_restriction = column.access_restriction_id
|
||||||
if access_restriction is None:
|
if access_restriction is None:
|
||||||
continue
|
continue
|
||||||
column.geometry = column.geometry.intersection(space.walkable_geom)
|
column.geometry = column.geometry.intersection(unwrap_geom(space.walkable_geom))
|
||||||
buffered_column = column.geometry.buffer(0.01)
|
buffered_column = column.geometry.buffer(0.01)
|
||||||
if intersects:
|
if intersects:
|
||||||
restricted_spaces_indoors.setdefault(access_restriction, []).append(buffered_column)
|
restricted_spaces_indoors.setdefault(access_restriction, []).append(buffered_column)
|
||||||
|
@ -156,14 +156,14 @@ class LevelGeometries:
|
||||||
obstacles.setdefault(
|
obstacles.setdefault(
|
||||||
int((obstacle.height+obstacle.altitude)*1000), {}
|
int((obstacle.height+obstacle.altitude)*1000), {}
|
||||||
).setdefault(obstacle.color, []).append(
|
).setdefault(obstacle.color, []).append(
|
||||||
obstacle.geometry.intersection(space.walkable_geom)
|
obstacle.geometry.intersection(unwrap_geom(space.walkable_geom))
|
||||||
)
|
)
|
||||||
|
|
||||||
for lineobstacle in space.lineobstacles.all():
|
for lineobstacle in space.lineobstacles.all():
|
||||||
if not lineobstacle.height:
|
if not lineobstacle.height:
|
||||||
continue
|
continue
|
||||||
obstacles.setdefault(int(lineobstacle.height*1000), {}).setdefault(lineobstacle.color, []).append(
|
obstacles.setdefault(int(lineobstacle.height*1000), {}).setdefault(lineobstacle.color, []).append(
|
||||||
lineobstacle.buffered_geometry.intersection(space.walkable_geom)
|
lineobstacle.buffered_geometry.intersection(unwrap_geom(space.walkable_geom))
|
||||||
)
|
)
|
||||||
|
|
||||||
geoms.ramps.extend(ramp.geometry for ramp in space.ramps.all())
|
geoms.ramps.extend(ramp.geometry for ramp in space.ramps.all())
|
||||||
|
@ -196,7 +196,7 @@ class LevelGeometries:
|
||||||
new_color_obstacles = []
|
new_color_obstacles = []
|
||||||
for obstacle in color_obstacles:
|
for obstacle in color_obstacles:
|
||||||
if altitudearea_prep.intersects(obstacle):
|
if altitudearea_prep.intersects(obstacle):
|
||||||
new_color_obstacles.append(obstacle.intersection(altitudearea.geometry))
|
new_color_obstacles.append(obstacle.intersection(unwrap_geom(altitudearea.geometry)))
|
||||||
if new_color_obstacles:
|
if new_color_obstacles:
|
||||||
new_height_obstacles[color] = new_color_obstacles
|
new_height_obstacles[color] = new_color_obstacles
|
||||||
if new_height_obstacles:
|
if new_height_obstacles:
|
||||||
|
@ -211,7 +211,7 @@ class LevelGeometries:
|
||||||
for height, geoms in sorted(heightareas.items(), key=operator.itemgetter(0)))
|
for height, geoms in sorted(heightareas.items(), key=operator.itemgetter(0)))
|
||||||
|
|
||||||
# merge access restrictions
|
# merge access restrictions
|
||||||
geoms.access_restriction_affected = {access_restriction: unary_union(areas)
|
geoms.access_restriction_affected = {access_restriction: unary_union([unwrap_geom(geom) for geom in areas])
|
||||||
for access_restriction, areas in access_restriction_affected.items()}
|
for access_restriction, areas in access_restriction_affected.items()}
|
||||||
geoms.restricted_spaces_indoors = {access_restriction: unary_union(spaces)
|
geoms.restricted_spaces_indoors = {access_restriction: unary_union(spaces)
|
||||||
for access_restriction, spaces in restricted_spaces_indoors.items()}
|
for access_restriction, spaces in restricted_spaces_indoors.items()}
|
||||||
|
@ -228,11 +228,11 @@ class LevelGeometries:
|
||||||
intersection = altitudearea.geometry.intersection(remaining).buffer(0)
|
intersection = altitudearea.geometry.intersection(remaining).buffer(0)
|
||||||
if intersection.is_empty:
|
if intersection.is_empty:
|
||||||
continue
|
continue
|
||||||
remaining = remaining.difference(altitudearea.geometry)
|
remaining = remaining.difference(unwrap_geom(altitudearea.geometry))
|
||||||
geoms.short_walls.append((altitudearea, intersection))
|
geoms.short_walls.append((altitudearea, intersection))
|
||||||
geoms.all_walls = geoms.walls
|
geoms.all_walls = geoms.walls
|
||||||
geoms.walls = geoms.walls.difference(
|
geoms.walls = geoms.walls.difference(
|
||||||
unary_union(tuple(altitudearea.geometry for altitudearea in altitudeareas_above))
|
unary_union(tuple(unwrap_geom(altitudearea.geometry) for altitudearea in altitudeareas_above))
|
||||||
)
|
)
|
||||||
|
|
||||||
# general level infos
|
# general level infos
|
||||||
|
|
|
@ -211,7 +211,7 @@ class LevelRenderData:
|
||||||
new_color_obstacles = []
|
new_color_obstacles = []
|
||||||
for obstacle in color_obstacles:
|
for obstacle in color_obstacles:
|
||||||
if new_geometry_prep.intersects(obstacle):
|
if new_geometry_prep.intersects(obstacle):
|
||||||
new_color_obstacles.append(obstacle.intersection(altitudearea.geometry))
|
new_color_obstacles.append(obstacle.intersection(unwrap_geom(altitudearea.geometry)))
|
||||||
if new_color_obstacles:
|
if new_color_obstacles:
|
||||||
new_height_obstacles[color] = new_color_obstacles
|
new_height_obstacles[color] = new_color_obstacles
|
||||||
if new_height_obstacles:
|
if new_height_obstacles:
|
||||||
|
@ -224,12 +224,12 @@ class LevelRenderData:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
new_geoms.ramps = tuple(
|
new_geoms.ramps = tuple(
|
||||||
ramp for ramp in (crop_to.intersection(ramp) for ramp in old_geoms.ramps)
|
ramp for ramp in (crop_to.intersection(unwrap_geom(ramp)) for ramp in old_geoms.ramps)
|
||||||
if not ramp.is_empty
|
if not ramp.is_empty
|
||||||
)
|
)
|
||||||
|
|
||||||
new_geoms.heightareas = tuple(
|
new_geoms.heightareas = tuple(
|
||||||
(area, height) for area, height in ((crop_to.intersection(area), height)
|
(area, height) for area, height in ((crop_to.intersection(unwrap_geom(area)), height)
|
||||||
for area, height in old_geoms.heightareas)
|
for area, height in old_geoms.heightareas)
|
||||||
if not area.is_empty
|
if not area.is_empty
|
||||||
)
|
)
|
||||||
|
|
|
@ -131,8 +131,8 @@ def good_representative_point(geometry):
|
||||||
if Polygon(polygon.exterior.coords).contains(c):
|
if Polygon(polygon.exterior.coords).contains(c):
|
||||||
return c
|
return c
|
||||||
x1, y1, x2, y2 = geometry.bounds
|
x1, y1, x2, y2 = geometry.bounds
|
||||||
lines = (tuple(assert_multilinestring(LineString(((x1, c.y), (x2, c.y))).intersection(geometry))) +
|
lines = (tuple(assert_multilinestring(LineString(((x1, c.y), (x2, c.y))).intersection(unwrap_geom(geometry)))) +
|
||||||
tuple(assert_multilinestring(LineString(((c.x, y1), (c.x, y2))).intersection(geometry))))
|
tuple(assert_multilinestring(LineString(((c.x, y1), (c.x, y2))).intersection(unwrap_geom(geometry)))))
|
||||||
return min(lines, key=lambda line: (line.distance(c), line.length),
|
return min(lines, key=lambda line: (line.distance(c), line.length),
|
||||||
default=geometry.representative_point()).centroid
|
default=geometry.representative_point()).centroid
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ from c3nav.mapdata.models.geometry.level import LevelGeometryMixin, Space
|
||||||
from c3nav.mapdata.models.geometry.space import SpaceGeometryMixin
|
from c3nav.mapdata.models.geometry.space import SpaceGeometryMixin
|
||||||
from c3nav.mapdata.models.locations import LocationRedirect, LocationSlug, Position, SpecificLocation
|
from c3nav.mapdata.models.locations import LocationRedirect, LocationSlug, Position, SpecificLocation
|
||||||
from c3nav.mapdata.utils.cache.local import LocalCacheProxy
|
from c3nav.mapdata.utils.cache.local import LocalCacheProxy
|
||||||
|
from c3nav.mapdata.utils.geometry import unwrap_geom
|
||||||
from c3nav.mapdata.utils.models import get_submodels
|
from c3nav.mapdata.utils.models import get_submodels
|
||||||
|
|
||||||
proxied_cache = LocalCacheProxy(maxsize=128)
|
proxied_cache = LocalCacheProxy(maxsize=128)
|
||||||
|
@ -137,7 +138,7 @@ def get_better_space_geometries():
|
||||||
result = {}
|
result = {}
|
||||||
for space in Space.objects.prefetch_related('columns', 'holes'):
|
for space in Space.objects.prefetch_related('columns', 'holes'):
|
||||||
geometry = space.geometry.difference(
|
geometry = space.geometry.difference(
|
||||||
unary_union(tuple(obj.geometry for obj in chain(space.columns.all(), space.holes.all())))
|
unary_union(tuple(unwrap_geom(obj.geometry) for obj in chain(space.columns.all(), space.holes.all())))
|
||||||
)
|
)
|
||||||
if not geometry.is_empty:
|
if not geometry.is_empty:
|
||||||
result[space.pk] = geometry
|
result[space.pk] = geometry
|
||||||
|
|
|
@ -78,13 +78,13 @@ class Router:
|
||||||
for space in level.spaces.all():
|
for space in level.spaces.all():
|
||||||
# create space geometries
|
# create space geometries
|
||||||
accessible_geom = space.geometry.difference(unary_union(
|
accessible_geom = space.geometry.difference(unary_union(
|
||||||
tuple(column.geometry for column in space.columns.all() if column.access_restriction_id is None) +
|
tuple(unwrap_geom(column.geometry) for column in space.columns.all() if column.access_restriction_id is None) +
|
||||||
tuple(hole.geometry for hole in space.holes.all()) +
|
tuple(unwrap_geom(hole.geometry) for hole in space.holes.all()) +
|
||||||
((buildings_geom, ) if space.outside else ())
|
((buildings_geom, ) if space.outside else ())
|
||||||
))
|
))
|
||||||
obstacles_geom = unary_union(
|
obstacles_geom = unary_union(
|
||||||
tuple(obstacle.geometry for obstacle in space.obstacles.all()) +
|
tuple(unwrap_geom(obstacle.geometry) for obstacle in space.obstacles.all()) +
|
||||||
tuple(lineobstacle.buffered_geometry for lineobstacle in space.lineobstacles.all())
|
tuple(unwrap_geom(lineobstacle.buffered_geometry) for lineobstacle in space.lineobstacles.all())
|
||||||
)
|
)
|
||||||
clear_geom = unary_union(tuple(get_rings(accessible_geom.difference(obstacles_geom))))
|
clear_geom = unary_union(tuple(get_rings(accessible_geom.difference(obstacles_geom))))
|
||||||
clear_geom_prep = prepared.prep(clear_geom)
|
clear_geom_prep = prepared.prep(clear_geom)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue