File: nodingSegmentIntersector.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 (209 lines) | stat: -rw-r--r-- 6,001 bytes parent folder | download | duplicates (2)
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
/**********************************************************************
 * $Id: nodingSegmentIntersector.cpp,v 1.7 2004/11/01 16:43:04 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 Licence as published
 * by the Free Software Foundation. 
 * See the COPYING file for more information.
 *
 **********************************************************************/

#include <geos/noding.h>

namespace geos {

bool
nodingSegmentIntersector::isAdjacentSegments(int i1, int i2)
{
	return abs(i1-i2)==1;
}



nodingSegmentIntersector::nodingSegmentIntersector(LineIntersector *newLi)
{
	li=newLi;
	hasIntersectionVar=false;
	hasProperVar = false;
	hasProperInteriorVar = false;
	hasInteriorVar = false;
	properIntersectionPoint=NULL;
	numIntersections = 0;
	numInteriorIntersections = 0;
	numProperIntersections = 0;
	numTests = 0;
	recordIsolated = false;
}

LineIntersector*
nodingSegmentIntersector::getLineIntersector()
{
	return li;
}

/**
 * @return the proper intersection point, or <code>null</code> if none was found
 */
Coordinate*
nodingSegmentIntersector::getProperIntersectionPoint()
{
	return properIntersectionPoint;
}

bool
nodingSegmentIntersector::hasIntersection()
{ 
	return hasIntersectionVar;
}

/**
 * A proper intersection is an intersection which is interior to at least two
 * line segments.  Note that a proper intersection is not necessarily
 * in the interior of the entire Geometry, since another edge may have
 * an endpoint equal to the intersection, which according to SFS semantics
 * can result in the point being on the Boundary of the Geometry.
 */
bool
nodingSegmentIntersector::hasProperIntersection()
{
	return hasProperVar;
}

/**
 * A proper interior intersection is a proper intersection which is <b>not</b>
 * contained in the set of boundary nodes set for this nodingSegmentIntersector.
 */
bool
nodingSegmentIntersector::hasProperInteriorIntersection()
{
	return hasProperInteriorVar;
}

/**
 * An interior intersection is an intersection which is
 * in the interior of some segment.
 */
bool
nodingSegmentIntersector::hasInteriorIntersection()
{
	return hasInteriorVar;
}

/**
 * A trivial intersection is an apparent self-intersection which in fact
 * is simply the point shared by adjacent line segments.
 * Note that closed edges require a special check for the point shared by
 * the beginning and end segments.
 */
bool
nodingSegmentIntersector::isTrivialIntersection(SegmentString *e0, int segIndex0, SegmentString *e1, int segIndex1)
{
	if (e0 == e1) {
		if (li->getIntersectionNum() == 1) {
			if (isAdjacentSegments(segIndex0, segIndex1))
				return true;
			if (e0->isClosed()) {
				int maxSegIndex = e0->size() - 1;
				if ((segIndex0 == 0 && segIndex1 == maxSegIndex) ||
					(segIndex1 == 0 && segIndex0 == maxSegIndex)) {
						return true;
				}
			}
		}
	}
	return false;
}

/**
 * This method is called by clients
 * of the nodingSegmentIntersector class to process
 * intersections for two segments of the SegmentString being intersected.
 * Note that some clients (such as MonotoneChain) may optimize away
 * this call for segment pairs which they have determined do not intersect
 * (e.g. by an disjoint envelope test).
 */
void
nodingSegmentIntersector::processIntersections(SegmentString *e0, int segIndex0,SegmentString *e1, int segIndex1)
{
	if (e0==e1 && segIndex0==segIndex1)
	{
		return;
	}
	numTests++;
	const Coordinate &p00=e0->getCoordinate(segIndex0);
	const Coordinate &p01=e0->getCoordinate(segIndex0+1);
	const Coordinate &p10=e1->getCoordinate(segIndex1);
	const Coordinate &p11=e1->getCoordinate(segIndex1+1);
	li->computeIntersection(p00, p01, p10, p11);
	//if (li.hasIntersection() && li.isProper()) Debug.println(li);
	if (li->hasIntersection()) {
		if (recordIsolated) {
			e0->setIsolated(false);
			e1->setIsolated(false);
		}
		//intersectionFound = true;
		numIntersections++;
		if (li->isInteriorIntersection()) {
			numInteriorIntersections++;
			hasInteriorVar = true;
			//System.out.println(li);
		}
		// if the segments are adjacent they have at least one
		// trivial intersection,
		// the shared endpoint.  Don't bother adding it if it is the
		// only intersection.
		if (!isTrivialIntersection(e0, segIndex0, e1, segIndex1)) {
			hasIntersectionVar = true;
			//Debug.println(li);
			e0->addIntersections(li, segIndex0, 0);
			e1->addIntersections(li, segIndex1, 1);
			if (li->isProper()) {
				numProperIntersections++;
				//properIntersectionPoint = (Coordinate) li.getIntersection(0).clone();
				hasProperVar = true;
				hasProperInteriorVar = true;
			}
		}
	}
}

} // namespace geos

/**********************************************************************
 * $Log: nodingSegmentIntersector.cpp,v $
 * Revision 1.7  2004/11/01 16:43:04  strk
 * Added Profiler code.
 * Temporarly patched a bug in DoubleBits (must check drawbacks).
 * Various cleanups and speedups.
 *
 * Revision 1.6  2004/07/08 19:34:49  strk
 * Mirrored JTS interface of CoordinateSequence, factory and
 * default implementations.
 * Added DefaultCoordinateSequenceFactory::instance() function.
 *
 * Revision 1.5  2004/07/02 13:28:27  strk
 * Fixed all #include lines to reflect headers layout change.
 * Added client application build tips in README.
 *
 * Revision 1.4  2004/06/16 13:13:25  strk
 * Changed interface of SegmentString, now copying CoordinateSequence argument.
 * Fixed memory leaks associated with this and MultiGeometry constructors.
 * Other associated fixes.
 *
 * Revision 1.3  2004/05/27 10:26:50  strk
 * set (useless?) recordIsolated member in constructor
 *
 * Revision 1.2  2004/05/03 12:09:22  strk
 * newline added at end of file
 *
 * Revision 1.1  2004/03/26 07:48:30  ybychkov
 * "noding" package ported (JTS 1.4)
 *
 *
 **********************************************************************/