Package org.geotools.geometry.iso.index.quadtree

Source Code of org.geotools.geometry.iso.index.quadtree.Node

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*   
*    (C) 2001-2006  Vivid Solutions
*    (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
*   
*    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;
*    version 2.1 of the License.
*
*    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.
*/
package org.geotools.geometry.iso.index.quadtree;

import org.geotools.geometry.iso.topograph2D.Coordinate;
import org.geotools.geometry.iso.topograph2D.Envelope;
import org.geotools.geometry.iso.util.Assert;

/**
* Represents a node of a {@link Quadtree}. Nodes contain items which have a
* spatial extent corresponding to the node's position in the quadtree.
*
*
*
*
*
* @source $URL$
* @version 1.7.2
*/
public class Node extends NodeBase {
  public static Node createNode(Envelope env) {
    Key key = new Key(env);
    Node node = new Node(key.getEnvelope(), key.getLevel());
    return node;
  }

  public static Node createExpanded(Node node, Envelope addEnv) {
    Envelope expandEnv = new Envelope(addEnv);
    if (node != null)
      expandEnv.expandToInclude(node.env);

    Node largerNode = createNode(expandEnv);
    if (node != null)
      largerNode.insertNode(node);
    return largerNode;
  }

  private Envelope env;

  private Coordinate centre;

  private int level;

  public Node(Envelope env, int level) {
    // this.parent = parent;
    this.env = env;
    this.level = level;
    centre = new Coordinate();
    centre.x = (env.getMinX() + env.getMaxX()) / 2;
    centre.y = (env.getMinY() + env.getMaxY()) / 2;
  }

  public Envelope getEnvelope() {
    return env;
  }

  protected boolean isSearchMatch(Envelope searchEnv) {
    return env.intersects(searchEnv);
  }

  /**
   * Returns the subquad containing the envelope. Creates the subquad if it
   * does not already exist.
   */
  public Node getNode(Envelope searchEnv) {
    int subnodeIndex = getSubnodeIndex(searchEnv, centre);
    // if subquadIndex is -1 searchEnv is not contained in a subquad
    if (subnodeIndex != -1) {
      // create the quad if it does not exist
      Node node = getSubnode(subnodeIndex);
      // recursively search the found/created quad
      return node.getNode(searchEnv);
    } else {
      return this;
    }
  }

  /**
   * Returns the smallest <i>existing</i> node containing the envelope.
   */
  public NodeBase find(Envelope searchEnv) {
    int subnodeIndex = getSubnodeIndex(searchEnv, centre);
    if (subnodeIndex == -1)
      return this;
    if (subnode[subnodeIndex] != null) {
      // query lies in subquad, so search it
      Node node = subnode[subnodeIndex];
      return node.find(searchEnv);
    }
    // no existing subquad, so return this one anyway
    return this;
  }

  void insertNode(Node node) {
    Assert.isTrue(env == null || env.contains(node.env));
    // System.out.println(env);
    // System.out.println(quad.env);
    int index = getSubnodeIndex(node.env, centre);
    // System.out.println(index);
    if (node.level == level - 1) {
      subnode[index] = node;
      // System.out.println("inserted");
    } else {
      // the quad is not a direct child, so make a new child quad to
      // contain it
      // and recursively insert the quad
      Node childNode = createSubnode(index);
      childNode.insertNode(node);
      subnode[index] = childNode;
    }
  }

  /**
   * get the subquad for the index. If it doesn't exist, create it
   */
  private Node getSubnode(int index) {
    if (subnode[index] == null) {
      subnode[index] = createSubnode(index);
    }
    return subnode[index];
  }

  private Node createSubnode(int index) {
    // create a new subquad in the appropriate quadrant

    double minx = 0.0;
    double maxx = 0.0;
    double miny = 0.0;
    double maxy = 0.0;

    switch (index) {
    case 0:
      minx = env.getMinX();
      maxx = centre.x;
      miny = env.getMinY();
      maxy = centre.y;
      break;
    case 1:
      minx = centre.x;
      maxx = env.getMaxX();
      miny = env.getMinY();
      maxy = centre.y;
      break;
    case 2:
      minx = env.getMinX();
      maxx = centre.x;
      miny = centre.y;
      maxy = env.getMaxY();
      break;
    case 3:
      minx = centre.x;
      maxx = env.getMaxX();
      miny = centre.y;
      maxy = env.getMaxY();
      break;
    }
    Envelope sqEnv = new Envelope(minx, maxx, miny, maxy);
    Node node = new Node(sqEnv, level - 1);
    return node;
  }

}
TOP

Related Classes of org.geotools.geometry.iso.index.quadtree.Node

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.