Coverage Report

Created: 2026-10-28 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/src/coverage/CoverageSimplifier.cpp
Line
Count
Source
1
/**********************************************************************
2
 *
3
 * GEOS - Geometry Engine Open Source
4
 * http://geos.osgeo.org
5
 *
6
 * Copyright (C) 2023 Paul Ramsey <pramsey@cleverelephant.ca>
7
 * Copyright (c) 2023 Martin Davis.
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/coverage/CoverageSimplifier.h>
17
#include <geos/coverage/CoverageEdge.h>
18
#include <geos/coverage/CoverageRingEdges.h>
19
#include <geos/coverage/TPVWSimplifier.h>
20
#include <geos/geom/Geometry.h>
21
#include <geos/geom/GeometryFactory.h>
22
#include <geos/geom/MultiLineString.h>
23
#include <geos/util/IllegalArgumentException.h>
24
25
26
using geos::geom::Geometry;
27
using geos::geom::GeometryFactory;
28
using geos::geom::MultiLineString;
29
using geos::util::ProgressFunction;
30
31
namespace geos {     // geos
32
namespace coverage { // geos.coverage
33
34
/* public static */
35
std::vector<std::unique_ptr<Geometry>>
36
CoverageSimplifier::simplify(
37
    std::vector<const Geometry*>& coverage,
38
    double tolerance,
39
    ProgressFunction* progressFunction)
40
0
{
41
0
    CoverageSimplifier simplifier(coverage);
42
0
    return simplifier.simplify(tolerance, progressFunction);
43
0
}
44
45
/* public static */
46
std::vector<std::unique_ptr<Geometry>>
47
CoverageSimplifier::simplify(
48
    const std::vector<std::unique_ptr<Geometry>>& coverage,
49
    double tolerance,
50
    ProgressFunction* progressFunction)
51
0
{
52
0
    std::vector<const Geometry*> geoms;
53
0
    for (auto& geom : coverage) {
54
0
        geoms.push_back(geom.get());
55
0
    }
56
0
    return simplify(geoms, tolerance, progressFunction);
57
0
}
58
59
60
/* public static */
61
std::vector<std::unique_ptr<Geometry>>
62
CoverageSimplifier::simplifyInner(
63
    std::vector<const Geometry*>& coverage,
64
    double tolerance,
65
    ProgressFunction* progressFunction)
66
0
{
67
0
    CoverageSimplifier simplifier(coverage);
68
0
    return simplifier.simplifyInner(tolerance, progressFunction);
69
0
}
70
71
72
/* public static */
73
std::vector<std::unique_ptr<Geometry>>
74
CoverageSimplifier::simplifyInner(
75
    const std::vector<std::unique_ptr<Geometry>>& coverage,
76
    double tolerance,
77
    ProgressFunction* progressFunction)
78
0
{
79
0
    std::vector<const Geometry*> geoms;
80
0
    for (auto& geom : coverage) {
81
0
        geoms.push_back(geom.get());
82
0
    }
83
0
    return simplifyInner(geoms, tolerance, progressFunction);
84
0
}
85
86
87
/* public */
88
CoverageSimplifier::CoverageSimplifier(const std::vector<const Geometry*>& coverage)
89
0
    : m_input(coverage)
90
0
    , m_geomFactory(coverage.empty() ? nullptr : coverage[0]->getFactory())
91
0
    {
92
0
        for (const Geometry* g: m_input) {
93
0
            auto typeId = g->getGeometryTypeId();
94
0
            if (typeId != geom::GEOS_POLYGON && typeId != geom::GEOS_MULTIPOLYGON)
95
0
                throw util::IllegalArgumentException("Argument is non-polygonal");
96
0
        }
97
0
    }
98
99
/* public */
100
std::vector<std::unique_ptr<Geometry>>
101
CoverageSimplifier::simplify(double tolerance,
102
                             ProgressFunction* progressFunction)
103
0
{
104
0
    CoverageRingEdges cov(m_input);
105
0
    simplifyEdges(cov.getEdges(), nullptr, tolerance, progressFunction);
106
0
    return cov.buildCoverage();
107
0
}
108
109
/* public */
110
std::vector<std::unique_ptr<Geometry>>
111
CoverageSimplifier::simplifyInner(double tolerance,
112
                                  ProgressFunction* progressFunction)
113
0
{
114
0
    CoverageRingEdges cov(m_input);
115
0
    std::vector<CoverageEdge*> innerEdges = cov.selectEdges(2);
116
0
    std::vector<CoverageEdge*> outerEdges = cov.selectEdges(1);
117
0
    std::unique_ptr<MultiLineString> constraintEdges = CoverageEdge::createLines(outerEdges, m_geomFactory);
118
119
0
    simplifyEdges(innerEdges, constraintEdges.get(), tolerance, progressFunction);
120
0
    return cov.buildCoverage();
121
0
}
122
123
/* private */
124
void
125
CoverageSimplifier::simplifyEdges(
126
    std::vector<CoverageEdge*> edges,
127
    const MultiLineString* constraints,
128
    double tolerance,
129
    ProgressFunction* progressFunction)
130
0
{
131
0
    std::unique_ptr<MultiLineString> lines = CoverageEdge::createLines(edges, m_geomFactory);
132
0
    std::vector<bool> freeRings = getFreeRings(edges);
133
0
    std::unique_ptr<MultiLineString> linesSimp = TPVWSimplifier::simplify(lines.get(), freeRings, constraints, tolerance, progressFunction);
134
    //Assert: mlsSimp.getNumGeometries = edges.length
135
136
0
    setCoordinates(edges, linesSimp.get());
137
0
}
138
139
140
/* private */
141
void
142
CoverageSimplifier::setCoordinates(std::vector<CoverageEdge*>& edges, const MultiLineString* lines)
143
0
{
144
0
    for (std::size_t i = 0; i < edges.size(); i++) {
145
0
        CoverageEdge* edge = edges[i];
146
0
        edge->setCoordinates(lines->getGeometryN(i)->getSharedCoordinates());
147
0
    }
148
0
}
149
150
151
/* private */
152
std::vector<bool>
153
CoverageSimplifier::getFreeRings(const std::vector<CoverageEdge*>& edges) const
154
0
{
155
0
    std::vector<bool> freeRings;
156
0
    for (auto edge: edges) {
157
0
        freeRings.push_back(edge->isFreeRing());
158
0
    }
159
0
    return freeRings;
160
0
}
161
162
163
} // geos.coverage
164
} // geos