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

com.vividsolutions.jts.index.bintree.Bintree Maven / Gradle / Ivy

There is a newer version: 0.1.4
Show newest version

/*
 * The JTS Topology Suite is a collection of Java classes that
 * implement the fundamental operations required to validate a given
 * geo-spatial data set to a known topological specification.
 *
 * Copyright (C) 2001 Vivid Solutions
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * For more information, contact:
 *
 *     Vivid Solutions
 *     Suite #1A
 *     2328 Government Street
 *     Victoria BC  V8T 5G5
 *     Canada
 *
 *     (250)385-6040
 *     www.vividsolutions.com
 */
package com.vividsolutions.jts.index.bintree;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import com.vividsolutions.jts.geom.Envelope;

/**
 * An BinTree (or "Binary Interval Tree")
 * is a 1-dimensional version of a quadtree.
 * It indexes 1-dimensional intervals (which may
 * be the projection of 2-D objects on an axis).
 * It supports range searching
 * (where the range may be a single point).
 * This structure is dynamic - 
 * new items can be added at any time,   
 * and it will support deletion of items 
 * (although this is not currently implemented).
 * 

* This implementation does not require specifying the extent of the inserted * items beforehand. It will automatically expand to accomodate any extent * of dataset. *

* The bintree structure is used to provide a primary filter * for interval queries. The query() method returns a list of * all objects which may intersect the query interval. * Note that it may return objects which do not in fact intersect. * A secondary filter is required to test for exact intersection. * Of course, this secondary filter may consist of other tests besides * intersection, such as testing other kinds of spatial relationships. *

* This index is different to the Interval Tree of Edelsbrunner * or the Segment Tree of Bentley. * * @version 1.7 */ public class Bintree { /** * Ensure that the Interval for the inserted item has non-zero extents. * Use the current minExtent to pad it, if necessary */ public static Interval ensureExtent(Interval itemInterval, double minExtent) { double min = itemInterval.getMin(); double max = itemInterval.getMax(); // has a non-zero extent if (min != max) return itemInterval; // pad extent if (min == max) { min = min - minExtent / 2.0; max = min + minExtent / 2.0; } return new Interval(min, max); } private Root root; /** * Statistics * * minExtent is the minimum extent of all items * inserted into the tree so far. It is used as a heuristic value * to construct non-zero extents for features with zero extent. * Start with a non-zero extent, in case the first feature inserted has * a zero extent in both directions. This value may be non-optimal, but * only one feature will be inserted with this value. **/ private double minExtent = 1.0; public Bintree() { root = new Root(); } public int depth() { if (root != null) return root.depth(); return 0; } public int size() { if (root != null) return root.size(); return 0; } /** * Compute the total number of nodes in the tree * * @return the number of nodes in the tree */ public int nodeSize() { if (root != null) return root.nodeSize(); return 0; } public void insert(Interval itemInterval, Object item) { collectStats(itemInterval); Interval insertInterval = ensureExtent(itemInterval, minExtent); //int oldSize = size(); root.insert(insertInterval, item); /* DEBUG int newSize = size(); System.out.println("BinTree: size = " + newSize + " node size = " + nodeSize()); if (newSize <= oldSize) { System.out.println("Lost item!"); root.insert(insertInterval, item); System.out.println("reinsertion size = " + size()); } */ } /** * Removes a single item from the tree. * * @param itemEnv the Envelope of the item to be removed * @param item the item to remove * @return true if the item was found (and thus removed) */ public boolean remove(Interval itemInterval, Object item) { Interval insertInterval = ensureExtent(itemInterval, minExtent); return root.remove(insertInterval, item); } public Iterator iterator() { List foundItems = new ArrayList(); root.addAllItems(foundItems); return foundItems.iterator(); } public List query(double x) { return query(new Interval(x, x)); } /** * Queries the tree to find all candidate items which * may overlap the query interval. * If the query interval is null, all items in the tree are found. * * min and max may be the same value */ public List query(Interval interval) { /** * the items that are matched are all items in intervals * which overlap the query interval */ List foundItems = new ArrayList(); query(interval, foundItems); return foundItems; } /** * Adds items in the tree which potentially overlap the query interval * to the given collection. * If the query interval is null, add all items in the tree. * * @param interval a query nterval, or null * @param resultItems the candidate items found */ public void query(Interval interval, Collection foundItems) { root.addAllItemsFromOverlapping(interval, foundItems); } private void collectStats(Interval interval) { double del = interval.getWidth(); if (del < minExtent && del > 0.0) minExtent = del; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy