Coverage Report

Created: 2026-07-16 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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