Skip to content

Commit 4530fb7

Browse files
authored
[GH-2830] Improve Geography query support - core (#2831)
1 parent 3409826 commit 4530fb7

32 files changed

Lines changed: 1991 additions & 193 deletions

File tree

common/src/main/java/org/apache/sedona/common/S2Geography/Distance.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,22 @@
2424

2525
public class Distance {
2626

27+
/**
28+
* Compute distance from a single point to a ShapeIndex using PointTarget. This avoids building a
29+
* ShapeIndex for the point side — only the complex geometry needs an index.
30+
*/
31+
public static double S2_distancePointToIndex(S2Point point, ShapeIndexGeography geo) {
32+
S2ClosestEdgeQuery query = S2ClosestEdgeQuery.builder().build(geo.shapeIndex);
33+
S2ClosestEdgeQuery.PointTarget<S1ChordAngle> target =
34+
new S2ClosestEdgeQuery.PointTarget<>(point);
35+
Optional<S2BestEdgesQueryBase.Result> result = query.findClosestEdge(target);
36+
if (!result.isPresent()) {
37+
return Double.POSITIVE_INFINITY;
38+
}
39+
S1ChordAngle chordAngle = (S1ChordAngle) result.get().distance();
40+
return chordAngle.toAngle().radians();
41+
}
42+
2743
public double S2_distance(ShapeIndexGeography geo1, ShapeIndexGeography geo2) {
2844
S2ShapeIndex index1 = geo1.shapeIndex;
2945
S2ShapeIndex index2 = geo2.shapeIndex;

common/src/main/java/org/apache/sedona/common/S2Geography/GeographySerializer.java

Lines changed: 0 additions & 36 deletions
This file was deleted.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.sedona.common.S2Geography;
20+
21+
import java.io.IOException;
22+
import java.util.Arrays;
23+
import org.locationtech.jts.io.ByteOrderValues;
24+
25+
/**
26+
* Serializer for Geography objects using WKB as the primary format. Byte layout: [4-byte SRID
27+
* big-endian][WKB payload].
28+
*/
29+
public class GeographyWKBSerializer {
30+
31+
/** Header size: 4 bytes SRID. */
32+
private static final int HEADER_SIZE = 4;
33+
34+
/**
35+
* Serialize a Geography to bytes using WKB format.
36+
*
37+
* @param geog the Geography to serialize
38+
* @return byte array with format: [SRID 4 bytes big-endian][WKB payload]
39+
*/
40+
public static byte[] serialize(Geography geog) throws IOException {
41+
byte[] wkb;
42+
if (geog instanceof WKBGeography) {
43+
wkb = ((WKBGeography) geog).getWKBBytes();
44+
} else {
45+
WKBWriter writer = new WKBWriter(2, ByteOrderValues.BIG_ENDIAN, false);
46+
wkb = writer.write(geog);
47+
}
48+
49+
byte[] result = new byte[HEADER_SIZE + wkb.length];
50+
int srid = geog.getSRID();
51+
result[0] = (byte) (srid >> 24);
52+
result[1] = (byte) (srid >> 16);
53+
result[2] = (byte) (srid >> 8);
54+
result[3] = (byte) srid;
55+
System.arraycopy(wkb, 0, result, HEADER_SIZE, wkb.length);
56+
return result;
57+
}
58+
59+
/**
60+
* Deserialize bytes to a Geography using the WKB format.
61+
*
62+
* @param buffer the byte array to deserialize
63+
* @return the deserialized Geography
64+
*/
65+
public static Geography deserialize(byte[] buffer) throws IOException {
66+
int srid =
67+
((buffer[0] & 0xFF) << 24)
68+
| ((buffer[1] & 0xFF) << 16)
69+
| ((buffer[2] & 0xFF) << 8)
70+
| (buffer[3] & 0xFF);
71+
byte[] wkb = Arrays.copyOfRange(buffer, HEADER_SIZE, buffer.length);
72+
return WKBGeography.fromWKB(wkb, srid);
73+
}
74+
}

0 commit comments

Comments
 (0)