Coverage Report

Created: 2026-09-14 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/src/operation/overlayng/LineLimiter.cpp
Line
Count
Source
1
/**********************************************************************
2
 *
3
 * GEOS - Geometry Engine Open Source
4
 * http://geos.osgeo.org
5
 *
6
 * Copyright (C) 2020 Paul Ramsey <pramsey@cleverelephant.ca>
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/operation/overlayng/LineLimiter.h>
16
#include <geos/geom/CoordinateSequence.h>
17
#include <geos/geom/Envelope.h>
18
#include <geos/geom/Coordinate.h>
19
#include <geos/util.h>
20
21
#include <algorithm>
22
23
using geos::geom::CoordinateSequence;
24
25
namespace geos {      // geos
26
namespace operation { // geos.operation
27
namespace overlayng { // geos.operation.overlayng
28
29
/*public*/
30
std::vector<std::unique_ptr<CoordinateSequence>>&
31
LineLimiter::limit(const CoordinateSequence *pts)
32
4.94k
{
33
    // Reset for new limit run
34
4.94k
    lastOutside = nullptr;
35
4.94k
    ptList.reset(nullptr);
36
4.94k
    sections.clear();
37
4.94k
    hasZ = pts->hasZ();
38
4.94k
    hasM = pts->hasM();
39
40
886k
    pts->forEach([this](const auto& p) {
41
886k
        if (limitEnv->intersects(p)) {
42
448k
            addPoint(p);
43
448k
        }
44
438k
        else {
45
438k
            addOutside(p);
46
438k
        }
47
886k
    });
Unexecuted instantiation: LineLimiter.cpp:auto geos::operation::overlayng::LineLimiter::limit(geos::geom::CoordinateSequence const*)::$_0::operator()<geos::geom::CoordinateXY>(geos::geom::CoordinateXY const&) const
LineLimiter.cpp:auto geos::operation::overlayng::LineLimiter::limit(geos::geom::CoordinateSequence const*)::$_0::operator()<geos::geom::Coordinate>(geos::geom::Coordinate const&) const
Line
Count
Source
40
196k
    pts->forEach([this](const auto& p) {
41
196k
        if (limitEnv->intersects(p)) {
42
103k
            addPoint(p);
43
103k
        }
44
93.0k
        else {
45
93.0k
            addOutside(p);
46
93.0k
        }
47
196k
    });
Unexecuted instantiation: LineLimiter.cpp:auto geos::operation::overlayng::LineLimiter::limit(geos::geom::CoordinateSequence const*)::$_0::operator()<geos::geom::CoordinateXYM>(geos::geom::CoordinateXYM const&) const
LineLimiter.cpp:auto geos::operation::overlayng::LineLimiter::limit(geos::geom::CoordinateSequence const*)::$_0::operator()<geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYZM const&) const
Line
Count
Source
40
690k
    pts->forEach([this](const auto& p) {
41
690k
        if (limitEnv->intersects(p)) {
42
344k
            addPoint(p);
43
344k
        }
44
345k
        else {
45
345k
            addOutside(p);
46
345k
        }
47
690k
    });
48
49
    // finish last section, if any
50
4.94k
    finishSection();
51
4.94k
    return sections;
52
4.94k
}
53
54
/*private*/
55
template<typename CoordType>
56
void
57
LineLimiter::addPoint(const CoordType& p)
58
660k
{
59
660k
    startSection<CoordType>();
60
660k
    ptList->add(p, false);
61
660k
}
Unexecuted instantiation: void geos::operation::overlayng::LineLimiter::addPoint<geos::geom::CoordinateXY>(geos::geom::CoordinateXY const&)
void geos::operation::overlayng::LineLimiter::addPoint<geos::geom::Coordinate>(geos::geom::Coordinate const&)
Line
Count
Source
58
168k
{
59
168k
    startSection<CoordType>();
60
168k
    ptList->add(p, false);
61
168k
}
Unexecuted instantiation: void geos::operation::overlayng::LineLimiter::addPoint<geos::geom::CoordinateXYM>(geos::geom::CoordinateXYM const&)
void geos::operation::overlayng::LineLimiter::addPoint<geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYZM const&)
Line
Count
Source
58
491k
{
59
491k
    startSection<CoordType>();
60
491k
    ptList->add(p, false);
61
491k
}
62
63
/*private*/
64
template<typename CoordType>
65
void
66
LineLimiter::addOutside(const CoordType& p)
67
438k
{
68
438k
    bool segIntersects = isLastSegmentIntersecting(p);
69
438k
    if (!segIntersects) {
70
281k
        finishSection();
71
281k
    }
72
156k
    else {
73
156k
        if(lastOutside != nullptr) {
74
55.4k
            addPoint(*static_cast<const CoordType*>(lastOutside));
75
55.4k
        }
76
156k
        addPoint(p);
77
156k
    }
78
438k
    lastOutside = &p;
79
438k
}
Unexecuted instantiation: void geos::operation::overlayng::LineLimiter::addOutside<geos::geom::CoordinateXY>(geos::geom::CoordinateXY const&)
void geos::operation::overlayng::LineLimiter::addOutside<geos::geom::Coordinate>(geos::geom::Coordinate const&)
Line
Count
Source
67
93.0k
{
68
93.0k
    bool segIntersects = isLastSegmentIntersecting(p);
69
93.0k
    if (!segIntersects) {
70
47.4k
        finishSection();
71
47.4k
    }
72
45.6k
    else {
73
45.6k
        if(lastOutside != nullptr) {
74
19.3k
            addPoint(*static_cast<const CoordType*>(lastOutside));
75
19.3k
        }
76
45.6k
        addPoint(p);
77
45.6k
    }
78
93.0k
    lastOutside = &p;
79
93.0k
}
Unexecuted instantiation: void geos::operation::overlayng::LineLimiter::addOutside<geos::geom::CoordinateXYM>(geos::geom::CoordinateXYM const&)
void geos::operation::overlayng::LineLimiter::addOutside<geos::geom::CoordinateXYZM>(geos::geom::CoordinateXYZM const&)
Line
Count
Source
67
345k
{
68
345k
    bool segIntersects = isLastSegmentIntersecting(p);
69
345k
    if (!segIntersects) {
70
234k
        finishSection();
71
234k
    }
72
111k
    else {
73
111k
        if(lastOutside != nullptr) {
74
36.1k
            addPoint(*static_cast<const CoordType*>(lastOutside));
75
36.1k
        }
76
111k
        addPoint(p);
77
111k
    }
78
345k
    lastOutside = &p;
79
345k
}
80
81
/*private*/
82
bool
83
LineLimiter::isLastSegmentIntersecting(const CoordinateXY& p) const
84
438k
{
85
438k
    if (lastOutside == nullptr) {
86
        // last point must have been inside
87
104k
        if (isSectionOpen())
88
101k
            return true;
89
2.92k
        return false;
90
104k
    }
91
334k
    return limitEnv->intersects(*lastOutside, p);
92
438k
}
93
94
/*private*/
95
bool
96
LineLimiter::isSectionOpen() const
97
1.05M
{
98
1.05M
    return ptList != nullptr;
99
1.05M
}
100
101
/*private*/
102
template<typename CoordType>
103
void
104
LineLimiter::startSection()
105
660k
{
106
660k
    if (!isSectionOpen()) {
107
61.7k
        ptList = std::make_unique<CoordinateSequence>(0, hasZ, hasM);
108
61.7k
    }
109
110
660k
    if (lastOutside != nullptr) {
111
156k
        ptList->add(*static_cast<const CoordType*>(lastOutside), false);
112
156k
    }
113
660k
    lastOutside = nullptr;
114
660k
}
Unexecuted instantiation: void geos::operation::overlayng::LineLimiter::startSection<geos::geom::CoordinateXY>()
void geos::operation::overlayng::LineLimiter::startSection<geos::geom::Coordinate>()
Line
Count
Source
105
168k
{
106
168k
    if (!isSectionOpen()) {
107
19.3k
        ptList = std::make_unique<CoordinateSequence>(0, hasZ, hasM);
108
19.3k
    }
109
110
168k
    if (lastOutside != nullptr) {
111
45.8k
        ptList->add(*static_cast<const CoordType*>(lastOutside), false);
112
45.8k
    }
113
168k
    lastOutside = nullptr;
114
168k
}
Unexecuted instantiation: void geos::operation::overlayng::LineLimiter::startSection<geos::geom::CoordinateXYM>()
void geos::operation::overlayng::LineLimiter::startSection<geos::geom::CoordinateXYZM>()
Line
Count
Source
105
491k
{
106
491k
    if (!isSectionOpen()) {
107
42.3k
        ptList = std::make_unique<CoordinateSequence>(0, hasZ, hasM);
108
42.3k
    }
109
110
491k
    if (lastOutside != nullptr) {
111
110k
        ptList->add(*static_cast<const CoordType*>(lastOutside), false);
112
110k
    }
113
491k
    lastOutside = nullptr;
114
491k
}
115
116
/*private*/
117
void
118
LineLimiter::finishSection()
119
286k
{
120
286k
    if (!isSectionOpen())
121
224k
        return;
122
123
    // finish off this section
124
61.7k
    if (lastOutside != nullptr) {
125
59.6k
        ptList->add(*lastOutside, false);
126
59.6k
        lastOutside = nullptr;
127
59.6k
    }
128
129
    // remove repeated points from the section
130
61.7k
    assert(!ptList->hasRepeatedPoints());
131
    //ptList->erase(std::unique(ptList->begin(), ptList->end()), ptList->end());
132
133
61.7k
    sections.push_back(std::move(ptList));
134
61.7k
    ptList.reset(nullptr);
135
61.7k
}
136
137
138
139
140
} // namespace geos.operation.overlayng
141
} // namespace geos.operation
142
} // namespace geos