import shapely shapes and NDArray only for type checking

This commit is contained in:
Gwendolyn 2025-04-18 00:29:17 +02:00
parent 60afb9fa60
commit 3d2b1dff4b
3 changed files with 31 additions and 27 deletions

View file

@ -12,7 +12,7 @@ if [[ "$1" == "git" ]]; then
CONTEXT="https://github.com/c3nav/c3nav.git#${COMMIT}" CONTEXT="https://github.com/c3nav/c3nav.git#${COMMIT}"
fi fi
docker buildx build -f docker/Dockerfile \ podman buildx build -f docker/Dockerfile \
--platform linux/arm64,linux/amd64 \ --platform linux/arm64,linux/amd64 \
--build-arg "COMMIT=${COMMIT}" \ --build-arg "COMMIT=${COMMIT}" \
--label "org.opencontainers.image.version=${COMMIT}" \ --label "org.opencontainers.image.version=${COMMIT}" \
@ -25,7 +25,7 @@ docker buildx build -f docker/Dockerfile \
--cache-to "type=registry,ref=ghcr.io/c3nav/c3nav_cache:main,mode=max" \ --cache-to "type=registry,ref=ghcr.io/c3nav/c3nav_cache:main,mode=max" \
--push "${CONTEXT}" --push "${CONTEXT}"
docker buildx build -f docker/tileserver.dockerfile \ podman buildx build -f docker/tileserver.dockerfile \
--platform linux/arm64,linux/amd64 \ --platform linux/arm64,linux/amd64 \
--build-arg "COMMIT=${COMMIT}" \ --build-arg "COMMIT=${COMMIT}" \
--label "org.opencontainers.image.version=${COMMIT}" \ --label "org.opencontainers.image.version=${COMMIT}" \

View file

@ -2,9 +2,11 @@ import operator
import struct import struct
from functools import reduce from functools import reduce
from os import PathLike from os import PathLike
from typing import Self, Iterator from typing import Self, Iterator, Union, TYPE_CHECKING
import numpy as np import numpy as np
if TYPE_CHECKING:
from numpy.typing import NDArray from numpy.typing import NDArray
from shapely import Polygon, MultiPolygon from shapely import Polygon, MultiPolygon
@ -59,7 +61,7 @@ class AccessRestrictionAffected(LevelGeometryIndexed):
self.restrictions.append(restriction) self.restrictions.append(restriction)
return i return i
def __getitem__(self, selector: tuple[slice, slice] | Polygon | MultiPolygon) -> "AccessRestrictionAffectedCells": def __getitem__(self, selector: Union[tuple[slice, slice], 'Polygon', 'MultiPolygon']) -> "AccessRestrictionAffectedCells":
return AccessRestrictionAffectedCells(self, selector) return AccessRestrictionAffectedCells(self, selector)
def __setitem__(self, selector, value): def __setitem__(self, selector, value):
@ -68,15 +70,15 @@ class AccessRestrictionAffected(LevelGeometryIndexed):
class AccessRestrictionAffectedCells: class AccessRestrictionAffectedCells:
def __init__(self, parent: AccessRestrictionAffected, def __init__(self, parent: AccessRestrictionAffected,
selector: tuple[slice, slice] | Polygon | MultiPolygon): selector: Union[tuple[slice, slice], 'Polygon','MultiPolygon']):
self.parent = parent self.parent = parent
self.selector = selector self.selector = selector
self.values = self._get_values() self.values = self._get_values()
def _get_values(self) -> NDArray: def _get_values(self) -> 'NDArray':
return LevelGeometryIndexed.__getitem__(self.parent, self.selector) return LevelGeometryIndexed.__getitem__(self.parent, self.selector)
def _set(self, values: NDArray): def _set(self, values: 'NDArray'):
self.values = values self.values = values
LevelGeometryIndexed.__setitem__(self.parent, self.selector, values) LevelGeometryIndexed.__setitem__(self.parent, self.selector, values)

View file

@ -2,8 +2,9 @@ import math
import struct import struct
from os import PathLike from os import PathLike
from pathlib import Path from pathlib import Path
from typing import Self, Optional from typing import Self, Optional, Union, TYPE_CHECKING
if TYPE_CHECKING:
from numpy.typing import NDArray from numpy.typing import NDArray
from shapely import Polygon, MultiPolygon from shapely import Polygon, MultiPolygon
@ -29,18 +30,18 @@ class GeometryIndexed:
variant_id = 0 variant_id = 0
def __init__(self, resolution: Optional[int] = None, x: int = 0, y: int = 0, def __init__(self, resolution: Optional[int] = None, x: int = 0, y: int = 0,
data: NDArray = None, filename: str | bytes | PathLike = None): data: 'NDArray' = None, filename: str | bytes | PathLike = None):
if resolution is None: if resolution is None:
from django.conf import settings from django.conf import settings
resolution = settings.CACHE_RESOLUTION resolution = settings.CACHE_RESOLUTION
self.resolution: int = resolution self.resolution: int = resolution
self.x = x self.x = x
self.y = y self.y = y
self.data: NDArray = data if data is not None else self._get_empty_array() self.data: 'NDArray' = data if data is not None else self._get_empty_array()
self.filename = filename self.filename = filename
@classmethod @classmethod
def _get_empty_array(cls) -> NDArray: def _get_empty_array(cls) -> 'NDArray':
return np.empty((0, 0), dtype=cls.dtype) return np.empty((0, 0), dtype=cls.dtype)
@classmethod @classmethod
@ -64,7 +65,8 @@ class GeometryIndexed:
cls._read_metadata(f, kwargs) cls._read_metadata(f, kwargs)
# noinspection PyTypeChecker # noinspection PyTypeChecker
kwargs['data'] = np.fromstring(f.read(width*height*cls.dtype().itemsize), cls.dtype).reshape((height, width)) kwargs['data'] = np.fromstring(f.read(width * height * cls.dtype().itemsize), cls.dtype).reshape(
(height, width))
return cls(**kwargs) return cls(**kwargs)
@classmethod @classmethod
@ -88,7 +90,7 @@ class GeometryIndexed:
def _write_metadata(self, f): def _write_metadata(self, f):
pass pass
def get_geometry_bounds(self, geometry: Polygon | MultiPolygon) -> tuple[int, int, int, int]: def get_geometry_bounds(self, geometry: Union['Polygon', 'MultiPolygon']) -> tuple[int, int, int, int]:
minx, miny, maxx, maxy = geometry.bounds minx, miny, maxx, maxy = geometry.bounds
return ( return (
int(math.floor(minx / self.resolution)), int(math.floor(minx / self.resolution)),
@ -117,8 +119,8 @@ class GeometryIndexed:
self.x = minx self.x = minx
self.y = miny self.y = miny
def get_geometry_cells(self, geometry: Polygon | MultiPolygon, def get_geometry_cells(self, geometry: Union['Polygon','MultiPolygon'],
bounds: Optional[tuple[int, int, int, int]] = None) -> NDArray: bounds: Optional[tuple[int, int, int, int]] = None) -> 'NDArray':
if bounds is None: if bounds is None:
bounds = self.get_geometry_bounds(geometry) bounds = self.get_geometry_bounds(geometry)
minx, miny, maxx, maxy = bounds minx, miny, maxx, maxy = bounds
@ -147,7 +149,7 @@ class GeometryIndexed:
height, width = self.data.shape height, width = self.data.shape
return self.x, self.y, self.x + width, self.y + height return self.x, self.y, self.x + width, self.y + height
def __getitem__(self, key: tuple[slice, slice] | Polygon | MultiPolygon) -> int: def __getitem__(self, key: Union[tuple[slice, slice], 'Polygon','MultiPolygon']) -> int:
if isinstance(key, tuple): if isinstance(key, tuple):
xx, yy = key xx, yy = key
@ -171,7 +173,7 @@ class GeometryIndexed:
raise TypeError('GeometryIndexed index must be a shapely geometry or tuple, not %s' % type(key).__name__) raise TypeError('GeometryIndexed index must be a shapely geometry or tuple, not %s' % type(key).__name__)
def __setitem__(self, key: Polygon | MultiPolygon, value: NDArray | int): def __setitem__(self, key: Union['Polygon','MultiPolygon'], value: 'NDArray' | int):
from shapely.geometry.base import BaseGeometry from shapely.geometry.base import BaseGeometry
if isinstance(key, BaseGeometry): if isinstance(key, BaseGeometry):
bounds = self.get_geometry_bounds(key) bounds = self.get_geometry_bounds(key)