Skip to content

Commit

Permalink
Adds antimeridian splitting code for spatial field backend
Browse files Browse the repository at this point in the history
Adds proper splitting and cropping along the antimeridian as well as
+/- 90 degreees latitude for Solr spatial field search backend.
  • Loading branch information
benjwadams committed Mar 8, 2024
1 parent 9383084 commit 19e369f
Showing 1 changed file with 42 additions and 7 deletions.
49 changes: 42 additions & 7 deletions ckanext/spatial/search/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,19 +182,54 @@ def index_dataset(self, dataset_dict):
if not shape.is_valid:
log.error("Wrong geometry, not indexing")
return dataset_dict
if shape.bounds[0] < -180 or shape.bounds[2] > 180:
log.error(
"""
Geometries outside the -180, -90, 180, 90 boundaries are not supported,
you need to split the geometry in order to fit the parts. Not indexing"""
)
try:
shape_cropped = split_geometry_antimeridian(shape)
except:
log.exception("Could not split geometry along antimeridian")
return dataset_dict
wkt = shape.wkt
wkt = shape_cropped.wkt

dataset_dict["spatial_geom"] = wkt

return dataset_dict

def split_geometry_antimeridian(self, geometry: shapely.Geometry) -> shapely.Geometry:
"""
Attempt to split on the antimeridian, and +/- 90 degree latitude bounds,
correcting and translating back to +/- 180 degree longitude bounds if
necessary
"""

spatial_joins = []

def intersect_and_translate(geometry: shapely.Geometry,
bbox: shapely.box,
longitude_translate: int) -> shapely.Geometry:

geom_clipped = geometry.intersection(bbox)
return shapely.affinity.translate(geom_clipped, longitude_translate)

if geometry.bounds[0] < -180:
spatial_joins.append(intersect_and_translate(geometry,
shapely.box(-360, -90,
-180, 90),
180))
if geometry.bounds[2] > 180:
spatial_joins.append(intersect_and_translate(geometry,
shapely.box(180, -90,
360, 90),
-180))
if (not spatial_joins or not (geometry.bounds[1] < -90 or
geometry.bounds[3] > 90)):
return geometry
else:
spatial_joins.append(intersect_and_translate(geometry,
shapely.box(-180, -90,
180, 90),
0))
return shapely.unary_union(spatial_joins)

def search_params(self, bbox, search_params):

bbox = fit_bbox(bbox)
Expand Down

0 comments on commit 19e369f

Please sign in to comment.