Coverage Report

Created: 2026-09-01 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/src/noding/MCIndexSegmentSetMutualIntersector.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
#include <geos/geom/Envelope.h>
16
#include <geos/noding/MCIndexSegmentSetMutualIntersector.h>
17
#include <geos/noding/SegmentSetMutualIntersector.h>
18
#include <geos/noding/SegmentString.h>
19
#include <geos/noding/SegmentIntersector.h>
20
#include <geos/index/SpatialIndex.h>
21
#include <geos/index/chain/MonotoneChain.h>
22
#include <geos/index/chain/MonotoneChainBuilder.h>
23
#include <geos/index/chain/MonotoneChainOverlapAction.h>
24
#include <geos/index/strtree/SimpleSTRtree.h>
25
26
// std
27
#include <cstddef>
28
29
using namespace geos::index::chain;
30
31
namespace geos {
32
namespace noding { // geos::noding
33
34
35
/*private*/
36
void
37
MCIndexSegmentSetMutualIntersector::addToIndex(SegmentString* segStr)
38
0
{
39
0
    MonotoneChainBuilder::getChains(segStr->getCoordinates().get(),
40
0
                                    segStr, indexChains);
41
42
0
}
43
44
45
/*private*/
46
void
47
MCIndexSegmentSetMutualIntersector::addToMonoChains(SegmentString* segStr)
48
0
{
49
0
    if (segStr->size() == 0)
50
0
        return;
51
0
    MonoChains segChains;
52
0
    MonotoneChainBuilder::getChains(segStr->getCoordinates().get(),
53
0
                                    segStr, segChains);
54
0
    for (auto& mc : segChains) {
55
0
        if (envelope == nullptr || envelope->intersects(mc.getEnvelope())) {
56
0
            monoChains.push_back(mc);
57
0
        }
58
0
    }
59
0
}
60
61
62
/*private*/
63
void
64
MCIndexSegmentSetMutualIntersector::intersectChains()
65
0
{
66
0
    MCIndexSegmentSetMutualIntersector::SegmentOverlapAction overlapAction(*segInt);
67
68
0
    for(auto& queryChain : monoChains) {
69
0
        index.query(queryChain.getEnvelope(overlapTolerance), [&queryChain, &overlapAction, this](const MonotoneChain* testChain) -> bool {
70
0
            queryChain.computeOverlaps(testChain, overlapTolerance, &overlapAction);
71
0
            nOverlaps++;
72
73
0
            return !segInt->isDone(); // abort early if segInt->isDone()
74
0
        });
75
0
    }
76
0
}
77
78
79
/* public */
80
void
81
MCIndexSegmentSetMutualIntersector::setBaseSegments(SegmentString::ConstVect* segStrings)
82
0
{
83
    // NOTE - mloskot: const qualifier is removed silently, dirty.
84
85
0
    for(const SegmentString* css: *segStrings) {
86
0
        if (css->size() == 0)
87
0
            continue;
88
0
        SegmentString* ss = const_cast<SegmentString*>(css);
89
0
        addToIndex(ss);
90
0
    }
91
0
}
92
93
/*public*/
94
void
95
MCIndexSegmentSetMutualIntersector::process(SegmentString::ConstVect* segStrings)
96
0
{
97
0
    if (!indexBuilt) {
98
0
        for (auto& mc: indexChains) {
99
0
            if (envelope == nullptr || envelope->intersects(mc.getEnvelope())) {
100
0
                index.insert(&(mc.getEnvelope(overlapTolerance)), &mc);
101
0
            }
102
0
        }
103
0
        indexBuilt = true;
104
0
    }
105
106
    // Reset counters for new inputs
107
0
    monoChains.clear();
108
0
    processCounter = indexCounter + 1;
109
0
    nOverlaps = 0;
110
111
0
    for(const SegmentString* css: *segStrings) {
112
0
        SegmentString* ss = const_cast<SegmentString*>(css);
113
0
        addToMonoChains(ss);
114
0
    }
115
0
    intersectChains();
116
0
}
117
118
119
/* public */
120
void
121
MCIndexSegmentSetMutualIntersector::SegmentOverlapAction::overlap(
122
    const MonotoneChain& mc1, std::size_t start1, const MonotoneChain& mc2, std::size_t start2)
123
0
{
124
0
    SegmentString* ss1 = static_cast<SegmentString*>(mc1.getContext());
125
0
    SegmentString* ss2 = static_cast<SegmentString*>(mc2.getContext());
126
127
0
    si.processIntersections(ss1, start1, ss2, start2);
128
0
}
129
130
} // geos::noding
131
} // geos