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 com.vividsolutions.jts.geomgraph.Position;
037: import com.vividsolutions.jts.geom.Location;
038:
039: /**
040: * A TopologyLocation is the labelling of a
041: * GraphComponent's topological relationship to a single Geometry.
042: * <p>
043: * If the parent component is an area edge, each side and the edge itself
044: * have a topological location. These locations are named
045: * <ul>
046: * <li> ON: on the edge
047: * <li> LEFT: left-hand side of the edge
048: * <li> RIGHT: right-hand side
049: * </ul>
050: * If the parent component is a line edge or node, there is a single
051: * topological relationship attribute, ON.
052: * <p>
053: * The possible values of a topological location are
054: * {Location.NONE, Location.EXTERIOR, Location.BOUNDARY, Location.INTERIOR}
055: * <p>
056: * The labelling is stored in an array location[j] where
057: * where j has the values ON, LEFT, RIGHT
058: * @version 1.7
059: */
060: public class TopologyLocation {
061:
062: int location[];
063:
064: public TopologyLocation(int[] location) {
065: init(location.length);
066: }
067:
068: /**
069: * Constructs a TopologyLocation specifying how points on, to the left of, and to the
070: * right of some GraphComponent relate to some Geometry. Possible values for the
071: * parameters are Location.NULL, Location.EXTERIOR, Location.BOUNDARY,
072: * and Location.INTERIOR.
073: * @see Location
074: */
075: public TopologyLocation(int on, int left, int right) {
076: init(3);
077: location[Position.ON] = on;
078: location[Position.LEFT] = left;
079: location[Position.RIGHT] = right;
080: }
081:
082: public TopologyLocation(int on) {
083: init(1);
084: location[Position.ON] = on;
085: }
086:
087: public TopologyLocation(TopologyLocation gl) {
088: init(gl.location.length);
089: if (gl != null) {
090: for (int i = 0; i < location.length; i++) {
091: location[i] = gl.location[i];
092: }
093: }
094: }
095:
096: private void init(int size) {
097: location = new int[size];
098: setAllLocations(Location.NONE);
099: }
100:
101: public int get(int posIndex) {
102: if (posIndex < location.length)
103: return location[posIndex];
104: return Location.NONE;
105: }
106:
107: /**
108: * @return true if all locations are NULL
109: */
110: public boolean isNull() {
111: for (int i = 0; i < location.length; i++) {
112: if (location[i] != Location.NONE)
113: return false;
114: }
115: return true;
116: }
117:
118: /**
119: * @return true if any locations are NULL
120: */
121: public boolean isAnyNull() {
122: for (int i = 0; i < location.length; i++) {
123: if (location[i] == Location.NONE)
124: return true;
125: }
126: return false;
127: }
128:
129: public boolean isEqualOnSide(TopologyLocation le, int locIndex) {
130: return location[locIndex] == le.location[locIndex];
131: }
132:
133: public boolean isArea() {
134: return location.length > 1;
135: }
136:
137: public boolean isLine() {
138: return location.length == 1;
139: }
140:
141: public void flip() {
142: if (location.length <= 1)
143: return;
144: int temp = location[Position.LEFT];
145: location[Position.LEFT] = location[Position.RIGHT];
146: location[Position.RIGHT] = temp;
147: }
148:
149: public void setAllLocations(int locValue) {
150: for (int i = 0; i < location.length; i++) {
151: location[i] = locValue;
152: }
153: }
154:
155: public void setAllLocationsIfNull(int locValue) {
156: for (int i = 0; i < location.length; i++) {
157: if (location[i] == Location.NONE)
158: location[i] = locValue;
159: }
160: }
161:
162: public void setLocation(int locIndex, int locValue) {
163: location[locIndex] = locValue;
164: }
165:
166: public void setLocation(int locValue) {
167: setLocation(Position.ON, locValue);
168: }
169:
170: public int[] getLocations() {
171: return location;
172: }
173:
174: public void setLocations(int on, int left, int right) {
175: location[Position.ON] = on;
176: location[Position.LEFT] = left;
177: location[Position.RIGHT] = right;
178: }
179:
180: public boolean allPositionsEqual(int loc) {
181: for (int i = 0; i < location.length; i++) {
182: if (location[i] != loc)
183: return false;
184: }
185: return true;
186: }
187:
188: /**
189: * merge updates only the NULL attributes of this object
190: * with the attributes of another.
191: */
192: public void merge(TopologyLocation gl) {
193: // if the src is an Area label & and the dest is not, increase the dest to be an Area
194: if (gl.location.length > location.length) {
195: int[] newLoc = new int[3];
196: newLoc[Position.ON] = location[Position.ON];
197: newLoc[Position.LEFT] = Location.NONE;
198: newLoc[Position.RIGHT] = Location.NONE;
199: location = newLoc;
200: }
201: for (int i = 0; i < location.length; i++) {
202: if (location[i] == Location.NONE && i < gl.location.length)
203: location[i] = gl.location[i];
204: }
205: }
206:
207: public String toString() {
208: StringBuffer buf = new StringBuffer();
209: if (location.length > 1)
210: buf.append(Location
211: .toLocationSymbol(location[Position.LEFT]));
212: buf.append(Location.toLocationSymbol(location[Position.ON]));
213: if (location.length > 1)
214: buf.append(Location
215: .toLocationSymbol(location[Position.RIGHT]));
216: return buf.toString();
217: }
218: }
|