You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sdap.apache.org by rk...@apache.org on 2023/01/25 17:55:39 UTC

[incubator-sdap-ingester] branch dev updated: SDAP-417: Prevent SolrStore from generating documents with incorrect WKT for spatially small tiles (#69)

This is an automated email from the ASF dual-hosted git repository.

rkk pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-sdap-ingester.git


The following commit(s) were added to refs/heads/dev by this push:
     new 5637f07  SDAP-417: Prevent SolrStore from generating documents with incorrect WKT for spatially small tiles (#69)
5637f07 is described below

commit 5637f07ff8bd9fe079f1e61ac3c05f5f4225aba8
Author: Riley Kuttruff <72...@users.noreply.github.com>
AuthorDate: Wed Jan 25 09:55:34 2023 -0800

    SDAP-417: Prevent SolrStore from generating documents with incorrect WKT for spatially small tiles (#69)
    
    * Potential fix
    
    * Fix for incorrect geo field
    
    Sometimes the rounding will turn a very narrow POLYGON into a line, ensure that doesn't happen
    
    * Changelog
    
    * Fixed possible typo in variable name
    
    * Changelog entry references Jira issue
    
    Co-authored-by: rileykk <ri...@jpl.nasa.gov>
---
 CHANGELOG.md                                       |  1 +
 .../granule_ingester/writers/SolrStore.py          | 31 +++++++++++++++++++---
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7033caf..5091938 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Removed
 ### Fixed
 - SDAP-423: Fixed verbosity settings not propagating to ingester subprocesses
+- SDAP-417: Fixed bug where very spatially narrow tiles would have their WKT for the geo field represent the incorrect shape (ie a very narrow polygon being rounded to a line), which would cause an error on write to Solr.
 ### Security
 
 ## [1.0.0] - 2022-12-05
diff --git a/granule_ingester/granule_ingester/writers/SolrStore.py b/granule_ingester/granule_ingester/writers/SolrStore.py
index cd9fe08..2dac038 100644
--- a/granule_ingester/granule_ingester/writers/SolrStore.py
+++ b/granule_ingester/granule_ingester/writers/SolrStore.py
@@ -15,6 +15,7 @@
 
 import asyncio
 import functools
+import math
 import json
 import logging
 from asyncio import AbstractEventLoop
@@ -207,8 +208,13 @@ class SolrStore(MetadataStore):
         return input_document
 
     @staticmethod
-    def _format_latlon_string(value):
-        rounded_value = round(value, 3)
+    def _format_latlon_string(value, rounding=0):
+        if rounding == 0:
+            rounded_value = round(value, 3)
+        elif rounding == 1:
+            rounded_value = math.ceil(value * 1000)/1000.0
+        else:
+            rounded_value = math.floor(value * 1000) / 1000.0
         return '{:.3f}'.format(rounded_value)
 
     @classmethod
@@ -227,9 +233,28 @@ class SolrStore(MetadataStore):
         # If lat min = lat max but lon min != lon max, or lon min = lon max but lat min != lat max,
         # then we essentially have a line.
         elif bbox.lat_min == bbox.lat_max or bbox.lon_min == bbox.lon_max:
-            geo = 'LINESTRING({} {}, {} {})'.format(lon_min_str, lat_min_str, lon_max_str, lat_min_str)
+            # If the rounding makes the non-equal coordinates equal, ensure they're expanded so we have a line and not
+            # a point
+            if bbox.lat_min == bbox.lat_max and lon_min_str == lon_max_str:
+                lon_min_str = cls._format_latlon_string(bbox.lon_min, rounding=-1)
+                lon_max_str = cls._format_latlon_string(bbox.lon_max, rounding=1)
+            elif bbox.lon_min == bbox.lon_max and lat_min_str == lat_max_str:
+                lat_min_str = cls._format_latlon_string(bbox.lat_min, rounding=-1)
+                lat_max_str = cls._format_latlon_string(bbox.lat_max, rounding=1)
+
+            geo = 'LINESTRING({} {}, {} {})'.format(lon_min_str, lat_min_str, lon_max_str, lat_max_str)
         # All other cases should use POLYGON
         else:
+            # If the rounding makes any min/max coord pairs equal, expand them so the polygon doesn't collapse into a
+            # line
+            if lon_min_str == lon_max_str:
+                lon_min_str = cls._format_latlon_string(bbox.lon_min, rounding=-1)
+                lon_max_str = cls._format_latlon_string(bbox.lon_max, rounding=1)
+
+            if lat_min_str == lat_max_str:
+                lat_min_str = cls._format_latlon_string(bbox.lat_min, rounding=-1)
+                lat_max_str = cls._format_latlon_string(bbox.lat_max, rounding=1)
+
             geo = 'POLYGON(({} {}, {} {}, {} {}, {} {}, {} {}))'.format(lon_min_str, lat_min_str,
                                                                         lon_max_str, lat_min_str,
                                                                         lon_max_str, lat_max_str,