001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005: * (C) 2002, Refractions Reserach Inc.
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation;
010: * version 2.1 of the License.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: */
017: package org.geotools.graph.build.line;
018:
019: import java.util.HashMap;
020: import java.util.Map;
021:
022: import org.geotools.graph.build.GraphBuilder;
023: import org.geotools.graph.build.GraphGenerator;
024: import org.geotools.graph.build.basic.BasicGraphBuilder;
025: import org.geotools.graph.structure.Edge;
026: import org.geotools.graph.structure.Graph;
027: import org.geotools.graph.structure.Graphable;
028: import org.geotools.graph.structure.Node;
029:
030: import com.vividsolutions.jts.geom.Coordinate;
031: import com.vividsolutions.jts.geom.LineSegment;
032:
033: /**
034: * An implementation of GraphGenerator used to generate a graph representing a
035: * line network. Graphs are generated by supplying the generator with objects
036: * of type LineSegment via the add(Object) method. <BR>
037: * <BR>
038: * For each line segment added, an edge in the graph is created. The builder
039: * records the end coordinates of each line added, and maintains a map of
040: * coordinates to nodes, creating nodes when neccessary.<BR>
041: * <BR>
042: * Edges created by the generator are of type BasicEdge and contain an object
043: * of type LineSegment.<BR>
044: * Nodes created by the generator are of type BasicXYNode and contain an object
045: * of type Coordinate.
046: *
047: * @see org.geotools.graph.structure.line.BasicXYNode
048: * @see org.geotools.graph.structure.basic.BasicEdge
049: * @see com.vividsolutions.jts.geom.LineSegment
050: * @see com.vividsolutions.jts.geom.Coordinate
051: *
052: * @author Justin Deoliveira, Refractions Research Inc, jdeolive@refractions.net
053: *
054: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/extension/graph/src/main/java/org/geotools/graph/build/line/BasicLineGraphGenerator.java $
055: */
056: public class BasicLineGraphGenerator implements LineGraphGenerator {
057:
058: /** coordinate to node map **/
059: private HashMap m_coord2node;
060:
061: /** underlying builder **/
062: private GraphBuilder m_builder;
063:
064: /**
065: * Constructs a new BasicLineGraphGenerator.
066: */
067: public BasicLineGraphGenerator() {
068: m_coord2node = new HashMap();
069: setGraphBuilder(new BasicGraphBuilder());
070: }
071:
072: /**
073: * Adds a line to the graph.
074: *
075: * @param obj An instance of LineSegment.
076: *
077: * @return A BasicEdge.
078: *
079: * @see LineSegment
080: * @see GraphGenerator#add(Object)
081: */
082: public Graphable add(Object obj) {
083: LineSegment line = (LineSegment) obj;
084: Coordinate c;
085: Node n1, n2;
086:
087: //check first coordinate
088: c = line.p0;
089: if ((n1 = (Node) m_coord2node.get(c)) == null) {
090: //first time coordinate seen, create node for it
091: n1 = getGraphBuilder().buildNode();
092:
093: //set underlying object to coordinate
094: //n1.setObject(c);
095: setObject(n1, c);
096:
097: getGraphBuilder().addNode(n1);
098: m_coord2node.put(c, n1);
099: }
100:
101: //check second coordinate
102: c = line.p1;
103: if ((n2 = (Node) m_coord2node.get(c)) == null) {
104: //first time coordinate seen, create node for it
105: n2 = getGraphBuilder().buildNode();
106:
107: //set underlying object to coordiante
108: //n2.setObject(c);
109: setObject(n2, c);
110:
111: getGraphBuilder().addNode(n2);
112: m_coord2node.put(c, n2);
113: }
114:
115: //build the edge setting underlying object to line
116: Edge e = getGraphBuilder().buildEdge(n1, n2);
117: //e.setObject(line);
118: setObject(e, line);
119:
120: getGraphBuilder().addEdge(e);
121:
122: //return the created edge
123: return (e);
124: }
125:
126: /**
127: * Returns the edge which represents a line. Note that if the exact same line
128: * has been added to the graph multiple times, then only one of the edges that
129: * represents it will be returned. It is undefined which edge will be returned.
130: *
131: * @param obj An instance of LineSegment.
132: *
133: * @return Edge that represents the line.
134: *
135: * @see GraphGenerator#get(Object)
136: */
137: public Graphable get(Object obj) {
138: LineSegment line = (LineSegment) obj;
139:
140: //get nodes representing coordinate
141: Node n1 = (Node) m_coord2node.get(line.p0);
142: Node n2 = (Node) m_coord2node.get(line.p1);
143:
144: if (n1 == null || n2 == null)
145: return (null);
146:
147: //return edge shared between them
148: return (n1.getEdge(n2));
149:
150: //note: if there are identical lines in the graph then it is undefined
151: //which of them will be returned
152: }
153:
154: /**
155: * Removes the edge from the graph that represents a line.
156: *
157: * @return Edge that represents the line.
158: *
159: * @see GraphGenerator#remove(Object)
160: */
161: public Graphable remove(Object obj) {
162: LineSegment line = (LineSegment) obj;
163: Node n1 = (Node) m_coord2node.get(line.p0);
164: Node n2 = (Node) m_coord2node.get(line.p1);
165:
166: if (n1 == null || n2 == null)
167: return (null);
168:
169: Edge e = (Edge) n1.getEdge(n2);
170: getGraphBuilder().removeEdge(e);
171:
172: return (e);
173: }
174:
175: /**
176: * @see GraphGenerator#setGraphBuilder(GraphBuilder)
177: */
178: public void setGraphBuilder(GraphBuilder builder) {
179: m_builder = builder;
180: }
181:
182: /**
183: * @see GraphGenerator#getGraphBuilder()
184: */
185: public GraphBuilder getGraphBuilder() {
186: return (m_builder);
187: }
188:
189: /**
190: * @see GraphGenerator#getGraph()
191: */
192: public Graph getGraph() {
193: return (getGraphBuilder().getGraph());
194: }
195:
196: /**
197: * Returns the coordinate to node map used to build nodes representing line
198: * endpoint coordinates.
199: *
200: * @return coordinate to ndoe map.
201: */
202: public Map getNodeMap() {
203: return (m_coord2node);
204: }
205:
206: //TODO COMMENT ME!
207: public Node getNode(Coordinate c) {
208: return ((Node) m_coord2node.get(c));
209: }
210:
211: public Edge getEdge(Coordinate c1, Coordinate c2) {
212: Node n1 = (Node) m_coord2node.get(c1);
213: Node n2 = (Node) m_coord2node.get(c2);
214:
215: return (n1.getEdge(n2));
216: }
217:
218: protected void setObject(Edge e, Object obj) {
219: e.setObject(obj);
220: }
221:
222: protected void setObject(Node n, Object obj) {
223: n.setObject(obj);
224: }
225: }
|