start modernizing renderdata code somewhat
This commit is contained in:
parent
0150851808
commit
551cb1e086
2 changed files with 25 additions and 16 deletions
|
@ -1,14 +1,17 @@
|
||||||
import operator
|
import operator
|
||||||
import pickle
|
import pickle
|
||||||
from collections import deque
|
from collections import deque
|
||||||
|
from dataclasses import dataclass, field
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from scipy.interpolate import NearestNDInterpolator
|
from scipy.interpolate import NearestNDInterpolator
|
||||||
from shapely import prepared
|
from shapely import prepared, Geometry, MultiPolygon
|
||||||
from shapely.geometry import GeometryCollection
|
from shapely.geometry import GeometryCollection
|
||||||
from shapely.ops import unary_union
|
from shapely.ops import unary_union
|
||||||
|
from shapely.prepared import PreparedGeometry
|
||||||
|
|
||||||
from c3nav.mapdata.models import Level, MapUpdate, Source
|
from c3nav.mapdata.models import Level, MapUpdate, Source
|
||||||
from c3nav.mapdata.render.geometry import AltitudeAreaGeometries, LevelGeometries
|
from c3nav.mapdata.render.geometry import AltitudeAreaGeometries, LevelGeometries
|
||||||
|
@ -24,10 +27,13 @@ except ImportError:
|
||||||
empty_geometry_collection = GeometryCollection()
|
empty_geometry_collection = GeometryCollection()
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class Cropper:
|
class Cropper:
|
||||||
def __init__(self, geometry=None):
|
geometry: Optional[Geometry]
|
||||||
self.geometry = geometry
|
geometry_prep: Optional[PreparedGeometry] = field(init=False, repr=False)
|
||||||
self.geometry_prep = None if geometry is None else prepared.prep(unwrap_geom(geometry))
|
|
||||||
|
def __post_init__(self):
|
||||||
|
self.geometry_prep = None if self.geometry is None else prepared.prep(unwrap_geom(self.geometry))
|
||||||
|
|
||||||
def intersection(self, other):
|
def intersection(self, other):
|
||||||
if self.geometry is None:
|
if self.geometry is None:
|
||||||
|
@ -37,19 +43,20 @@ class Cropper:
|
||||||
return empty_geometry_collection
|
return empty_geometry_collection
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class LevelRenderData:
|
class LevelRenderData:
|
||||||
"""
|
"""
|
||||||
Renderdata for a level to display.
|
Renderdata for a level to display.
|
||||||
This contains multiple LevelGeometries instances because you might to look through holes onto lower levels.
|
This contains multiple LevelGeometries instances because you might to look through holes onto lower levels.
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
base_altitude: float
|
||||||
self.levels = []
|
lowest_important_level: int
|
||||||
self.base_altitude = None
|
levels: list[LevelGeometries] = field(default_factory=list)
|
||||||
self.lowest_important_level = None
|
darken_area: MultiPolygon | None = None
|
||||||
self.darken_area = None
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def rebuild():
|
def rebuild():
|
||||||
|
# Levels are automatically sorted by base_altitude, ascending
|
||||||
levels = tuple(Level.objects.prefetch_related('altitudeareas', 'buildings', 'doors', 'spaces',
|
levels = tuple(Level.objects.prefetch_related('altitudeareas', 'buildings', 'doors', 'spaces',
|
||||||
'spaces__holes', 'spaces__areas', 'spaces__columns',
|
'spaces__holes', 'spaces__areas', 'spaces__columns',
|
||||||
'spaces__obstacles', 'spaces__lineobstacles',
|
'spaces__obstacles', 'spaces__lineobstacles',
|
||||||
|
@ -58,11 +65,12 @@ class LevelRenderData:
|
||||||
package = CachePackage(bounds=tuple(chain(*Source.max_bounds())))
|
package = CachePackage(bounds=tuple(chain(*Source.max_bounds())))
|
||||||
|
|
||||||
# first pass in reverse to collect some data that we need later
|
# first pass in reverse to collect some data that we need later
|
||||||
single_level_geoms = {}
|
single_level_geoms: dict[int, LevelGeometries] = {}
|
||||||
interpolators = {}
|
interpolators = {}
|
||||||
last_interpolator = None
|
last_interpolator: NearestNDInterpolator | None = None
|
||||||
altitudeareas_above = []
|
altitudeareas_above = [] # todo: typing
|
||||||
for level in reversed(levels):
|
for level in reversed(levels):
|
||||||
|
# build level geometry for every single level
|
||||||
single_level_geoms[level.pk] = LevelGeometries.build_for_level(level, altitudeareas_above)
|
single_level_geoms[level.pk] = LevelGeometries.build_for_level(level, altitudeareas_above)
|
||||||
|
|
||||||
# ignore intermediate levels in this pass
|
# ignore intermediate levels in this pass
|
||||||
|
@ -143,9 +151,10 @@ class LevelRenderData:
|
||||||
if crop_to.is_empty:
|
if crop_to.is_empty:
|
||||||
break
|
break
|
||||||
|
|
||||||
render_data = LevelRenderData()
|
render_data = LevelRenderData(
|
||||||
render_data.base_altitude = level.base_altitude
|
base_altitude=level.base_altitude,
|
||||||
render_data.lowest_important_level = lowest_important_level.pk
|
lowest_important_level=lowest_important_level.pk,
|
||||||
|
)
|
||||||
access_restriction_affected = {}
|
access_restriction_affected = {}
|
||||||
|
|
||||||
# go through sublevels, get their level geometries and crop them
|
# go through sublevels, get their level geometries and crop them
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from enum import StrEnum
|
from enum import StrEnum
|
||||||
from typing import Annotated, Union, Optional
|
from typing import Annotated, Optional, Union
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue