|
19 | 19 | class SpatialSearchBackend: |
20 | 20 | """Base class for all datastore backends.""" |
21 | 21 |
|
| 22 | + def process_spatial_field(self, geom_from_metadata): |
| 23 | + """Process spatial field based on its format (dict with spatial_type or GeoJSON string)""" |
| 24 | + # if string then convert to dict |
| 25 | + if isinstance(geom_from_metadata, str): |
| 26 | + geom_from_metadata = dict(json.loads(geom_from_metadata)) |
| 27 | + |
| 28 | + # Handle dict format with spatial_type |
| 29 | + if isinstance(geom_from_metadata, dict): |
| 30 | + spatial_type = geom_from_metadata.get("spatial_type") |
| 31 | + value = geom_from_metadata.get("value") |
| 32 | + |
| 33 | + if spatial_type == "bbox" and value: |
| 34 | + # Convert bbox array to GeoJSON polygon |
| 35 | + # bbox format: [Northernmost latitude, Southernmost latitude, Easternmost longitude, Westernmost longitude] |
| 36 | + if len(value) == 4: |
| 37 | + maxy, miny, maxx, minx = value |
| 38 | + geometry = { |
| 39 | + "type": "Polygon", |
| 40 | + "coordinates": [[ |
| 41 | + [minx, miny], |
| 42 | + [maxx, miny], |
| 43 | + [maxx, maxy], |
| 44 | + [minx, maxy], |
| 45 | + [minx, miny] |
| 46 | + ]] |
| 47 | + } |
| 48 | + return geometry |
| 49 | + else: |
| 50 | + log.error("Invalid bbox format, expected 4 values, not indexing :: {}".format(value)) |
| 51 | + return None |
| 52 | + |
| 53 | + elif spatial_type == "wkt" and value: |
| 54 | + # Convert WKT to GeoJSON using shapely |
| 55 | + try: |
| 56 | + from shapely import wkt as shapely_wkt |
| 57 | + shape = shapely_wkt.loads(value.strip()) |
| 58 | + # Convert shapely geometry to GeoJSON-like dict |
| 59 | + geometry = shapely.geometry.mapping(shape) |
| 60 | + return geometry |
| 61 | + except Exception as e: |
| 62 | + log.error("Failed to parse WKT geometry: {}, not indexing :: {}".format(e, value[:100])) |
| 63 | + return None |
| 64 | + else: |
| 65 | + log.error("Unknown spatial_type or missing value: {}".format(spatial_type)) |
| 66 | + return None |
| 67 | + # Handle existing GeoJSON string format |
| 68 | + return self.parse_geojson(geom_from_metadata) |
| 69 | + |
22 | 70 | def parse_geojson(self, geom_from_metadata): |
23 | 71 |
|
24 | 72 | try: |
@@ -51,10 +99,15 @@ def index_dataset(self, dataset_dict): |
51 | 99 | """ |
52 | 100 |
|
53 | 101 | geom_from_metadata = dataset_dict.get("spatial") |
| 102 | + |
54 | 103 | if not geom_from_metadata: |
55 | 104 | return dataset_dict |
56 | 105 |
|
57 | | - geometry = self.parse_geojson(geom_from_metadata) |
| 106 | + geometry = self.process_spatial_field(geom_from_metadata) |
| 107 | + |
| 108 | + if not geometry: |
| 109 | + return dataset_dict |
| 110 | + |
58 | 111 | shape = self.shape_from_geometry(geometry) |
59 | 112 |
|
60 | 113 | if not shape: |
@@ -134,10 +187,12 @@ class SolrSpatialFieldSearchBackend(SpatialSearchBackend): |
134 | 187 | def index_dataset(self, dataset_dict): |
135 | 188 | wkt = None |
136 | 189 | geom_from_metadata = dataset_dict.get("spatial") |
| 190 | + |
137 | 191 | if not geom_from_metadata: |
138 | 192 | return dataset_dict |
139 | 193 |
|
140 | | - geometry = self.parse_geojson(geom_from_metadata) |
| 194 | + geometry = self.process_spatial_field(geom_from_metadata) |
| 195 | + |
141 | 196 | if not geometry: |
142 | 197 | return dataset_dict |
143 | 198 |
|
|
0 commit comments