diff --git a/pymeos/main/tpoint.py b/pymeos/main/tpoint.py index 904035cf..12f3f162 100644 --- a/pymeos/main/tpoint.py +++ b/pymeos/main/tpoint.py @@ -1064,6 +1064,35 @@ def nearest_approach_distance( else: raise TypeError(f"Operation not supported with type {other.__class__}") + def min_distance(self, other: Union[shpb.BaseGeometry, TPoint]) -> float: + """ + Returns the minimum spatial distance between the temporal point and + `other`, ignoring time. + + When `other` is a static geometry, this is equivalent to + :meth:`nearest_approach_distance` because the geometry has no time + dimension. When `other` is a temporal point, the result is the + minimum distance over every pair of points on the two trajectories, + regardless of whether the pair shares a timestamp. + + Args: + other: An object to check the minimum spatial distance to. + + Returns: + A :class:`float` indicating the minimum spatial distance between + the temporal point and `other`. + + MEOS Functions: + nad_tgeo_geo, mindistance_tgeo_tgeo + """ + if isinstance(other, shpb.BaseGeometry): + gs = geo_to_gserialized(other, isinstance(self, TGeogPoint)) + return nad_tgeo_geo(self._inner, gs) + elif isinstance(other, TPoint): + return mindistance_tgeo_tgeo(self._inner, other._inner, float("inf")) + else: + raise TypeError(f"Operation not supported with type {other.__class__}") + def nearest_approach_instant(self, other: Union[shpb.BaseGeometry, TPoint]) -> TI: """ Returns the nearest approach instant between the temporal point and `other`. diff --git a/tests/main/tgeogpoint_test.py b/tests/main/tgeogpoint_test.py index 5e803f9d..60e2d69a 100644 --- a/tests/main/tgeogpoint_test.py +++ b/tests/main/tgeogpoint_test.py @@ -2617,6 +2617,38 @@ def test_nearest_approach_instant(self, temporal, argument): "Point(1 1)@2019-09-01" ) + @pytest.mark.parametrize( + "temporal, argument", + [ + (tpi, Point(1, 1)), + (tpds, Point(1, 1)), + (tps, Point(1, 1)), + (tpss, Point(1, 1)), + (tpi, TGeogPointInst("Point(1 1)@2019-09-01")), + (tpds, TGeogPointSeq("{Point(1 1)@2019-09-01, Point(1 1)@2019-09-02}")), + (tps, TGeogPointSeq("[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]")), + ( + tpss, + TGeogPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]," + "[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" + ), + ), + ], + ids=[ + "Instant Geo", + "Discrete Sequence Geo", + "Sequence Geo", + "SequenceSet Geo", + "Instant TPoint", + "Discrete Sequence TPoint", + "Sequence TPoint", + "SequenceSet TPoint", + ], + ) + def test_min_distance(self, temporal, argument): + assert round(temporal.min_distance(argument), 3) == 0.0 + @pytest.mark.parametrize( "temporal, argument", [ diff --git a/tests/main/tgeompoint_test.py b/tests/main/tgeompoint_test.py index abb38b6a..ae905cd8 100644 --- a/tests/main/tgeompoint_test.py +++ b/tests/main/tgeompoint_test.py @@ -3260,6 +3260,38 @@ def test_nearest_approach_instant(self, temporal, argument): "Point(1 1)@2019-09-01" ) + @pytest.mark.parametrize( + "temporal, argument", + [ + (tpi, Point(1, 1)), + (tpds, Point(1, 1)), + (tps, Point(1, 1)), + (tpss, Point(1, 1)), + (tpi, TGeomPointInst("Point(1 1)@2019-09-01")), + (tpds, TGeomPointSeq("{Point(1 1)@2019-09-01, Point(1 1)@2019-09-02}")), + (tps, TGeomPointSeq("[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]")), + ( + tpss, + TGeomPointSeqSet( + "{[Point(1 1)@2019-09-01, Point(1 1)@2019-09-02]," + "[Point(1 1)@2019-09-03, Point(1 1)@2019-09-05]}" + ), + ), + ], + ids=[ + "Instant Geo", + "Discrete Sequence Geo", + "Sequence Geo", + "SequenceSet Geo", + "Instant TPoint", + "Discrete Sequence TPoint", + "Sequence TPoint", + "SequenceSet TPoint", + ], + ) + def test_min_distance(self, temporal, argument): + assert temporal.min_distance(argument) == 0.0 + @pytest.mark.parametrize( "temporal, argument", [