Coverage Report

Created: 2026-04-01 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/src/operation/union/PointGeometryUnion.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/PointGeometryUnion.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
#include <geos/operation/union/PointGeometryUnion.h>
23
#include <geos/geom/Coordinate.h>
24
#include <geos/geom/Point.h>
25
#include <geos/geom/MultiPoint.h>
26
#include <geos/geom/Geometry.h>
27
#include <geos/geom/Location.h>
28
#include <geos/geom/GeometryFactory.h>
29
#include <geos/geom/util/GeometryCombiner.h>
30
#include <geos/algorithm/PointLocator.h>
31
32
namespace geos {
33
namespace operation { // geos::operation
34
namespace geounion {  // geos::operation::geounion
35
36
/* public */
37
std::unique_ptr<geom::Geometry>
38
PointGeometryUnion::Union() const
39
0
{
40
0
    using namespace geom;
41
0
    using algorithm::PointLocator;
42
0
    using geom::util::GeometryCombiner;
43
44
0
    PointLocator locater;
45
    // use a set to eliminate duplicates, as required for union
46
0
    std::set<Coordinate> exteriorCoords;
47
48
0
    for(std::size_t i = 0, n = pointGeom.getNumGeometries(); i < n; ++i) {
49
0
        const Point* point = dynamic_cast<const Point*>(pointGeom.getGeometryN(i));
50
0
        assert(point);
51
52
0
        if (point->isEmpty()) {
53
0
            continue;
54
0
        }
55
56
0
        const Coordinate* coord = static_cast<const Coordinate*>(point->getCoordinate());
57
0
        Location loc = locater.locate(*coord, &otherGeom);
58
0
        if(loc == Location::EXTERIOR) {
59
0
            exteriorCoords.insert(*coord);
60
0
        }
61
0
    }
62
63
    // if no points are in exterior, return the other geom
64
0
    if(exteriorCoords.empty()) {
65
0
        return otherGeom.clone();
66
0
    }
67
68
    // make a puntal geometry of appropriate size
69
0
    std::unique_ptr<Geometry> ptComp;
70
71
0
    if(exteriorCoords.size() == 1) {
72
0
        ptComp = geomFact->createPoint(*(exteriorCoords.begin()));
73
0
    }
74
0
    else {
75
0
        ptComp = geomFact->createMultiPoint(exteriorCoords);
76
0
    }
77
78
    // add point component to the other geometry
79
0
    return GeometryCombiner::combine(ptComp.get(), &otherGeom);
80
0
}
81
82
/* public  static */
83
std::unique_ptr<geom::Geometry>
84
PointGeometryUnion::Union(const geom::Geometry& pointGeom,
85
                          const geom::Geometry& otherGeom)
86
0
{
87
0
    PointGeometryUnion unioner(pointGeom, otherGeom);
88
0
    return unioner.Union();
89
0
}
90
91
/* public */
92
PointGeometryUnion::PointGeometryUnion(const geom::Geometry& pointGeom_,
93
                                       const geom::Geometry& otherGeom_)
94
    :
95
0
    pointGeom(pointGeom_),
96
0
    otherGeom(otherGeom_)
97
0
{
98
0
    geomFact = otherGeom.getFactory();
99
0
}
100
101
} // namespace geos::operation::union
102
} // namespace geos::operation
103
} // namespace geos