Libosmium  2.1.0
Fast and flexible C++ library for working with OpenStreetMap data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
geos.hpp
Go to the documentation of this file.
1 #ifndef OSMIUM_GEOM_GEOS_HPP
2 #define OSMIUM_GEOM_GEOS_HPP
3 
4 /*
5 
6 This file is part of Osmium (http://osmcode.org/libosmium).
7 
8 Copyright 2013-2015 Jochen Topf <jochen@topf.org> and others (see README).
9 
10 Boost Software License - Version 1.0 - August 17th, 2003
11 
12 Permission is hereby granted, free of charge, to any person or organization
13 obtaining a copy of the software and accompanying documentation covered by
14 this license (the "Software") to use, reproduce, display, distribute,
15 execute, and transmit the Software, and to prepare derivative works of the
16 Software, and to permit third-parties to whom the Software is furnished to
17 do so, all subject to the following:
18 
19 The copyright notices in the Software and this entire statement, including
20 the above license grant, this restriction and the following disclaimer,
21 must be included in all copies of the Software, in whole or in part, and
22 all derivative works of the Software, unless such copies or derivative
23 works are solely in the form of machine-executable object code generated by
24 a source language processor.
25 
26 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
29 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
30 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
31 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32 DEALINGS IN THE SOFTWARE.
33 
34 */
35 
45 #include <utility>
46 
47 #include <geos/geom/Coordinate.h>
48 #include <geos/geom/CoordinateSequence.h>
49 #include <geos/geom/CoordinateSequenceFactory.h>
50 #include <geos/geom/GeometryFactory.h>
51 #include <geos/geom/LinearRing.h>
52 #include <geos/geom/MultiPolygon.h>
53 #include <geos/geom/Point.h>
54 #include <geos/geom/Polygon.h>
55 #include <geos/geom/PrecisionModel.h>
56 #include <geos/util/GEOSException.h>
57 
58 #include <osmium/geom/factory.hpp>
60 
61 // MSVC doesn't support throw_with_nested yet
62 #ifdef _MSC_VER
63 # define THROW throw
64 #else
65 # define THROW std::throw_with_nested
66 #endif
67 
68 namespace osmium {
69 
71 
73  geometry_error("geometry creation failed in GEOS library, see nested exception for details") {
74  }
75 
76  }; // struct geos_geometry_error
77 
78  namespace geom {
79 
80  namespace detail {
81 
82  class GEOSFactoryImpl {
83 
84  geos::geom::PrecisionModel m_precision_model;
85  geos::geom::GeometryFactory m_geos_factory;
86 
87  std::unique_ptr<geos::geom::CoordinateSequence> m_coordinate_sequence;
88  std::vector<std::unique_ptr<geos::geom::LinearRing>> m_rings;
89  std::vector<std::unique_ptr<geos::geom::Polygon>> m_polygons;
90 
91  public:
92 
93  typedef std::unique_ptr<geos::geom::Point> point_type;
94  typedef std::unique_ptr<geos::geom::LineString> linestring_type;
95  typedef std::unique_ptr<geos::geom::Polygon> polygon_type;
96  typedef std::unique_ptr<geos::geom::MultiPolygon> multipolygon_type;
97  typedef std::unique_ptr<geos::geom::LinearRing> ring_type;
98 
99  explicit GEOSFactoryImpl(int srid = -1) :
100  m_precision_model(),
101  m_geos_factory(&m_precision_model, srid) {
102  }
103 
104  /* Point */
105 
106  point_type make_point(const osmium::geom::Coordinates& xy) const {
107  try {
108  return point_type(m_geos_factory.createPoint(geos::geom::Coordinate(xy.x, xy.y)));
109  } catch (geos::util::GEOSException&) {
111  }
112  }
113 
114  /* LineString */
115 
116  void linestring_start() {
117  try {
118  m_coordinate_sequence.reset(m_geos_factory.getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2));
119  } catch (geos::util::GEOSException&) {
121  }
122  }
123 
124  void linestring_add_location(const osmium::geom::Coordinates& xy) {
125  try {
126  m_coordinate_sequence->add(geos::geom::Coordinate(xy.x, xy.y));
127  } catch (geos::util::GEOSException&) {
129  }
130  }
131 
132  linestring_type linestring_finish(size_t /* num_points */) {
133  try {
134  return linestring_type(m_geos_factory.createLineString(m_coordinate_sequence.release()));
135  } catch (geos::util::GEOSException&) {
137  }
138  }
139 
140  /* MultiPolygon */
141 
142  void multipolygon_start() {
143  m_polygons.clear();
144  }
145 
146  void multipolygon_polygon_start() {
147  m_rings.clear();
148  }
149 
150  void multipolygon_polygon_finish() {
151  try {
152  assert(!m_rings.empty());
153  auto inner_rings = new std::vector<geos::geom::Geometry*>;
154  std::transform(std::next(m_rings.begin(), 1), m_rings.end(), std::back_inserter(*inner_rings), [](std::unique_ptr<geos::geom::LinearRing>& r) {
155  return r.release();
156  });
157  m_polygons.emplace_back(m_geos_factory.createPolygon(m_rings[0].release(), inner_rings));
158  m_rings.clear();
159  } catch (geos::util::GEOSException&) {
161  }
162  }
163 
164  void multipolygon_outer_ring_start() {
165  try {
166  m_coordinate_sequence.reset(m_geos_factory.getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2));
167  } catch (geos::util::GEOSException&) {
169  }
170  }
171 
172  void multipolygon_outer_ring_finish() {
173  try {
174  m_rings.emplace_back(m_geos_factory.createLinearRing(m_coordinate_sequence.release()));
175  } catch (geos::util::GEOSException&) {
177  }
178  }
179 
180  void multipolygon_inner_ring_start() {
181  try {
182  m_coordinate_sequence.reset(m_geos_factory.getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2));
183  } catch (geos::util::GEOSException&) {
185  }
186  }
187 
188  void multipolygon_inner_ring_finish() {
189  try {
190  m_rings.emplace_back(m_geos_factory.createLinearRing(m_coordinate_sequence.release()));
191  } catch (geos::util::GEOSException&) {
193  }
194  }
195 
196  void multipolygon_add_location(const osmium::geom::Coordinates& xy) {
197  try {
198  m_coordinate_sequence->add(geos::geom::Coordinate(xy.x, xy.y));
199  } catch (geos::util::GEOSException&) {
201  }
202  }
203 
204  multipolygon_type multipolygon_finish() {
205  try {
206  auto polygons = new std::vector<geos::geom::Geometry*>;
207  std::transform(m_polygons.begin(), m_polygons.end(), std::back_inserter(*polygons), [](std::unique_ptr<geos::geom::Polygon>& p) {
208  return p.release();
209  });
210  m_polygons.clear();
211  return multipolygon_type(m_geos_factory.createMultiPolygon(polygons));
212  } catch (geos::util::GEOSException&) {
214  }
215  }
216 
217  }; // class GEOSFactoryImpl
218 
219  } // namespace detail
220 
221  template <class TProjection = IdentityProjection>
223 
224  } // namespace geom
225 
226 } // namespace osmium
227 
228 #undef THROW
229 
230 #endif // OSMIUM_GEOM_GEOS_HPP
double y
Definition: coordinates.hpp:50
Definition: factory.hpp:117
#define THROW
Definition: geos.hpp:65
Definition: geos.hpp:70
Namespace for everything in the Osmium library.
Definition: assembler.hpp:55
Definition: coordinates.hpp:47
Definition: factory.hpp:57
geos_geometry_error()
Definition: geos.hpp:72
double x
Definition: coordinates.hpp:49