File: DirectedEdge.cpp

package info (click to toggle)
geos 2.1.1-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 4,784 kB
  • ctags: 3,505
  • sloc: cpp: 24,991; sh: 8,431; xml: 6,597; makefile: 401; python: 77
file content (296 lines) | stat: -rw-r--r-- 7,603 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
/**********************************************************************
 * $Id: DirectedEdge.cpp,v 1.2 2004/07/02 13:28:26 strk Exp $
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.refractions.net
 *
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation. 
 * See the COPYING file for more information.
 *
 **********************************************************************
 * $Log: DirectedEdge.cpp,v $
 * Revision 1.2  2004/07/02 13:28:26  strk
 * Fixed all #include lines to reflect headers layout change.
 * Added client application build tips in README.
 *
 * Revision 1.1  2004/03/19 09:48:45  ybychkov
 * "geomgraph" and "geomgraph/indexl" upgraded to JTS 1.4
 *
 * Revision 1.10  2003/11/07 01:23:42  pramsey
 * Add standard CVS headers licence notices and copyrights to all cpp and h
 * files.
 *
 *
 **********************************************************************/


#include <geos/geomgraph.h>
#include <math.h>

namespace geos {

/**
 * Computes the factor for the change in depth when moving from one location to another.
 * E.g. if crossing from the INTERIOR to the EXTERIOR the depth decreases, so the factor is -1
 */
int DirectedEdge::depthFactor(int currLocation, int nextLocation){
	if (currLocation==Location::EXTERIOR && nextLocation==Location::INTERIOR)
		return 1;
	else if (currLocation==Location::INTERIOR && nextLocation==Location::EXTERIOR)
		return -1;
	return 0;
}

DirectedEdge::DirectedEdge(): EdgeEnd() {
	isInResultVar=false;
	isVisitedVar=false;
	depth[0]=0;
	depth[1]=-999;
	depth[2]=-999;

	sym=NULL;
	next=NULL;
	nextMin=NULL;

	edgeRing=NULL;
	minEdgeRing=NULL;
}

DirectedEdge::~DirectedEdge() {
//aaaa
}

DirectedEdge::DirectedEdge(Edge *newEdge, bool newIsForward): EdgeEnd(newEdge){
	isInResultVar=false;
	isVisitedVar=false;
	depth[0]=0;
	depth[1]=-999;
	depth[2]=-999;

	sym=NULL;
	next=NULL;
	nextMin=NULL;

	edgeRing=NULL;
	minEdgeRing=NULL;

	isForwardVar=newIsForward;
	if (isForwardVar) {
		init(edge->getCoordinate(0), edge->getCoordinate(1));
	} else {
		int n=edge->getNumPoints()-1;
		init(edge->getCoordinate(n), edge->getCoordinate(n-1));
	}
	computeDirectedLabel();
}

Edge* DirectedEdge::getEdge() {
	return edge;
}

void DirectedEdge::setInResult(bool newIsInResult) {
	isInResultVar=newIsInResult;
}

bool DirectedEdge::isInResult() {
	return isInResultVar;
}

bool DirectedEdge::isVisited() {
	return isVisitedVar;
}

void DirectedEdge::setVisited(bool newIsVisited) {
	isVisitedVar=newIsVisited;
}

void DirectedEdge::setEdgeRing(EdgeRing *newEdgeRing) {
	edgeRing=newEdgeRing;
}

EdgeRing* DirectedEdge::getEdgeRing() {
	return edgeRing;
}

void DirectedEdge::setMinEdgeRing(EdgeRing *newMinEdgeRing) {
	minEdgeRing=newMinEdgeRing;
}

EdgeRing* DirectedEdge::getMinEdgeRing() {
	return minEdgeRing;
}

int DirectedEdge::getDepth(int position){
	return depth[position];
}

void DirectedEdge::setDepth(int position, int newDepth) {
	if (depth[position]!=-999) {
		//if (depth[position]!=newDepth) {
		//	cout << "Debug: " << this <<endl;;
		//}
		if (depth[position]!=newDepth)
			throw new TopologyException("assigned depths do not match", &getCoordinate());
			//Assert.isTrue(depth[position] == depthVal, "assigned depths do not match at " + getCoordinate());
	}
	depth[position]=newDepth;
}

int DirectedEdge::getDepthDelta(){
	int depthDelta=edge->getDepthDelta();
	if (!isForwardVar) depthDelta=-depthDelta;
	return depthDelta;
}

/**
 * setVisitedEdge marks both DirectedEdges attached to a given Edge.
 * This is used for edges corresponding to lines, which will only
 * appear oriented in a single direction in the result.
 */
void DirectedEdge::setVisitedEdge(bool newIsVisited){
	setVisited(newIsVisited);
	sym->setVisited(newIsVisited);
}

/**
 * Each Edge gives rise to a pair of symmetric DirectedEdges, in opposite
 * directions.
 * @return the DirectedEdge for the same Edge but in the opposite direction
 */
DirectedEdge* DirectedEdge::getSym() {
	return sym;
}

bool DirectedEdge::isForward() {
	return isForwardVar;
}

void DirectedEdge::setSym(DirectedEdge *de){
	sym=de;
}

DirectedEdge* DirectedEdge::getNext() {
	return next;
}

void DirectedEdge::setNext(DirectedEdge *newNext) {
	next=newNext;
}

DirectedEdge* DirectedEdge::getNextMin() {
	return nextMin;
}

void DirectedEdge::setNextMin(DirectedEdge *newNextMin) {
	nextMin=newNextMin;
}

/**
 * This edge is a line edge if
 * <ul>
 * <li> at least one of the labels is a line label
 * <li> any labels which are not line labels have all Locations = EXTERIOR
 * </ul>
 */
bool DirectedEdge::isLineEdge() {
	bool isLine=label->isLine(0) || label->isLine(1);
	bool isExteriorIfArea0=!label->isArea(0) || label->allPositionsEqual(0,Location::EXTERIOR);
	bool isExteriorIfArea1=!label->isArea(1) || label->allPositionsEqual(1,Location::EXTERIOR);
	return isLine && isExteriorIfArea0 && isExteriorIfArea1;
}

/**
 * This is an interior Area edge if
 * <ul>
 * <li> its label is an Area label for both Geometries
 * <li> and for each Geometry both sides are in the interior.
 * </ul>
 *
 * @return true if this is an interior Area edge
 */
bool DirectedEdge::isInteriorAreaEdge(){
	bool isInteriorAreaEdge=true;
	for (int i=0; i<2; i++) {
		if (!(label->isArea(i)
			&& label->getLocation(i,Position::LEFT )==Location::INTERIOR
			&& label->getLocation(i,Position::RIGHT)==Location::INTERIOR)) {
				isInteriorAreaEdge=false;
		}
	}
	return isInteriorAreaEdge;
}

/**
 * Compute the label in the appropriate orientation for this DirEdge
 */
void DirectedEdge::computeDirectedLabel(){
	delete label;
	label=new Label(edge->getLabel());
	if (!isForwardVar)
		label->flip();
}

/**
 * Set both edge depths.  One depth for a given side is provided.  The other is
 * computed depending on the Location transition and the depthDelta of the edge.
 */
void DirectedEdge::setEdgeDepths(int position, int newDepth){
	// get the depth transition delta from R to L for this directed Edge
	int depthDelta=getEdge()->getDepthDelta();
	if (!isForwardVar) depthDelta=-depthDelta;
	// if moving from L to R instead of R to L must change sign of delta
	int directionFactor=1;
	if (position==Position::LEFT)
		directionFactor=-1;
	int oppositePos=Position::opposite(position);
	int delta=depthDelta*directionFactor;
	//TESTINGint delta = depthDelta * DirectedEdge.depthFactor(loc, oppositeLoc);
	int oppositeDepth=newDepth+delta;
	setDepth(position,newDepth);
	setDepth(oppositePos,oppositeDepth);
}

/**
 * Set both edge depths.  One depth for a given side is provided.  The other is
 * computed depending on the Location transition and the depthDelta of the edge.
 */
void DirectedEdge::OLDsetEdgeDepths(int position, int newDepth){
	int depthDelta=getEdge()->getDepthDelta();
	int loc=label->getLocation(0, position);
	int oppositePos=Position::opposite(position);
	int oppositeLoc=label->getLocation(0, oppositePos);
	int delta=abs(depthDelta)*DirectedEdge::depthFactor(loc,oppositeLoc);
	int oppositeDepth=newDepth + delta;
	setDepth(position, newDepth);
	setDepth(oppositePos,oppositeDepth);
}

string DirectedEdge::print(){
	string out=EdgeEnd::print();
	out+=" ";
	out+=depth[Position::LEFT];
	out+="/";
	out+=depth[Position::RIGHT];
	out+=" (";
	out+=getDepthDelta();
	out+=")";
	if (isInResultVar) out+=" inResult";
	return out;
}

string DirectedEdge::printEdge(){
	string out=print();
	out+=" ";
	if (isForwardVar)
		out+=edge->print();
	else
		out+=edge->printReverse();
	return out;
}

}