Skip to content

Commit

Permalink
fix: capture area rounding TDE-1237 (#1116)
Browse files Browse the repository at this point in the history
### Motivation

Although the footprint files are rounded to 8 decimal places, when they
are combined into a capture area this can create some co-ordinates with
more than 8 decimal places, which we then need to round.

### Modifications

Use Shapely to round the co-ordinates to 8 decimal places after merging
the footprint geometries.

### Verification

Unit test created, unit tests updated for new capture area rounding.
Manually compared
[capture-area-compare.zip](https://github.com/user-attachments/files/17299987/capture-area-compare.zip).
  • Loading branch information
amfage authored Oct 9, 2024
1 parent e253a4c commit d055f49
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
5 changes: 3 additions & 2 deletions scripts/stac/imagery/capture_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Any, Sequence

from linz_logger import get_log
from shapely import BufferCapStyle, BufferJoinStyle, to_geojson, union_all
from shapely import BufferCapStyle, BufferJoinStyle, to_geojson, union_all, wkt
from shapely.geometry.base import BaseGeometry
from shapely.ops import orient

Expand Down Expand Up @@ -62,9 +62,10 @@ def merge_polygons(polygons: Sequence[BaseGeometry], buffer_distance: float) ->
# Negative buffer back in the polygons
union_unbuffered = union_buffered.buffer(-buffer_distance, cap_style=BufferCapStyle.flat, join_style=BufferJoinStyle.mitre)
union_simplified = union_unbuffered.simplify(buffer_distance)
union_rounded = wkt.loads(wkt.dumps(union_simplified, rounding_precision=8))
# Apply right-hand rule winding order (exterior rings should be counter-clockwise) to the geometry
# Ref: https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.6
oriented_union_simplified = orient(union_simplified, sign=1.0)
oriented_union_simplified = orient(union_rounded, sign=1.0)

return oriented_union_simplified

Expand Down
47 changes: 43 additions & 4 deletions scripts/stac/imagery/tests/capture_area_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ def test_merge_polygons_with_rounding_margin_too_big() -> None:
(1.0, 1.0),
(0.0, 1.0),
(0.0, 0.0),
(1.9999999999999998, 0.0),
(1.9999999999999998, 1.0),
(2.0, 0.0),
(2.0, 1.0),
(1.1, 1.0),
(1.015018629811984, 0.1501862981198402),
(1.0, 0.15093536161009757),
(1.01501863, 0.1501863),
(1.0, 0.15093536),
(1.0, 1.0),
]
)
Expand Down Expand Up @@ -190,3 +190,42 @@ def test_capture_area_orientation_multipolygon() -> None:
capture_area = generate_capture_area(polygons, Decimal("0.05"))
mp_geom = cast(MultiPolygon, shape(capture_area["geometry"]))
assert is_ccw(get_exterior_ring(mp_geom.geoms[0]))


def test_capture_area_rounding_decimal_places() -> None:
# Test that the capture area is rounded to 8 decimal places
polygons = []
polygons.append(
shape(
{
"type": "MultiPolygon",
"coordinates": [
[
[
[174.673418475601466, -37.051277768264598],
[174.673425023818197, -37.051550327851878],
[174.673479898051271, -37.051280958541774],
[174.673418475601466, -37.051277768264598],
]
]
],
}
)
)
capture_area_expected = {
"geometry": {
"type": "Polygon",
"coordinates": [
[
[174.67342502, -37.05155033],
[174.6734799, -37.05128096],
[174.67341848, -37.05127777],
[174.67342502, -37.05155033],
]
],
},
"type": "Feature",
"properties": {},
}
capture_area = generate_capture_area(polygons, Decimal("1"))
assert capture_area == capture_area_expected
7 changes: 2 additions & 5 deletions scripts/stac/imagery/tests/collection_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,17 +310,14 @@ def test_capture_area_added(fake_collection_metadata: CollectionMetadata, subtes

with subtests.test():
assert collection.stac["assets"]["capture_area"]["file:checksum"] in (
"1220369cd5d4179f5f68ca0fd9be70b9f66033fcc6bb2f3305c0ad977adc79d7ad53", # geos 3.11 - geos 3.12 as yet untested
"1220ba57cd77defc7fa72e140f4faa0846e8905ae443de04aef99bf381d4650c17a0", # geos 3.11 - geos 3.12 as yet untested
)

with subtests.test():
assert "file:size" in collection.stac["assets"]["capture_area"]

with subtests.test():
assert collection.stac["assets"]["capture_area"]["file:size"] in (
339, # geos 3.11
299, # geos 3.12
)
assert collection.stac["assets"]["capture_area"]["file:size"] in (269,) # geos 3.11 - geos 3.12 as yet untested


def test_event_name_is_present(fake_collection_metadata: CollectionMetadata) -> None:
Expand Down

0 comments on commit d055f49

Please sign in to comment.