[Git][debian-gis-team/asf-search][upstream] New upstream version 11.0.3
Antonio Valentino (@antonio.valentino)
gitlab at salsa.debian.org
Sat Feb 7 11:18:48 GMT 2026
Antonio Valentino pushed to branch upstream at Debian GIS Project / asf-search
Commits:
ac264e6b by Antonio Valentino at 2026-02-07T11:11:59+00:00
New upstream version 11.0.3
- - - - -
4 changed files:
- CHANGELOG.md
- asf_search/ASFProduct.py
- asf_search/Products/NISARProduct.py
- tests/yml_tests/test_authenticated/test_ASFSubproduct_Auth.yml
Changes:
=====================================
CHANGELOG.md
=====================================
@@ -25,6 +25,11 @@ and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-
-->
+------
+## [v11.0.3](https://github.com/asfadmin/Discovery-asf_search/compare/v11.0.2...v11.0.3)
+### Fixed
+- Properly parse multipolygons from NISAR UMM-G that cross dateline, unwrap geometry (add 360 to negative longitude polygon)
+
------
## [v11.0.2](https://github.com/asfadmin/Discovery-asf_search/compare/v11.0.1...v11.0.2)
### Fixed
=====================================
asf_search/ASFProduct.py
=====================================
@@ -357,9 +357,9 @@ class ASFProduct:
return self.umm_cast(mapping['cast'], value)
- def translate_product(self, item: Dict) -> Dict:
- """
- Generates `properties` and `geometry` from the CMR UMM response
+ def _get_geometry(self, item: Dict):
+ """Helper method that creates a geometry context dictionary.
+ Meant primarily for NISARProduct to override for dateline multipolygon parsing.
"""
try:
coordinates = item['umm']['SpatialExtent']['HorizontalSpatialDomain']['Geometry'][
@@ -370,6 +370,13 @@ class ASFProduct:
except KeyError:
geometry = {'coordinates': None, 'type': 'Polygon'}
+ return geometry
+
+ def translate_product(self, item: Dict) -> Dict:
+ """
+ Generates `properties` and `geometry` from the CMR UMM response
+ """
+ geometry = self._get_geometry(item)
umm = item.get('umm')
# additionalAttributes = {attr['Name']: attr['Values'] for attr in umm['AdditionalAttributes']}
=====================================
asf_search/Products/NISARProduct.py
=====================================
@@ -1,7 +1,10 @@
+from shapely import unary_union, multipolygons
from typing import Dict, Tuple, Union
from asf_search import ASFSearchOptions, ASFSession, ASFStackableProduct
from asf_search.CMR.translate import try_parse_frame_coverage, try_parse_bool, try_parse_int
-
+from shapely.geometry import shape, MultiPolygon
+from shapely.geometry.base import BaseGeometry
+from shapely.ops import transform
class NISARProduct(ASFStackableProduct):
"""
Used for NISAR dataset products
@@ -73,3 +76,50 @@ class NISARProduct(ASFStackableProduct):
return (self._read_property('processingDate', ''), keys[1])
return keys
+
+
+ def _get_geometry(self, item: Dict) -> dict:
+ """Overload for dateline multipolygon parsing.
+ # TODO consider implications of moving this to base ASFProduct class in future
+ """
+ try:
+ polygons = item['umm']['SpatialExtent']['HorizontalSpatialDomain']['Geometry'][
+ 'GPolygons'
+ ]
+ # dateline spanning scenes are stored as multiple polygons in CMR,
+ # we need to unwrap and merge them
+ if len(polygons) > 1:
+ polygon_shapes = []
+ for polygon in polygons:
+ coordinates = [[c['Longitude'], c['Latitude']] for c in polygon['Boundary']['Points']]
+ geometry = self._get_unwrapped({'coordinates': [coordinates], 'type': 'Polygon'})
+
+ polygon_shapes.append(geometry)
+
+ geom = unary_union(multipolygons(polygon_shapes))
+
+ # sometimes the dateline spanning polygons don't overlap properly
+ if isinstance(geom, MultiPolygon):
+ geom = geom.convex_hull
+
+ return {'coordinates': [geom.exterior.coords], 'type': 'Polygon'}
+ else:
+ coordinates = polygons[0]['Boundary']['Points']
+ coordinates = [[c['Longitude'], c['Latitude']] for c in coordinates]
+ geometry = {'coordinates': [coordinates], 'type': 'Polygon'}
+ except KeyError:
+ geometry = {'coordinates': None, 'type': 'Polygon'}
+
+ return geometry
+
+ def _get_unwrapped(self, geometry: dict) -> BaseGeometry:
+ def unwrap_shape(x, y, z=None):
+ x = x if x > 0 else x + 360
+ return tuple([x, y])
+ wrapped = shape(geometry)
+ if wrapped.bounds[0] < 0 or wrapped.bounds[2] < 0:
+ unwrapped = transform(unwrap_shape, wrapped)
+ else:
+ unwrapped = wrapped
+
+ return unwrapped
=====================================
tests/yml_tests/test_authenticated/test_ASFSubproduct_Auth.yml
=====================================
@@ -2,4 +2,11 @@ tests:
- test-collection-attributes RSLC:
params:
processingLevel: RSLC
- expected_attributes: ['ASCENDING_DESCENDING', 'TRACK_NUMBER', 'FRAME_NUMBER', 'FREQUENCY_A_POLARIZATION', 'FREQUENCY_B_POLARIZATION', 'PRODUCT_VERSION', 'PROCESSING_CENTER', 'FREQUENCIES', 'FULL_FRAME', 'FREQUENCY_A_RANGE_BANDWIDTH', 'FREQUENCY_B_RANGE_BANDWIDTH', 'RANGE_BANDWIDTH_CONCAT', 'JOINT_OBSERVATION', 'PROCESSING_LEVEL', 'PRODUCT_TYPE', 'PRODUCT_TYPE_DESC', 'PRODUCTION_PIPELINE', 'FREQUENCY_A_POLARIZATION_CONCAT', 'FREQUENCY_B_POLARIZATION_CONCAT', 'ORBIT_TYPE', 'STACK_ID', 'INPUT_RCID']
\ No newline at end of file
+ expected_attributes: ['ASCENDING_DESCENDING', 'TRACK_NUMBER', 'FRAME_NUMBER', 'FREQUENCY_A_POLARIZATION', 'FREQUENCY_B_POLARIZATION', 'PRODUCT_VERSION', 'PROCESSING_CENTER', 'FREQUENCIES', 'FULL_FRAME', 'FREQUENCY_A_RANGE_BANDWIDTH', 'FREQUENCY_B_RANGE_BANDWIDTH', 'RANGE_BANDWIDTH_CONCAT', 'JOINT_OBSERVATION', 'PROCESSING_LEVEL', 'PRODUCT_TYPE', 'PRODUCT_TYPE_DESC', 'PRODUCTION_PIPELINE', 'FREQUENCY_A_POLARIZATION_CONCAT', 'FREQUENCY_B_POLARIZATION_CONCAT', 'ORBIT_TYPE', 'STACK_ID', 'INPUT_RCID']
+
+- Test NISAR ASFSubproduct cross-dateline:
+ scenes: [
+ 'NISAR_L0_PR_RRSD_008_005_A_153S_20251022T161112_20251022T161132_P05000_F_J_001', # polygons don't overlap correctly, need convex_hull
+ 'NISAR_L0_PR_RRSD_008_086_D_148S_20251028T071837_20251028T071901_P05000_F_J_001' # simple unary union case
+ ]
+ expected_subclass: NISARProduct
View it on GitLab: https://salsa.debian.org/debian-gis-team/asf-search/-/commit/ac264e6bade6a89809112f31c0e8446fa37eb978
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/asf-search/-/commit/ac264e6bade6a89809112f31c0e8446fa37eb978
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20260207/06f4875f/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list