Coverage Report

Created: 2026-04-01 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/src/operation/predicate/RectangleContains.cpp
Line
Count
Source
1
/**********************************************************************
2
 *
3
 * GEOS - Geometry Engine Open Source
4
 * http://geos.osgeo.org
5
 *
6
 * Copyright (C) 2006 Refractions Research 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: operation/predicate/RectangleContains.java rev 1.5 (JTS-1.10)
16
 *
17
 **********************************************************************/
18
19
#include <geos/operation/predicate/RectangleContains.h>
20
#include <geos/geom/Geometry.h>
21
#include <geos/geom/Envelope.h>
22
#include <geos/geom/Point.h>
23
#include <geos/geom/Polygon.h>
24
#include <geos/geom/LineString.h>
25
#include <geos/geom/Coordinate.h>
26
#include <geos/geom/CoordinateSequence.h>
27
28
using namespace geos::geom;
29
30
namespace geos {
31
namespace operation { // geos.operation
32
namespace predicate { // geos.operation.predicate
33
34
bool
35
RectangleContains::contains(const Geometry& geom)
36
0
{
37
0
    if(! rectEnv.contains(geom.getEnvelopeInternal())) {
38
0
        return false;
39
0
    }
40
41
    // check that geom is not contained entirely in the rectangle boundary
42
0
    if(isContainedInBoundary(geom)) {
43
0
        return false;
44
0
    }
45
46
0
    return true;
47
0
}
48
49
/*private*/
50
bool
51
RectangleContains::isContainedInBoundary(const Geometry& geom)
52
0
{
53
    // polygons can never be wholly contained in the boundary
54
0
    if(dynamic_cast<const geom::Polygon*>(&geom)) {
55
0
        return false;
56
0
    }
57
0
    if(const Point* p = dynamic_cast<const Point*>(&geom)) {
58
0
        return isPointContainedInBoundary(*p);
59
0
    }
60
0
    if(const LineString* l = dynamic_cast<const LineString*>(&geom)) {
61
0
        return isLineStringContainedInBoundary(*l);
62
0
    }
63
64
0
    for(std::size_t i = 0, n = geom.getNumGeometries(); i < n; ++i) {
65
0
        const Geometry& comp = *(geom.getGeometryN(i));
66
0
        if(!isContainedInBoundary(comp)) {
67
0
            return false;
68
0
        }
69
0
    }
70
71
0
    return true;
72
0
}
73
74
/*private*/
75
bool
76
RectangleContains::isPointContainedInBoundary(const Point& point)
77
0
{
78
0
    return isPointContainedInBoundary(*(point.getCoordinate()));
79
0
}
80
81
/*private*/
82
bool
83
RectangleContains::isPointContainedInBoundary(const CoordinateXY& pt)
84
0
{
85
    /**
86
     * contains = false iff the point is properly contained
87
     * in the rectangle.
88
     *
89
     * This code assumes that the point lies in the rectangle envelope
90
     */
91
0
    return pt.x == rectEnv.getMinX()
92
0
           || pt.x == rectEnv.getMaxX()
93
0
           || pt.y == rectEnv.getMinY()
94
0
           || pt.y == rectEnv.getMaxY();
95
0
}
96
97
/*private*/
98
bool
99
RectangleContains::isLineStringContainedInBoundary(const LineString& line)
100
0
{
101
0
    const CoordinateSequence& seq = *(line.getCoordinatesRO());
102
0
    for(std::size_t i = 0, n = seq.size() - 1; i < n; ++i) {
103
0
        const Coordinate& p0 = seq.getAt(i);
104
0
        const Coordinate& p1 = seq.getAt(i + 1);
105
0
        if(! isLineSegmentContainedInBoundary(p0, p1)) {
106
0
            return false;
107
0
        }
108
0
    }
109
0
    return true;
110
0
}
111
112
/*private*/
113
bool
114
RectangleContains::isLineSegmentContainedInBoundary(const Coordinate& p0,
115
        const Coordinate& p1)
116
0
{
117
0
    if(p0.equals2D(p1)) {
118
0
        return isPointContainedInBoundary(p0);
119
0
    }
120
121
    // we already know that the segment is contained in
122
    // the rectangle envelope
123
0
    if(p0.x == p1.x) {
124
0
        if(p0.x == rectEnv.getMinX() ||
125
0
                p0.x == rectEnv.getMaxX()) {
126
0
            return true;
127
0
        }
128
0
    }
129
0
    else if(p0.y == p1.y) {
130
0
        if(p0.y == rectEnv.getMinY() ||
131
0
                p0.y == rectEnv.getMaxY()) {
132
0
            return true;
133
0
        }
134
0
    }
135
136
    /*
137
     * Either
138
     *   both x and y values are different
139
     * or
140
     *   one of x and y are the same, but the other ordinate
141
     *   is not the same as a boundary ordinate
142
     *
143
     * In either case, the segment is not wholly in the boundary
144
     */
145
0
    return false;
146
0
}
147
148
149
150
} // namespace geos.operation.predicate
151
} // namespace geos.operation
152
} // namespace geos
153
154
155