Complete Note#1 in the http://wiki.osgeo.org/wiki/GEOS_Provenance_Review to get out...
[geos.git] / src / noding / snapround / HotPixel.cpp
blobb6190721a57a75fb3327eeb07e72421acb6f4667
1 /**********************************************************************
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
6 * Copyright (C) 2006 Refractions Research Inc.
8 * This is free software; you can redistribute and/or modify it under
9 * the terms of the GNU Lesser General Licence as published
10 * by the Free Software Foundation.
11 * See the COPYING file for more information.
13 **********************************************************************
15 * Last port: noding/snapround/HotPixel.java r320 (JTS-1.12)
17 **********************************************************************/
19 #include <geos/noding/snapround/HotPixel.h>
20 #include <geos/noding/NodedSegmentString.h>
21 #include <geos/algorithm/LineIntersector.h>
22 #include <geos/geom/Coordinate.h>
24 #ifndef GEOS_INLINE
25 # include "geos/noding/snapround/HotPixel.inl"
26 #endif
28 #include <algorithm> // for std::min and std::max
29 #include <cassert>
30 #include <memory>
32 using namespace std;
33 using namespace geos::algorithm;
34 using namespace geos::geom;
36 namespace geos {
37 namespace noding { // geos.noding
38 namespace snapround { // geos.noding.snapround
40 HotPixel::HotPixel(const Coordinate& newPt, double newScaleFactor,
41 LineIntersector& newLi)
43 li(newLi),
44 pt(newPt),
45 originalPt(newPt),
46 scaleFactor(newScaleFactor)
48 if (scaleFactor != 1.0) {
49 pt.x=scale(pt.x);
50 pt.y=scale(pt.y);
52 initCorners(pt);
55 const Envelope&
56 HotPixel::getSafeEnvelope() const
58 static const double SAFE_ENV_EXPANSION_FACTOR = 0.75;
60 if (safeEnv.get() == NULL) {
61 double safeTolerance = SAFE_ENV_EXPANSION_FACTOR / scaleFactor;
62 safeEnv = auto_ptr<Envelope>(new Envelope(originalPt.x - safeTolerance,
63 originalPt.x + safeTolerance,
64 originalPt.y - safeTolerance,
65 originalPt.y + safeTolerance
66 ));
68 return *safeEnv;
71 /*private*/
72 void
73 HotPixel::initCorners(const Coordinate& pt)
75 double tolerance = 0.5;
76 minx = pt.x - tolerance;
77 maxx = pt.x + tolerance;
78 miny = pt.y - tolerance;
79 maxy = pt.y + tolerance;
81 corner.resize(4);
82 corner[0] = Coordinate(maxx, maxy);
83 corner[1] = Coordinate(minx, maxy);
84 corner[2] = Coordinate(minx, miny);
85 corner[3] = Coordinate(maxx, maxy);
88 bool
89 HotPixel::intersects(const Coordinate& p0,
90 const Coordinate& p1) const
92 if (scaleFactor == 1.0) return intersectsScaled(p0, p1);
94 copyScaled(p0, p0Scaled);
95 copyScaled(p1, p1Scaled);
97 return intersectsScaled(p0Scaled, p1Scaled);
100 /* private */
101 bool
102 HotPixel::intersectsScaled(const Coordinate& p0,
103 const Coordinate& p1) const
106 double const segMinx = (std::min)(p0.x, p1.x);
107 double const segMaxx = (std::max)(p0.x, p1.x);
108 double const segMiny = (std::min)(p0.y, p1.y);
109 double const segMaxy = (std::max)(p0.y, p1.y);
111 bool isOutsidePixelEnv = maxx < segMinx
112 || minx > segMaxx
113 || maxy < segMiny
114 || miny > segMaxy;
116 if (isOutsidePixelEnv) return false;
118 bool intersects = intersectsToleranceSquare(p0, p1);
120 // Found bad envelope test
121 assert(!(isOutsidePixelEnv && intersects));
123 return intersects;
126 /*private*/
127 bool
128 HotPixel::intersectsToleranceSquare(const Coordinate& p0,
129 const Coordinate& p1) const
131 bool intersectsLeft = false;
132 bool intersectsBottom = false;
134 li.computeIntersection(p0, p1, corner[0], corner[1]);
135 if (li.isProper()) return true;
137 li.computeIntersection(p0, p1, corner[1], corner[2]);
138 if (li.isProper()) return true;
139 if (li.hasIntersection()) intersectsLeft = true;
141 li.computeIntersection(p0, p1, corner[2], corner[3]);
142 if (li.isProper()) return true;
143 if (li.hasIntersection()) intersectsBottom = true;
145 li.computeIntersection(p0, p1, corner[3], corner[0]);
146 if (li.isProper()) return true;
148 if (intersectsLeft && intersectsBottom) return true;
150 if (p0.equals2D(pt)) return true;
151 if (p1.equals2D(pt)) return true;
153 return false;
156 /*private*/
157 bool
158 HotPixel::intersectsPixelClosure(const Coordinate& p0,
159 const Coordinate& p1)
161 li.computeIntersection(p0, p1, corner[0], corner[1]);
162 if (li.hasIntersection()) return true;
163 li.computeIntersection(p0, p1, corner[1], corner[2]);
164 if (li.hasIntersection()) return true;
165 li.computeIntersection(p0, p1, corner[2], corner[3]);
166 if (li.hasIntersection()) return true;
167 li.computeIntersection(p0, p1, corner[3], corner[0]);
168 if (li.hasIntersection()) return true;
170 return false;
173 bool
174 HotPixel::addSnappedNode(NodedSegmentString& segStr, size_t segIndex)
176 const Coordinate& p0 = segStr.getCoordinate(segIndex);
177 const Coordinate& p1 = segStr.getCoordinate(segIndex + 1);
179 if (intersects(p0, p1))
181 //cout << "snapped: " << snapPt << endl;
182 segStr.addIntersection(getCoordinate(), segIndex);
183 return true;
185 return false;
189 } // namespace geos.noding.snapround
190 } // namespace geos.noding
191 } // namespace geos
193 /**********************************************************************
194 * $Log$
195 * Revision 1.8 2006/05/03 17:51:24 strk
196 * system headers included after package headers
198 * Revision 1.7 2006/03/24 09:52:41 strk
199 * USE_INLINE => GEOS_INLINE
201 * Revision 1.6 2006/03/14 12:55:56 strk
202 * Headers split: geomgraphindex.h, nodingSnapround.h
204 * Revision 1.5 2006/03/03 10:46:21 strk
205 * Removed 'using namespace' from headers, added missing headers in .cpp files, removed useless includes in headers (bug#46)
207 * Revision 1.4 2006/02/21 16:53:49 strk
208 * MCIndexPointSnapper, MCIndexSnapRounder
210 * Revision 1.3 2006/02/19 19:46:49 strk
211 * Packages <-> namespaces mapping for most GEOS internal code (uncomplete, but working). Dir-level libs for index/ subdirs.
213 * Revision 1.2 2006/02/18 21:08:09 strk
214 * - new CoordinateSequence::applyCoordinateFilter method (slow but useful)
215 * - SegmentString::getCoordinates() doesn't return a clone anymore.
216 * - SegmentString::getCoordinatesRO() obsoleted.
217 * - SegmentString constructor does not promises constness of passed
218 * CoordinateSequence anymore.
219 * - NEW ScaledNoder class
220 * - Stubs for MCIndexPointSnapper and MCIndexSnapRounder
221 * - Simplified internal interaces of OffsetCurveBuilder and OffsetCurveSetBuilder
223 * Revision 1.1 2006/02/14 13:28:26 strk
224 * New SnapRounding code ported from JTS-1.7 (not complete yet).
225 * Buffer op optimized by using new snaprounding code.
226 * Leaks fixed in XMLTester.
228 **********************************************************************/