more performance optimization in altitudearea building and more comments

This commit is contained in:
Laura Klünder 2019-12-20 20:05:14 +01:00
parent 1e2119fb80
commit 484f725aa6
2 changed files with 27 additions and 7 deletions

View file

@ -8,6 +8,7 @@ import numpy as np
from django.core.validators import MinValueValidator
from django.db import models
from django.urls import reverse
from django.utils.functional import cached_property
from django.utils.text import format_lazy
from django.utils.translation import ugettext_lazy as _
from scipy.sparse.csgraph._shortest_path import dijkstra
@ -157,6 +158,16 @@ class Door(LevelGeometryMixin, AccessRestrictionMixin, models.Model):
default_related_name = 'doors'
class ItemWithValue:
def __init__(self, obj, func):
self.obj = obj
self._func = func
@cached_property
def value(self):
return self._func()
class AltitudeArea(LevelGeometryMixin, models.Model):
"""
An altitude area
@ -529,15 +540,17 @@ class AltitudeArea(LevelGeometryMixin, models.Model):
buffered = polygon.buffer(0.001)
center = polygon.centroid
touches = tuple((area, buffered.intersection(area.orig_geometry).area)
touches = tuple(ItemWithValue(area, lambda: buffered.intersection(area.orig_geometry).area)
for area in our_areas
if area.orig_geometry_prep.intersects(buffered))
if touches:
min_touches = sum((t[1] for t in touches), 0)/4
area = max(touches, key=lambda item: (item[1] > min_touches,
item[0].altitude2 is not None,
item[0].altitude,
item[1]))[0]
if len(touches) == 1:
area = touches[0].obj
elif touches:
min_touches = sum((t.value for t in touches), 0)/4
area = max(touches, key=lambda item: (item.value > min_touches,
item.obj.altitude2 is not None,
item.obj.altitude,
item.value)).obj
else:
area = min(our_areas,
key=lambda a: a.orig_geometry.distance(center)-(0 if a.altitude2 is None else 0.6))

View file

@ -361,16 +361,23 @@ def clean_cut_polygon(polygon: Polygon) -> Polygon:
def cut_ring(ring: LinearRing) -> List[LinearRing]:
"""
Cuts a Linearring into multiple linearrings. Useful if the ring intersects with itself.
An 8-ring would be split into it's two circles for example.
"""
rings = []
new_ring = []
# noinspection PyPropertyAccess
for point in ring.coords:
try:
# check if this point is already part of the ring
index = new_ring.index(point)
except ValueError:
# if not, append it
new_ring.append(point)
continue
# if yes, we got a loop, add it to the result and remove it from new_ring.
if len(new_ring) > 2+index:
rings.append(LinearRing(new_ring[index:]+[point]))
new_ring = new_ring[:index+1]