Skip to content

Commit

Permalink
make sure CRS bounds have latlon CRS set; fix pyproj.CRS parsing issue
Browse files Browse the repository at this point in the history
  • Loading branch information
ungarj committed Nov 4, 2024
1 parent 837de4c commit 86b524a
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 17 deletions.
22 changes: 12 additions & 10 deletions mapchete/geometry/repair.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@
from mapchete.geometry.types import Geometry, MultiPolygon, Polygon


def repair(geometry: Geometry) -> Geometry:
repaired = (
geometry.buffer(0)
if isinstance(geometry, (Polygon, MultiPolygon))
else geometry
)
if repaired.is_valid:
return repaired
def repair(geometry: Geometry, normalize: bool = True) -> Geometry:
if isinstance(geometry, (Polygon, MultiPolygon)):
out = geometry.buffer(0)
else:
out = geometry

if normalize:
out = out.normalize()

if out.is_valid:
return out
else:
raise TopologicalError(
"geometry is invalid (%s) and cannot be repaired"
% explain_validity(repaired)
f"geometry is invalid ({explain_validity(out)}) and cannot be repaired"
)
26 changes: 19 additions & 7 deletions mapchete/geometry/reproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import fiona
import pyproj
from pyproj.exceptions import CRSError
from fiona.transform import transform_geom
from rasterio.crs import CRS
from shapely.geometry import mapping, shape
Expand All @@ -29,11 +30,11 @@

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


Expand All @@ -42,15 +43,26 @@ def get_crs_bounds(crs: CRS) -> Bounds:
# get bounds from known CRSes
return CRS_BOUNDS[crs]
except KeyError:
logger.debug("try to determine CRS bounds using pyproj ...")
# 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:
# on UTM CRS, the area_of_use is None if pyproj.CRS is initialized with CRS.to_proj4(), thus
# prefer using CRS.to_epsg() and only use CRS.to_proj4() as backup
pyproj_crs = (
pyproj.CRS(crs.to_epsg())
if crs.is_epsg_code
else pyproj.CRS(crs.to_proj4())
)
if pyproj_crs.area_of_use:
return Bounds.from_inp(pyproj_crs.area_of_use.bounds, crs=LATLON_CRS)
except CRSError as exc:
logger.debug(exc)
pass
raise ValueError(f"bounds of CRS {crs} could not be determined")


def crs_is_epsg_4326(crs: CRS) -> bool:
return crs.is_epsg_code and crs.get("init") == "epsg:4326"
return crs == LATLON_CRS


def reproject_geometry(
Expand Down

0 comments on commit 86b524a

Please sign in to comment.