1#ifndef OSMIUM_GEOM_WKB_HPP
2#define OSMIUM_GEOM_WKB_HPP
62 inline void str_push(std::string& str, T data) {
63 str.append(
reinterpret_cast<const char*
>(&data),
sizeof(T));
66 inline std::string convert_to_hex(
const std::string& str) {
67 static const char* lookup_hex =
"0123456789ABCDEF";
69 out.reserve(str.size() * 2);
71 for (
const char c : str) {
72 out += lookup_hex[(
static_cast<unsigned int>(c) >> 4U) & 0xfU];
73 out += lookup_hex[
static_cast<unsigned int>(c) & 0xfU];
79 class WKBFactoryImpl {
88 enum wkbGeometryType : uint32_t {
93 wkbMultiLineString = 5,
95 wkbGeometryCollection = 7,
104 enum class wkb_byte_order_type : uint8_t {
110 uint32_t m_points = 0;
115 std::size_t m_linestring_size_offset = 0;
116 std::size_t m_polygons = 0;
117 std::size_t m_rings = 0;
118 std::size_t m_multipolygon_size_offset = 0;
119 std::size_t m_polygon_size_offset = 0;
120 std::size_t m_ring_size_offset = 0;
122 std::size_t header(std::string& str, wkbGeometryType
type,
bool add_length)
const {
123#if __BYTE_ORDER == __LITTLE_ENDIAN
124 str_push(str, wkb_byte_order_type::NDR);
126 str_push(str, wkb_byte_order_type::XDR);
129 str_push(str,
type | wkbSRID);
130 str_push(str, m_srid);
134 const std::size_t offset = str.size();
136 str_push(str,
static_cast<uint32_t
>(0));
141 void set_size(
const std::size_t offset,
const std::size_t size) {
142 if (size > std::numeric_limits<uint32_t>::max()) {
143 throw geometry_error{
"Too many points in geometry"};
145 const auto s =
static_cast<uint32_t
>(size);
146 std::copy_n(
reinterpret_cast<const char*
>(&s),
sizeof(uint32_t), &m_data[offset]);
151 using point_type = std::string;
152 using linestring_type = std::string;
153 using polygon_type = std::string;
154 using multipolygon_type = std::string;
155 using ring_type = std::string;
167 header(data, wkbPoint,
false);
168 str_push(data, xy.
x);
169 str_push(data, xy.
y);
172 return convert_to_hex(data);
180 void linestring_start() {
182 m_linestring_size_offset = header(m_data, wkbLineString,
true);
186 str_push(m_data, xy.
x);
187 str_push(m_data, xy.
y);
190 linestring_type linestring_finish(std::size_t num_points) {
191 set_size(m_linestring_size_offset, num_points);
198 return convert_to_hex(data);
206 void polygon_start() {
208 set_size(header(m_data, wkbPolygon,
true), 1);
209 m_ring_size_offset = m_data.size();
210 str_push(m_data,
static_cast<uint32_t
>(0));
214 str_push(m_data, xy.
x);
215 str_push(m_data, xy.
y);
218 polygon_type polygon_finish(std::size_t num_points) {
219 set_size(m_ring_size_offset, num_points);
226 return convert_to_hex(data);
234 void multipolygon_start() {
237 m_multipolygon_size_offset = header(m_data, wkbMultiPolygon,
true);
240 void multipolygon_polygon_start() {
243 m_polygon_size_offset = header(m_data, wkbPolygon,
true);
246 void multipolygon_polygon_finish() {
247 set_size(m_polygon_size_offset, m_rings);
250 void multipolygon_outer_ring_start() {
253 m_ring_size_offset = m_data.size();
254 str_push(m_data,
static_cast<uint32_t
>(0));
257 void multipolygon_outer_ring_finish() {
258 set_size(m_ring_size_offset, m_points);
261 void multipolygon_inner_ring_start() {
264 m_ring_size_offset = m_data.size();
265 str_push(m_data,
static_cast<uint32_t
>(0));
268 void multipolygon_inner_ring_finish() {
269 set_size(m_ring_size_offset, m_points);
273 str_push(m_data, xy.
x);
274 str_push(m_data, xy.
y);
278 multipolygon_type multipolygon_finish() {
279 set_size(m_multipolygon_size_offset, m_polygons);
286 return convert_to_hex(data);
296 template <
typename TProjection = IdentityProjection>
Definition: factory.hpp:149
wkb_type
Definition: wkb.hpp:49
out_type
Definition: wkb.hpp:54
type
Definition: entity_bits.hpp:63
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53
Definition: coordinates.hpp:48
double y
Definition: coordinates.hpp:51
double x
Definition: coordinates.hpp:50