Skip to content

Commit

Permalink
make check for known CRSes to determine their bounds more solid; fix …
Browse files Browse the repository at this point in the history
…code smells
  • Loading branch information
ungarj committed Nov 4, 2024
1 parent fc04ced commit 837de4c
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 38 deletions.
78 changes: 41 additions & 37 deletions mapchete/geometry/reproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@
from shapely.geometry import mapping, shape

from mapchete.bounds import Bounds
from mapchete.errors import GeometryTypeError, ReprojectionFailed
from mapchete.errors import ReprojectionFailed
from mapchete.geometry.latlon import LATLON_CRS
from mapchete.geometry.repair import repair
from mapchete.geometry.segmentize import get_segmentize_value, segmentize_geometry
from mapchete.geometry.shape import to_shape
from mapchete.types import Geometry, GeometryLike
from mapchete.types import (
Geometry,
GeometryLike,
Polygon,
LinearRing,
LineString,
MultiPolygon,
)
from mapchete.types import CRSLike
from mapchete.validate import validate_crs

Expand All @@ -22,24 +29,23 @@

CRS_BOUNDS = {
# http://spatialreference.org/ref/epsg/wgs-84/
"epsg:4326": Bounds(-180.0, -90.0, 180.0, 90.0),
CRS.from_epsg(4326): Bounds(-180.0, -90.0, 180.0, 90.0),
# unknown source
"epsg:3857": Bounds(-180.0, -85.0511, 180.0, 85.0511),
CRS.from_epsg(3857): Bounds(-180.0, -85.0511, 180.0, 85.0511),
# http://spatialreference.org/ref/epsg/3035/
"epsg:3035": Bounds(-10.6700, 34.5000, 31.5500, 71.0500),
CRS.from_epsg(3035): Bounds(-10.6700, 34.5000, 31.5500, 71.0500),
}


def get_crs_bounds(crs: CRS) -> Bounds:
if crs.is_epsg_code:
try:
# get bounds from known CRSes
return CRS_BOUNDS[crs.get("init")]
except KeyError:
# try to get bounds using pyproj
area_of_use = pyproj.CRS(crs.to_epsg()).area_of_use
if area_of_use:
return Bounds.from_inp(area_of_use.bounds)
try:
# get bounds from known CRSes
return CRS_BOUNDS[crs]
except KeyError:
# try to get bounds using pyproj
area_of_use = pyproj.CRS(crs.to_epsg()).area_of_use
if area_of_use:
return Bounds.from_inp(area_of_use.bounds)
raise ValueError(f"bounds of CRS {crs} could not be determined")


Expand Down Expand Up @@ -127,14 +133,13 @@ def reproject_geometry(

# segmentize clipped geometry using one 100th of with or height depending on
# which is shorter
if segmentize_on_clip or segmentize:
try:
clipped_latlon = segmentize_geometry(
clipped_latlon,
get_segmentize_value(clipped_latlon, segmentize_fraction),
)
except GeometryTypeError:
pass
if (segmentize_on_clip or segmentize) and isinstance(
clipped_latlon, (Polygon, LinearRing, LineString, MultiPolygon)
):
clipped_latlon = segmentize_geometry(
clipped_latlon,
get_segmentize_value(clipped_latlon, segmentize_fraction),
)

# clip geometry dst_crs boundaries and return
return _reproject_geom(
Expand All @@ -148,21 +153,20 @@ def reproject_geometry(

# return without clipping if destination CRS does not have defined bounds
try:
if segmentize:
try:
return _reproject_geom(
segmentize_geometry(
geometry,
get_segmentize_value(geometry, segmentize_fraction),
),
src_crs,
dst_crs,
validity_check,
antimeridian_cutting,
fiona_env,
)
except GeometryTypeError:
pass
if segmentize and isinstance(
geometry, (Polygon, LinearRing, LineString, MultiPolygon)
):
return _reproject_geom(
segmentize_geometry(
geometry,
get_segmentize_value(geometry, segmentize_fraction),
),
src_crs,
dst_crs,
validity_check,
antimeridian_cutting,
fiona_env,
)
return _reproject_geom(
geometry,
src_crs,
Expand Down
2 changes: 1 addition & 1 deletion mapchete/geometry/segmentize.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,5 @@ def coords_segmentize(coords: CoordArrays, segmentize_value: float) -> CoordArra

def get_segmentize_value(geometry: Geometry, segmentize_fraction: float) -> float:
"""Divide the smaller one of geometry height or width by segmentize fraction."""
bounds = Bounds.from_inp(geometry, strict=False)
bounds = Bounds.from_inp(geometry.bounds, strict=False)
return min([bounds.height, bounds.width]) / segmentize_fraction

0 comments on commit 837de4c

Please sign in to comment.