Coverage Report

Created: 2026-02-14 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/src/operation/union/UnaryUnionOp.cpp
Line
Count
Source
1
/**********************************************************************
2
 *
3
 * GEOS - Geometry Engine Open Source
4
 * http://geos.osgeo.org
5
 *
6
 * Copyright (C) 2011 Sandro Santilli <strk@kbt.io
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
 * Last port: operation/union/UnaryUnionOp.java r320 (JTS-1.12)
16
 *
17
 **********************************************************************/
18
19
#include <memory> // for unique_ptr
20
#include <cassert> // for assert
21
#include <algorithm> // for copy
22
23
#include <geos/operation/union/UnaryUnionOp.h>
24
#include <geos/operation/union/CascadedPolygonUnion.h>
25
#include <geos/operation/union/PointGeometryUnion.h>
26
#include <geos/geom/Coordinate.h>
27
#include <geos/geom/Point.h>
28
#include <geos/geom/MultiPoint.h>
29
#include <geos/geom/MultiLineString.h>
30
#include <geos/geom/MultiPolygon.h>
31
#include <geos/geom/GeometryCollection.h>
32
#include <geos/geom/Geometry.h>
33
#include <geos/geom/Location.h>
34
#include <geos/geom/GeometryFactory.h>
35
#include <geos/geom/util/GeometryCombiner.h>
36
#include <geos/algorithm/PointLocator.h>
37
38
#include "geos/util.h"
39
40
namespace geos {
41
namespace operation { // geos::operation
42
namespace geounion {  // geos::operation::geounion
43
44
/*private*/
45
std::unique_ptr<geom::Geometry>
46
UnaryUnionOp::unionWithNull(std::unique_ptr<geom::Geometry> g0,
47
                            std::unique_ptr<geom::Geometry> g1)
48
55.2k
{
49
55.2k
    std::unique_ptr<geom::Geometry> ret;
50
55.2k
    if((! g0.get()) && (! g1.get())) {
51
43.6k
        return ret;
52
43.6k
    }
53
54
11.6k
    if(! g0.get()) {
55
3.71k
        return g1;
56
3.71k
    }
57
7.88k
    if(! g1.get()) {
58
7.88k
        return g0;
59
7.88k
    }
60
61
0
    ret = g0->Union(g1.get());
62
0
    return ret;
63
7.88k
}
64
65
/*public*/
66
std::unique_ptr<geom::Geometry>
67
UnaryUnionOp::Union()
68
56.6k
{
69
56.6k
    typedef std::unique_ptr<geom::Geometry> GeomPtr;
70
71
56.6k
    GeomPtr ret;
72
56.6k
    if(! geomFact) {
73
0
        return ret;
74
0
    }
75
76
    /*
77
     * For points and lines, only a single union operation is
78
     * required, since the OGC model allows self-intersecting
79
     * MultiPoint and MultiLineStrings.
80
     * This is not the case for polygons, so Cascaded Union is required.
81
     */
82
83
56.6k
    GeomPtr unionPoints;
84
56.6k
    if(!points.empty()) {
85
8.01k
        GeomPtr ptGeom = geomFact->buildGeometry(points.begin(),
86
8.01k
                         points.end());
87
8.01k
        unionPoints = unionNoOpt(*ptGeom);
88
8.01k
    }
89
90
56.6k
    GeomPtr unionLines;
91
56.6k
    if(!lines.empty()) {
92
7.98k
        auto combinedLines = geomFact->buildGeometry(lines.begin(), lines.end());
93
7.98k
        unionLines = unionNoOpt(*combinedLines);
94
7.98k
    }
95
96
56.6k
    GeomPtr unionPolygons;
97
56.6k
    if(!polygons.empty()) {
98
5.06k
        unionPolygons = CascadedPolygonUnion::Union(polygons.begin(), polygons.end(), unionFunction);
99
5.06k
    }
100
101
    /*
102
     * Performing two unions is somewhat inefficient,
103
     * but is mitigated by unioning lines and polygons first
104
     * (since point union can be done efficiently
105
     * against a collection of lines and polygons)
106
     */
107
108
56.6k
    GeomPtr unionLA = unionWithNull(std::move(unionLines), std::move(unionPolygons));
109
110
111
56.6k
    if(! unionPoints.get()) {
112
47.2k
        ret = std::move(unionLA);
113
47.2k
    }
114
9.45k
    else if(! unionLA.get()) {
115
8.01k
        ret = std::move(unionPoints);
116
8.01k
    }
117
1.43k
    else {
118
1.43k
        ret = PointGeometryUnion::Union(*unionPoints, *unionLA);
119
1.43k
    }
120
121
56.6k
    if(! ret.get()) {
122
35.6k
        ret = geomFact->createGeometryCollection();
123
35.6k
    }
124
125
56.6k
    return ret;
126
127
56.6k
}
128
129
} // namespace geos::operation::union
130
} // namespace geos::operation
131
} // namespace geos