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.Iterator;
021: import java.util.Map;
022:
023: import org.geotools.graph.structure.Edge;
024: import org.geotools.graph.structure.Graphable;
025: import org.geotools.graph.structure.Node;
026: import org.geotools.graph.structure.line.OptDirectedXYNode;
027: import org.geotools.graph.structure.opt.OptDirectedNode;
028:
029: import com.vividsolutions.jts.geom.Coordinate;
030: import com.vividsolutions.jts.geom.LineSegment;
031:
032: /**
033: * An implementation of GraphGenerator used to generate an optimized graph
034: * representing a line network. Graphs are generated by supplying the generator
035: * with objects of type LineSegment via the add(Object) method. <BR>
036: * <BR>
037: * For each line segment added, an edge in the graph is created. The builder
038: * records the end coordinates of each line added, and maintains a map of
039: * coordinates to nodes, creating nodes when neccessary.<BR>
040: * <BR>
041: * Edges created by the generator are of type OptBasicEdge.
042: * Nodes created by the generator are of type OptXYNode.
043: *
044: * @see org.geotools.graph.structure.opt.OptEdge
045: * @see org.geotools.graph.structure.line.OptXYNode
046: *
047: * @author Justin Deoliveira, Refractions Research Inc, jdeolive@refractions.net
048: *
049: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/extension/graph/src/main/java/org/geotools/graph/build/line/OptDirectedLineGraphGenerator.java $
050: */
051: public class OptDirectedLineGraphGenerator extends
052: OptLineGraphGenerator {
053:
054: /** maps in coordinates to count / node **/
055: HashMap m_in2count;
056:
057: /** maps out coordinates to count / node **/
058: HashMap m_out2count;
059:
060: /**
061: * Constructs a new OptLineGraphGenerator.
062: */
063: public OptDirectedLineGraphGenerator() {
064: super ();
065:
066: m_in2count = new HashMap();
067: m_out2count = new HashMap();
068:
069: setGraphBuilder(new OptDirectedLineGraphBuilder());
070: }
071:
072: /**
073: * Adds a line to the graph. Note that this method returns null since actual
074: * building of the graph components is delayed until generate() is called.
075: *
076: * @param obj A LineSegment object.
077: *
078: * @return null because the actual building of the graph components is delayed
079: * until generate() is called.
080: */
081: public Graphable add(Object obj) {
082: LineSegment line = (LineSegment) obj;
083: Integer count;
084:
085: //increment the count of the in coordinate
086: if ((count = (Integer) m_in2count.get(line.p0)) == null) {
087: m_in2count.put(line.p0, new Integer(1));
088: } else
089: m_in2count.put(line.p0, new Integer(count.intValue() + 1));
090:
091: //increment the count of the out coordinate
092: if ((count = (Integer) m_out2count.get(line.p1)) == null) {
093: m_out2count.put(line.p1, new Integer(1));
094: } else
095: m_out2count.put(line.p1, new Integer(count.intValue() + 1));
096:
097: getLines().add(line);
098:
099: return (null);
100: }
101:
102: /**
103: * Returns the coordinate to <B>in</B> node map. Note that before the call to
104: * generate the map does not contain any nodes.
105: *
106: * @return Coordinate to in node map.
107: */
108: public Map getInNodeMap() {
109: return (m_in2count);
110: }
111:
112: /**
113: * Returns the coordinate to <B>out</B> node map. Note that before the call to
114: * generate the map does not contain any nodes.
115: *
116: * @return Coordinate to out node map.
117: */
118: public Map getOutNodeMap() {
119: return (m_out2count);
120: }
121:
122: protected void generateNodes() {
123: //create the nodes, starting with in nodes
124: for (Iterator itr = m_in2count.entrySet().iterator(); itr
125: .hasNext();) {
126: Map.Entry entry = (Map.Entry) itr.next();
127: Coordinate coord = (Coordinate) entry.getKey();
128: Integer count = (Integer) entry.getValue();
129:
130: OptDirectedXYNode node = (OptDirectedXYNode) getGraphBuilder()
131: .buildNode();
132: node.setCoordinate(coord);
133:
134: //set the out degree (in count means => out degree)
135: node.setOutDegree(count.intValue());
136:
137: //get the in degree (out count) from the out map, if no entry, set to 0
138: count = (Integer) m_out2count.get(coord);
139: if (count != null)
140: node.setInDegree(count.intValue());
141: else
142: node.setInDegree(0);
143:
144: getGraphBuilder().addNode(node);
145:
146: //set map value to be node instead of count
147: entry.setValue(node);
148: }
149:
150: //create only nodes that are not in the in set
151: for (Iterator itr = m_out2count.entrySet().iterator(); itr
152: .hasNext();) {
153: Map.Entry entry = (Map.Entry) itr.next();
154: Coordinate coord = (Coordinate) entry.getKey();
155: Integer count = (Integer) entry.getValue();
156:
157: //look for the node in the in set, if not there, it means that the
158: // node is never an in node => out degree = 0
159: OptDirectedXYNode node = (OptDirectedXYNode) m_in2count
160: .get(coord);
161: if (node == null) {
162: node = (OptDirectedXYNode) getGraphBuilder()
163: .buildNode();
164: node.setCoordinate(coord);
165:
166: node.setOutDegree(0);
167: node.setInDegree(count.intValue());
168:
169: getGraphBuilder().addNode(node);
170: }
171: //else do nothing, the node was already set when processing in set
172:
173: //set map value to be node instead of count
174: entry.setValue(node);
175: }
176: }
177:
178: protected Edge generateEdge(LineSegment line) {
179: OptDirectedNode n1 = (OptDirectedNode) m_in2count.get(line.p0);
180: OptDirectedNode n2 = (OptDirectedNode) m_out2count.get(line.p1);
181:
182: Edge edge = getGraphBuilder().buildEdge(n1, n2);
183: getGraphBuilder().addEdge(edge);
184:
185: return (edge);
186: }
187:
188: public Node getNode(Coordinate c) {
189: Node n = (Node) m_in2count.get(c);
190:
191: if (n != null)
192: return (n);
193: return ((Node) m_out2count.get(c));
194: }
195:
196: public Edge getEdge(Coordinate c1, Coordinate c2) {
197: //TODO: IMPLEMENT
198:
199: return (null);
200: }
201:
202: }
|