Skip to content

Commit 1ecfb5e

Browse files
committed
make message more ambiguous
1 parent 573dc1b commit 1ecfb5e

File tree

2 files changed

+51
-12
lines changed

2 files changed

+51
-12
lines changed

stac_check/lint.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -554,15 +554,22 @@ def check_catalog_file_name(self) -> bool:
554554
return True
555555

556556
def check_geometry_coordinates_order(self) -> bool:
557-
"""Checks if the coordinates in a geometry are in the correct order (longitude, latitude).
557+
"""Checks if the coordinates in a geometry may be in the incorrect order.
558558
559-
This function verifies that coordinates follow the GeoJSON specification where positions are in
560-
[longitude, latitude] order. It detects cases where coordinates might be accidentally reversed
561-
by checking if latitude values (which should be the second element in each coordinate pair)
562-
are within the valid range of -90 to 90 degrees.
559+
This function attempts to detect cases where coordinates might not follow the GeoJSON
560+
specification where positions should be in [longitude, latitude] order. It uses several
561+
heuristics to identify potentially problematic coordinates:
562+
563+
1. Checks if latitude values (second element) exceed ±90 degrees
564+
2. Checks if longitude values (first element) exceed ±180 degrees
565+
3. Uses a heuristic to detect when coordinates are likely reversed
566+
(when first value > 90, second value < 90, and first value > second value*2)
567+
568+
Note that this check can never definitively determine if coordinates are reversed
569+
or simply contain errors, it can only flag suspicious patterns.
563570
564571
Returns:
565-
bool: True if coordinates appear to be in the correct order, False if they seem reversed.
572+
bool: True if coordinates appear to be in the expected order, False if they may be reversed.
566573
"""
567574
if "geometry" not in self.data or self.data["geometry"] is None:
568575
return True
@@ -577,15 +584,19 @@ def is_valid_coordinate(coord):
577584
lon, lat = coord[0], coord[1]
578585

579586
# Check if latitude (second value) is outside the valid range
580-
# This could indicate reversed coordinates
581587
if abs(lat) > 90:
582588
return False
583589

584590
# Check if longitude (first value) is outside the valid range
585-
# This is another indicator of possible coordinate reversal
586591
if abs(lon) > 180:
587592
return False
588593

594+
# Additional heuristic for likely reversed coordinates
595+
# If the first value (supposed longitude) is > 90, second value (supposed latitude) is < 90,
596+
# and first value is significantly larger than second value, they may be reversed
597+
if abs(lon) > 90 and abs(lat) < 90 and abs(lon) > abs(lat) * 2:
598+
return False
599+
589600
return True
590601

591602
# Function to recursively check all coordinates in a geometry
@@ -706,7 +717,7 @@ def create_best_practices_dict(self) -> Dict:
706717
not self.check_geometry_coordinates_order()
707718
and config["geometry_coordinates_order"] == True
708719
):
709-
msg_1 = "Geometry coordinates should be in the correct order (longitude, latitude)"
720+
msg_1 = "Geometry coordinates may be reversed or contain errors (expected order: longitude, latitude)"
710721
best_practices_dict["geometry_coordinates_order"] = [msg_1]
711722

712723
return best_practices_dict

tests/test_lint.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -639,23 +639,51 @@ def test_geometry_coordinates_order():
639639
"properties": {"datetime": "2023-01-01T00:00:00Z"},
640640
}
641641

642+
# Create a test item with coordinates that may be reversed based on heuristic
643+
# (first value > 90, second value < 90, first value > second value*2)
644+
heuristic_incorrect_item = {
645+
"stac_version": "1.0.0",
646+
"stac_extensions": [],
647+
"type": "Feature",
648+
"id": "test-coordinates-heuristic-incorrect",
649+
"bbox": [10.0, -10.0, 20.0, 10.0],
650+
"geometry": {
651+
"type": "Polygon",
652+
"coordinates": [
653+
[
654+
[120.0, 40.0], # First value > 90, second < 90, first > second*2
655+
[120.0, 40.0],
656+
[120.0, 40.0],
657+
[120.0, 40.0],
658+
[120.0, 40.0],
659+
]
660+
],
661+
},
662+
"properties": {"datetime": "2023-01-01T00:00:00Z"},
663+
}
664+
642665
# Test with correct coordinates - this should pass
643666
linter = Linter(correct_item)
644667
assert linter.check_geometry_coordinates_order() == True
645668

646-
# Test with incorrect coordinates - this should fail
669+
# Test with incorrect coordinates that are within valid ranges
670+
# This will now fail with our enhanced heuristic
647671
linter = Linter(incorrect_item)
648672
assert (
649673
linter.check_geometry_coordinates_order() == True
650-
) # This will still pass because values are within valid ranges
674+
) # Still passes as values are within valid ranges
651675

652676
# Test with clearly incorrect coordinates - this should fail
653677
linter = Linter(clearly_incorrect_item)
654678
assert linter.check_geometry_coordinates_order() == False
655679

680+
# Test with coordinates that trigger the heuristic - this should fail
681+
linter = Linter(heuristic_incorrect_item)
682+
assert linter.check_geometry_coordinates_order() == False
683+
656684
# Test that the best practices dictionary contains the error message
657685
best_practices = linter.create_best_practices_dict()
658686
assert "geometry_coordinates_order" in best_practices
659687
assert best_practices["geometry_coordinates_order"] == [
660-
"Geometry coordinates should be in the correct order (longitude, latitude)"
688+
"Geometry coordinates may be reversed or contain errors (expected order: longitude, latitude)"
661689
]

0 commit comments

Comments
 (0)