From 1c8f7a1ad6755465ebc7e5725737bcf9b73a2cb5 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Thu, 8 Oct 2026 20:27:08 +0200 Subject: [PATCH] Convert a temporal point between geography and geometry on the generated surface GeneratedSurfaceTest calls tgeogpoint_to_tgeompoint and tgeompoint_to_tgeogpoint, which answer what tgeompoint(tgeogpoint) and tgeogpoint(tgeompoint) answer in MobilityDB. A linear lon/lat trip from POINT(80 -30) to POINT(179 -30) crosses the envelope POLYGON((93.41 -60.55, 173.34 -60.55, 173.34 -8.47, 93.41 -8.47, 93.41 -60.55)) only between its two instants: converted to a temporal geometry point it stays linear and ever intersects the envelope, the step trip with the same instants does not, and converting back gives the trip it started from. Witness: a table of flights holds tgeogpoint values, and comparing them with a lon/lat envelope or reprojecting them to a planar SRID needs them as tgeompoint; the generated surface named no conversion between the two point types, and tgeography_to_tgeogpoint refuses a tgeogpoint ("The temporal value must be of type tgeography"). MobilityDB #2994 states the two conversions in MEOS. Measured: tools/refresh-from-master.sh over MobilityDB master a0860d4731, MEOS-API 0438baabc6 and JMEOS bade99212b, then mvn -B clean test: 35 tests, 0 failures, 0 errors, 0 skipped, the new case among the 18 of GeneratedSurfaceTest. Why: the conversion keeps the interpolation of the trip, so a query on the converted trip answers for the motion between the instants, and the step control is what shows it does. --- .../spark/GeneratedSurfaceTest.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/test/java/org/mobilitydb/spark/GeneratedSurfaceTest.java b/src/test/java/org/mobilitydb/spark/GeneratedSurfaceTest.java index 14ed2821..e50387ac 100644 --- a/src/test/java/org/mobilitydb/spark/GeneratedSurfaceTest.java +++ b/src/test/java/org/mobilitydb/spark/GeneratedSurfaceTest.java @@ -409,6 +409,30 @@ void nxn_array_tgeoarr_udfs() { "SELECT size(eDwithinPairs(" + p + ", " + p + ", 1000.0))")).intValue()); } + @Test + void point_conversion_between_geography_and_geometry_keeps_the_interpolation() { + // tgeogpoint_to_tgeompoint and tgeompoint_to_tgeogpoint answer what + // tgeompoint(tgeogpoint) and tgeogpoint(tgeompoint) answer in MobilityDB. A linear + // lon/lat trip whose two instants lie west and east of a lon/lat envelope crosses it + // only between them, so the converted trip intersects the envelope when the + // conversion keeps the linear interpolation, and the step trip with the same + // instants does not. + String trip = "tgeogpoint_in('SRID=4326;[POINT(80 -30)@2001-01-01, " + + "POINT(179 -30)@2001-01-02]')"; + String step = "tgeogpoint_in('SRID=4326;Interp=Step;[POINT(80 -30)@2001-01-01, " + + "POINT(179 -30)@2001-01-02]')"; + String box = "SRID=4326;POLYGON((93.41 -60.55,173.34 -60.55,173.34 -8.47," + + "93.41 -8.47,93.41 -60.55))"; + String geom = "tgeogpoint_to_tgeompoint(" + trip + ")"; + assertEquals("Linear", scalar("SELECT temporal_interp(" + geom + ")")); + assertEquals(Boolean.TRUE, scalar("SELECT eIntersects(" + geom + ", '" + box + "')")); + assertEquals(Boolean.FALSE, scalar( + "SELECT eIntersects(tgeogpoint_to_tgeompoint(" + step + "), '" + box + "')")); + // The reverse conversion gives back the trip it started from. + assertEquals(scalar("SELECT tspatial_as_text(" + trip + ", 6)"), + scalar("SELECT tspatial_as_text(tgeompoint_to_tgeogpoint(" + geom + "), 6)")); + } + @Test void h3_cell_prefilter_surface() { // The temporal-H3 cell surface (th3index / geoToH3IndexSet / the