All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.conversantmedia.util.collection.spatial.RTree Maven / Gradle / Ivy

package com.conversantmedia.util.collection.spatial;

/*
 * #%L
 * Conversant RTree
 * ~~
 * Conversantmedia.com © 2016, Conversant, Inc. Conversant® is a trademark of Conversant, Inc.
 * ~~
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import java.util.function.Consumer;

/**
 * 

Data structure to make range searching more efficient. Indexes multi-dimensional information * such as geographical coordinates or rectangles. Groups information and represents them with a * minimum bounding rectangle (mbr). When searching through the tree, any query that does not * intersect an mbr can ignore any data entries in that mbr.

*

More information can be @see https://en.wikipedia.org/wiki/R-tree

*

* Created by jcairns on 4/30/15.

*/ public final class RTree implements SpatialSearch { private static final double EPSILON = 1e-12; private final int mMin; private final int mMax; private final RectBuilder builder; private Node root; private Split splitType; private int entryCount; protected RTree(final RectBuilder builder, final int mMin, final int mMax, final Split splitType) { this.mMin = mMin; this.mMax = mMax; this.builder = builder; this.splitType = splitType; this.entryCount = 0; root = Leaf.create(builder, mMin, mMax, splitType); } @Override public int search(final HyperRect rect, final T[] t) { return root.search(rect, t, 0); } @Override public void add(final T t) { root = root.add(t); entryCount++; } @Override public void remove(final T t) { Node removed = root.remove(t); if (removed != null) { entryCount--; } } @Override public void update(final T told, final T tnew) { root.update(told, tnew); } /** * returns whether or not the HyperRect will enclose all of the data entries in t * * @param rect HyperRect to contain entries * @param t Data entries to be evaluated * @return Whether or not all entries lie inside rect */ public boolean contains(final HyperRect rect, final T[] t) { for (int i = 0; i < t.length; i++) { if (!rect.contains(builder.getBBox(t[i]))) { return false; } } return true; } /** * @return number of data entries stored in the RTree */ public int getEntryCount() { return entryCount; } final static boolean isEqual(final double a, final double b) { return isEqual(a, b, EPSILON); } final static boolean isEqual(final double a, final double b, final double eps) { return Math.abs(a - b) <= ((Math.abs(a) < Math.abs(b) ? Math.abs(b) : Math.abs(a)) * eps); } public void forEach(Consumer consumer) { root.forEach(consumer); } public void forEach(Consumer consumer, HyperRect rect) { root.forEach(consumer, rect); } void instrumentTree() { root = root.instrument(); ((CounterNode) root).searchCount = 0; ((CounterNode) root).bboxEvalCount = 0; } public Stats collectStats() { Stats stats = new Stats(); stats.setType(splitType); stats.setMaxFill(mMax); stats.setMinFill(mMin); root.collectStats(stats, 0); return stats; } public Node getRoot() { return this.root; } /** * Different methods for splitting nodes in an RTree. * AXIAL has been shown to give the best performance and should be used * in the AdServer *

* Created by ewhite on 10/28/15. */ public enum Split { AXIAL, LINEAR, QUADRATIC, } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy