Skip to content

Commit

Permalink
Enhancements in NN search.
Browse files Browse the repository at this point in the history
  • Loading branch information
thegeekyasian committed Feb 13, 2023
1 parent 3db6ce0 commit f81b8c1
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 27 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

<groupId>com.thegeekyasian</groupId>
<artifactId>geo-assist</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>

<distributionManagement>
<snapshotRepository>
Expand Down
70 changes: 44 additions & 26 deletions src/main/java/com/thegeekyasian/geoassist/kdtree/KDTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,44 +83,62 @@ public List<KDTreeObject<T, O>> findNearestNeighbor(Point point, double distance
// Initialize a list to store the closest points
List<KDTreeObject<T, O>> closestPoints = new ArrayList<>();
// Call the recursive helper method with the root node, point, distance, and closestPoints list
findNearestNeighbor(root, point, distance, closestPoints);
findNearestNeighbor(root, point, distance, closestPoints, 0);
// Return the list of closest points
return closestPoints;
}

private void findNearestNeighbor(Node node, Point point, double distance, List<KDTreeObject<T, O>> closestPoints) {
private void findNearestNeighbor(Node node, Point point, double distance, List<KDTreeObject<T, O>> closestPoints, int depth) {
if (node == null) {
return;
}

// calculate the haversine distance between the current node's point and the given point
double currentDistance = getHaversineDistance(node.getKdTreeObject().getPoint(), point);

// if the current distance is less than or equal to the provided distance
// add the current node's point to the closestPoints list
if (currentDistance <= distance) {
closestPoints.add(node.getKdTreeObject());
}

// compare the latitude of the given point and the current node's point
// if the latitude of the given point is less than the current node's point, search the left subtree
if (point.getLatitude() < node.getKdTreeObject().getPoint().getLatitude()) {
findNearestNeighbor(node.left, point, distance, closestPoints);
// Determine which dimension to compare based on the depth of the current node in the K-d tree
int dim = depth % 2;

// check if the difference in latitudes is less than or equal to the provided distance
// if so, also search the right subtree
if (Math.abs(point.getLatitude() - node.getKdTreeObject().getPoint().getLatitude()) <= distance) {
findNearestNeighbor(node.right, point, distance, closestPoints);
}
}
// if the latitude of the given point is greater than or equal to the current node's point, search the right subtree
else {
findNearestNeighbor(node.right, point, distance, closestPoints);
// If the `dim`-th coordinate of the input point is less than the `dim`-th coordinate of the current node's point,
// continue searching in the left subtree and check if the absolute difference between the `dim`-th coordinates
// is less than or equal to the maximum distance
if (dim == 0) {
if (point.getLatitude() < node.getKdTreeObject().getPoint().getLatitude()) {
findNearestNeighbor(node.left, point, distance, closestPoints, depth + 1);

// check if the difference in latitudes is less than or equal to the provided distance
// if so, also search the right subtree
if (node.right != null && Math.abs(node.getKdTreeObject().getPoint().getLatitude() - point.getLatitude()) <= distance) {
findNearestNeighbor(node.right, point, distance, closestPoints, depth + 1);
}
} else {
// If the `dim`-th coordinate of the input point is greater than or equal to the `dim`-th coordinate of the current node's point,
// continue searching in the right subtree and check if the absolute difference between the `dim`-th coordinates
// is less than or equal to the maximum distance
findNearestNeighbor(node.right, point, distance, closestPoints, depth + 1);

// check if the difference in latitudes is less than or equal to the provided distance
// if so, also search the left subtree
if (Math.abs(point.getLatitude() - node.getKdTreeObject().getPoint().getLatitude()) <= distance) {
findNearestNeighbor(node.left, point, distance, closestPoints);
// check if the difference in latitudes is less than or equal to the provided distance
// if so, also search the left subtree
if (node.left != null && Math.abs(node.getKdTreeObject().getPoint().getLatitude() - point.getLatitude()) <= distance) {
findNearestNeighbor(node.left, point, distance, closestPoints, depth + 1);
}
}
} else {
// using the same logic as above but for longitude i.e. the second dimension.
if (point.getLongitude() < node.getKdTreeObject().getPoint().getLongitude()) {
findNearestNeighbor(node.left, point, distance, closestPoints, depth + 1);
if (node.right != null && Math.abs(node.getKdTreeObject().getPoint().getLongitude() - point.getLongitude()) <= distance) {
findNearestNeighbor(node.right, point, distance, closestPoints, depth + 1);
}
}
else {
findNearestNeighbor(node.right, point, distance, closestPoints, depth + 1);
if (node.left != null && Math.abs(node.getKdTreeObject().getPoint().getLongitude() - point.getLongitude()) <= distance) {
findNearestNeighbor(node.left, point, distance, closestPoints, depth + 1);
}
}
}
}
Expand Down Expand Up @@ -175,10 +193,10 @@ public void update(T id, O data) {
* */
public boolean delete(T id) {
return Optional.ofNullable(map.get(id)).map(node -> {
deleteNode(node);
map.remove(id);
return true;
}).orElse(false);
deleteNode(node);
map.remove(id);
return true;
}).orElse(false);
}

private void deleteNode(Node node) {
Expand Down

0 comments on commit f81b8c1

Please sign in to comment.