/src/geos/src/geom/prep/PreparedPolygon.cpp
Line | Count | Source |
1 | | /********************************************************************** |
2 | | * |
3 | | * GEOS - Geometry Engine Open Source |
4 | | * http://geos.osgeo.org |
5 | | * |
6 | | * Copyright (C) 2001-2002 Vivid Solutions Inc. |
7 | | * |
8 | | * This is free software; you can redistribute and/or modify it under |
9 | | * the terms of the GNU Lesser General Public Licence as published |
10 | | * by the Free Software Foundation. |
11 | | * See the COPYING file for more information. |
12 | | * |
13 | | ********************************************************************** |
14 | | * |
15 | | * Last port: geom/prep/PreparedPolygon.java rev 1.7 (JTS-1.10) |
16 | | * |
17 | | **********************************************************************/ |
18 | | |
19 | | #include <geos/geom/Polygon.h> |
20 | | #include <geos/geom/prep/PreparedPolygon.h> |
21 | | #include <geos/geom/prep/PreparedPolygonContains.h> |
22 | | #include <geos/geom/prep/PreparedPolygonContainsProperly.h> |
23 | | #include <geos/geom/prep/PreparedPolygonCovers.h> |
24 | | #include <geos/geom/prep/PreparedPolygonDistance.h> |
25 | | #include <geos/geom/prep/PreparedPolygonIntersects.h> |
26 | | #include <geos/geom/prep/PreparedPolygonPredicate.h> |
27 | | #include <geos/noding/FastSegmentSetIntersectionFinder.h> |
28 | | #include <geos/noding/SegmentStringUtil.h> |
29 | | #include <geos/operation/predicate/RectangleContains.h> |
30 | | #include <geos/operation/predicate/RectangleIntersects.h> |
31 | | #include <geos/algorithm/locate/PointOnGeometryLocator.h> |
32 | | #include <geos/algorithm/locate/IndexedPointInAreaLocator.h> |
33 | | #include <geos/algorithm/locate/SimplePointInAreaLocator.h> |
34 | | // std |
35 | | #include <cstddef> |
36 | | |
37 | | namespace geos { |
38 | | namespace geom { // geos.geom |
39 | | namespace prep { // geos.geom.prep |
40 | | // |
41 | | // public: |
42 | | // |
43 | | PreparedPolygon::PreparedPolygon(const geom::Geometry* geom) |
44 | 0 | : BasicPreparedGeometry(geom) |
45 | 0 | { |
46 | 0 | isRectangle = getGeometry().isRectangle(); |
47 | 0 | } |
48 | | |
49 | | PreparedPolygon::~PreparedPolygon() |
50 | 0 | { |
51 | 0 | for(std::size_t i = 0, ni = segStrings.size(); i < ni; i++) { |
52 | 0 | delete segStrings[ i ]; |
53 | 0 | } |
54 | 0 | } |
55 | | |
56 | | |
57 | | noding::FastSegmentSetIntersectionFinder* |
58 | | PreparedPolygon:: |
59 | | getIntersectionFinder() const |
60 | 0 | { |
61 | 0 | if(! segIntFinder) { |
62 | 0 | noding::SegmentStringUtil::extractSegmentStrings(&getGeometry(), segStrings); |
63 | 0 | segIntFinder.reset(new noding::FastSegmentSetIntersectionFinder(&segStrings)); |
64 | 0 | } |
65 | 0 | return segIntFinder.get(); |
66 | 0 | } |
67 | | |
68 | | algorithm::locate::PointOnGeometryLocator* |
69 | | PreparedPolygon:: |
70 | | getPointLocator() const |
71 | 0 | { |
72 | | // If we are only going to locate a single point, it's faster to do a brute-force SimplePointInAreaLocator |
73 | | // instead of an IndexedPointInAreaLocator. There's a reasonable chance we will only use this locator |
74 | | // once (for example, if we get here through Geometry::intersects). So we create a simple locator for the |
75 | | // first usage and switch to an indexed locator when it is clear we're in a multiple-use scenario. |
76 | 0 | if(! ptOnGeomLoc) { |
77 | 0 | ptOnGeomLoc = detail::make_unique<algorithm::locate::SimplePointInAreaLocator>(&getGeometry()); |
78 | 0 | return ptOnGeomLoc.get(); |
79 | 0 | } else if (!indexedPtOnGeomLoc) { |
80 | 0 | indexedPtOnGeomLoc = detail::make_unique<algorithm::locate::IndexedPointInAreaLocator>(getGeometry()); |
81 | 0 | } |
82 | | |
83 | 0 | return indexedPtOnGeomLoc.get(); |
84 | 0 | } |
85 | | |
86 | | bool |
87 | | PreparedPolygon:: |
88 | | contains(const geom::Geometry* g) const |
89 | 0 | { |
90 | | // short-circuit test |
91 | 0 | if(!envelopeCovers(g)) { |
92 | 0 | return false; |
93 | 0 | } |
94 | | |
95 | | // optimization for rectangles |
96 | 0 | if(isRectangle) { |
97 | 0 | geom::Geometry const& geom = getGeometry(); |
98 | 0 | geom::Polygon const& poly = *detail::down_cast<geom::Polygon const*>(&geom); |
99 | |
|
100 | 0 | return operation::predicate::RectangleContains::contains(poly, *g); |
101 | 0 | } |
102 | | |
103 | 0 | return PreparedPolygonContains::contains(this, g); |
104 | 0 | } |
105 | | |
106 | | bool |
107 | | PreparedPolygon:: |
108 | | containsProperly(const geom::Geometry* g) const |
109 | 0 | { |
110 | | // short-circuit test |
111 | 0 | if(!envelopeCovers(g)) { |
112 | 0 | return false; |
113 | 0 | } |
114 | | |
115 | 0 | return PreparedPolygonContainsProperly::containsProperly(this, g); |
116 | 0 | } |
117 | | |
118 | | bool |
119 | | PreparedPolygon:: |
120 | | covers(const geom::Geometry* g) const |
121 | 0 | { |
122 | | // short-circuit test |
123 | 0 | if(!envelopeCovers(g)) { |
124 | 0 | return false; |
125 | 0 | } |
126 | | |
127 | | // optimization for rectangle arguments |
128 | 0 | if(isRectangle) { |
129 | 0 | return true; |
130 | 0 | } |
131 | | |
132 | 0 | return PreparedPolygonCovers::covers(this, g); |
133 | 0 | } |
134 | | |
135 | | bool |
136 | | PreparedPolygon:: |
137 | | intersects(const geom::Geometry* g) const |
138 | 0 | { |
139 | 0 | geos::util::ensureNoCurvedComponents(g); |
140 | | |
141 | | // envelope test |
142 | 0 | if(!envelopesIntersect(g)) { |
143 | 0 | return false; |
144 | 0 | } |
145 | | |
146 | | // optimization for rectangles |
147 | 0 | if(isRectangle) { |
148 | 0 | geom::Geometry const& geom = getGeometry(); |
149 | 0 | geom::Polygon const& poly = dynamic_cast<geom::Polygon const&>(geom); |
150 | |
|
151 | 0 | return operation::predicate::RectangleIntersects::intersects(poly, *g); |
152 | 0 | } |
153 | | |
154 | 0 | return PreparedPolygonIntersects::intersects(this, g); |
155 | 0 | } |
156 | | |
157 | | /* public */ |
158 | | operation::distance::IndexedFacetDistance* |
159 | | PreparedPolygon:: |
160 | | getIndexedFacetDistance() const |
161 | 0 | { |
162 | 0 | if(! indexedDistance ) { |
163 | 0 | indexedDistance.reset(new operation::distance::IndexedFacetDistance(&getGeometry())); |
164 | 0 | } |
165 | 0 | return indexedDistance.get(); |
166 | 0 | } |
167 | | |
168 | | double |
169 | | PreparedPolygon::distance(const geom::Geometry* g) const |
170 | 0 | { |
171 | 0 | return PreparedPolygonDistance::distance(*this, g); |
172 | 0 | } |
173 | | |
174 | | bool |
175 | | PreparedPolygon::isWithinDistance(const geom::Geometry* g, double d) const |
176 | 0 | { |
177 | 0 | return PreparedPolygonDistance(*this).isWithinDistance(g, d); |
178 | 0 | } |
179 | | |
180 | | } // namespace geos.geom.prep |
181 | | } // namespace geos.geom |
182 | | } // namespace geos |