diff --git a/CHANGELOG.md b/CHANGELOG.md index dc401c2..c261773 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). Note: Minor version `0.X.0` update might break the API, It's recommended to pin geojson-pydantic to minor version: `geojson-pydantic>=0.6,<0.7` +## [1.1.2] - 2024-10-22 + +* relax `bbox` validation and allow antimeridian crossing bboxes + ## [1.1.1] - 2024-08-29 * add python 3.12 support @@ -365,7 +369,10 @@ Although the type file was added in `0.2.0` it wasn't included in the distribute ### Added - Initial Release -[unreleased]: https://github.com/developmentseed/geojson-pydantic/compare/1.0.2...HEAD +[unreleased]: https://github.com/developmentseed/geojson-pydantic/compare/1.1.2...HEAD +[1.1.2]: https://github.com/developmentseed/geojson-pydantic/compare/1.1.1...1.1.2 +[1.1.1]: https://github.com/developmentseed/geojson-pydantic/compare/1.1.0...1.1.1 +[1.1.0]: https://github.com/developmentseed/geojson-pydantic/compare/1.0.2...1.1.0 [1.0.2]: https://github.com/developmentseed/geojson-pydantic/compare/1.0.1...1.0.2 [1.0.1]: https://github.com/developmentseed/geojson-pydantic/compare/1.0.0...1.0.1 [1.0.0]: https://github.com/developmentseed/geojson-pydantic/compare/0.6.3...1.0.0 diff --git a/geojson_pydantic/base.py b/geojson_pydantic/base.py index 718f297..90c547b 100644 --- a/geojson_pydantic/base.py +++ b/geojson_pydantic/base.py @@ -1,6 +1,7 @@ """pydantic BaseModel for GeoJSON objects.""" from __future__ import annotations +import warnings from typing import Any, Dict, List, Optional, Set from pydantic import BaseModel, SerializationInfo, field_validator, model_serializer @@ -38,10 +39,15 @@ def validate_bbox(cls, bbox: Optional[BBox]) -> Optional[BBox]: # Check X if bbox[0] > bbox[offset]: - errors.append(f"Min X ({bbox[0]}) must be <= Max X ({bbox[offset]}).") + warnings.warn( + f"BBOX crossing the Antimeridian line, Min X ({bbox[0]}) > Max X ({bbox[offset]}).", + UserWarning, + ) + # Check Y if bbox[1] > bbox[1 + offset]: errors.append(f"Min Y ({bbox[1]}) must be <= Max Y ({bbox[1 + offset]}).") + # If 3D, check Z values. if offset > 2 and bbox[2] > bbox[2 + offset]: errors.append(f"Min Z ({bbox[2]}) must be <= Max Z ({bbox[2 + offset]}).") diff --git a/tests/test_base.py b/tests/test_base.py index 971fb6d..1f2170f 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -6,7 +6,6 @@ from geojson_pydantic.base import _GeoJsonBase BBOXES = ( - (100, 0, 0, 0), # Incorrect Order (0, 100, 0, 0), (0, 0, 100, 0, 0, 0), (0, "a", 0, 0), # Invalid Type @@ -20,6 +19,11 @@ def test_bbox_validation(values: Tuple) -> None: _GeoJsonBase(bbox=values) +def test_bbox_antimeridian() -> None: + with pytest.warns(UserWarning): + _GeoJsonBase(bbox=(100, 0, 0, 0)) + + @pytest.mark.parametrize("values", BBOXES) def test_bbox_validation_subclass(values: Tuple) -> None: # Ensure validation is happening correctly when subclassed diff --git a/tests/test_features.py b/tests/test_features.py index 63eb013..ef311a8 100644 --- a/tests/test_features.py +++ b/tests/test_features.py @@ -253,14 +253,26 @@ def test_feature_validation(): with pytest.raises(ValidationError): # bad bbox2d - Feature(type="Feature", properties=None, bbox=(100, 100, 0, 0), geometry=None) + Feature(type="Feature", properties=None, bbox=(0, 100, 100, 0), geometry=None) with pytest.raises(ValidationError): # bad bbox3d Feature( type="Feature", properties=None, - bbox=(100, 100, 100, 0, 0, 0), + bbox=(0, 100, 100, 100, 0, 0), + geometry=None, + ) + + # Antimeridian + with pytest.warns(UserWarning): + Feature(type="Feature", properties=None, bbox=(100, 0, 0, 100), geometry=None) + + with pytest.warns(UserWarning): + Feature( + type="Feature", + properties=None, + bbox=(100, 0, 0, 0, 100, 100), geometry=None, )