001:
002: /*
003: * The JTS Topology Suite is a collection of Java classes that
004: * implement the fundamental operations required to validate a given
005: * geo-spatial data set to a known topological specification.
006: *
007: * Copyright (C) 2001 Vivid Solutions
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
022: *
023: * For more information, contact:
024: *
025: * Vivid Solutions
026: * Suite #1A
027: * 2328 Government Street
028: * Victoria BC V8T 5G5
029: * Canada
030: *
031: * (250)385-6040
032: * www.vividsolutions.com
033: */
034: package com.vividsolutions.jts.geomgraph;
035:
036: import java.io.PrintStream;
037: import java.util.*;
038: import com.vividsolutions.jts.geom.Coordinate;
039: import com.vividsolutions.jts.geom.IntersectionMatrix;
040: import com.vividsolutions.jts.geom.Location;
041: import com.vividsolutions.jts.geomgraph.GraphComponent;
042: import com.vividsolutions.jts.geomgraph.Label;
043: import com.vividsolutions.jts.util.*;
044:
045: /**
046: * @version 1.7
047: */
048: public class Node extends GraphComponent {
049: protected Coordinate coord; // only non-null if this node is precise
050: protected EdgeEndStar edges;
051:
052: public Node(Coordinate coord, EdgeEndStar edges) {
053: this .coord = coord;
054: this .edges = edges;
055: label = new Label(0, Location.NONE);
056: }
057:
058: public Coordinate getCoordinate() {
059: return coord;
060: }
061:
062: public EdgeEndStar getEdges() {
063: return edges;
064: }
065:
066: /**
067: * Tests whether any incident edge is flagged as
068: * being in the result.
069: * This test can be used to determine if the node is in the result,
070: * since if any incident edge is in the result, the node must be in the result as well.
071: *
072: * @return <code>true</code> if any indicident edge in the in the result
073: */
074: public boolean isIncidentEdgeInResult() {
075: for (Iterator it = getEdges().getEdges().iterator(); it
076: .hasNext();) {
077: DirectedEdge de = (DirectedEdge) it.next();
078: if (de.getEdge().isInResult())
079: return true;
080: }
081: return false;
082: }
083:
084: public boolean isIsolated() {
085: return (label.getGeometryCount() == 1);
086: }
087:
088: /**
089: * Basic nodes do not compute IMs
090: */
091: protected void computeIM(IntersectionMatrix im) {
092: }
093:
094: /**
095: * Add the edge to the list of edges at this node
096: */
097: public void add(EdgeEnd e) {
098: // Assert: start pt of e is equal to node point
099: edges.insert(e);
100: e.setNode(this );
101: }
102:
103: public void mergeLabel(Node n) {
104: mergeLabel(n.label);
105: }
106:
107: /**
108: * To merge labels for two nodes,
109: * the merged location for each LabelElement is computed.
110: * The location for the corresponding node LabelElement is set to the result,
111: * as long as the location is non-null.
112: */
113:
114: public void mergeLabel(Label label2) {
115: for (int i = 0; i < 2; i++) {
116: int loc = computeMergedLocation(label2, i);
117: int this Loc = label.getLocation(i);
118: if (this Loc == Location.NONE)
119: label.setLocation(i, loc);
120: }
121: }
122:
123: public void setLabel(int argIndex, int onLocation) {
124: if (label == null) {
125: label = new Label(argIndex, onLocation);
126: } else
127: label.setLocation(argIndex, onLocation);
128: }
129:
130: /**
131: * Updates the label of a node to BOUNDARY,
132: * obeying the mod-2 boundaryDetermination rule.
133: */
134: public void setLabelBoundary(int argIndex) {
135: // determine the current location for the point (if any)
136: int loc = Location.NONE;
137: if (label != null)
138: loc = label.getLocation(argIndex);
139: // flip the loc
140: int newLoc;
141: switch (loc) {
142: case Location.BOUNDARY:
143: newLoc = Location.INTERIOR;
144: break;
145: case Location.INTERIOR:
146: newLoc = Location.BOUNDARY;
147: break;
148: default:
149: newLoc = Location.BOUNDARY;
150: break;
151: }
152: label.setLocation(argIndex, newLoc);
153: }
154:
155: /**
156: * The location for a given eltIndex for a node will be one
157: * of { null, INTERIOR, BOUNDARY }.
158: * A node may be on both the boundary and the interior of a geometry;
159: * in this case, the rule is that the node is considered to be in the boundary.
160: * The merged location is the maximum of the two input values.
161: */
162: int computeMergedLocation(Label label2, int eltIndex) {
163: int loc = Location.NONE;
164: loc = label.getLocation(eltIndex);
165: if (!label2.isNull(eltIndex)) {
166: int nLoc = label2.getLocation(eltIndex);
167: if (loc != Location.BOUNDARY)
168: loc = nLoc;
169: }
170: return loc;
171: }
172:
173: public void print(PrintStream out) {
174: out.println("node " + coord + " lbl: " + label);
175: }
176: }
|