Repository navigation
Geo spatial interfaces - #16029
Geo spatial interfaces#16029
Conversation
| Assert.assertFalse(bound.containsDouble(geoPoint)); | ||
| float[] floatPoint = new float[]{ | ||
| Float.parseFloat(String.valueOf(geoPoint[0])), // this is how legacy sptial index | ||
| Float.parseFloat(String.valueOf(geoPoint[1])) |
Check notice
Code scanning / CodeQL
Missing catch of NumberFormatException
|
Can you please take look at this? |
| Assert.assertTrue(distance < circleRadius); | ||
| Assert.assertTrue(bound.containsDouble(geoPoint)); | ||
| float[] floatPoint = new float[]{ | ||
| Float.parseFloat(String.valueOf(geoPoint[0])), |
Check notice
Code scanning / CodeQL
Missing catch of NumberFormatException
| Assert.assertTrue(haversineDistance > circleRadius); // asserts that point is outside | ||
| Assert.assertFalse(bound.containsDouble(geoPoint)); | ||
| float[] floatPoint = new float[]{ | ||
| Float.parseFloat(String.valueOf(geoPoint[0])), |
Check notice
Code scanning / CodeQL
Missing catch of NumberFormatException
| double lat1 = coord1[0]; | ||
| double lon1 = coord1[1]; | ||
| double lat2 = coord2[0]; | ||
| double lon2 = coord2[1]; |
There was a problem hiding this comment.
nit: maybe just inline these in the next 4 double declarations since they aren't used separately
(also a lot of these could be marked final)
| import org.apache.druid.collections.spatial.hp.ImmutableDoublePoint; | ||
|
|
||
| /** | ||
| * |
There was a problem hiding this comment.
nit: maybe either add real javadoc or delete this
| /** | ||
| * An immutable representation of an {@link RTree} for spatial indexing. | ||
| */ | ||
| public final class ImmutableRTree32BitImpl implements ImmutableRTree |
There was a problem hiding this comment.
nit: how about ImmutableFloatRTree? or this is fine too, naming things is the worst
48f71dd to
f827ea7
Compare
| Assert.assertTrue(bound.contains(geoPoint)); | ||
| float[] floatPoint = new float[]{ | ||
| Float.parseFloat(String.valueOf(geoPoint[0])), | ||
| Float.parseFloat(String.valueOf(geoPoint[1])) |
Check notice
Code scanning / CodeQL
Missing catch of NumberFormatException
| } | ||
|
|
||
| @Test | ||
| public void testDeSerForDoubleArrays() throws JsonProcessingException |
There was a problem hiding this comment.
nit: test name is stale i guess. Also instead of doing it with a string, it would be nicer to make a RectangularBound serialize it to string, and then deserialize back to an object to make sure round tripping works ok
| @JsonProperty("radius") float radius, | ||
| @JsonProperty("limit") int limit | ||
| @JsonProperty("limit") int limit, | ||
| @JsonProperty("radiusUnit") RadiusUnit radiusUnit |
There was a problem hiding this comment.
should probably add a serde test to RadiusBoundTest with the new parameter. also it should be marked @Nullable
There was a problem hiding this comment.
added more tests for nullable
abhishekagarwal87
left a comment
There was a problem hiding this comment.
Minor comments but not a blocker so I will merge the PR.
| this.childrenOffset = initialOffset | ||
| + offsetFromInitial | ||
| + HEADER_NUM_BYTES | ||
| + 2 * numDims * Float.BYTES | ||
| + Integer.BYTES | ||
| + bitmapSize; |
There was a problem hiding this comment.
| this.childrenOffset = initialOffset | |
| + offsetFromInitial | |
| + HEADER_NUM_BYTES | |
| + 2 * numDims * Float.BYTES | |
| + Integer.BYTES | |
| + bitmapSize; | |
| this.childrenOffset = sizePosition | |
| + Integer.BYTES | |
| + bitmapSize; |
| final int sizePosition = initialOffset + offsetFromInitial + HEADER_NUM_BYTES + 2 * numDims * Float.BYTES; | ||
| int bitmapSize = data.getInt(sizePosition); | ||
| this.childrenOffset = initialOffset | ||
| + offsetFromInitial | ||
| + HEADER_NUM_BYTES | ||
| + 2 * numDims * Float.BYTES | ||
| + Integer.BYTES | ||
| + bitmapSize; | ||
|
|
||
| this.data = data; |
There was a problem hiding this comment.
| final int sizePosition = initialOffset + offsetFromInitial + HEADER_NUM_BYTES + 2 * numDims * Float.BYTES; | |
| int bitmapSize = data.getInt(sizePosition); | |
| this.childrenOffset = initialOffset | |
| + offsetFromInitial | |
| + HEADER_NUM_BYTES | |
| + 2 * numDims * Float.BYTES | |
| + Integer.BYTES | |
| + bitmapSize; | |
| this.data = data; | |
| this(numDims, initialOffset, offsetFromInitial, numChildren, leaf, data, bitmapFactory) |
There was a problem hiding this comment.
This does not work as this( ) calls needs to first statement. I just renamed the class here with no other changes.
| import java.util.Iterator; | ||
|
|
||
| /** | ||
| * Byte layout: |
There was a problem hiding this comment.
What is the child here and what is the dim?
There was a problem hiding this comment.
Nums of dims = size of float array, needs it here esp for byte layout. Child here in byte layout represents the child node stored at the childOffeset
this.childrenOffset = initialOffset
+ offsetFromInitial
+ HEADER_NUM_BYTES
+ 2 * numDims * Float.BYTES
+ Integer.BYTES
+ bitmapSize;
| { | ||
| private static Random random = ThreadLocalRandom.current(); | ||
|
|
||
| public static float[][] generateGeoCoordinatesAroundCircle( |
There was a problem hiding this comment.
since its only used in test, the method should be moved to test code
There was a problem hiding this comment.
it is already in test package.
This PR creates an interface for ImmutableRTree and moved the existing implementation to new class which represent 32 bit implementation (stores coordinate as floats). This PR makes the ImmutableRTree extendable to create higher precision implementation as well (64 bit). In all spatial bound filters, we accept float as input which might not be accurate in the case of high precision implementation of ImmutableRTree. This PR changed the bound filters to accepts the query bounds as double instead of float and it is backward compatible change as it compares double to existing float values in RTree. Previously it was comparing input float to RTree floats which can cause precision loss, now it is little better as it compares double to float which is still not 100% accurate. There are no changes in the way that we query spatial dimension today except input bound parsing. There is little improvement in string filter predicate which now parse double strings instead of float and compares double to double which is 100% accurate but string predicate is only called when we dont have spatial index. With allowing the interface to extend ImmutableRTree, we allow to create high precision (HP) implementation and defines new search strategies to perform HP search Iterable<ImmutableBitmap> search(ImmutableDoubleNode node, Bound bound); With possible HP implementations, Radius bound filter can not really focus on accuracy, it is calculating Euclidean distance in comparing. As EARTH 🌍 is round and not flat, Euclidean distances are not accurate in geo system. This PR adds new param called 'radiusUnit' which allows you to specify units like meters, km, miles etc. It uses https://en.wikipedia.org/wiki/Haversine_formula to check if given geo point falls inside circle or not. Added a test that generates set of points inside and outside in RadiusBoundTest.
Description
Iterable<ImmutableBitmap> search(ImmutableDoubleNode node, Bound bound);PR is fully backward compatible. Let me know if you have any questions.
Release Notes:
Adding radiusUnit in Radius Bound filter. radiusUnit : String value of radius unit in lowercase, default value is 'euclidean'. Allowed units are euclidean, meters, miles, kilometers.This PR has: