move clip_altitudes() to base RenderEngine
This commit is contained in:
parent
400f2892bb
commit
80fb9e2df7
2 changed files with 18 additions and 23 deletions
|
@ -2,6 +2,8 @@ import math
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
from shapely.ops import unary_union
|
||||||
|
|
||||||
|
|
||||||
class FillAttribs:
|
class FillAttribs:
|
||||||
__slots__ = ('color', 'opacity')
|
__slots__ = ('color', 'opacity')
|
||||||
|
@ -42,11 +44,26 @@ class RenderEngine(ABC):
|
||||||
|
|
||||||
self.background_rgb = tuple(int(background[i:i + 2], 16) for i in range(1, 6, 2))
|
self.background_rgb = tuple(int(background[i:i + 2], 16) for i in range(1, 6, 2))
|
||||||
|
|
||||||
|
# keep track which area of the image has which altitude currently
|
||||||
|
self.altitudes = {}
|
||||||
|
self.last_altitude = None
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_png(self) -> bytes:
|
def get_png(self) -> bytes:
|
||||||
# render the image to png.
|
# render the image to png.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def clip_altitudes(self, new_geometry, new_altitude=None):
|
||||||
|
# register new geometry with an altitude
|
||||||
|
# a geometry with no altitude will reset the altitude information of its area as if nothing was ever there
|
||||||
|
if self.last_altitude is not None and self.last_altitude > new_altitude:
|
||||||
|
raise ValueError('Altitudes have to be ascending.')
|
||||||
|
|
||||||
|
if new_altitude in self.altitudes:
|
||||||
|
self.altitudes[new_altitude] = unary_union([self.altitudes[new_altitude], new_geometry])
|
||||||
|
else:
|
||||||
|
self.altitudes[new_altitude] = new_geometry
|
||||||
|
|
||||||
def add_geometry(self, geometry, fill: Optional[FillAttribs] = None, stroke: Optional[StrokeAttribs] = None,
|
def add_geometry(self, geometry, fill: Optional[FillAttribs] = None, stroke: Optional[StrokeAttribs] = None,
|
||||||
altitude=None, height=None, shape_cache_key=None):
|
altitude=None, height=None, shape_cache_key=None):
|
||||||
# draw a shapely geometry with a given style
|
# draw a shapely geometry with a given style
|
||||||
|
|
|
@ -6,12 +6,11 @@ from itertools import chain
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from PIL import Image
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core import checks
|
from django.core import checks
|
||||||
from PIL import Image
|
|
||||||
from shapely.affinity import translate
|
from shapely.affinity import translate
|
||||||
from shapely.geometry import LineString, Polygon
|
from shapely.geometry import LineString, Polygon
|
||||||
from shapely.ops import unary_union
|
|
||||||
|
|
||||||
# import gobject-inspect, cairo and rsvg if the native rsvg SVG_RENDERER should be used
|
# import gobject-inspect, cairo and rsvg if the native rsvg SVG_RENDERER should be used
|
||||||
from c3nav.mapdata.render.engines.base import FillAttribs, RenderEngine, StrokeAttribs
|
from c3nav.mapdata.render.engines.base import FillAttribs, RenderEngine, StrokeAttribs
|
||||||
|
@ -47,10 +46,6 @@ class SVGEngine(RenderEngine):
|
||||||
self.defs = ''
|
self.defs = ''
|
||||||
self.clip_path_i = 0
|
self.clip_path_i = 0
|
||||||
|
|
||||||
# keep track which area of the image has which altitude currently
|
|
||||||
self.altitudes = {}
|
|
||||||
self.last_altitude = None
|
|
||||||
|
|
||||||
# for fast numpy operations
|
# for fast numpy operations
|
||||||
self.np_scale = np.array((self.scale, -self.scale))
|
self.np_scale = np.array((self.scale, -self.scale))
|
||||||
self.np_offset = np.array((-self.minx * self.scale, self.maxy * self.scale))
|
self.np_offset = np.array((-self.minx * self.scale, self.maxy * self.scale))
|
||||||
|
@ -201,23 +196,6 @@ class SVGEngine(RenderEngine):
|
||||||
shadow = self._create_geometry(shadow_geom, attribs)
|
shadow = self._create_geometry(shadow_geom, attribs)
|
||||||
self.g += shadow
|
self.g += shadow
|
||||||
|
|
||||||
def clip_altitudes(self, new_geometry, new_altitude=None):
|
|
||||||
# register new geometry with specific (or no) altitude
|
|
||||||
# a geometry with no altitude will reset the altitude information of its area as if nothing was ever there
|
|
||||||
for altitude, geometry in tuple(self.altitudes.items()):
|
|
||||||
if altitude != new_altitude:
|
|
||||||
self.altitudes[altitude] = geometry.difference(new_geometry)
|
|
||||||
if self.altitudes[altitude].is_empty:
|
|
||||||
self.altitudes.pop(altitude)
|
|
||||||
if new_altitude is not None:
|
|
||||||
if self.last_altitude is not None and self.last_altitude > new_altitude:
|
|
||||||
raise ValueError('Altitudes have to be ascending.')
|
|
||||||
self.last_altitude = new_altitude
|
|
||||||
if new_altitude in self.altitudes:
|
|
||||||
self.altitudes[new_altitude] = unary_union([self.altitudes[new_altitude], new_geometry])
|
|
||||||
else:
|
|
||||||
self.altitudes[new_altitude] = new_geometry
|
|
||||||
|
|
||||||
def _add_geometry(self, geometry, fill: Optional[FillAttribs] = None, stroke: Optional[StrokeAttribs] = None,
|
def _add_geometry(self, geometry, fill: Optional[FillAttribs] = None, stroke: Optional[StrokeAttribs] = None,
|
||||||
altitude=None, height=None, shape_cache_key=None):
|
altitude=None, height=None, shape_cache_key=None):
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue