/** * Gets all objects within a certain distance around x/y * * @param x left-right location, longitude * @param y up-down location, latitude * @param distance the maximal distance returned objects can be away from x/y * @return the objects found within distance to x/y */ public Collection<T> getDisk(final double x, final double y, final double distance) { return this.top.get(x, y, distance, new ArrayList<>()); }
/** * Gets all objects within a linear ring (including borders). * * Note by JI (sept '15): This method can be significant faster than calling {@link #getDisk(double, double, double)} * and a manual check on the returned elements for >= r_min. For randomly distributed points one can use the * following rule-of-thumb: if r_min/r_max > 0.4 this method is likely to be faster than retrieving all elements within r_max. * * @param x left-right location, longitude * @param y up-down location, latitude * @param r_min inner ring radius * @param r_max outer rind radius * @return objects within the ring */ public Collection<T> getRing(final double x, final double y, final double r_min, final double r_max) { return this.top.get(x, y, r_min, r_max, new ArrayList<>()); }
/* default */ Collection<T> get(final double x, final double y, final double maxDistance, final Collection<T> values) { if (this.hasChilds) { if (this.northwest.bounds.calcDistance(x, y) <= maxDistance) { this.northwest.get(x, y, maxDistance, values); this.northeast.get(x, y, maxDistance, values); this.southeast.get(x, y, maxDistance, values); this.southwest.get(x, y, maxDistance, values);
Node<T> bestChild = this.getChild(x, y); if (bestChild != null) { closest = bestChild.get(x, y, bestDistance); T value = this.northwest.get(x, y, bestDistance); if (value != null) { closest = value; } T value = this.northeast.get(x, y, bestDistance); if (value != null) { closest = value; } T value = this.southeast.get(x, y, bestDistance); if (value != null) { closest = value; } T value = this.southwest.get(x, y, bestDistance); if (value != null) { closest = value; }
/* default */ Collection<T> get(final Rect bounds, final Collection<T> values) { if (this.hasChilds) { if (this.northwest.bounds.intersects(bounds)) { this.northwest.get(bounds, values); } if (this.northeast.bounds.intersects(bounds)) { this.northeast.get(bounds, values); } if (this.southeast.bounds.intersects(bounds)) { this.southeast.get(bounds, values); } if (this.southwest.bounds.intersects(bounds)) { this.southwest.get(bounds, values); } return values; } // no more childs, so we must contain the closest object if (this.leaves != null) { for (Leaf<T> leaf : this.leaves) { if (bounds.containsOrEquals(leaf.x, leaf.y)) { if (leaf.value != null) { values.add(leaf.value); } else { values.addAll(leaf.values); } } } } return values; }
/** * Gets the object closest to x/y * * @param x easting, left-right location, longitude * @param y northing, up-down location, latitude * @return the object found closest to x/y */ public T getClosest(final double x, final double y) { return this.top.get(x, y, new MutableDouble(Double.POSITIVE_INFINITY)); }
/** * Gets all objects inside the specified boundary. Objects on the border of the * boundary are not included. * * @param bounds The bounds of the area of interest. * @param values1 A collection to store the found objects in. * @return The objects found within the area. */ public Collection<T> getRectangle(final Rect bounds, final Collection<T> values1) { return this.top.get(bounds, values1); }
private void stepInto(Node node, double x, double y, double r_min, double r_max, Collection<T> values) { double minDistance = node.bounds.calcDistance(x, y); double maxDistance = node.bounds.calcMaxDistance(x, y); if(minDistance <= r_max && maxDistance >= r_min) { node.get(x, y, r_min, r_max, values); } }