/src/geos/src/operation/relateng/IMPatternMatcher.cpp
Line | Count | Source |
1 | | /********************************************************************** |
2 | | * |
3 | | * GEOS - Geometry Engine Open Source |
4 | | * http://geos.osgeo.org |
5 | | * |
6 | | * Copyright (c) 2024 Martin Davis |
7 | | * Copyright (C) 2024 Paul Ramsey <pramsey@cleverelephant.ca> |
8 | | * |
9 | | * This is free software; you can redistribute and/or modify it under |
10 | | * the terms of the GNU Lesser General Public Licence as published |
11 | | * by the Free Software Foundation. |
12 | | * See the COPYING file for more information. |
13 | | * |
14 | | **********************************************************************/ |
15 | | |
16 | | #include <geos/operation/relateng/IMPatternMatcher.h> |
17 | | #include <geos/geom/Envelope.h> |
18 | | #include <geos/geom/Location.h> |
19 | | |
20 | | #include <sstream> |
21 | | |
22 | | |
23 | | using geos::geom::Envelope; |
24 | | using geos::geom::Location; |
25 | | |
26 | | |
27 | | namespace geos { // geos |
28 | | namespace operation { // geos.operation |
29 | | namespace relateng { // geos.operation.relateng |
30 | | |
31 | | |
32 | | /* public */ |
33 | | std::string |
34 | | IMPatternMatcher::name() const |
35 | 0 | { |
36 | 0 | return "IMPattern"; |
37 | 0 | } |
38 | | |
39 | | |
40 | | /* public */ |
41 | | void |
42 | | IMPatternMatcher::init(const Envelope& envA, const Envelope& envB) |
43 | 0 | { |
44 | 0 | IMPredicate::init(dimA, dimB); |
45 | | //-- if pattern specifies any non-E/non-E interaction, envelopes must not be disjoint |
46 | 0 | bool requiresInteraction = requireInteraction(patternMatrix); |
47 | 0 | bool isDisjoint = envA.disjoint(&envB); |
48 | 0 | setValueIf(false, requiresInteraction && isDisjoint); |
49 | 0 | } |
50 | | |
51 | | |
52 | | /* public */ |
53 | | bool |
54 | | IMPatternMatcher::requireInteraction() const |
55 | 0 | { |
56 | 0 | return requireInteraction(patternMatrix); |
57 | 0 | } |
58 | | |
59 | | |
60 | | /* private static */ |
61 | | bool |
62 | | IMPatternMatcher::requireInteraction(const IntersectionMatrix& im) |
63 | 0 | { |
64 | 0 | bool requiresInteraction = |
65 | 0 | isInteraction(im.get(Location::INTERIOR, Location::INTERIOR)) || |
66 | 0 | isInteraction(im.get(Location::INTERIOR, Location::BOUNDARY)) || |
67 | 0 | isInteraction(im.get(Location::BOUNDARY, Location::INTERIOR)) || |
68 | 0 | isInteraction(im.get(Location::BOUNDARY, Location::BOUNDARY)); |
69 | 0 | return requiresInteraction; |
70 | 0 | } |
71 | | |
72 | | |
73 | | /* private static */ |
74 | | bool |
75 | | IMPatternMatcher::isInteraction(int imDim) |
76 | 0 | { |
77 | 0 | return imDim == Dimension::True || imDim >= Dimension::P; |
78 | 0 | } |
79 | | |
80 | | |
81 | | /* public */ |
82 | | bool |
83 | | IMPatternMatcher::isDetermined() const |
84 | 0 | { |
85 | | /** |
86 | | * Matrix entries only increase in dimension as topology is computed. |
87 | | * The predicate can be short-circuited (as false) if |
88 | | * any computed entry is greater than the mask value. |
89 | | */ |
90 | 0 | std::array<Location,3> locs = { |
91 | 0 | Location::INTERIOR, Location::BOUNDARY, Location::EXTERIOR}; |
92 | |
|
93 | 0 | for (Location i : locs) { |
94 | 0 | for (Location j : locs) { |
95 | 0 | int patternEntry = patternMatrix.get(i, j); |
96 | |
|
97 | 0 | if (patternEntry == Dimension::DONTCARE) |
98 | 0 | continue; |
99 | | |
100 | 0 | int matrixVal = getDimension(i, j); |
101 | | |
102 | | //-- mask entry TRUE requires a known matrix entry |
103 | 0 | if (patternEntry == Dimension::True) { |
104 | 0 | if (matrixVal < 0) |
105 | 0 | return false; |
106 | 0 | } |
107 | | //-- result is known (false) if matrix entry has exceeded mask |
108 | 0 | else if (matrixVal > patternEntry) |
109 | 0 | return true; |
110 | 0 | } |
111 | 0 | } |
112 | 0 | return false; |
113 | 0 | } |
114 | | |
115 | | |
116 | | /* public */ |
117 | | bool |
118 | | IMPatternMatcher::valueIM() |
119 | 0 | { |
120 | 0 | bool val = intMatrix.matches(imPattern); |
121 | 0 | return val; |
122 | 0 | } |
123 | | |
124 | | |
125 | | /* public */ |
126 | | std::string |
127 | | IMPatternMatcher::toString() const |
128 | 0 | { |
129 | 0 | return name() + "(" + imPattern + ")"; |
130 | 0 | } |
131 | | |
132 | | |
133 | | /* public friend */ |
134 | | std::ostream& |
135 | | operator<<(std::ostream& os, const IMPatternMatcher& imp) |
136 | 0 | { |
137 | 0 | os << imp.toString(); |
138 | 0 | return os; |
139 | 0 | } |
140 | | |
141 | | |
142 | | |
143 | | } // namespace geos.operation.overlayng |
144 | | } // namespace geos.operation |
145 | | } // namespace geos |
146 | | |
147 | | |
148 | | |
149 | | |