Package org.geotools.graph.build.line

Source Code of org.geotools.graph.build.line.OptLineGraphGenerator

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2002-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.graph.build.line;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.geotools.graph.build.GraphBuilder;
import org.geotools.graph.build.GraphGenerator;
import org.geotools.graph.structure.Edge;
import org.geotools.graph.structure.Graph;
import org.geotools.graph.structure.Graphable;
import org.geotools.graph.structure.Node;
import org.geotools.graph.structure.line.OptXYNode;
import org.geotools.graph.structure.opt.OptEdge;
import org.geotools.graph.structure.opt.OptNode;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.LineSegment;

/**
* An implementation of GraphGenerator used to generate an optimized graph
* representing a line network. Graphs are generated by supplying the generator
* with objects of type LineSegment via the add(Object) method. <BR>
* <BR>
* For each line segment added, an edge in the graph is created. The builder
* records the end coordinates of each line added, and maintains a map of
* coordinates to nodes, creating nodes when neccessary.<BR>
* <BR>
* Edges created by the generator are of type OptBasicEdge.<BR>
* Nodes created by the generator are of type OptXYNode. <BR>
* <BR>
* Since building optimized graphs requires knowing the degree of nodes before
* creating them, the physical construction of the graph is delayed until a call
* to generate() is made. No component is created with a call to add(Object),
* only information about the object is recorded.
*
* @see org.geotools.graph.structure.opt.OptEdge
* @see org.geotools.graph.structure.line.OptXYNode
*
* @author Justin Deoliveira, Refractions Research Inc, jdeolive@refractions.net
*
*
*
* @source $URL$
*/
public class OptLineGraphGenerator implements LineGraphGenerator {

  /** coordinate to node / count **/
  private HashMap m_coord2count;
 
  /** lines added to the network **/
  private ArrayList m_lines;
 
  /** underlying builder **/
  private GraphBuilder m_builder;
 
  /**
   * Constructs a new OptLineGraphGenerator.
   */
  public OptLineGraphGenerator() {
    m_coord2count = new HashMap()
    m_lines = new ArrayList();
    setGraphBuilder(new OptLineGraphBuilder());
  }
 
  /**
   * Adds a line to the graph. Note that this method returns null since actual
   * building of the graph components is delayed until generate() is called.
   *
   * @param obj A LineSegment object.
   *
   * @return null because the actual building of the graph components is delayed
   *         until generate() is called.
   */
  public Graphable add(Object obj) {
    LineSegment line = (LineSegment)obj;
    Integer count;
   
    //update count of first coordinate
    if ((count = (Integer)m_coord2count.get(line.p0)) == null) {
      m_coord2count.put(line.p0, new Integer(1));
    }
    else m_coord2count.put(line.p0, new Integer(count.intValue()+1));
   
    //update count of second coordinate
    if ((count = (Integer)m_coord2count.get(line.p1)) == null) {
      m_coord2count.put(line.p1, new Integer(1));
    }
    else m_coord2count.put(line.p1, new Integer(count.intValue()+1));
  
    //hold onto a reference to the line
    m_lines.add(line);
   
    //return null, no componenets created
    return(null);
  }

  /**
   * Returns the edge which represents a line. This method must be called
   * after the call to generate(). Note that if the exact same line
   * has been added to the graph multiple times, then only one of the edges
   * that represents it will be returned. It is undefined which edge will be
   * returned.
   *
   * @param obj An instance of LineSegment.
   *
   * @return Edge that represents the line.
   *
   * @see GraphGenerator#get(Object)
   */
  public Graphable get(Object obj) {
    LineSegment line = (LineSegment)obj;
   
    Node n1 = (Node)m_coord2count.get(line.p0);
    Node n2 = (Node)m_coord2count.get(line.p0);
   
    return(n1.getEdge(n2));
   
    //note: if there are identical lines in the graph then it is undefined
    //which of them will be returned
  }

  /**
   * Unsupported operation.
   *
   * @throws UnsupportedOperationException
   */
  public Graphable remove(Object obj) {
    throw new UnsupportedOperationException(
      getClass().getName() + "#remove(Object)"
    );
  }

  /**
   * @see GraphGenerator#setGraphBuilder(GraphBuilder)
   */
  public void setGraphBuilder(GraphBuilder builder) {
    m_builder = builder;
  }

  /**
   * @see GraphGenerator#getGraphBuilder()
   */
  public GraphBuilder getGraphBuilder() {
    return(m_builder);
  }

  /**
   * @see GraphGenerator#getGraph()
   */
  public Graph getGraph() {
    return(m_builder.getGraph());
  }
 
  /**
   * Performs the actual generation of the graph.
   */
  public void generate() {
    generateNodes();
    generateEdges();
  }
 
  /**
   * Returns the coordinate to node map. Note that before the call to generate
   * the map does not contain any nodes.
   *
   * @return Coordinate to node map.
   */
  public Map getNodeMap() {
    return(m_coord2count)
  }
 
  /**
   * Returns the lines added to the graph.
   *
   * @return A list of LineSegment objects.
   */
  protected List getLines() {
    return(m_lines)
  }
 
 
  protected void generateNodes() {
    //create nodes from coordiante counts
    for (Iterator itr = m_coord2count.entrySet().iterator(); itr.hasNext();) {
      Map.Entry entry = (Map.Entry)itr.next();
      Coordinate coord = (Coordinate)entry.getKey();
      Integer count = (Integer)entry.getValue();
     
      OptXYNode node = (OptXYNode)m_builder.buildNode();
      node.setDegree(count.intValue());
      node.setCoordinate(coord);
     
      m_builder.addNode(node);
     
      entry.setValue(node);
    }
  }
 
  protected void generateEdges() {
    //relate nodes
    for (Iterator itr = m_lines.iterator(); itr.hasNext();) {
      LineSegment line = (LineSegment)itr.next();
      generateEdge(line);
    }
  }
 
  protected Edge generateEdge(LineSegment line) {
    OptNode n1 = (OptNode)m_coord2count.get(line.p0);
    OptNode n2 = (OptNode)m_coord2count.get(line.p1);
   
    OptEdge edge = (OptEdge)m_builder.buildEdge(n1,n2);
    m_builder.addEdge(edge);
   
    return(edge)
  }

  //TODO DOCUMENT ME!
  public Node getNode(Coordinate c) {
    return((Node)m_coord2count.get(c));
   
  }

  public Edge getEdge(Coordinate c1, Coordinate c2) {
    Node n1 = (Node)m_coord2count.get(c1);
    Node n2 = (Node)m_coord2count.get(c2);
   
    return(n1.getEdge(n2))
  }
}
TOP

Related Classes of org.geotools.graph.build.line.OptLineGraphGenerator

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.