/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 |