/* * 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.HashMap; import java.util.Map; import org.geotools.graph.build.GraphBuilder; import org.geotools.graph.build.GraphGenerator; import org.geotools.graph.build.basic.BasicGraphBuilder; 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 com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.LineSegment; /** * An implementation of GraphGenerator used to generate a 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 BasicEdge and contain an object * of type LineSegment.<BR> * Nodes created by the generator are of type BasicXYNode and contain an object * of type Coordinate. * * @see org.geotools.graph.structure.line.BasicXYNode * @see org.geotools.graph.structure.basic.BasicEdge * @see com.vividsolutions.jts.geom.LineSegment * @see com.vividsolutions.jts.geom.Coordinate * * @author Justin Deoliveira, Refractions Research Inc, jdeolive@refractions.net * * * @source $URL$ */ public class BasicLineGraphGenerator implements LineGraphGenerator { /** coordinate to node map **/ private HashMap m_coord2node; /** underlying builder **/ private GraphBuilder m_builder; /** * Constructs a new BasicLineGraphGenerator. */ public BasicLineGraphGenerator () { m_coord2node = new HashMap(); setGraphBuilder(new BasicGraphBuilder()); } /** * Adds a line to the graph. * * @param obj An instance of LineSegment. * * @return A BasicEdge. * * @see LineSegment * @see GraphGenerator#add(Object) */ public Graphable add(Object obj) { LineSegment line = (LineSegment)obj; Coordinate c; Node n1, n2; //check first coordinate c = line.p0; if ((n1 = (Node)m_coord2node.get(c)) == null) { //first time coordinate seen, create node for it n1 = getGraphBuilder().buildNode(); //set underlying object to coordinate //n1.setObject(c); setObject(n1, c); getGraphBuilder().addNode(n1); m_coord2node.put(c,n1); } //check second coordinate c = line.p1; if ((n2 = (Node)m_coord2node.get(c)) == null) { //first time coordinate seen, create node for it n2 = getGraphBuilder().buildNode(); //set underlying object to coordiante //n2.setObject(c); setObject(n2,c); getGraphBuilder().addNode(n2); m_coord2node.put(c,n2); } //build the edge setting underlying object to line Edge e = getGraphBuilder().buildEdge(n1,n2); //e.setObject(line); setObject(e, line); getGraphBuilder().addEdge(e); //return the created edge return(e); } /** * Returns the edge which represents a line. 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; //get nodes representing coordinate Node n1 = (Node)m_coord2node.get(line.p0); Node n2 = (Node)m_coord2node.get(line.p1); if (n1 == null || n2 == null) return(null); //return edge shared between them return(n1.getEdge(n2)); //note: if there are identical lines in the graph then it is undefined //which of them will be returned } /** * Removes the edge from the graph that represents a line. * * @return Edge that represents the line. * * @see GraphGenerator#remove(Object) */ public Graphable remove(Object obj) { LineSegment line = (LineSegment)obj; Node n1 = (Node)m_coord2node.get(line.p0); Node n2 = (Node)m_coord2node.get(line.p1); if (n1 == null || n2 == null) return(null); Edge e = (Edge)n1.getEdge(n2); getGraphBuilder().removeEdge(e); return(e); } /** * @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(getGraphBuilder().getGraph()); } /** * Returns the coordinate to node map used to build nodes representing line * endpoint coordinates. * * @return coordinate to ndoe map. */ public Map getNodeMap() { return(m_coord2node); } //TODO COMMENT ME! public Node getNode(Coordinate c) { return((Node)m_coord2node.get(c)); } public Edge getEdge(Coordinate c1, Coordinate c2) { Node n1 = (Node)m_coord2node.get(c1); Node n2 = (Node)m_coord2node.get(c2); return(n1.getEdge(n2)); } protected void setObject(Edge e, Object obj) { e.setObject(obj); } protected void setObject(Node n, Object obj) { n.setObject(obj); } }