From 5043f5978449ec58d33f9ce193ce50a1ba838853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20Zim=C3=A1nyi?= Date: Fri, 9 Oct 2026 16:02:40 +0200 Subject: [PATCH] Pass the model of the earth MEOS measures a geography on The MEOS functions measuring a geography take a last bool spheroid. The benchmark queries pass true, the model each measured on: the ever-within tests of a vehicle or a trip against a zone, a geofence, a road segment or another trip (edwithin_tgeo_geo, edwithin_tgeo_tgeo), the set-set joins (edwithin_tgeoarr_tgeoarr, tdwithin_tgeoarr_tgeoarr, spheroid before the count), and the distances between two geographies of queries 6, 7 and 9 and MEOSBridge (geog_distance, whose MEOS body fixed use_spheroid to true). The example of MeosCrossStreamJoin calls edwithin_tgeo_tgeo with its spheroid in both modules. Witness: over MobilityDB 8a9bc20b62, where #3005 adds spheroid, and the jar JMEOS builds from it, the benchmark fails to compile: "method geog_distance in class functions.GeneratedFunctions cannot be applied to given types; required: jnr.ffi.Pointer,jnr.ffi.Pointer,boolean". Measured over MobilityDB 8a9bc20b62 and MEOS-API c6f423d2ef, with the jar and generators of JMEOS codegen/pass-spheroid: the binding module passes its 21 tests and the benchmark module its 12, and the build prints no warning. Why: a call passes every argument of the MEOS function it calls, and a benchmark answers on the model of the earth it was written for. --- benchmark/src/main/java/aisdata/Query1_Main.java | 2 +- benchmark/src/main/java/aisdata/Query5_Main.java | 2 +- benchmark/src/main/java/aisdata/Query6_Main.java | 2 +- benchmark/src/main/java/aisdata/Query7_Main.java | 2 +- benchmark/src/main/java/aisdata/Query9_Main.java | 2 +- benchmark/src/main/java/berlinmod/MEOSBridge.java | 8 ++++---- .../flink/meos/wirings/MeosCrossStreamJoin.java | 2 +- .../src/main/java/org/mobilitydb/meos/MeosSetSetJoin.java | 4 ++-- benchmark/src/main/java/sncbdata/Query1_Main.java | 2 +- benchmark/src/main/java/sncbdata/Query5_Main.java | 4 ++-- benchmark/src/main/java/sncbdata/Query6_Main.java | 2 +- benchmark/src/main/java/sncbdata/Query7_Main.java | 2 +- benchmark/src/main/java/sncbdata/Query9_Main.java | 2 +- .../src/test/java/berlinmod/BerlinMODSetSetJoinTest.java | 2 +- .../flink/meos/wirings/MeosCrossStreamJoin.java | 2 +- 15 files changed, 20 insertions(+), 20 deletions(-) diff --git a/benchmark/src/main/java/aisdata/Query1_Main.java b/benchmark/src/main/java/aisdata/Query1_Main.java index 0047c6c..94047dd 100644 --- a/benchmark/src/main/java/aisdata/Query1_Main.java +++ b/benchmark/src/main/java/aisdata/Query1_Main.java @@ -341,7 +341,7 @@ public void process( // edwithin_tgeo_geo returns 1 if tpoint is within distanceMeters of the // zone polygon at any instant — implements paper Line 2. int within = GeneratedFunctions.edwithin_tgeo_geo( - tpoint, hazardZones[i], distanceMeters); + tpoint, hazardZones[i], distanceMeters, true); if (within == 1) { String alert = String.format( diff --git a/benchmark/src/main/java/aisdata/Query5_Main.java b/benchmark/src/main/java/aisdata/Query5_Main.java index c152107..7f11dc8 100644 --- a/benchmark/src/main/java/aisdata/Query5_Main.java +++ b/benchmark/src/main/java/aisdata/Query5_Main.java @@ -358,7 +358,7 @@ public void process( // Paper Line 2: edwithin_tgeo_geo(lon, lat, ts, POLYGON, 1) == 1 // Distance=1m is effectively an intersection test. - if (GeneratedFunctions.edwithin_tgeo_geo(tpoint, geofence, geofenceDistMeters) != 1) { + if (GeneratedFunctions.edwithin_tgeo_geo(tpoint, geofence, geofenceDistMeters, true) != 1) { log.debug("MMSI={} skipped: outside geofence at ts={}", mmsi, ts); continue; } diff --git a/benchmark/src/main/java/aisdata/Query6_Main.java b/benchmark/src/main/java/aisdata/Query6_Main.java index 2a0f95d..8e96aa9 100644 --- a/benchmark/src/main/java/aisdata/Query6_Main.java +++ b/benchmark/src/main/java/aisdata/Query6_Main.java @@ -255,7 +255,7 @@ public String join(AISData left, AISData right) throws Exception { return null; } - double mindist = GeneratedFunctions.geog_distance(geoLeft, geoRight); + double mindist = GeneratedFunctions.geog_distance(geoLeft, geoRight, true); // Paper Line 5: filter(lat > 0.0): keep only pairs where left-side lat is positive. // All AIS positions in this dataset are in the Northern Hemisphere (~55–58°N), diff --git a/benchmark/src/main/java/aisdata/Query7_Main.java b/benchmark/src/main/java/aisdata/Query7_Main.java index 82a4a5e..6fb34c8 100644 --- a/benchmark/src/main/java/aisdata/Query7_Main.java +++ b/benchmark/src/main/java/aisdata/Query7_Main.java @@ -298,7 +298,7 @@ public void coGroup( // Paper Line 2: device_id < device_id2 if (left.getMmsi() >= right.getMmsi()) continue; - double dist = GeneratedFunctions.geog_distance(geoLeft, geoRight); + double dist = GeneratedFunctions.geog_distance(geoLeft, geoRight, true); // Keep only the minimum distance per unique (mmsi1, mmsi2) pair. String key = left.getMmsi() + ":" + right.getMmsi(); diff --git a/benchmark/src/main/java/aisdata/Query9_Main.java b/benchmark/src/main/java/aisdata/Query9_Main.java index 5e9e5b4..f9655b2 100644 --- a/benchmark/src/main/java/aisdata/Query9_Main.java +++ b/benchmark/src/main/java/aisdata/Query9_Main.java @@ -256,7 +256,7 @@ public void coGroup( // Paper Line 2: device_id != device_id2 if (left.getMmsi() == right.getMmsi()) continue; - double dist = GeneratedFunctions.geog_distance(geoLeft, geoRight); + double dist = GeneratedFunctions.geog_distance(geoLeft, geoRight, true); // Key: directed pair "mmsi1→mmsi2" String key = left.getMmsi() + "->" + right.getMmsi(); diff --git a/benchmark/src/main/java/berlinmod/MEOSBridge.java b/benchmark/src/main/java/berlinmod/MEOSBridge.java index d438f60..780ed17 100644 --- a/benchmark/src/main/java/berlinmod/MEOSBridge.java +++ b/benchmark/src/main/java/berlinmod/MEOSBridge.java @@ -65,7 +65,7 @@ public static boolean dwithinMetres(double lon1, double lat1, double lon2, double lat2, double radiusMetres) { return GeneratedFunctions.edwithin_tgeo_geo( - tgeogInst(lon1, lat1), pointGeog(lon2, lat2), radiusMetres) == 1; + tgeogInst(lon1, lat1), pointGeog(lon2, lat2), radiusMetres, true) == 1; } /** @@ -80,7 +80,7 @@ public static boolean dwithinSegmentMetres(double pLon, double pLat, double radiusMetres) { return GeneratedFunctions.edwithin_tgeo_geo( tgeogInst(pLon, pLat), - lineGeog(s1Lon, s1Lat, s2Lon, s2Lat), radiusMetres) == 1; + lineGeog(s1Lon, s1Lat, s2Lon, s2Lat), radiusMetres, true) == 1; } /** @@ -102,7 +102,7 @@ public static boolean intersectsBox(double lon, double lat, */ public static double distanceMetres(double lon1, double lat1, double lon2, double lat2) { - return GeneratedFunctions.geog_distance(pointGeog(lon1, lat1), pointGeog(lon2, lat2)); + return GeneratedFunctions.geog_distance(pointGeog(lon1, lat1), pointGeog(lon2, lat2), true); } /** @@ -113,7 +113,7 @@ public static double distanceSegmentMetres(double pLon, double pLat, double s1Lon, double s1Lat, double s2Lon, double s2Lat) { return GeneratedFunctions.geog_distance( - pointGeog(pLon, pLat), lineGeog(s1Lon, s1Lat, s2Lon, s2Lat)); + pointGeog(pLon, pLat), lineGeog(s1Lon, s1Lat, s2Lon, s2Lat), true); } // ---------------------------------------------------------------------- diff --git a/benchmark/src/main/java/org/mobilitydb/flink/meos/wirings/MeosCrossStreamJoin.java b/benchmark/src/main/java/org/mobilitydb/flink/meos/wirings/MeosCrossStreamJoin.java index f11c8b8..e4f6b36 100644 --- a/benchmark/src/main/java/org/mobilitydb/flink/meos/wirings/MeosCrossStreamJoin.java +++ b/benchmark/src/main/java/org/mobilitydb/flink/meos/wirings/MeosCrossStreamJoin.java @@ -63,7 +63,7 @@ * (left, right, ctx) -> { * Pointer leftT = left.toTGeoPointer(); * Pointer rightT = right.toTGeoPointer(); - * if (MeosOpsFreeGeo.edwithin_tgeo_tgeo(leftT, rightT, 100.0) != 0) { + * if (MeosOpsFreeGeo.edwithin_tgeo_tgeo(leftT, rightT, 100.0, true) != 0) { * return new MeetingEvent(left.id(), right.id(), ctx.getLeftTimestamp()); * } * return null; // no output for non-matches diff --git a/benchmark/src/main/java/org/mobilitydb/meos/MeosSetSetJoin.java b/benchmark/src/main/java/org/mobilitydb/meos/MeosSetSetJoin.java index 08ea2cb..d3cf07d 100644 --- a/benchmark/src/main/java/org/mobilitydb/meos/MeosSetSetJoin.java +++ b/benchmark/src/main/java/org/mobilitydb/meos/MeosSetSetJoin.java @@ -39,7 +39,7 @@ public static int[][] eDwithinPairs(Pointer[] a, Pointer[] b, double dist) { Pointer arr1 = marshal(a, rt); Pointer arr2 = marshal(b, rt); Pointer countPtr = Memory.allocateDirect(rt, 4); - Pointer res = GeneratedFunctions.edwithin_tgeoarr_tgeoarr(arr1, a.length, arr2, b.length, dist, countPtr); + Pointer res = GeneratedFunctions.edwithin_tgeoarr_tgeoarr(arr1, a.length, arr2, b.length, dist, true, countPtr); Reference.reachabilityFence(arr1); Reference.reachabilityFence(arr2); return readPairsAndFree(res, countPtr.getInt(0L)); @@ -68,7 +68,7 @@ public static TDwithin tDwithinPairs(Pointer[] a, Pointer[] b, double dist) { Pointer arr2 = marshal(b, rt); Pointer countPtr = Memory.allocateDirect(rt, 4); Pointer periodsPtr = Memory.allocateDirect(rt, 8); - Pointer res = GeneratedFunctions.tdwithin_tgeoarr_tgeoarr(arr1, a.length, arr2, b.length, dist, countPtr, periodsPtr); + Pointer res = GeneratedFunctions.tdwithin_tgeoarr_tgeoarr(arr1, a.length, arr2, b.length, dist, true, countPtr, periodsPtr); Reference.reachabilityFence(arr1); Reference.reachabilityFence(arr2); int cnt = countPtr.getInt(0L); diff --git a/benchmark/src/main/java/sncbdata/Query1_Main.java b/benchmark/src/main/java/sncbdata/Query1_Main.java index a5bc64f..ab23886 100644 --- a/benchmark/src/main/java/sncbdata/Query1_Main.java +++ b/benchmark/src/main/java/sncbdata/Query1_Main.java @@ -168,7 +168,7 @@ public void process(Integer deviceId, Context context, Iterable elemen if (hazardZones[i] == null) continue; // Paper Line 2: edwithin_tgeo_geo returns 1 if tpoint is within // distanceMeters of the zone polygon at any instant. - if (GeneratedFunctions.edwithin_tgeo_geo(tpoint, hazardZones[i], distanceMeters) == 1) { + if (GeneratedFunctions.edwithin_tgeo_geo(tpoint, hazardZones[i], distanceMeters, true) == 1) { String alert = String.format( "[ALERT][Q1] DeviceID=%-6d | lon=%10.5f lat=%9.5f" + " | ts=%s | within %.0f m of ZONE %d | window [%s - %s]", diff --git a/benchmark/src/main/java/sncbdata/Query5_Main.java b/benchmark/src/main/java/sncbdata/Query5_Main.java index ce11f41..62a2b89 100644 --- a/benchmark/src/main/java/sncbdata/Query5_Main.java +++ b/benchmark/src/main/java/sncbdata/Query5_Main.java @@ -179,7 +179,7 @@ public void process(Integer deviceId, Context context, event.getLon(), event.getLat(), millisToTs(event.getTimestamp())); Pointer tpoint = GeneratedFunctions.tgeogpoint_in(wkt); if (tpoint == null) continue; - if (GeneratedFunctions.edwithin_tgeo_geo(tpoint, geofence, geofenceDistMeters) != 1) continue; + if (GeneratedFunctions.edwithin_tgeo_geo(tpoint, geofence, geofenceDistMeters, true) != 1) continue; surviving.add(event); } @@ -289,7 +289,7 @@ public void process(Integer deviceId, Context context, } // Geofence filter: reuse the already-parsed instant pointer. - if (GeneratedFunctions.edwithin_tgeo_geo(inst, geofence, geofenceDistMeters) != 1) continue; + if (GeneratedFunctions.edwithin_tgeo_geo(inst, geofence, geofenceDistMeters, true) != 1) continue; double speedMs = event.getGpsSpeed() * KMH_TO_MS; speedSumMs += speedMs; diff --git a/benchmark/src/main/java/sncbdata/Query6_Main.java b/benchmark/src/main/java/sncbdata/Query6_Main.java index c1ce913..9b83121 100644 --- a/benchmark/src/main/java/sncbdata/Query6_Main.java +++ b/benchmark/src/main/java/sncbdata/Query6_Main.java @@ -133,7 +133,7 @@ public String join(SNCBData left, SNCBData right) throws Exception { return null; } - double mindist = GeneratedFunctions.geog_distance(geoLeft, geoRight); + double mindist = GeneratedFunctions.geog_distance(geoLeft, geoRight, true); // Paper Line 5: lat > 0.0. if (left.getLat() <= 0.0 || right.getLat() <= 0.0) return null; diff --git a/benchmark/src/main/java/sncbdata/Query7_Main.java b/benchmark/src/main/java/sncbdata/Query7_Main.java index a0b0d61..4ba7f05 100644 --- a/benchmark/src/main/java/sncbdata/Query7_Main.java +++ b/benchmark/src/main/java/sncbdata/Query7_Main.java @@ -175,7 +175,7 @@ public void coGroup(Iterable leftEvents, Iterable rightEvent // Paper Line 2: device_id < device_id2 if (left.getDeviceId() >= right.getDeviceId()) continue; - double dist = GeneratedFunctions.geog_distance(geoLeft, geoRight); + double dist = GeneratedFunctions.geog_distance(geoLeft, geoRight, true); String key = left.getDeviceId() + ":" + right.getDeviceId(); if (!pairMap.containsKey(key) || dist < pairMap.get(key)[2]) { pairMap.put(key, new double[]{ diff --git a/benchmark/src/main/java/sncbdata/Query9_Main.java b/benchmark/src/main/java/sncbdata/Query9_Main.java index e61940c..3b13ead 100644 --- a/benchmark/src/main/java/sncbdata/Query9_Main.java +++ b/benchmark/src/main/java/sncbdata/Query9_Main.java @@ -177,7 +177,7 @@ public void coGroup(Iterable leftEvents, Iterable rightEvent // Paper Line 2: device_id != device_id2 if (left.getDeviceId() == right.getDeviceId()) continue; - double dist = GeneratedFunctions.geog_distance(geoLeft, geoRight); + double dist = GeneratedFunctions.geog_distance(geoLeft, geoRight, true); String key = left.getDeviceId() + "->" + right.getDeviceId(); if (!minDistMap.containsKey(key) || dist < minDistMap.get(key)[2]) { minDistMap.put(key, new double[]{ diff --git a/benchmark/src/test/java/berlinmod/BerlinMODSetSetJoinTest.java b/benchmark/src/test/java/berlinmod/BerlinMODSetSetJoinTest.java index 11f770f..72232a0 100644 --- a/benchmark/src/test/java/berlinmod/BerlinMODSetSetJoinTest.java +++ b/benchmark/src/test/java/berlinmod/BerlinMODSetSetJoinTest.java @@ -75,7 +75,7 @@ void eDwithinPairsMatchesScalarBaseline() { Set baseline = new HashSet<>(); for (int i = 0; i < trips.length; i++) for (int j = 0; j < trips.length; j++) - if (GeneratedFunctions.edwithin_tgeo_tgeo(trips[i], trips[j], MEET_DIST) == 1) + if (GeneratedFunctions.edwithin_tgeo_tgeo(trips[i], trips[j], MEET_DIST, true) == 1) baseline.add(((long) i << 32) | j); assertEquals(baseline, kernel, "set-set eDwithinPairs must equal the per-pair edwithin scalar"); // T0/T3 coincide and T1 crosses T0 — the join is non-empty. diff --git a/binding/src/main/java/org/mobilitydb/flink/meos/wirings/MeosCrossStreamJoin.java b/binding/src/main/java/org/mobilitydb/flink/meos/wirings/MeosCrossStreamJoin.java index f11c8b8..e4f6b36 100644 --- a/binding/src/main/java/org/mobilitydb/flink/meos/wirings/MeosCrossStreamJoin.java +++ b/binding/src/main/java/org/mobilitydb/flink/meos/wirings/MeosCrossStreamJoin.java @@ -63,7 +63,7 @@ * (left, right, ctx) -> { * Pointer leftT = left.toTGeoPointer(); * Pointer rightT = right.toTGeoPointer(); - * if (MeosOpsFreeGeo.edwithin_tgeo_tgeo(leftT, rightT, 100.0) != 0) { + * if (MeosOpsFreeGeo.edwithin_tgeo_tgeo(leftT, rightT, 100.0, true) != 0) { * return new MeetingEvent(left.id(), right.id(), ctx.getLeftTimestamp()); * } * return null; // no output for non-matches