Coverage Report

Created: 2025-09-27 06:58

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