/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 | | |