~ubuntu-branches/ubuntu/natty/jts/natty

« back to all changes in this revision

Viewing changes to src/com/vividsolutions/jts/geomgraph/DirectedEdge.java

  • Committer: Bazaar Package Importer
  • Author(s): Wolfgang Baer
  • Date: 2005-08-07 14:12:35 UTC
  • Revision ID: james.westby@ubuntu.com-20050807141235-7hy3ll3xpq79djcb
Tags: upstream-1.6
ImportĀ upstreamĀ versionĀ 1.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
 
 
3
 
 
4
/*
 
5
 * The JTS Topology Suite is a collection of Java classes that
 
6
 * implement the fundamental operations required to validate a given
 
7
 * geo-spatial data set to a known topological specification.
 
8
 *
 
9
 * Copyright (C) 2001 Vivid Solutions
 
10
 *
 
11
 * This library is free software; you can redistribute it and/or
 
12
 * modify it under the terms of the GNU Lesser General Public
 
13
 * License as published by the Free Software Foundation; either
 
14
 * version 2.1 of the License, or (at your option) any later version.
 
15
 *
 
16
 * This library is distributed in the hope that it will be useful,
 
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
19
 * Lesser General Public License for more details.
 
20
 *
 
21
 * You should have received a copy of the GNU Lesser General Public
 
22
 * License along with this library; if not, write to the Free Software
 
23
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
24
 *
 
25
 * For more information, contact:
 
26
 *
 
27
 *     Vivid Solutions
 
28
 *     Suite #1A
 
29
 *     2328 Government Street
 
30
 *     Victoria BC  V8T 5G5
 
31
 *     Canada
 
32
 *
 
33
 *     (250)385-6040
 
34
 *     www.vividsolutions.com
 
35
 */
 
36
package com.vividsolutions.jts.geomgraph;
 
37
 
 
38
import java.io.PrintStream;
 
39
import com.vividsolutions.jts.util.*;
 
40
import com.vividsolutions.jts.geom.*;
 
41
 
 
42
 
 
43
/**
 
44
 * @version 1.6
 
45
 */
 
46
public class DirectedEdge
 
47
  extends EdgeEnd
 
48
{
 
49
 
 
50
  /**
 
51
   * Computes the factor for the change in depth when moving from one location to another.
 
52
   * E.g. if crossing from the INTERIOR to the EXTERIOR the depth decreases, so the factor is -1
 
53
   */
 
54
  public static int depthFactor(int currLocation, int nextLocation)
 
55
  {
 
56
    if (currLocation == Location.EXTERIOR && nextLocation == Location.INTERIOR)
 
57
       return 1;
 
58
    else if (currLocation == Location.INTERIOR && nextLocation == Location.EXTERIOR)
 
59
       return -1;
 
60
    return 0;
 
61
  }
 
62
 
 
63
  protected boolean isForward;
 
64
  private boolean isInResult = false;
 
65
  private boolean isVisited = false;
 
66
 
 
67
  private DirectedEdge sym; // the symmetric edge
 
68
  private DirectedEdge next;  // the next edge in the edge ring for the polygon containing this edge
 
69
  private DirectedEdge nextMin;  // the next edge in the MinimalEdgeRing that contains this edge
 
70
  private EdgeRing edgeRing;  // the EdgeRing that this edge is part of
 
71
  private EdgeRing minEdgeRing;  // the MinimalEdgeRing that this edge is part of
 
72
  /**
 
73
   * The depth of each side (position) of this edge.
 
74
   * The 0 element of the array is never used.
 
75
   */
 
76
  private int[] depth = { 0, -999, -999 };
 
77
 
 
78
  public DirectedEdge(Edge edge, boolean isForward)
 
79
  {
 
80
    super(edge);
 
81
    this.isForward = isForward;
 
82
    if (isForward) {
 
83
      init(edge.getCoordinate(0), edge.getCoordinate(1));
 
84
    }
 
85
    else {
 
86
      int n = edge.getNumPoints() - 1;
 
87
      init(edge.getCoordinate(n), edge.getCoordinate(n-1));
 
88
    }
 
89
    computeDirectedLabel();
 
90
  }
 
91
  public Edge getEdge() { return edge; }
 
92
  public void setInResult(boolean isInResult) { this.isInResult = isInResult; }
 
93
  public boolean isInResult() { return isInResult; }
 
94
  public boolean isVisited() { return isVisited; }
 
95
  public void setVisited(boolean isVisited) { this.isVisited = isVisited; }
 
96
  public void setEdgeRing(EdgeRing edgeRing) { this.edgeRing = edgeRing; }
 
97
  public EdgeRing getEdgeRing() { return edgeRing; }
 
98
  public void setMinEdgeRing(EdgeRing minEdgeRing) { this.minEdgeRing = minEdgeRing; }
 
99
  public EdgeRing getMinEdgeRing() { return minEdgeRing; }
 
100
  public int getDepth(int position) { return depth[position]; }
 
101
 
 
102
  public void setDepth(int position, int depthVal)
 
103
  {
 
104
    if (depth[position] != -999) {
 
105
      if (depth[position] != depthVal) {
 
106
        Debug.print(this);
 
107
      }
 
108
      if (depth[position] != depthVal)
 
109
        throw new TopologyException("assigned depths do not match", getCoordinate());
 
110
      //Assert.isTrue(depth[position] == depthVal, "assigned depths do not match at " + getCoordinate());
 
111
    }
 
112
    depth[position] = depthVal;
 
113
  }
 
114
 
 
115
  public int getDepthDelta()
 
116
  {
 
117
    int depthDelta = edge.getDepthDelta();
 
118
    if (! isForward) depthDelta = -depthDelta;
 
119
    return depthDelta;
 
120
  }
 
121
 
 
122
  /**
 
123
   * setVisitedEdge marks both DirectedEdges attached to a given Edge.
 
124
   * This is used for edges corresponding to lines, which will only
 
125
   * appear oriented in a single direction in the result.
 
126
   */
 
127
  public void setVisitedEdge(boolean isVisited)
 
128
  {
 
129
    setVisited(isVisited);
 
130
    sym.setVisited(isVisited);
 
131
  }
 
132
  /**
 
133
   * Each Edge gives rise to a pair of symmetric DirectedEdges, in opposite
 
134
   * directions.
 
135
   * @return the DirectedEdge for the same Edge but in the opposite direction
 
136
   */
 
137
  public DirectedEdge getSym() { return sym; }
 
138
  public boolean isForward() { return isForward; }
 
139
  public void setSym(DirectedEdge de)
 
140
  {
 
141
    sym = de;
 
142
  }
 
143
  public DirectedEdge getNext() { return next; }
 
144
  public void setNext(DirectedEdge next) { this.next = next; }
 
145
  public DirectedEdge getNextMin() { return nextMin; }
 
146
  public void setNextMin(DirectedEdge nextMin) { this.nextMin = nextMin; }
 
147
 
 
148
  /**
 
149
   * This edge is a line edge if
 
150
   * <ul>
 
151
   * <li> at least one of the labels is a line label
 
152
   * <li> any labels which are not line labels have all Locations = EXTERIOR
 
153
   * </ul>
 
154
   */
 
155
  public boolean isLineEdge()
 
156
  {
 
157
    boolean isLine = label.isLine(0) || label.isLine(1);
 
158
    boolean isExteriorIfArea0 =
 
159
      ! label.isArea(0) || label.allPositionsEqual(0, Location.EXTERIOR);
 
160
    boolean isExteriorIfArea1 =
 
161
      ! label.isArea(1) || label.allPositionsEqual(1, Location.EXTERIOR);
 
162
 
 
163
    return isLine && isExteriorIfArea0 && isExteriorIfArea1;
 
164
  }
 
165
  /**
 
166
   * This is an interior Area edge if
 
167
   * <ul>
 
168
   * <li> its label is an Area label for both Geometries
 
169
   * <li> and for each Geometry both sides are in the interior.
 
170
   * </ul>
 
171
   *
 
172
   * @return true if this is an interior Area edge
 
173
   */
 
174
  public boolean isInteriorAreaEdge()
 
175
  {
 
176
    boolean isInteriorAreaEdge = true;
 
177
    for (int i = 0; i < 2; i++) {
 
178
      if (! ( label.isArea(i)
 
179
            && label.getLocation(i, Position.LEFT ) == Location.INTERIOR
 
180
            && label.getLocation(i, Position.RIGHT) == Location.INTERIOR) ) {
 
181
        isInteriorAreaEdge = false;
 
182
      }
 
183
    }
 
184
    return isInteriorAreaEdge;
 
185
  }
 
186
 
 
187
  /**
 
188
   * Compute the label in the appropriate orientation for this DirEdge
 
189
   */
 
190
  private void computeDirectedLabel()
 
191
  {
 
192
    label = new Label(edge.getLabel());
 
193
    if (! isForward)
 
194
      label.flip();
 
195
  }
 
196
 
 
197
  /**
 
198
   * Set both edge depths.  One depth for a given side is provided.  The other is
 
199
   * computed depending on the Location transition and the depthDelta of the edge.
 
200
   */
 
201
  public void setEdgeDepths(int position, int depth)
 
202
  {
 
203
    // get the depth transition delta from R to L for this directed Edge
 
204
    int depthDelta = getEdge().getDepthDelta();
 
205
    if (! isForward) depthDelta = -depthDelta;
 
206
 
 
207
    // if moving from L to R instead of R to L must change sign of delta
 
208
    int directionFactor = 1;
 
209
    if (position == Position.LEFT)
 
210
      directionFactor = -1;
 
211
 
 
212
    int oppositePos = Position.opposite(position);
 
213
    int delta = depthDelta * directionFactor;
 
214
    //TESTINGint delta = depthDelta * DirectedEdge.depthFactor(loc, oppositeLoc);
 
215
    int oppositeDepth = depth + delta;
 
216
    setDepth(position, depth);
 
217
    setDepth(oppositePos, oppositeDepth);
 
218
  }
 
219
 
 
220
  public void print(PrintStream out)
 
221
  {
 
222
    super.print(out);
 
223
    out.print(" " + depth[Position.LEFT] + "/" + depth[Position.RIGHT]);
 
224
    out.print(" (" + getDepthDelta() + ")");
 
225
    //out.print(" " + this.hashCode());
 
226
    //if (next != null) out.print(" next:" + next.hashCode());
 
227
    if (isInResult) out.print(" inResult");
 
228
  }
 
229
  public void printEdge(PrintStream out)
 
230
  {
 
231
    print(out);
 
232
    out.print(" ");
 
233
    if (isForward)
 
234
      edge.print(out);
 
235
    else
 
236
      edge.printReverse(out);
 
237
  }
 
238
 
 
239
}