1 #ifndef OSMIUM_GEOM_GEOS_HPP
2 #define OSMIUM_GEOM_GEOS_HPP
54 #include <geos/geom/Coordinate.h>
55 #include <geos/geom/CoordinateSequence.h>
56 #include <geos/geom/CoordinateSequenceFactory.h>
57 #include <geos/geom/GeometryFactory.h>
58 #include <geos/geom/LinearRing.h>
59 #include <geos/geom/MultiPolygon.h>
60 #include <geos/geom/Point.h>
61 #include <geos/geom/Polygon.h>
62 #include <geos/geom/PrecisionModel.h>
63 #include <geos/util/GEOSException.h>
74 # define THROW std::throw_with_nested
82 geometry_error(
std::string{
"geometry creation failed in GEOS library: "} + message) {
91 class GEOSFactoryImpl {
93 std::unique_ptr<const geos::geom::PrecisionModel> m_precision_model;
94 std::unique_ptr<geos::geom::GeometryFactory> m_our_geos_factory;
95 geos::geom::GeometryFactory* m_geos_factory;
97 std::unique_ptr<geos::geom::CoordinateSequence> m_coordinate_sequence;
98 std::vector<std::unique_ptr<geos::geom::LinearRing>> m_rings;
99 std::vector<std::unique_ptr<geos::geom::Polygon>> m_polygons;
103 using point_type = std::unique_ptr<geos::geom::Point>;
104 using linestring_type = std::unique_ptr<geos::geom::LineString>;
105 using polygon_type = std::unique_ptr<geos::geom::Polygon>;
106 using multipolygon_type = std::unique_ptr<geos::geom::MultiPolygon>;
107 using ring_type = std::unique_ptr<geos::geom::LinearRing>;
109 explicit GEOSFactoryImpl(
int , geos::geom::GeometryFactory& geos_factory) :
110 m_precision_model(nullptr),
111 m_our_geos_factory(nullptr),
112 m_geos_factory(&geos_factory) {
120 m_precision_model(new geos::geom::PrecisionModel),
121 m_our_geos_factory(new geos::geom::GeometryFactory(m_precision_model.get(), srid)),
122 m_geos_factory(m_our_geos_factory.get()) {
125 explicit GEOSFactoryImpl(
int srid) :
126 m_precision_model(new geos::geom::PrecisionModel),
127 m_our_geos_factory(new geos::geom::GeometryFactory(m_precision_model.get(), srid)),
128 m_geos_factory(m_our_geos_factory.get()) {
135 return point_type(m_geos_factory->createPoint(geos::geom::Coordinate(xy.
x, xy.
y)));
136 }
catch (
const geos::util::GEOSException& e) {
143 void linestring_start() {
145 m_coordinate_sequence.reset(m_geos_factory->getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2));
146 }
catch (
const geos::util::GEOSException& e) {
153 m_coordinate_sequence->add(geos::geom::Coordinate(xy.
x, xy.
y));
154 }
catch (
const geos::util::GEOSException& e) {
159 linestring_type linestring_finish(
size_t ) {
161 return linestring_type(m_geos_factory->createLineString(m_coordinate_sequence.release()));
162 }
catch (
const geos::util::GEOSException& e) {
169 void multipolygon_start() {
173 void multipolygon_polygon_start() {
177 void multipolygon_polygon_finish() {
179 assert(!m_rings.empty());
180 auto inner_rings =
new std::vector<geos::geom::Geometry*>;
181 std::transform(std::next(m_rings.begin(), 1), m_rings.end(), std::back_inserter(*inner_rings), [](std::unique_ptr<geos::geom::LinearRing>& r) {
184 m_polygons.emplace_back(m_geos_factory->createPolygon(m_rings[0].release(), inner_rings));
186 }
catch (
const geos::util::GEOSException& e) {
191 void multipolygon_outer_ring_start() {
193 m_coordinate_sequence.reset(m_geos_factory->getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2));
194 }
catch (
const geos::util::GEOSException& e) {
199 void multipolygon_outer_ring_finish() {
201 m_rings.emplace_back(m_geos_factory->createLinearRing(m_coordinate_sequence.release()));
202 }
catch (
const geos::util::GEOSException& e) {
207 void multipolygon_inner_ring_start() {
209 m_coordinate_sequence.reset(m_geos_factory->getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2));
210 }
catch (
const geos::util::GEOSException& e) {
215 void multipolygon_inner_ring_finish() {
217 m_rings.emplace_back(m_geos_factory->createLinearRing(m_coordinate_sequence.release()));
218 }
catch (
const geos::util::GEOSException& e) {
225 m_coordinate_sequence->add(geos::geom::Coordinate(xy.
x, xy.
y));
226 }
catch (
const geos::util::GEOSException& e) {
231 multipolygon_type multipolygon_finish() {
233 auto polygons =
new std::vector<geos::geom::Geometry*>;
234 std::transform(m_polygons.begin(), m_polygons.end(), std::back_inserter(*polygons), [](std::unique_ptr<geos::geom::Polygon>& p) {
238 return multipolygon_type(m_geos_factory->createMultiPolygon(polygons));
239 }
catch (
const geos::util::GEOSException& e) {
248 template <
typename TProjection = IdentityProjection>
257 #endif // OSMIUM_GEOM_GEOS_HPP
double y
Definition: coordinates.hpp:49
#define OSMIUM_DEPRECATED
Definition: compatibility.hpp:50
Definition: factory.hpp:148
#define THROW
Definition: geos.hpp:74
Definition: reader_iterator.hpp:39
Coordinates transform(const CRS &src, const CRS &dest, Coordinates c)
Definition: projection.hpp:113
Definition: factory.hpp:59
Namespace for everything in the Osmium library.
Definition: assembler.hpp:73
geos_geometry_error(const char *message)
Definition: geos.hpp:81
Definition: coordinates.hpp:46
double x
Definition: coordinates.hpp:48