9 #include <simo/geom/detail/geometry.hpp> 10 #include <simo/geom/detail/bounds.hpp> 17 template <
typename T,
typename AllocatorType = std::allocator<T>>
19 :
public std::vector<T, AllocatorType>,
23 using base_type = std::vector<T, AllocatorType>;
25 using polygon_type = T;
26 using polygon_iterator =
typename std::vector<polygon_type>::iterator;
27 using polygon_const_iterator =
typename std::vector<polygon_type>::const_iterator;
29 using point_type =
typename T::point_type;
30 using point_iterator =
typename std::vector<point_type>::iterator;
31 using point_const_iterator =
typename std::vector<point_type>::const_iterator;
33 using coord_type =
typename T::coord_type;
34 using coord_iterator =
typename std::vector<coord_type>::iterator;
35 using coord_const_iterator =
typename std::vector<coord_type>::const_iterator;
41 : base_type(first, last)
46 : base_type(first, last)
51 : base_type(init.begin(), init.end()) {}
53 template <
typename CoordIterator,
typename OffsetIterator>
54 basic_multipolygon(CoordIterator coord_first, CoordIterator coord_last, OffsetIterator offset_first, OffsetIterator offset_last)
56 if (std::distance(coord_first, coord_last) > 0)
58 auto n = this->
ndim();
59 this->reserve((coord_last - coord_first) / n);
61 for (
auto it = offset_first; it != offset_last; ++it)
64 this->emplace_back(coord_first + lo, coord_first + hi);
74 if (lhs.size() != rhs.size())
78 for (
size_t i = 0; i < lhs.size(); ++i)
90 return not operator==(lhs, rhs);
93 std::vector<std::tuple<double, double>> xy()
const 95 std::vector<std::tuple<double, double>> res;
96 res.reserve(this->size());
97 for (
const auto& p : *
this)
99 res.emplace_back(p.x, p.y);
109 geometry_type geom_type_() const noexcept
113 return geometry_type::MULTIPOLYGONZ;
117 return geometry_type::MULTIPOLYGONM;
121 return geometry_type::MULTIPOLYGONZM;
123 return geometry_type::MULTIPOLYGON;
127 bool is_closed_() const noexcept
133 return *
this[0] == *
this[this->size() - 1];
137 void throw_for_invalid_()
const 139 for (
const auto& ls : *
this)
141 ls.throw_for_invalid();
149 for (
const auto& p : *
this)
163 auto j = nlohmann::json::parse(json);
164 auto geom_type = j.at(
"type").get<std::string>();
169 const auto& polygons = j.at(
"coordinates");
171 res.reserve(polygons.size());
172 std::vector<point_type> points;
173 for (
const auto&
polygon : polygons)
177 const auto& coords =
polygon.get<std::vector<std::vector<double>>>();
178 points.reserve(coords.size());
179 std::for_each(std::begin(coords), std::end(coords),
180 [&points](
const std::vector<double>& coord) {
181 points.emplace_back(coord.begin(), coord.end());
183 res.emplace_back(points.begin(), points.end());
189 catch (
const nlohmann::json::exception& e)
200 std::string json_(std::int32_t precision = -1)
const 202 std::stringstream ss;
205 ss << std::setprecision(precision);
207 ss <<
"{\"type\":\"Multipolygon\",\"coordinates\":[";
208 for (
size_t polygon_index = 0; polygon_index < this->size(); ++polygon_index)
210 const auto& pg = (*this)[polygon_index];
211 if (polygon_index > 0)
216 for (
size_t ring_index = 0; ring_index < pg.size(); ++ring_index)
218 const auto& ring = pg[ring_index];
224 for (
size_t point_index = 0; point_index < ring.size(); ++point_index)
226 const auto& p = ring[point_index];
232 for (
size_t coord_index = 0; coord_index < p.size(); ++coord_index)
238 ss << p.coords[coord_index];
256 auto result = reader.
read(wkt);
257 const auto& data = result.
data;
258 if (not utils::is_multipolygon(data.geom_type))
262 return basic_multipolygon<T>(data.coords.begin(), data.coords.end(), data.offsets.begin(), data.offsets.end());
266 std::string wkt_(std::int32_t precision = -1)
const 268 std::stringstream ss;
271 ss << std::setprecision(precision);
273 ss <<
"MULTIPOLYGON";
282 size_t polygon_index = 0;
284 for (
const auto& pg : *
this)
286 if (polygon_index > 0)
291 size_t ring_index = 0;
292 for (
const auto& ring : pg)
299 size_t point_index = 0;
300 for (
const auto& p : ring)
306 for (
size_t k = 0; k < p.ndim(); ++k)
331 template <
typename T>
339 template <
typename T>
347 template <
typename T>
355 template <
typename T>
geometry_type geom_type() const noexcept
Returns the geometry type.
Base class for all geometries.
wkt_data data
the parser result data
wkt_result read(const std::string &wkt)
parse the given wkt string
Exception thrown when a geometry error is found.
const char * what() const noexceptoverride
Returns the exception reason.
Represents an axis-aligned bounding box.
bool has_z() const noexcept
Whether the geometry has the z-coordinate.
bounds_t & extend(double x, double y)
Extends the bounds to contain the given point.
Exception thrown when an error has been found while parsing.
std::string json(std::int32_t precision=-1) const
Dumps the geojson representation of the geometry.
bool has_m() const noexcept
Whether the geometry has the m-coordinate (measurement coordinate)
std::string wkt(std::int32_t precision=-1) const
Dumps the wkt representation of the geometry.
size_t ndim() const noexcept
Returns the number of dimensions of the geometry.