From 710e74219a0e164d5e026602990378103ab7bcc5 Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Wed, 29 Oct 2014 16:27:48 -0400 Subject: [PATCH] libosmium version bump --- ThirdParty/osmium/area/assembler.hpp | 58 +- .../osmium/area/detail/node_ref_segment.hpp | 65 +- ThirdParty/osmium/area/detail/proto_ring.hpp | 10 +- .../osmium/area/detail/segment_list.hpp | 12 +- .../osmium/area/multipolygon_collector.hpp | 422 +++---- ThirdParty/osmium/area/problem_reporter.hpp | 298 ++--- .../osmium/area/problem_reporter_ogr.hpp | 6 +- .../osmium/area/problem_reporter_stream.hpp | 192 +-- ThirdParty/osmium/builder/builder.hpp | 399 +++--- .../osmium/builder/osm_object_builder.hpp | 100 +- ThirdParty/osmium/dynamic_handler.hpp | 390 +++--- ThirdParty/osmium/geom/coordinates.hpp | 43 +- ThirdParty/osmium/geom/factory.hpp | 60 +- ThirdParty/osmium/geom/geojson.hpp | 11 +- ThirdParty/osmium/geom/haversine.hpp | 190 ++- .../osmium/geom/mercator_projection.hpp | 12 +- ThirdParty/osmium/geom/ogr.hpp | 24 +- ThirdParty/osmium/geom/projection.hpp | 4 +- ThirdParty/osmium/geom/util.hpp | 146 +-- ThirdParty/osmium/geom/wkb.hpp | 27 +- ThirdParty/osmium/geom/wkt.hpp | 12 +- ThirdParty/osmium/handler/chain.hpp | 256 ++-- ThirdParty/osmium/handler/dump.hpp | 588 ++++----- .../handler/node_locations_for_ways.hpp | 318 ++--- .../osmium/index/detail/mmap_vector_base.hpp | 366 +++--- .../osmium/index/detail/mmap_vector_file.hpp | 165 ++- ThirdParty/osmium/index/detail/tmpfile.hpp | 4 +- ThirdParty/osmium/index/detail/typed_mmap.hpp | 42 +- ThirdParty/osmium/index/map.hpp | 311 +++-- ThirdParty/osmium/index/map/sparse_table.hpp | 280 ++--- ThirdParty/osmium/index/map/stl_map.hpp | 224 ++-- ThirdParty/osmium/index/map/vector.hpp | 416 +++---- ThirdParty/osmium/index/multimap.hpp | 254 ++-- ThirdParty/osmium/index/multimap/hybrid.hpp | 398 +++--- .../osmium/index/multimap/stl_multimap.hpp | 302 ++--- ThirdParty/osmium/index/multimap/vector.hpp | 292 ++--- ThirdParty/osmium/io/bzip2_compression.hpp | 115 +- ThirdParty/osmium/io/compression.hpp | 83 +- ThirdParty/osmium/io/detail/input_format.hpp | 2 +- .../osmium/io/detail/opl_output_format.hpp | 22 +- ThirdParty/osmium/io/detail/pbf.hpp | 6 +- .../osmium/io/detail/pbf_input_format.hpp | 141 ++- .../osmium/io/detail/pbf_output_format.hpp | 33 +- .../osmium/io/detail/pbf_stringtable.hpp | 16 +- ThirdParty/osmium/io/detail/read_thread.hpp | 5 +- ThirdParty/osmium/io/detail/read_write.hpp | 64 +- .../osmium/io/detail/xml_input_format.hpp | 200 +-- .../osmium/io/detail/xml_output_format.hpp | 15 +- ThirdParty/osmium/io/detail/zlib.hpp | 4 +- ThirdParty/osmium/io/file.hpp | 677 ++++++----- ThirdParty/osmium/io/file_compression.hpp | 4 + ThirdParty/osmium/io/file_format.hpp | 4 + ThirdParty/osmium/io/gzip_compression.hpp | 128 +- ThirdParty/osmium/io/header.hpp | 12 +- ThirdParty/osmium/io/input_iterator.hpp | 6 +- ThirdParty/osmium/io/output_iterator.hpp | 230 ++-- ThirdParty/osmium/io/reader.hpp | 51 +- ThirdParty/osmium/io/writer.hpp | 3 +- ThirdParty/osmium/memory/buffer.hpp | 81 +- ThirdParty/osmium/memory/collection.hpp | 306 ++--- ThirdParty/osmium/memory/item.hpp | 40 +- ThirdParty/osmium/memory/item_iterator.hpp | 415 ++++--- .../osmium/object_pointer_collection.hpp | 224 ++-- ThirdParty/osmium/osm/area.hpp | 25 +- ThirdParty/osmium/osm/box.hpp | 10 +- ThirdParty/osmium/osm/changeset.hpp | 124 +- ThirdParty/osmium/osm/diff_object.hpp | 312 ++--- ThirdParty/osmium/osm/entity.hpp | 129 +- ThirdParty/osmium/osm/entity_bits.hpp | 8 +- ThirdParty/osmium/osm/item_type.hpp | 16 +- ThirdParty/osmium/osm/location.hpp | 56 +- ThirdParty/osmium/osm/node.hpp | 8 +- ThirdParty/osmium/osm/node_ref.hpp | 47 +- ThirdParty/osmium/osm/node_ref_list.hpp | 270 ++--- ThirdParty/osmium/osm/object.hpp | 190 +-- ThirdParty/osmium/osm/object_comparisons.hpp | 220 ++-- ThirdParty/osmium/osm/relation.hpp | 22 +- ThirdParty/osmium/osm/segment.hpp | 10 +- ThirdParty/osmium/osm/tag.hpp | 2 +- ThirdParty/osmium/osm/timestamp.hpp | 24 +- ThirdParty/osmium/osm/undirected_segment.hpp | 8 +- ThirdParty/osmium/osm/way.hpp | 230 ++-- ThirdParty/osmium/relations/collector.hpp | 1077 +++++++++-------- .../osmium/relations/detail/member_meta.hpp | 289 +++-- .../osmium/relations/detail/relation_meta.hpp | 272 ++--- ThirdParty/osmium/tags/filter.hpp | 12 +- ThirdParty/osmium/tags/regex_filter.hpp | 116 +- ThirdParty/osmium/thread/function_wrapper.hpp | 208 ++-- ThirdParty/osmium/thread/pool.hpp | 384 +++--- ThirdParty/osmium/util/compatibility.hpp | 6 +- ThirdParty/osmium/util/verbose_output.hpp | 2 +- 91 files changed, 7244 insertions(+), 6417 deletions(-) diff --git a/ThirdParty/osmium/area/assembler.hpp b/ThirdParty/osmium/area/assembler.hpp index 5c8e6c906..155fa24c2 100644 --- a/ThirdParty/osmium/area/assembler.hpp +++ b/ThirdParty/osmium/area/assembler.hpp @@ -152,15 +152,26 @@ namespace osmium { } } + struct MPFilter : public osmium::tags::KeyFilter { + + MPFilter() : osmium::tags::KeyFilter(true) { + add(false, "type"); + add(false, "created_by"); + add(false, "source"); + add(false, "note"); + add(false, "test:id"); + add(false, "test:section"); + } + + }; // struct MPFilter + + static MPFilter& filter() { + static MPFilter filter; + return filter; + } + void add_tags_to_area(osmium::builder::AreaBuilder& builder, const osmium::Relation& relation) const { - osmium::tags::KeyFilter filter(true); - filter.add(false, "type").add(false, "created_by").add(false, "source").add(false, "note"); - filter.add(false, "test:id").add(false, "test:section"); - - osmium::tags::KeyFilter::iterator fi_begin(filter, relation.tags().begin(), relation.tags().end()); - osmium::tags::KeyFilter::iterator fi_end(filter, relation.tags().end(), relation.tags().end()); - - auto count = std::distance(fi_begin, fi_end); + auto count = std::count_if(relation.tags().begin(), relation.tags().end(), filter()); if (debug()) { std::cerr << " found " << count << " tags on relation (without ignored ones)\n"; @@ -728,27 +739,26 @@ namespace osmium { const osmium::TagList& area_tags = out_buffer.get(area_offset).tags(); // tags of the area we just built + // Find all closed ways that are inner rings and check their + // tags. If they are not the same as the tags of the area we + // just built, add them to a list and later build areas for + // them, too. + std::vector ways_that_should_be_areas; if (m_inner_outer_mismatches == 0) { auto memit = relation.members().begin(); for (size_t offset : members) { if (!std::strcmp(memit->role(), "inner")) { const osmium::Way& way = in_buffer.get(offset); if (way.is_closed() && way.tags().size() > 0) { - osmium::tags::KeyFilter filter(true); - filter.add(false, "created_by").add(false, "source").add(false, "note"); - filter.add(false, "test:id").add(false, "test:section"); - - osmium::tags::KeyFilter::iterator fi_begin(filter, way.tags().begin(), way.tags().end()); - osmium::tags::KeyFilter::iterator fi_end(filter, way.tags().end(), way.tags().end()); - - auto d = std::distance(fi_begin, fi_end); + auto d = std::count_if(way.tags().begin(), way.tags().end(), filter()); if (d > 0) { - osmium::tags::KeyFilter::iterator area_fi_begin(filter, area_tags.begin(), area_tags.end()); - osmium::tags::KeyFilter::iterator area_fi_end(filter, area_tags.end(), area_tags.end()); + osmium::tags::KeyFilter::iterator way_fi_begin(filter(), way.tags().begin(), way.tags().end()); + osmium::tags::KeyFilter::iterator way_fi_end(filter(), way.tags().end(), way.tags().end()); + osmium::tags::KeyFilter::iterator area_fi_begin(filter(), area_tags.begin(), area_tags.end()); + osmium::tags::KeyFilter::iterator area_fi_end(filter(), area_tags.end(), area_tags.end()); - if (!std::equal(fi_begin, fi_end, area_fi_begin) || d != std::distance(area_fi_begin, area_fi_end)) { - Assembler assembler(m_config); - assembler(way, out_buffer); + if (!std::equal(way_fi_begin, way_fi_end, area_fi_begin) || d != std::distance(area_fi_begin, area_fi_end)) { + ways_that_should_be_areas.push_back(&way); } } } @@ -756,6 +766,12 @@ namespace osmium { ++memit; } } + + // Now build areas for all ways found in the last step. + for (const osmium::Way* way : ways_that_should_be_areas) { + Assembler assembler(m_config); + assembler(*way, out_buffer); + } } }; // class Assembler diff --git a/ThirdParty/osmium/area/detail/node_ref_segment.hpp b/ThirdParty/osmium/area/detail/node_ref_segment.hpp index 62905d675..5b251bb5b 100644 --- a/ThirdParty/osmium/area/detail/node_ref_segment.hpp +++ b/ThirdParty/osmium/area/detail/node_ref_segment.hpp @@ -78,7 +78,7 @@ namespace osmium { swap(m_first, m_second); } - explicit NodeRefSegment() : + explicit NodeRefSegment() noexcept : m_first(), m_second(), m_role(nullptr), @@ -104,12 +104,12 @@ namespace osmium { ~NodeRefSegment() = default; /// Return first NodeRef of Segment according to sorting order (bottom left to top right). - const osmium::NodeRef& first() const { + const osmium::NodeRef& first() const noexcept { return m_first; } /// Return second NodeRef of Segment according to sorting order (bottom left to top right). - const osmium::NodeRef& second() const { + const osmium::NodeRef& second() const noexcept { return m_second; } @@ -138,26 +138,26 @@ namespace osmium { return ((bx - ax)*(ly - ay) - (by - ay)*(lx - ax)) <= 0; } - bool role_outer() const { + bool role_outer() const noexcept { return !strcmp(m_role, "outer"); } - bool role_inner() const { + bool role_inner() const noexcept { return !strcmp(m_role, "inner"); } - const osmium::Way* way() const { + const osmium::Way* way() const noexcept { return m_way; } }; // class NodeRefSegment /// NodeRefSegments are equal if both their locations are equal - inline bool operator==(const NodeRefSegment& lhs, const NodeRefSegment& rhs) { + inline bool operator==(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept { return lhs.first().location() == rhs.first().location() && lhs.second().location() == rhs.second().location(); } - inline bool operator!=(const NodeRefSegment& lhs, const NodeRefSegment& rhs) { + inline bool operator!=(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept { return ! (lhs == rhs); } @@ -166,19 +166,19 @@ namespace osmium { * segment. The first() location is checked first() and only if they have the * same first() location the second() location is taken into account. */ - inline bool operator<(const NodeRefSegment& lhs, const NodeRefSegment& rhs) { + inline bool operator<(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept { return (lhs.first().location() == rhs.first().location() && lhs.second().location() < rhs.second().location()) || lhs.first().location() < rhs.first().location(); } - inline bool operator>(const NodeRefSegment& lhs, const NodeRefSegment& rhs) { + inline bool operator>(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept { return rhs < lhs; } - inline bool operator<=(const NodeRefSegment& lhs, const NodeRefSegment& rhs) { + inline bool operator<=(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept { return ! (rhs < lhs); } - inline bool operator>=(const NodeRefSegment& lhs, const NodeRefSegment& rhs) { + inline bool operator>=(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept { return ! (lhs < rhs); } @@ -187,7 +187,7 @@ namespace osmium { return out << segment.first() << "--" << segment.second(); } - inline bool outside_x_range(const NodeRefSegment& s1, const NodeRefSegment& s2) { + inline bool outside_x_range(const NodeRefSegment& s1, const NodeRefSegment& s2) noexcept { if (s1.first().location().x() > s2.second().location().x()) { return true; } @@ -204,20 +204,20 @@ namespace osmium { } /** - * Calculate the intersection between to NodeRefSegments. The result is returned - * as a Location. Note that because the Location uses integers with limited - * precision internally, the result might be slightly different than the - * numerically correct location. - * - * If the segments touch in one of their endpoints, it doesn't count as an - * intersection. - * - * If the segments intersect not in a single point but in multiple points, ie - * if they overlap, this is NOT detected. - * - * @returns Undefined osmium::Location if there is no intersection or a defined - * Location if the segments intersect. - */ + * Calculate the intersection between to NodeRefSegments. The result is returned + * as a Location. Note that because the Location uses integers with limited + * precision internally, the result might be slightly different than the + * numerically correct location. + * + * If the segments touch in one of their endpoints, it doesn't count as an + * intersection. + * + * If the segments intersect not in a single point but in multiple points, ie + * if they overlap, this is NOT detected. + * + * @returns Undefined osmium::Location if there is no intersection or a defined + * Location if the segments intersect. + */ inline osmium::Location calculate_intersection(const NodeRefSegment& s1, const NodeRefSegment& s2) { if (s1.first().location() == s2.first().location() || s1.first().location() == s2.second().location() || @@ -226,10 +226,15 @@ namespace osmium { return osmium::Location(); } - double denom = ((s2.second().lat() - s2.first().lat())*(s1.second().lon() - s1.first().lon())) - - ((s2.second().lon() - s2.first().lon())*(s1.second().lat() - s1.first().lat())); + auto d = (static_cast(s2.second().y()) - static_cast(s2.first().y())) * + (static_cast(s1.second().x()) - static_cast(s1.first().x())) - + (static_cast(s2.second().x()) - static_cast(s2.first().x())) * + (static_cast(s1.second().y()) - static_cast(s1.first().y())); + + if (d != 0) { + double denom = ((s2.second().lat() - s2.first().lat())*(s1.second().lon() - s1.first().lon())) - + ((s2.second().lon() - s2.first().lon())*(s1.second().lat() - s1.first().lat())); - if (denom != 0) { double nume_a = ((s2.second().lon() - s2.first().lon())*(s1.first().lat() - s2.first().lat())) - ((s2.second().lat() - s2.first().lat())*(s1.first().lon() - s2.first().lon())); diff --git a/ThirdParty/osmium/area/detail/proto_ring.hpp b/ThirdParty/osmium/area/detail/proto_ring.hpp index 1dd236d21..63fec5b79 100644 --- a/ThirdParty/osmium/area/detail/proto_ring.hpp +++ b/ThirdParty/osmium/area/detail/proto_ring.hpp @@ -70,7 +70,7 @@ namespace osmium { public: - explicit ProtoRing(const NodeRefSegment& segment) : + explicit ProtoRing(const NodeRefSegment& segment) noexcept : m_segments() { add_segment_back(segment); } @@ -80,19 +80,19 @@ namespace osmium { std::copy(sbegin, send, m_segments.begin()); } - bool outer() const { + bool outer() const noexcept { return m_outer; } - void set_inner() { + void set_inner() noexcept { m_outer = false; } - segments_type& segments() { + segments_type& segments() noexcept { return m_segments; } - const segments_type& segments() const { + const segments_type& segments() const noexcept { return m_segments; } diff --git a/ThirdParty/osmium/area/detail/segment_list.hpp b/ThirdParty/osmium/area/detail/segment_list.hpp index dcee3d00a..7bb887d79 100644 --- a/ThirdParty/osmium/area/detail/segment_list.hpp +++ b/ThirdParty/osmium/area/detail/segment_list.hpp @@ -64,7 +64,7 @@ namespace osmium { public: - explicit SegmentList(bool debug) : + explicit SegmentList(bool debug) noexcept : m_debug(debug) { } @@ -77,21 +77,21 @@ namespace osmium { SegmentList& operator=(SegmentList&& other) = delete; /// The number of segments in the list. - size_t size() const { + size_t size() const noexcept { return m_segments.size(); } - bool empty() const { + bool empty() const noexcept { return m_segments.empty(); } typedef slist_type::const_iterator const_iterator; - const_iterator begin() const { + const_iterator begin() const noexcept { return m_segments.begin(); } - const_iterator end() const { + const_iterator end() const noexcept { return m_segments.end(); } @@ -99,7 +99,7 @@ namespace osmium { * Enable or disable debug output to stderr. This is for Osmium * developers only. */ - void enable_debug_output(bool debug=true) { + void enable_debug_output(bool debug=true) noexcept { m_debug = debug; } diff --git a/ThirdParty/osmium/area/multipolygon_collector.hpp b/ThirdParty/osmium/area/multipolygon_collector.hpp index 24aa89c48..f02eff5fb 100644 --- a/ThirdParty/osmium/area/multipolygon_collector.hpp +++ b/ThirdParty/osmium/area/multipolygon_collector.hpp @@ -1,211 +1,211 @@ -#ifndef OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP -#define OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace osmium { - - struct invalid_location; - - namespace relations { - class RelationMeta; - } - - /** - * @brief Code related to the building of areas (multipolygons) from relations. - */ - namespace area { - - /** - * This class collects all data needed for creating areas from - * relations tagged with type=multipolygon or type=boundary. - * Most of its functionality is derived from the parent class - * osmium::relations::Collector. - * - * The actual assembling of the areas is done by the assembler - * class given as template argument. - * - * @tparam TAssembler Multipolygon Assembler class. - */ - template - class MultipolygonCollector : public osmium::relations::Collector, false, true, false> { - - typedef typename osmium::relations::Collector, false, true, false> collector_type; - - typedef typename TAssembler::config_type assembler_config_type; - const assembler_config_type m_assembler_config; - - osmium::memory::Buffer m_output_buffer; - - static constexpr size_t initial_output_buffer_size = 1024 * 1024; - static constexpr size_t max_buffer_size_for_flush = 100 * 1024; - - void flush_output_buffer() { - if (this->callback()) { - this->callback()(m_output_buffer); - m_output_buffer.clear(); - } - } - - void possibly_flush_output_buffer() { - if (m_output_buffer.committed() > max_buffer_size_for_flush) { - flush_output_buffer(); - } - } - - public: - - explicit MultipolygonCollector(const assembler_config_type& assembler_config) : - collector_type(), - m_assembler_config(assembler_config), - m_output_buffer(initial_output_buffer_size, osmium::memory::Buffer::auto_grow::yes) { - } - - /** - * We are interested in all relations tagged with type=multipolygon or - * type=boundary. - * - * Overwritten from the base class. - */ - bool keep_relation(const osmium::Relation& relation) const { - const char* type = relation.tags().get_value_by_key("type"); - - // ignore relations without "type" tag - if (!type) { - return false; - } - - if ((!strcmp(type, "multipolygon")) || (!strcmp(type, "boundary"))) { - return true; - } - - return false; - } - - /** - * Overwritten from the base class. - */ - bool keep_member(const osmium::relations::RelationMeta& /*relation_meta*/, const osmium::RelationMember& member) const { - // We are only interested in members of type way. - return member.type() == osmium::item_type::way; - } - - /** - * This is called when a way is not in any multipolygon - * relation. - * - * Overwritten from the base class. - */ - void way_not_in_any_relation(const osmium::Way& way) { - if (way.ends_have_same_location() && way.nodes().size() > 3) { - // way is closed and has enough nodes, build simple multipolygon - try { - TAssembler assembler(m_assembler_config); - assembler(way, m_output_buffer); - possibly_flush_output_buffer(); - } catch (osmium::invalid_location&) { - // XXX ignore - } - } - } - - void complete_relation(osmium::relations::RelationMeta& relation_meta) { - const osmium::Relation& relation = this->get_relation(relation_meta); - std::vector offsets; - for (const auto& member : relation.members()) { - if (member.ref() != 0) { - offsets.push_back(this->get_offset(member.type(), member.ref())); - } - } - try { - TAssembler assembler(m_assembler_config); - assembler(relation, offsets, this->members_buffer(), m_output_buffer); - possibly_flush_output_buffer(); - } catch (osmium::invalid_location&) { - // XXX ignore - } - - // clear member metas - for (const auto& member : relation.members()) { - if (member.ref() != 0) { - auto& mmv = this->member_meta(member.type()); - auto range = std::equal_range(mmv.begin(), mmv.end(), osmium::relations::MemberMeta(member.ref())); - assert(range.first != range.second); - - // if this is the last time this object was needed - // then mark it as removed - if (range.first + 1 == range.second) { - this->get_member(range.first->buffer_offset()).removed(true); - } - - for (auto it = range.first; it != range.second; ++it) { - if (relation.id() == this->get_relation(it->relation_pos()).id()) { - mmv.erase(it); - break; - } - } - } - } - } - - void flush() { - flush_output_buffer(); - } - - osmium::memory::Buffer read() { - osmium::memory::Buffer buffer(initial_output_buffer_size, osmium::memory::Buffer::auto_grow::yes); - std::swap(buffer, m_output_buffer); - return buffer; - } - - }; // class MultipolygonCollector - - } // namespace area - -} // namespace osmium - -#endif // OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP +#ifndef OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP +#define OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace osmium { + + struct invalid_location; + + namespace relations { + class RelationMeta; + } + + /** + * @brief Code related to the building of areas (multipolygons) from relations. + */ + namespace area { + + /** + * This class collects all data needed for creating areas from + * relations tagged with type=multipolygon or type=boundary. + * Most of its functionality is derived from the parent class + * osmium::relations::Collector. + * + * The actual assembling of the areas is done by the assembler + * class given as template argument. + * + * @tparam TAssembler Multipolygon Assembler class. + */ + template + class MultipolygonCollector : public osmium::relations::Collector, false, true, false> { + + typedef typename osmium::relations::Collector, false, true, false> collector_type; + + typedef typename TAssembler::config_type assembler_config_type; + const assembler_config_type m_assembler_config; + + osmium::memory::Buffer m_output_buffer; + + static constexpr size_t initial_output_buffer_size = 1024 * 1024; + static constexpr size_t max_buffer_size_for_flush = 100 * 1024; + + void flush_output_buffer() { + if (this->callback()) { + this->callback()(m_output_buffer); + m_output_buffer.clear(); + } + } + + void possibly_flush_output_buffer() { + if (m_output_buffer.committed() > max_buffer_size_for_flush) { + flush_output_buffer(); + } + } + + public: + + explicit MultipolygonCollector(const assembler_config_type& assembler_config) : + collector_type(), + m_assembler_config(assembler_config), + m_output_buffer(initial_output_buffer_size, osmium::memory::Buffer::auto_grow::yes) { + } + + /** + * We are interested in all relations tagged with type=multipolygon or + * type=boundary. + * + * Overwritten from the base class. + */ + bool keep_relation(const osmium::Relation& relation) const { + const char* type = relation.tags().get_value_by_key("type"); + + // ignore relations without "type" tag + if (!type) { + return false; + } + + if ((!strcmp(type, "multipolygon")) || (!strcmp(type, "boundary"))) { + return true; + } + + return false; + } + + /** + * Overwritten from the base class. + */ + bool keep_member(const osmium::relations::RelationMeta& /*relation_meta*/, const osmium::RelationMember& member) const { + // We are only interested in members of type way. + return member.type() == osmium::item_type::way; + } + + /** + * This is called when a way is not in any multipolygon + * relation. + * + * Overwritten from the base class. + */ + void way_not_in_any_relation(const osmium::Way& way) { + if (way.ends_have_same_location() && way.nodes().size() > 3) { + // way is closed and has enough nodes, build simple multipolygon + try { + TAssembler assembler(m_assembler_config); + assembler(way, m_output_buffer); + possibly_flush_output_buffer(); + } catch (osmium::invalid_location&) { + // XXX ignore + } + } + } + + void complete_relation(osmium::relations::RelationMeta& relation_meta) { + const osmium::Relation& relation = this->get_relation(relation_meta); + std::vector offsets; + for (const auto& member : relation.members()) { + if (member.ref() != 0) { + offsets.push_back(this->get_offset(member.type(), member.ref())); + } + } + try { + TAssembler assembler(m_assembler_config); + assembler(relation, offsets, this->members_buffer(), m_output_buffer); + possibly_flush_output_buffer(); + } catch (osmium::invalid_location&) { + // XXX ignore + } + + // clear member metas + for (const auto& member : relation.members()) { + if (member.ref() != 0) { + auto& mmv = this->member_meta(member.type()); + auto range = std::equal_range(mmv.begin(), mmv.end(), osmium::relations::MemberMeta(member.ref())); + assert(range.first != range.second); + + // if this is the last time this object was needed + // then mark it as removed + if (osmium::relations::count_not_removed(range.first, range.second) == 1) { + this->get_member(range.first->buffer_offset()).set_removed(true); + } + + for (auto it = range.first; it != range.second; ++it) { + if (!it->removed() && relation.id() == this->get_relation(it->relation_pos()).id()) { + it->remove(); + break; + } + } + } + } + } + + void flush() { + flush_output_buffer(); + } + + osmium::memory::Buffer read() { + osmium::memory::Buffer buffer(initial_output_buffer_size, osmium::memory::Buffer::auto_grow::yes); + std::swap(buffer, m_output_buffer); + return buffer; + } + + }; // class MultipolygonCollector + + } // namespace area + +} // namespace osmium + +#endif // OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP diff --git a/ThirdParty/osmium/area/problem_reporter.hpp b/ThirdParty/osmium/area/problem_reporter.hpp index 9e3eece8d..5e255db50 100644 --- a/ThirdParty/osmium/area/problem_reporter.hpp +++ b/ThirdParty/osmium/area/problem_reporter.hpp @@ -1,149 +1,149 @@ -#ifndef OSMIUM_AREA_PROBLEM_REPORTER_HPP -#define OSMIUM_AREA_PROBLEM_REPORTER_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include - -namespace osmium { - - namespace area { - - /** - * When assembling a multipolygon/area from a multipolygon relation - * or a closed way several problems can be detected. This includes - * intersections between lines, wrong role attributes on relation - * members etc. These problems are reported by the area::Assembler - * class to the ProblemReporter class or one of its child classes. - * - * This is the parent class which does nothing with the reports. - * Child classes are expected to implement different ways of - * reporting the problems. - */ - class ProblemReporter { - - protected: - - // Type of object we are currently working on - osmium::item_type m_object_type; - - // ID of the relation/way we are currently working on - osmium::object_id_type m_object_id; - - public: - - ProblemReporter() = default; - - virtual ~ProblemReporter() = default; - - /** - * Set the object the next problem reports will be on. - * - * @param object_type The type of the object. - * @param object_id The ID of the object. - */ - void set_object(osmium::item_type object_type, osmium::object_id_type object_id) { - m_object_type = object_type; - m_object_id = object_id; - } - -// Disable "unused-parameter" warning, so that the compiler will not complain. -// We can't remove the parameter names, because then doxygen will complain. -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" - - /** - * Report a duplicate node, ie. two nodes with the same location. - * - * @param node_id1 ID of the first node. - * @param node_id2 ID of the second node. - * @param location Location of both nodes. - */ - virtual void report_duplicate_node(osmium::object_id_type node_id1, osmium::object_id_type node_id2, osmium::Location location) { - } - - /** - * Report an intersection between two segments. - * - * @param way1_id ID of the first involved way. - * @param way1_seg_start Location where the segment of the first way with the intersection starts - * @param way1_seg_end Location where the segment of the first way with the intersection ends - * @param way2_id ID of the second involved way. - * @param way2_seg_start Location where the segment of the second way with the intersection starts - * @param way2_seg_end Location where the segment of the second way with the intersection ends - * @param intersection Location of the intersection. This might be slightly off the correct location due to rounding. - */ - virtual void report_intersection(osmium::object_id_type way1_id, osmium::Location way1_seg_start, osmium::Location way1_seg_end, - osmium::object_id_type way2_id, osmium::Location way2_seg_start, osmium::Location way2_seg_end, osmium::Location intersection) { - } - - /** - * Report an open ring. - * - * @param end1 Location of the first open end. - * @param end2 Location of the second open end. - */ - virtual void report_ring_not_closed(osmium::Location end1, osmium::Location end2) { - } - - /** - * Report a segment that should have role "outer", but has a different role. - * - * @param way_id ID of the way this segment is in. - * @param seg_start Start of the segment with the wrong role. - * @param seg_end End of the segment with the wrong role. - */ - virtual void report_role_should_be_outer(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) { - } - - /** - * Report a segment that should have role "inner", but has a different role. - * - * @param way_id ID of the way this segment is in. - * @param seg_start Start of the segment with the wrong role. - * @param seg_end End of the segment with the wrong role. - */ - virtual void report_role_should_be_inner(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) { - } - -#pragma GCC diagnostic pop - - }; // class ProblemReporter - - } // namespace area - -} // namespace osmium - -#endif // OSMIUM_AREA_PROBLEM_REPORTER_HPP +#ifndef OSMIUM_AREA_PROBLEM_REPORTER_HPP +#define OSMIUM_AREA_PROBLEM_REPORTER_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include + +namespace osmium { + + namespace area { + + /** + * When assembling a multipolygon/area from a multipolygon relation + * or a closed way several problems can be detected. This includes + * intersections between lines, wrong role attributes on relation + * members etc. These problems are reported by the area::Assembler + * class to the ProblemReporter class or one of its child classes. + * + * This is the parent class which does nothing with the reports. + * Child classes are expected to implement different ways of + * reporting the problems. + */ + class ProblemReporter { + + protected: + + // Type of object we are currently working on + osmium::item_type m_object_type; + + // ID of the relation/way we are currently working on + osmium::object_id_type m_object_id; + + public: + + ProblemReporter() = default; + + virtual ~ProblemReporter() = default; + + /** + * Set the object the next problem reports will be on. + * + * @param object_type The type of the object. + * @param object_id The ID of the object. + */ + void set_object(osmium::item_type object_type, osmium::object_id_type object_id) noexcept { + m_object_type = object_type; + m_object_id = object_id; + } + +// Disable "unused-parameter" warning, so that the compiler will not complain. +// We can't remove the parameter names, because then doxygen will complain. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" + + /** + * Report a duplicate node, ie. two nodes with the same location. + * + * @param node_id1 ID of the first node. + * @param node_id2 ID of the second node. + * @param location Location of both nodes. + */ + virtual void report_duplicate_node(osmium::object_id_type node_id1, osmium::object_id_type node_id2, osmium::Location location) { + } + + /** + * Report an intersection between two segments. + * + * @param way1_id ID of the first involved way. + * @param way1_seg_start Location where the segment of the first way with the intersection starts + * @param way1_seg_end Location where the segment of the first way with the intersection ends + * @param way2_id ID of the second involved way. + * @param way2_seg_start Location where the segment of the second way with the intersection starts + * @param way2_seg_end Location where the segment of the second way with the intersection ends + * @param intersection Location of the intersection. This might be slightly off the correct location due to rounding. + */ + virtual void report_intersection(osmium::object_id_type way1_id, osmium::Location way1_seg_start, osmium::Location way1_seg_end, + osmium::object_id_type way2_id, osmium::Location way2_seg_start, osmium::Location way2_seg_end, osmium::Location intersection) { + } + + /** + * Report an open ring. + * + * @param end1 Location of the first open end. + * @param end2 Location of the second open end. + */ + virtual void report_ring_not_closed(osmium::Location end1, osmium::Location end2) { + } + + /** + * Report a segment that should have role "outer", but has a different role. + * + * @param way_id ID of the way this segment is in. + * @param seg_start Start of the segment with the wrong role. + * @param seg_end End of the segment with the wrong role. + */ + virtual void report_role_should_be_outer(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) { + } + + /** + * Report a segment that should have role "inner", but has a different role. + * + * @param way_id ID of the way this segment is in. + * @param seg_start Start of the segment with the wrong role. + * @param seg_end End of the segment with the wrong role. + */ + virtual void report_role_should_be_inner(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) { + } + +#pragma GCC diagnostic pop + + }; // class ProblemReporter + + } // namespace area + +} // namespace osmium + +#endif // OSMIUM_AREA_PROBLEM_REPORTER_HPP diff --git a/ThirdParty/osmium/area/problem_reporter_ogr.hpp b/ThirdParty/osmium/area/problem_reporter_ogr.hpp index f1bcf87ac..a9eb1359f 100644 --- a/ThirdParty/osmium/area/problem_reporter_ogr.hpp +++ b/ThirdParty/osmium/area/problem_reporter_ogr.hpp @@ -37,10 +37,14 @@ DEALINGS IN THE SOFTWARE. #define OSMIUM_LINK_WITH_LIBS_OGR `gdal-config --libs` #pragma GCC diagnostic push +#ifdef __clang__ +# pragma GCC diagnostic ignored "-Wdocumentation-unknown-command" +#endif +#pragma GCC diagnostic ignored "-Wfloat-equal" #pragma GCC diagnostic ignored "-Wold-style-cast" +#pragma GCC diagnostic ignored "-Wpadded" #pragma GCC diagnostic ignored "-Wredundant-decls" #pragma GCC diagnostic ignored "-Wshadow" -#pragma GCC diagnostic ignored "-Wdocumentation-unknown-command" # include # include #pragma GCC diagnostic pop diff --git a/ThirdParty/osmium/area/problem_reporter_stream.hpp b/ThirdParty/osmium/area/problem_reporter_stream.hpp index 3ff2f20bb..6bee56816 100644 --- a/ThirdParty/osmium/area/problem_reporter_stream.hpp +++ b/ThirdParty/osmium/area/problem_reporter_stream.hpp @@ -1,96 +1,96 @@ -#ifndef OSMIUM_AREA_PROBLEM_REPORTER_STREAM_HPP -#define OSMIUM_AREA_PROBLEM_REPORTER_STREAM_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include - -#include -#include -#include -#include - -namespace osmium { - - namespace area { - - class ProblemReporterStream : public ProblemReporter { - - std::ostream& m_out; - - public: - - explicit ProblemReporterStream(std::ostream& out) : - m_out(out) { - } - - virtual ~ProblemReporterStream() = default; - - void header(const char* msg) { - m_out << "DATA PROBLEM: " << msg << " on " << item_type_to_char(m_object_type) << m_object_id << ": "; - } - - void report_duplicate_node(osmium::object_id_type node_id1, osmium::object_id_type node_id2, osmium::Location location) override { - header("duplicate node"); - m_out << "node_id1=" << node_id1 << " node_id2=" << node_id2 << " location=" << location << "\n"; - } - - void report_intersection(osmium::object_id_type way1_id, osmium::Location way1_seg_start, osmium::Location way1_seg_end, - osmium::object_id_type way2_id, osmium::Location way2_seg_start, osmium::Location way2_seg_end, osmium::Location intersection) override { - header("intersection"); - m_out << "way1_id=" << way1_id << " way1_seg_start=" << way1_seg_start << " way1_seg_end=" << way1_seg_end - << " way2_id=" << way2_id << " way2_seg_start=" << way2_seg_start << " way2_seg_end=" << way2_seg_end << " intersection=" << intersection << "\n"; - } - - void report_ring_not_closed(osmium::Location end1, osmium::Location end2) override { - header("ring not closed"); - m_out << "end1=" << end1 << " end2=" << end2 << "\n"; - } - - void report_role_should_be_outer(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) override { - header("role should be outer"); - m_out << "way_id=" << way_id << " seg_start=" << seg_start << " seg_end=" << seg_end << "\n"; - } - - void report_role_should_be_inner(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) override { - header("role should be inner"); - m_out << "way_id=" << way_id << " seg_start=" << seg_start << " seg_end=" << seg_end << "\n"; - } - - }; // class ProblemReporterStream - - } // namespace area - -} // namespace osmium - -#endif // OSMIUM_AREA_PROBLEM_REPORTER_STREAM_HPP +#ifndef OSMIUM_AREA_PROBLEM_REPORTER_STREAM_HPP +#define OSMIUM_AREA_PROBLEM_REPORTER_STREAM_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include + +#include +#include +#include +#include + +namespace osmium { + + namespace area { + + class ProblemReporterStream : public ProblemReporter { + + std::ostream* m_out; + + public: + + explicit ProblemReporterStream(std::ostream& out) : + m_out(&out) { + } + + virtual ~ProblemReporterStream() = default; + + void header(const char* msg) { + *m_out << "DATA PROBLEM: " << msg << " on " << item_type_to_char(m_object_type) << m_object_id << ": "; + } + + void report_duplicate_node(osmium::object_id_type node_id1, osmium::object_id_type node_id2, osmium::Location location) override { + header("duplicate node"); + *m_out << "node_id1=" << node_id1 << " node_id2=" << node_id2 << " location=" << location << "\n"; + } + + void report_intersection(osmium::object_id_type way1_id, osmium::Location way1_seg_start, osmium::Location way1_seg_end, + osmium::object_id_type way2_id, osmium::Location way2_seg_start, osmium::Location way2_seg_end, osmium::Location intersection) override { + header("intersection"); + *m_out << "way1_id=" << way1_id << " way1_seg_start=" << way1_seg_start << " way1_seg_end=" << way1_seg_end + << " way2_id=" << way2_id << " way2_seg_start=" << way2_seg_start << " way2_seg_end=" << way2_seg_end << " intersection=" << intersection << "\n"; + } + + void report_ring_not_closed(osmium::Location end1, osmium::Location end2) override { + header("ring not closed"); + *m_out << "end1=" << end1 << " end2=" << end2 << "\n"; + } + + void report_role_should_be_outer(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) override { + header("role should be outer"); + *m_out << "way_id=" << way_id << " seg_start=" << seg_start << " seg_end=" << seg_end << "\n"; + } + + void report_role_should_be_inner(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) override { + header("role should be inner"); + *m_out << "way_id=" << way_id << " seg_start=" << seg_start << " seg_end=" << seg_end << "\n"; + } + + }; // class ProblemReporterStream + + } // namespace area + +} // namespace osmium + +#endif // OSMIUM_AREA_PROBLEM_REPORTER_STREAM_HPP diff --git a/ThirdParty/osmium/builder/builder.hpp b/ThirdParty/osmium/builder/builder.hpp index bd762be2c..61e853e70 100644 --- a/ThirdParty/osmium/builder/builder.hpp +++ b/ThirdParty/osmium/builder/builder.hpp @@ -1,179 +1,220 @@ -#ifndef OSMIUM_BUILDER_BUILDER_HPP -#define OSMIUM_BUILDER_BUILDER_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include -#include - -#include -#include - -namespace osmium { - - /** - * @brief Classes for building OSM objects and other items in buffers - */ - namespace builder { - - class Builder { - - osmium::memory::Buffer& m_buffer; - Builder* m_parent; - size_t m_item_offset; - - Builder(const Builder&) = delete; - Builder(Builder&&) = delete; - - Builder& operator=(const Builder&) = delete; - Builder& operator=(Builder&&) = delete; - - protected: - - explicit Builder(osmium::memory::Buffer& buffer, Builder* parent, size_t size) : - m_buffer(buffer), - m_parent(parent), - m_item_offset(buffer.written()) { - m_buffer.reserve_space(size); - assert(buffer.is_aligned()); - if (m_parent) { - m_parent->add_size(size); - } - } - - ~Builder() = default; - - osmium::memory::Item& item() const { - return *reinterpret_cast(m_buffer.data() + m_item_offset); - } - - public: - - /** - * Add padding to buffer (if needed) to align data properly. - * - * This calculates how many padding bytes are needed and adds - * as many zero bytes to the buffer. It also adds this number - * to the size of the current item (if the "self" param is - * true) and recursively to all the parent items. - * - * @param self If true add number of padding bytes to size - * of current item. Size is always added to - * parent item (if any). - * - */ - void add_padding(bool self=false) { - size_t padding = osmium::memory::align_bytes - (size() % osmium::memory::align_bytes); - if (padding != osmium::memory::align_bytes) { - std::memset(m_buffer.reserve_space(padding), 0, padding); - if (self) { - add_size(padding); - } else if (m_parent) { - m_parent->add_size(padding); - assert(m_parent->size() % osmium::memory::align_bytes == 0); - } - } - } - - void add_size(uint32_t size) { - item().add_size(size); - if (m_parent) { - m_parent->add_size(size); - } - } - - uint32_t size() const { - return item().byte_size(); - } - - void add_item(const osmium::memory::Item* item) { - std::memcpy(m_buffer.reserve_space(item->padded_size()), item, item->padded_size()); - add_size(item->padded_size()); - } - - /** - * Reserve space for an object of class T in buffer and return - * pointer to it. - */ - template - T* reserve_space_for() { - assert(m_buffer.is_aligned()); - return reinterpret_cast(m_buffer.reserve_space(sizeof(T))); - } - - /** - * Append \0-terminated string to buffer. - */ - size_t append(const char* str) { - size_t length = std::strlen(str) + 1; - std::memcpy(m_buffer.reserve_space(length), str, length); - return length; - } - - /// Return the buffer this builder is using. - osmium::memory::Buffer& buffer() { - return m_buffer; - } - - }; // class Builder - - template - class ObjectBuilder : public Builder { - - public: - - explicit ObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) : - Builder(buffer, parent, sizeof(T)) { - new (&item()) T(); - } - - T& object() { - return static_cast(item()); - } - - void add_user(const char* user) { - object().user_size(std::strlen(user) + 1); - add_size(append(user)); - add_padding(true); - } - - }; // class ObjectBuilder - - } // namespace builder - -} // namespace osmium - -#endif // OSMIUM_BUILDER_BUILDER_HPP +#ifndef OSMIUM_BUILDER_BUILDER_HPP +#define OSMIUM_BUILDER_BUILDER_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace osmium { + + /** + * @brief Classes for building OSM objects and other items in buffers + */ + namespace builder { + + class Builder { + + osmium::memory::Buffer& m_buffer; + Builder* m_parent; + size_t m_item_offset; + + Builder(const Builder&) = delete; + Builder(Builder&&) = delete; + + Builder& operator=(const Builder&) = delete; + Builder& operator=(Builder&&) = delete; + + protected: + + explicit Builder(osmium::memory::Buffer& buffer, Builder* parent, osmium::memory::item_size_type size) : + m_buffer(buffer), + m_parent(parent), + m_item_offset(buffer.written()) { + m_buffer.reserve_space(size); + assert(buffer.is_aligned()); + if (m_parent) { + m_parent->add_size(size); + } + } + + ~Builder() = default; + + osmium::memory::Item& item() const { + return *reinterpret_cast(m_buffer.data() + m_item_offset); + } + + public: + + /** + * Add padding to buffer (if needed) to align data properly. + * + * This calculates how many padding bytes are needed and adds + * as many zero bytes to the buffer. It also adds this number + * to the size of the current item (if the "self" param is + * true) and recursively to all the parent items. + * + * @param self If true add number of padding bytes to size + * of current item. Size is always added to + * parent item (if any). + * + */ + void add_padding(bool self=false) { + auto padding = osmium::memory::align_bytes - (size() % osmium::memory::align_bytes); + if (padding != osmium::memory::align_bytes) { + std::memset(m_buffer.reserve_space(padding), 0, padding); + if (self) { + add_size(padding); + } else if (m_parent) { + m_parent->add_size(padding); + assert(m_parent->size() % osmium::memory::align_bytes == 0); + } + } + } + + void add_size(uint32_t size) { + item().add_size(size); + if (m_parent) { + m_parent->add_size(size); + } + } + + uint32_t size() const noexcept { + return item().byte_size(); + } + + void add_item(const osmium::memory::Item* item) { + std::memcpy(m_buffer.reserve_space(item->padded_size()), item, item->padded_size()); + add_size(item->padded_size()); + } + + /** + * Reserve space for an object of class T in buffer and return + * pointer to it. + */ + template + T* reserve_space_for() { + assert(m_buffer.is_aligned()); + return reinterpret_cast(m_buffer.reserve_space(sizeof(T))); + } + + /** + * Append data to buffer. + * + * @param data Pointer to data. + * @param length Length of data in bytes. If data is a + * \0-terminated string, length must contain the + * \0 byte. + */ + osmium::memory::item_size_type append(const char* data, const osmium::memory::item_size_type length) { + std::memcpy(m_buffer.reserve_space(length), data, length); + return length; + } + + /** + * Append \0-terminated string to buffer. + */ + osmium::memory::item_size_type append(const char* str) { + return append(str, static_cast(std::strlen(str) + 1)); + } + + /// Return the buffer this builder is using. + osmium::memory::Buffer& buffer() noexcept { + return m_buffer; + } + + }; // class Builder + + template + class ObjectBuilder : public Builder { + + static_assert(std::is_base_of::value, + "ObjectBuilder can only build objects derived from osmium::memory::Item"); + + public: + + explicit ObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) : + Builder(buffer, parent, sizeof(TItem)) { + new (&item()) TItem(); + } + + TItem& object() noexcept { + return static_cast(item()); + } + + /** + * Add user name to buffer. + * + * @param user Pointer to user name. + * @param length Length of user name including \0 byte. + */ + void add_user(const char* user, const string_size_type length) { + object().set_user_size(length); + add_size(append(user, length)); + add_padding(true); + } + + /** + * Add user name to buffer. + * + * @param user Pointer to \0-terminated user name. + */ + void add_user(const char* user) { + add_user(user, static_cast_with_assert(std::strlen(user) + 1)); + } + + /** + * Add user name to buffer. + * + * @param user User name. + */ + void add_user(const std::string& user) { + add_user(user.data(), static_cast_with_assert(user.size() + 1)); + } + + }; // class ObjectBuilder + + } // namespace builder + +} // namespace osmium + +#endif // OSMIUM_BUILDER_BUILDER_HPP diff --git a/ThirdParty/osmium/builder/osm_object_builder.hpp b/ThirdParty/osmium/builder/osm_object_builder.hpp index 0fb26c8ae..851eb85f8 100644 --- a/ThirdParty/osmium/builder/osm_object_builder.hpp +++ b/ThirdParty/osmium/builder/osm_object_builder.hpp @@ -46,6 +46,7 @@ DEALINGS IN THE SOFTWARE. #include #include #include +#include namespace osmium { @@ -67,10 +68,27 @@ namespace osmium { add_padding(); } + /** + * Add tag to buffer. + * + * @param key Tag key. + * @param value Tag value. + */ void add_tag(const char* key, const char* value) { add_size(append(key) + append(value)); } + /** + * Add tag to buffer. + * + * @param key Tag key. + * @param value Tag value. + */ + void add_tag(const std::string& key, const std::string& value) { + add_size(append(key.data(), static_cast_with_assert(key.size() + 1)) + + append(value.data(), static_cast_with_assert(value.size() + 1))); + } + }; // class TagListBuilder template @@ -103,14 +121,42 @@ namespace osmium { class RelationMemberListBuilder : public ObjectBuilder { - void add_role(osmium::RelationMember* member, const char* role) { - size_t length = std::strlen(role) + 1; - assert(length < std::numeric_limits::max()); - member->set_role_size(static_cast(length)); - add_size(append(role)); + /** + * Add role to buffer. + * + * @param member Relation member object where the length of the role + * will be set. + * @param role The role. + * @param length Length of role string including \0 termination. + */ + void add_role(osmium::RelationMember& member, const char* role, const string_size_type length) { + member.set_role_size(length); + add_size(append(role, length)); add_padding(true); } + /** + * Add role to buffer. + * + * @param member Relation member object where the length of the role + * will be set. + * @param role \0-terminated role. + */ + void add_role(osmium::RelationMember& member, const char* role) { + add_role(member, role, static_cast_with_assert(std::strlen(role) + 1)); + } + + /** + * Add role to buffer. + * + * @param member Relation member object where the length of the role + * will be set. + * @param role Role. + */ + void add_role(osmium::RelationMember& member, const std::string& role) { + add_role(member, role.data(), static_cast_with_assert(role.size() + 1)); + } + public: explicit RelationMemberListBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) : @@ -121,11 +167,41 @@ namespace osmium { add_padding(); } + /** + * Add a member to the relation. + * + * @param type The type (node, way, or relation). + * @param ref The ID of the member. + * @param role The role of the member. + * @param full_member Optional pointer to the member object. If it + * is available a copy will be added to the + * relation. + */ void add_member(osmium::item_type type, object_id_type ref, const char* role, const osmium::OSMObject* full_member = nullptr) { osmium::RelationMember* member = reserve_space_for(); new (member) osmium::RelationMember(ref, type, full_member != nullptr); add_size(sizeof(RelationMember)); - add_role(member, role); + add_role(*member, role); + if (full_member) { + add_item(full_member); + } + } + + /** + * Add a member to the relation. + * + * @param type The type (node, way, or relation). + * @param ref The ID of the member. + * @param role The role of the member. + * @param full_member Optional pointer to the member object. If it + * is available a copy will be added to the + * relation. + */ + void add_member(osmium::item_type type, object_id_type ref, const std::string& role, const osmium::OSMObject* full_member = nullptr) { + osmium::RelationMember* member = reserve_space_for(); + new (member) osmium::RelationMember(ref, type, full_member != nullptr); + add_size(sizeof(RelationMember)); + add_role(*member, role); if (full_member) { add_item(full_member); } @@ -186,12 +262,12 @@ namespace osmium { */ void initialize_from_object(const osmium::OSMObject& source) { osmium::Area& area = object(); - area.id(osmium::object_id_to_area_id(source.id(), source.type())); - area.version(source.version()); - area.changeset(source.changeset()); - area.timestamp(source.timestamp()); - area.visible(source.visible()); - area.uid(source.uid()); + area.set_id(osmium::object_id_to_area_id(source.id(), source.type())); + area.set_version(source.version()); + area.set_changeset(source.changeset()); + area.set_timestamp(source.timestamp()); + area.set_visible(source.visible()); + area.set_uid(source.uid()); add_user(source.user()); } diff --git a/ThirdParty/osmium/dynamic_handler.hpp b/ThirdParty/osmium/dynamic_handler.hpp index 115c09d3d..bc593131c 100644 --- a/ThirdParty/osmium/dynamic_handler.hpp +++ b/ThirdParty/osmium/dynamic_handler.hpp @@ -1,195 +1,195 @@ -#ifndef OSMIUM_DYNAMIC_HANDLER_HPP -#define OSMIUM_DYNAMIC_HANDLER_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include - -#include - -namespace osmium { - - class Node; - class Way; - class Relation; - class Area; - class Changeset; - - namespace handler { - - namespace detail { - - class HandlerWrapperBase { - - public: - - virtual ~HandlerWrapperBase() { - } - - virtual void node(const osmium::Node&) { - } - - virtual void way(const osmium::Way&) { - } - - virtual void relation(const osmium::Relation&) { - } - - virtual void area(const osmium::Area&) { - } - - virtual void changeset(const osmium::Changeset&) { - } - - virtual void flush() { - } - - }; // class HandlerWrapperBase - - - // The following uses trick from - // http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence - // to either call handler style functions or visitor style operator(). - -#define OSMIUM_DYNAMIC_HANDLER_DISPATCH(_name_, _type_) \ -template \ -auto _name_##_dispatch(THandler& handler, const osmium::_type_& object, int) -> decltype(handler._name_(object), void()) { \ - handler._name_(object); \ -} \ -template \ -auto _name_##_dispatch(THandler& handler, const osmium::_type_& object, long) -> decltype(handler(object), void()) { \ - handler(object); \ -} - - OSMIUM_DYNAMIC_HANDLER_DISPATCH(node, Node) - OSMIUM_DYNAMIC_HANDLER_DISPATCH(way, Way) - OSMIUM_DYNAMIC_HANDLER_DISPATCH(relation, Relation) - OSMIUM_DYNAMIC_HANDLER_DISPATCH(changeset, Changeset) - OSMIUM_DYNAMIC_HANDLER_DISPATCH(area, Area) - - template - auto flush_dispatch(THandler& handler, int) -> decltype(handler.flush(), void()) { - handler.flush(); - } - - template - void flush_dispatch(THandler&, long) {} - - template - class HandlerWrapper : public HandlerWrapperBase { - - THandler m_handler; - - public: - - template - HandlerWrapper(TArgs&&... args) : - m_handler(std::forward(args)...) { - } - - void node(const osmium::Node& node) override final { - node_dispatch(m_handler, node, 0); - } - - void way(const osmium::Way& way) override final { - way_dispatch(m_handler, way, 0); - } - - void relation(const osmium::Relation& relation) override final { - relation_dispatch(m_handler, relation, 0); - } - - void area(const osmium::Area& area) override final { - area_dispatch(m_handler, area, 0); - } - - void changeset(const osmium::Changeset& changeset) override final { - changeset_dispatch(m_handler, changeset, 0); - } - - void flush() override final { - flush_dispatch(m_handler, 0); - } - - }; // HandlerWrapper - - } // namespace detail - - class DynamicHandler : public osmium::handler::Handler { - - typedef std::unique_ptr impl_ptr; - impl_ptr m_impl; - - public: - - DynamicHandler() : - m_impl(impl_ptr(new osmium::handler::detail::HandlerWrapperBase)) { - } - - template - void set(TArgs&&... args) { - m_impl = impl_ptr(new osmium::handler::detail::HandlerWrapper(std::forward(args)...)); - } - - void node(const osmium::Node& node) { - m_impl->node(node); - } - - void way(const osmium::Way& way) { - m_impl->way(way); - } - - void relation(const osmium::Relation& relation) { - m_impl->relation(relation); - } - - void area(const osmium::Area& area) { - m_impl->area(area); - } - - void changeset(const osmium::Changeset& changeset) { - m_impl->changeset(changeset); - } - - void flush() { - m_impl->flush(); - } - - }; // DynamicHandler - - } // namspace handler - -} // namespace osmium - -#endif // OSMIUM_DYNAMIC_HANDLER_HPP +#ifndef OSMIUM_DYNAMIC_HANDLER_HPP +#define OSMIUM_DYNAMIC_HANDLER_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include + +#include + +namespace osmium { + + class Node; + class Way; + class Relation; + class Area; + class Changeset; + + namespace handler { + + namespace detail { + + class HandlerWrapperBase { + + public: + + virtual ~HandlerWrapperBase() { + } + + virtual void node(const osmium::Node&) { + } + + virtual void way(const osmium::Way&) { + } + + virtual void relation(const osmium::Relation&) { + } + + virtual void area(const osmium::Area&) { + } + + virtual void changeset(const osmium::Changeset&) { + } + + virtual void flush() { + } + + }; // class HandlerWrapperBase + + + // The following uses trick from + // http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence + // to either call handler style functions or visitor style operator(). + +#define OSMIUM_DYNAMIC_HANDLER_DISPATCH(_name_, _type_) \ +template \ +auto _name_##_dispatch(THandler& handler, const osmium::_type_& object, int) -> decltype(handler._name_(object), void()) { \ + handler._name_(object); \ +} \ +template \ +auto _name_##_dispatch(THandler& handler, const osmium::_type_& object, long) -> decltype(handler(object), void()) { \ + handler(object); \ +} + + OSMIUM_DYNAMIC_HANDLER_DISPATCH(node, Node) + OSMIUM_DYNAMIC_HANDLER_DISPATCH(way, Way) + OSMIUM_DYNAMIC_HANDLER_DISPATCH(relation, Relation) + OSMIUM_DYNAMIC_HANDLER_DISPATCH(changeset, Changeset) + OSMIUM_DYNAMIC_HANDLER_DISPATCH(area, Area) + + template + auto flush_dispatch(THandler& handler, int) -> decltype(handler.flush(), void()) { + handler.flush(); + } + + template + void flush_dispatch(THandler&, long) {} + + template + class HandlerWrapper : public HandlerWrapperBase { + + THandler m_handler; + + public: + + template + HandlerWrapper(TArgs&&... args) : + m_handler(std::forward(args)...) { + } + + void node(const osmium::Node& node) override final { + node_dispatch(m_handler, node, 0); + } + + void way(const osmium::Way& way) override final { + way_dispatch(m_handler, way, 0); + } + + void relation(const osmium::Relation& relation) override final { + relation_dispatch(m_handler, relation, 0); + } + + void area(const osmium::Area& area) override final { + area_dispatch(m_handler, area, 0); + } + + void changeset(const osmium::Changeset& changeset) override final { + changeset_dispatch(m_handler, changeset, 0); + } + + void flush() override final { + flush_dispatch(m_handler, 0); + } + + }; // class HandlerWrapper + + } // namespace detail + + class DynamicHandler : public osmium::handler::Handler { + + typedef std::unique_ptr impl_ptr; + impl_ptr m_impl; + + public: + + DynamicHandler() : + m_impl(impl_ptr(new osmium::handler::detail::HandlerWrapperBase)) { + } + + template + void set(TArgs&&... args) { + m_impl = impl_ptr(new osmium::handler::detail::HandlerWrapper(std::forward(args)...)); + } + + void node(const osmium::Node& node) { + m_impl->node(node); + } + + void way(const osmium::Way& way) { + m_impl->way(way); + } + + void relation(const osmium::Relation& relation) { + m_impl->relation(relation); + } + + void area(const osmium::Area& area) { + m_impl->area(area); + } + + void changeset(const osmium::Changeset& changeset) { + m_impl->changeset(changeset); + } + + void flush() { + m_impl->flush(); + } + + }; // class DynamicHandler + + } // namspace handler + +} // namespace osmium + +#endif // OSMIUM_DYNAMIC_HANDLER_HPP diff --git a/ThirdParty/osmium/geom/coordinates.hpp b/ThirdParty/osmium/geom/coordinates.hpp index 694143c22..1ff27fea4 100644 --- a/ThirdParty/osmium/geom/coordinates.hpp +++ b/ThirdParty/osmium/geom/coordinates.hpp @@ -38,59 +38,50 @@ DEALINGS IN THE SOFTWARE. #include #include +#include namespace osmium { namespace geom { - namespace detail { - - /** - * Append double to string, removing superfluous '0' characters at - * the end. The decimal dot will also be removed if necessary. - */ - inline void double2string(std::string& s, double value) { - s += std::to_string(value); - - size_t len = s.size()-1; - while (s[len] == '0') --len; - if (s[len] == '.') --len; - - s.resize(len+1); - } - - } // namespace detail - struct Coordinates { double x; double y; - explicit Coordinates(double cx, double cy) : x(cx), y(cy) { + explicit Coordinates(double cx, double cy) noexcept : x(cx), y(cy) { } Coordinates(const osmium::Location& location) : x(location.lon()), y(location.lat()) { } - void append_to_string(std::string& s, const char infix) const { - osmium::geom::detail::double2string(s, x); + void append_to_string(std::string& s, const char infix, int precision) const { + osmium::util::double2string(s, x, precision); s += infix; - osmium::geom::detail::double2string(s, y); + osmium::util::double2string(s, y, precision); } - void append_to_string(std::string& s, const char prefix, const char infix, const char suffix) const { + void append_to_string(std::string& s, const char prefix, const char infix, const char suffix, int precision) const { s += prefix; - append_to_string(s, infix); + append_to_string(s, infix, precision); s += suffix; } }; // struct coordinates - inline bool operator==(const Coordinates& lhs, const Coordinates& rhs) { + /** + * Compare whether two Coordinates are identical. Might not give the + * right result if the coordinates have been the result of some + * calculation that introduced rounding errors. + */ + inline bool operator==(const Coordinates& lhs, const Coordinates& rhs) noexcept { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" return lhs.x == rhs.x && lhs.y == rhs.y; +#pragma GCC diagnostic pop } - inline bool operator!=(const Coordinates& lhs, const Coordinates& rhs) { + inline bool operator!=(const Coordinates& lhs, const Coordinates& rhs) noexcept { return ! operator==(lhs, rhs); } diff --git a/ThirdParty/osmium/geom/factory.hpp b/ThirdParty/osmium/geom/factory.hpp index 1be404848..4097b5dac 100644 --- a/ThirdParty/osmium/geom/factory.hpp +++ b/ThirdParty/osmium/geom/factory.hpp @@ -33,6 +33,7 @@ DEALINGS IN THE SOFTWARE. */ +#include #include #include #include @@ -49,6 +50,10 @@ DEALINGS IN THE SOFTWARE. namespace osmium { + /** + * Exception thrown when an invalid geometry is encountered. An example + * would be a linestring with less than two points. + */ struct geometry_error : public std::runtime_error { geometry_error(const std::string& what) : @@ -72,7 +77,7 @@ namespace osmium { enum class use_nodes : bool { unique = true, ///< Remove consecutive nodes with same location. all = false ///< Use all nodes. - }; + }; // enum class use_nodes /** * Which direction the linestring created from a way @@ -81,7 +86,7 @@ namespace osmium { enum class direction : bool { backward = true, ///< Linestring has reverse direction. forward = false ///< Linestring has same direction as way. - }; + }; // enum class direction /** * This pseudo projection just returns its WGS84 input unchanged. @@ -95,7 +100,7 @@ namespace osmium { return Coordinates{location.lon(), location.lat()}; } - int epsg() const { + int epsg() const noexcept { return 4326; } @@ -178,6 +183,10 @@ namespace osmium { /* LineString */ + void linestring_start() { + m_impl.linestring_start(); + } + template size_t fill_linestring(TIter it, TIter end) { size_t num_points = 0; @@ -201,8 +210,12 @@ namespace osmium { return num_points; } + linestring_type linestring_finish(size_t num_points) { + return m_impl.linestring_finish(num_points); + } + linestring_type create_linestring(const osmium::WayNodeList& wnl, use_nodes un=use_nodes::unique, direction dir=direction::forward) { - m_impl.linestring_start(); + linestring_start(); size_t num_points = 0; if (un == use_nodes::unique) { @@ -227,16 +240,49 @@ namespace osmium { } if (num_points < 2) { - throw geometry_error("not enough points for linestring"); + throw osmium::geometry_error("not enough points for linestring"); } - return m_impl.linestring_finish(num_points); + return linestring_finish(num_points); } linestring_type create_linestring(const osmium::Way& way, use_nodes un=use_nodes::unique, direction dir=direction::forward) { return create_linestring(way.nodes(), un, dir); } + /* Polygon */ + + void polygon_start() { + m_impl.polygon_start(); + } + + template + size_t fill_polygon(TIter it, TIter end) { + size_t num_points = 0; + for (; it != end; ++it, ++num_points) { + m_impl.polygon_add_location(m_projection(it->location())); + } + return num_points; + } + + template + size_t fill_polygon_unique(TIter it, TIter end) { + size_t num_points = 0; + osmium::Location last_location; + for (; it != end; ++it) { + if (last_location != it->location()) { + last_location = it->location(); + m_impl.polygon_add_location(m_projection(last_location)); + ++num_points; + } + } + return num_points; + } + + polygon_type polygon_finish(size_t num_points) { + return m_impl.polygon_finish(num_points); + } + /* MultiPolygon */ multipolygon_type create_multipolygon(const osmium::Area& area) { @@ -266,7 +312,7 @@ namespace osmium { // if there are no rings, this area is invalid if (num_rings == 0) { - throw geometry_error("invalid area"); + throw osmium::geometry_error("invalid area"); } m_impl.multipolygon_polygon_finish(); diff --git a/ThirdParty/osmium/geom/geojson.hpp b/ThirdParty/osmium/geom/geojson.hpp index 89efc3831..f6d7ee6e4 100644 --- a/ThirdParty/osmium/geom/geojson.hpp +++ b/ThirdParty/osmium/geom/geojson.hpp @@ -49,6 +49,7 @@ namespace osmium { class GeoJSONFactoryImpl { std::string m_str; + int m_precision; public: @@ -58,14 +59,16 @@ namespace osmium { typedef std::string multipolygon_type; typedef std::string ring_type; - GeoJSONFactoryImpl() = default; + GeoJSONFactoryImpl(int precision = 7) : + m_precision(precision) { + } /* Point */ // { "type": "Point", "coordinates": [100.0, 0.0] } point_type make_point(const osmium::geom::Coordinates& xy) const { std::string str {"{\"type\":\"Point\",\"coordinates\":"}; - xy.append_to_string(str, '[', ',', ']'); + xy.append_to_string(str, '[', ',', ']', m_precision); str += "}"; return str; } @@ -78,7 +81,7 @@ namespace osmium { } void linestring_add_location(const osmium::geom::Coordinates& xy) { - xy.append_to_string(m_str, '[', ',', ']'); + xy.append_to_string(m_str, '[', ',', ']', m_precision); m_str += ','; } @@ -124,7 +127,7 @@ namespace osmium { } void multipolygon_add_location(const osmium::geom::Coordinates& xy) { - xy.append_to_string(m_str, '[', ',', ']'); + xy.append_to_string(m_str, '[', ',', ']', m_precision); m_str += ','; } diff --git a/ThirdParty/osmium/geom/haversine.hpp b/ThirdParty/osmium/geom/haversine.hpp index 5ce09b58d..b8d013492 100644 --- a/ThirdParty/osmium/geom/haversine.hpp +++ b/ThirdParty/osmium/geom/haversine.hpp @@ -1,96 +1,94 @@ -#ifndef OSMIUM_GEOM_HAVERSINE_HPP -#define OSMIUM_GEOM_HAVERSINE_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace osmium { - - namespace geom { - - /** - * @brief Functions to calculate arc distance on Earth using the haversine formula. - * - * See http://en.wikipedia.org/wiki/Haversine_formula - * - * Implementation derived from - * http://blog.julien.cayzac.name/2008/10/arc-and-distance-between-two-points-on.html - */ - namespace haversine { - - /// @brief Earth's quadratic mean radius for WGS84 - constexpr double EARTH_RADIUS_IN_METERS = 6372797.560856; - - /** - * Calculate distance in meters between two sets of coordinates. - */ - inline double distance(const osmium::geom::Coordinates& c1, const osmium::geom::Coordinates& c2) { - double lonh = sin(deg_to_rad(c1.x - c2.x) * 0.5); - lonh *= lonh; - double lath = sin(deg_to_rad(c1.y - c2.y) * 0.5); - lath *= lath; - const double tmp = cos(deg_to_rad(c1.y)) * cos(deg_to_rad(c2.y)); - return 2.0 * EARTH_RADIUS_IN_METERS * asin(sqrt(lath + tmp*lonh)); - } - - /** - * Calculate length of way. - */ - inline double distance(const osmium::WayNodeList& wnl) { - double sum_length=0; - - for (auto it = wnl.begin(); it != wnl.end(); ++it) { - if (std::next(it) != wnl.end()) { - sum_length += distance(it->location(), std::next(it)->location()); - } - } - - return sum_length; - } - - } // namespace haversine - - } // namespace geom - -} // namespace osmium - -#endif // OSMIUM_GEOM_HAVERSINE_HPP +#ifndef OSMIUM_GEOM_HAVERSINE_HPP +#define OSMIUM_GEOM_HAVERSINE_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include + +#include +#include +#include +#include + +namespace osmium { + + namespace geom { + + /** + * @brief Functions to calculate arc distance on Earth using the haversine formula. + * + * See http://en.wikipedia.org/wiki/Haversine_formula + * + * Implementation derived from + * http://blog.julien.cayzac.name/2008/10/arc-and-distance-between-two-points-on.html + */ + namespace haversine { + + /// @brief Earth's quadratic mean radius for WGS84 + constexpr double EARTH_RADIUS_IN_METERS = 6372797.560856; + + /** + * Calculate distance in meters between two sets of coordinates. + */ + inline double distance(const osmium::geom::Coordinates& c1, const osmium::geom::Coordinates& c2) { + double lonh = sin(deg_to_rad(c1.x - c2.x) * 0.5); + lonh *= lonh; + double lath = sin(deg_to_rad(c1.y - c2.y) * 0.5); + lath *= lath; + const double tmp = cos(deg_to_rad(c1.y)) * cos(deg_to_rad(c2.y)); + return 2.0 * EARTH_RADIUS_IN_METERS * asin(sqrt(lath + tmp*lonh)); + } + + /** + * Calculate length of way. + */ + inline double distance(const osmium::WayNodeList& wnl) { + double sum_length=0; + + for (auto it = wnl.begin(); it != wnl.end(); ++it) { + if (std::next(it) != wnl.end()) { + sum_length += distance(it->location(), std::next(it)->location()); + } + } + + return sum_length; + } + + } // namespace haversine + + } // namespace geom + +} // namespace osmium + +#endif // OSMIUM_GEOM_HAVERSINE_HPP diff --git a/ThirdParty/osmium/geom/mercator_projection.hpp b/ThirdParty/osmium/geom/mercator_projection.hpp index df0d47d8a..d17001717 100644 --- a/ThirdParty/osmium/geom/mercator_projection.hpp +++ b/ThirdParty/osmium/geom/mercator_projection.hpp @@ -46,22 +46,22 @@ namespace osmium { namespace detail { - constexpr double EARTH_RADIUS_FOR_EPSG3857 = 6378137.0; + constexpr double earth_radius_for_epsg3857 = 6378137.0; constexpr inline double lon_to_x(double lon) { - return EARTH_RADIUS_FOR_EPSG3857 * deg_to_rad(lon); + return earth_radius_for_epsg3857 * deg_to_rad(lon); } inline double lat_to_y(double lat) { // not constexpr because math functions aren't - return EARTH_RADIUS_FOR_EPSG3857 * std::log(std::tan(osmium::geom::PI/4 + deg_to_rad(lat)/2)); + return earth_radius_for_epsg3857 * std::log(std::tan(osmium::geom::PI/4 + deg_to_rad(lat)/2)); } constexpr inline double x_to_lon(double x) { - return rad_to_deg(x) / EARTH_RADIUS_FOR_EPSG3857; + return rad_to_deg(x) / earth_radius_for_epsg3857; } inline double y_to_lat(double y) { // not constexpr because math functions aren't - return rad_to_deg(2 * std::atan(std::exp(y / EARTH_RADIUS_FOR_EPSG3857)) - osmium::geom::PI/2); + return rad_to_deg(2 * std::atan(std::exp(y / earth_radius_for_epsg3857)) - osmium::geom::PI/2); } } // namespace detail @@ -92,7 +92,7 @@ namespace osmium { return Coordinates {detail::lon_to_x(location.lon()), detail::lat_to_y(location.lat())}; } - int epsg() const { + int epsg() const noexcept { return 3857; } diff --git a/ThirdParty/osmium/geom/ogr.hpp b/ThirdParty/osmium/geom/ogr.hpp index c730de85c..2727f2fd8 100644 --- a/ThirdParty/osmium/geom/ogr.hpp +++ b/ThirdParty/osmium/geom/ogr.hpp @@ -37,11 +37,16 @@ DEALINGS IN THE SOFTWARE. #define OSMIUM_LINK_WITH_LIBS_OGR `gdal-config --libs` #include +#include #include #include #pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdocumentation-unknown-command" +#ifdef __clang__ +# pragma GCC diagnostic ignored "-Wdocumentation-unknown-command" +#endif +#pragma GCC diagnostic ignored "-Wfloat-equal" +#pragma GCC diagnostic ignored "-Wpadded" # include #pragma GCC diagnostic pop @@ -96,6 +101,23 @@ namespace osmium { return std::move(m_linestring); } + /* Polygon */ + + void polygon_start() { + m_ring = std::unique_ptr(new OGRLinearRing()); + } + + void polygon_add_location(const osmium::geom::Coordinates& xy) { + assert(!!m_ring); + m_ring->addPoint(xy.x, xy.y); + } + + polygon_type polygon_finish(size_t /* num_points */) { + std::unique_ptr polygon = std::unique_ptr(new OGRPolygon()); + polygon->addRingDirectly(m_ring.release()); + return polygon; + } + /* MultiPolygon */ void multipolygon_start() { diff --git a/ThirdParty/osmium/geom/projection.hpp b/ThirdParty/osmium/geom/projection.hpp index 2f9849fe7..72ff945e9 100644 --- a/ThirdParty/osmium/geom/projection.hpp +++ b/ThirdParty/osmium/geom/projection.hpp @@ -57,7 +57,7 @@ namespace osmium { void operator()(void* crs) { pj_free(crs); } - }; + }; // struct ProjCRSDeleter std::unique_ptr m_crs; @@ -142,7 +142,7 @@ namespace osmium { } } - int epsg() const { + int epsg() const noexcept { return m_epsg; } diff --git a/ThirdParty/osmium/geom/util.hpp b/ThirdParty/osmium/geom/util.hpp index 25ea74626..1f1a50dc8 100644 --- a/ThirdParty/osmium/geom/util.hpp +++ b/ThirdParty/osmium/geom/util.hpp @@ -1,71 +1,75 @@ -#ifndef OSMIUM_GEOM_UTIL_HPP -#define OSMIUM_GEOM_UTIL_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include - -namespace osmium { - - struct projection_error : public std::runtime_error { - - projection_error(const std::string& what) : - std::runtime_error(what) { - } - - projection_error(const char* what) : - std::runtime_error(what) { - } - - }; // struct projection_error - - namespace geom { - - constexpr double PI = 3.14159265358979323846; - - /// Convert angle from degrees to radians. - inline constexpr double deg_to_rad(double degree) { - return degree * (PI / 180.0); - } - - /// Convert angle from radians to degrees. - inline constexpr double rad_to_deg(double radians) { - return radians * (180.0 / PI); - } - - } // namespace geom - -} // namespace osmium - -#endif // OSMIUM_GEOM_UTIL_HPP +#ifndef OSMIUM_GEOM_UTIL_HPP +#define OSMIUM_GEOM_UTIL_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include + +namespace osmium { + + /** + * Exception thrown when a projection object can not be initialized or the + * projection of some coordinates can not be calculated. + */ + struct projection_error : public std::runtime_error { + + projection_error(const std::string& what) : + std::runtime_error(what) { + } + + projection_error(const char* what) : + std::runtime_error(what) { + } + + }; // struct projection_error + + namespace geom { + + constexpr double PI = 3.14159265358979323846; + + /// Convert angle from degrees to radians. + inline constexpr double deg_to_rad(double degree) noexcept { + return degree * (PI / 180.0); + } + + /// Convert angle from radians to degrees. + inline constexpr double rad_to_deg(double radians) noexcept { + return radians * (180.0 / PI); + } + + } // namespace geom + +} // namespace osmium + +#endif // OSMIUM_GEOM_UTIL_HPP diff --git a/ThirdParty/osmium/geom/wkb.hpp b/ThirdParty/osmium/geom/wkb.hpp index ac4c47bc8..0748ede54 100644 --- a/ThirdParty/osmium/geom/wkb.hpp +++ b/ThirdParty/osmium/geom/wkb.hpp @@ -38,8 +38,18 @@ DEALINGS IN THE SOFTWARE. #include #include +// Windows is only available for little endian architectures +// http://stackoverflow.com/questions/6449468/can-i-safely-assume-that-windows-installations-will-always-be-little-endian +#if !defined(_WIN32) && !defined(__APPLE__) +# include +#else +# define __LITTLE_ENDIAN 1234 +# define __BYTE_ORDER __LITTLE_ENDIAN +#endif + #include #include +#include namespace osmium { @@ -48,12 +58,12 @@ namespace osmium { enum class wkb_type : bool { wkb = false, ewkb = true - }; + }; // enum class wkb_type enum class out_type : bool { binary = false, hex = true - }; + }; // enum class out_type namespace detail { @@ -99,7 +109,7 @@ namespace osmium { // SRID-presence flag (EWKB) wkbSRID = 0x20000000 - }; + }; // enum wkbGeometryType /** * Byte order marker in WKB geometry. @@ -107,7 +117,7 @@ namespace osmium { enum class wkb_byte_order_type : uint8_t { XDR = 0, // Big Endian NDR = 1 // Little Endian - }; + }; // enum class wkb_byte_order_type std::string m_data; uint32_t m_points {0}; @@ -122,7 +132,11 @@ namespace osmium { size_t m_ring_size_offset = 0; size_t header(std::string& str, wkbGeometryType type, bool add_length) const { +#if __BYTE_ORDER == __LITTLE_ENDIAN str_push(str, wkb_byte_order_type::NDR); +#else + str_push(str, wkb_byte_order_type::XDR); +#endif if (m_wkb_type == wkb_type::ewkb) { str_push(str, type | wkbSRID); str_push(str, srid); @@ -136,8 +150,9 @@ namespace osmium { return offset; } - void set_size(const size_t offset, const uint32_t size) { - memcpy(&m_data[offset], &size, sizeof(uint32_t)); + void set_size(const size_t offset, const size_t size) { + const uint32_t s = static_cast_with_assert(size); + memcpy(&m_data[offset], &s, sizeof(uint32_t)); } public: diff --git a/ThirdParty/osmium/geom/wkt.hpp b/ThirdParty/osmium/geom/wkt.hpp index dd12ad34e..0ef304a86 100644 --- a/ThirdParty/osmium/geom/wkt.hpp +++ b/ThirdParty/osmium/geom/wkt.hpp @@ -34,6 +34,7 @@ DEALINGS IN THE SOFTWARE. */ #include +#include #include #include @@ -49,6 +50,7 @@ namespace osmium { class WKTFactoryImpl { std::string m_str; + int m_precision; public: @@ -58,11 +60,15 @@ namespace osmium { typedef std::string multipolygon_type; typedef std::string ring_type; + WKTFactoryImpl(int precision = 7) : + m_precision(precision) { + } + /* Point */ point_type make_point(const osmium::geom::Coordinates& xy) const { std::string str {"POINT"}; - xy.append_to_string(str, '(', ' ', ')'); + xy.append_to_string(str, '(', ' ', ')', m_precision); return str; } @@ -73,7 +79,7 @@ namespace osmium { } void linestring_add_location(const osmium::geom::Coordinates& xy) { - xy.append_to_string(m_str, ' '); + xy.append_to_string(m_str, ' ', m_precision); m_str += ','; } @@ -118,7 +124,7 @@ namespace osmium { } void multipolygon_add_location(const osmium::geom::Coordinates& xy) { - xy.append_to_string(m_str, ' '); + xy.append_to_string(m_str, ' ', m_precision); m_str += ','; } diff --git a/ThirdParty/osmium/handler/chain.hpp b/ThirdParty/osmium/handler/chain.hpp index a7bf10e9a..868632d7e 100644 --- a/ThirdParty/osmium/handler/chain.hpp +++ b/ThirdParty/osmium/handler/chain.hpp @@ -1,128 +1,128 @@ -#ifndef OSMIUM_HANDLER_CHAIN_HPP -#define OSMIUM_HANDLER_CHAIN_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include - -#include - -#define OSMIUM_CHAIN_HANDLER_CALL(_func_, _type_) \ - template \ - struct call_ ## _func_ { \ - void operator()(THandlers& handlers, osmium::_type_& object) { \ - std::get(handlers)._func_(object); \ - call_ ## _func_()(handlers, object); \ - } \ - }; \ - template \ - struct call_ ## _func_ { \ - void operator()(THandlers&, osmium::_type_&) {} \ - }; - -namespace osmium { - - class Node; - class Way; - class Relation; - class Area; - class Changeset; - - namespace handler { - - /** - * This handler allows chaining of any number of handlers into a single - * handler. - */ - template - class ChainHandler : public osmium::handler::Handler { - - typedef std::tuple handlers_type; - handlers_type m_handlers; - - template - struct call_flush { - void operator()(THandlers& handlers) { - std::get(handlers).flush(); - call_flush()(handlers); - } - }; - - template - struct call_flush { - void operator()(THandlers&) {} - }; - - OSMIUM_CHAIN_HANDLER_CALL(node, Node) - OSMIUM_CHAIN_HANDLER_CALL(way, Way) - OSMIUM_CHAIN_HANDLER_CALL(relation, Relation) - OSMIUM_CHAIN_HANDLER_CALL(changeset, Changeset) - OSMIUM_CHAIN_HANDLER_CALL(area, Area) - - public: - - explicit ChainHandler(THandler&... handlers) : - m_handlers(handlers...) { - } - - void node(osmium::Node& node) { - call_node<0, sizeof...(THandler), handlers_type>()(m_handlers, node); - } - - void way(osmium::Way& way) { - call_way<0, sizeof...(THandler), handlers_type>()(m_handlers, way); - } - - void relation(osmium::Relation& relation) { - call_relation<0, sizeof...(THandler), handlers_type>()(m_handlers, relation); - } - - void changeset( osmium::Changeset& changeset) { - call_changeset<0, sizeof...(THandler), handlers_type>()(m_handlers, changeset); - } - - void area(osmium::Area& area) { - call_area<0, sizeof...(THandler), handlers_type>()(m_handlers, area); - } - - void flush() { - call_flush<0, sizeof...(THandler), handlers_type>()(m_handlers); - } - - }; // class ChainHandler - - } // namespace handler - -} // namespace osmium - -#endif // OSMIUM_HANDLER_CHAIN_HPP +#ifndef OSMIUM_HANDLER_CHAIN_HPP +#define OSMIUM_HANDLER_CHAIN_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include + +#include + +#define OSMIUM_CHAIN_HANDLER_CALL(_func_, _type_) \ + template \ + struct call_ ## _func_ { \ + void operator()(THandlers& handlers, osmium::_type_& object) { \ + std::get(handlers)._func_(object); \ + call_ ## _func_()(handlers, object); \ + } \ + }; \ + template \ + struct call_ ## _func_ { \ + void operator()(THandlers&, osmium::_type_&) {} \ + }; + +namespace osmium { + + class Node; + class Way; + class Relation; + class Area; + class Changeset; + + namespace handler { + + /** + * This handler allows chaining of any number of handlers into a single + * handler. + */ + template + class ChainHandler : public osmium::handler::Handler { + + typedef std::tuple handlers_type; + handlers_type m_handlers; + + template + struct call_flush { + void operator()(THandlers& handlers) { + std::get(handlers).flush(); + call_flush()(handlers); + } + }; // struct call_flush + + template + struct call_flush { + void operator()(THandlers&) {} + }; // struct call_flush + + OSMIUM_CHAIN_HANDLER_CALL(node, Node) + OSMIUM_CHAIN_HANDLER_CALL(way, Way) + OSMIUM_CHAIN_HANDLER_CALL(relation, Relation) + OSMIUM_CHAIN_HANDLER_CALL(changeset, Changeset) + OSMIUM_CHAIN_HANDLER_CALL(area, Area) + + public: + + explicit ChainHandler(THandler&... handlers) : + m_handlers(handlers...) { + } + + void node(osmium::Node& node) { + call_node<0, sizeof...(THandler), handlers_type>()(m_handlers, node); + } + + void way(osmium::Way& way) { + call_way<0, sizeof...(THandler), handlers_type>()(m_handlers, way); + } + + void relation(osmium::Relation& relation) { + call_relation<0, sizeof...(THandler), handlers_type>()(m_handlers, relation); + } + + void changeset( osmium::Changeset& changeset) { + call_changeset<0, sizeof...(THandler), handlers_type>()(m_handlers, changeset); + } + + void area(osmium::Area& area) { + call_area<0, sizeof...(THandler), handlers_type>()(m_handlers, area); + } + + void flush() { + call_flush<0, sizeof...(THandler), handlers_type>()(m_handlers); + } + + }; // class ChainHandler + + } // namespace handler + +} // namespace osmium + +#endif // OSMIUM_HANDLER_CHAIN_HPP diff --git a/ThirdParty/osmium/handler/dump.hpp b/ThirdParty/osmium/handler/dump.hpp index 63c66e39e..e62c4b071 100644 --- a/ThirdParty/osmium/handler/dump.hpp +++ b/ThirdParty/osmium/handler/dump.hpp @@ -1,294 +1,294 @@ -#ifndef OSMIUM_HANDLER_DUMP_HPP -#define OSMIUM_HANDLER_DUMP_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace osmium { - - namespace handler { - - class Dump : public osmium::handler::Handler { - - std::ostream& m_out; - bool m_with_size; - std::string m_prefix; - - void print_title(const char* title, const osmium::memory::Item& item) { - m_out << m_prefix - << title - << ":"; - - if (m_with_size) { - m_out << " [" - << item.byte_size() - << "]"; - } - - m_out << "\n"; - } - - void print_meta(const osmium::OSMObject& object) { - m_out << m_prefix - << " id=" - << object.id() - << "\n"; - m_out << m_prefix - << " version=" - << object.version() - << "\n"; - m_out << m_prefix - << " uid=" - << object.uid() - << "\n"; - m_out << m_prefix - << " user=|" - << object.user() - << "|\n"; - m_out << m_prefix - << " changeset=" - << object.changeset() - << "\n"; - m_out << m_prefix - << " timestamp=" - << object.timestamp().to_iso() - << "\n"; - m_out << m_prefix - << " visible=" - << (object.visible() ? "yes" : "no") - << "\n"; - - Dump dump(m_out, m_with_size, m_prefix + " "); - osmium::apply(object.cbegin(), object.cend(), dump); - } - - void print_location(const osmium::Node& node) { - const osmium::Location& location = node.location(); - - if (location) { - m_out << m_prefix - << " lon=" - << std::fixed - << std::setprecision(7) - << location.lon_without_check() - << "\n"; - m_out << m_prefix - << " lat=" - << location.lat_without_check() - << "\n"; - } else { - m_out << m_prefix - << " lon=\n" - << m_prefix - << " lat=\n"; - } - } - - public: - - explicit Dump(std::ostream& out, bool with_size=true, const std::string& prefix="") : - m_out(out), - m_with_size(with_size), - m_prefix(prefix) { - } - - void tag_list(const osmium::TagList& tags) { - print_title("TAGS", tags); - for (const auto& tag : tags) { - m_out << m_prefix - << " k=|" - << tag.key() - << "| v=|" - << tag.value() - << "|" - << "\n"; - } - } - - void way_node_list(const osmium::WayNodeList& wnl) { - print_title("NODES", wnl); - for (const auto& node_ref : wnl) { - m_out << m_prefix - << " ref=" - << node_ref.ref(); - if (node_ref.location()) { - m_out << " pos=" - << node_ref.location(); - } - m_out << "\n"; - } - } - - void relation_member_list(const osmium::RelationMemberList& rml) { - print_title("MEMBERS", rml); - for (const auto& member : rml) { - m_out << m_prefix - << " type=" - << item_type_to_name(member.type()) - << " ref=" - << member.ref() - << " role=|" - << member.role() - << "|\n"; - if (member.full_member()) { - Dump dump(m_out, m_with_size, m_prefix + " | "); - osmium::apply_item(member.get_object(), dump); - } - } - } - - void outer_ring(const osmium::OuterRing& ring) { - print_title("OUTER RING", ring); - for (const auto& node_ref : ring) { - m_out << m_prefix - << " ref=" - << node_ref.ref(); - if (node_ref.location()) { - m_out << " pos=" - << node_ref.location(); - } - m_out << "\n"; - } - } - - void inner_ring(const osmium::InnerRing& ring) { - print_title("INNER RING", ring); - for (const auto& node_ref : ring) { - m_out << m_prefix - << " ref=" - << node_ref.ref(); - if (node_ref.location()) { - m_out << " pos=" - << node_ref.location(); - } - m_out << "\n"; - } - } - - void node(const osmium::Node& node) { - print_title("NODE", node); - print_meta(node); - print_location(node); - } - - void way(const osmium::Way& way) { - print_title("WAY", way); - print_meta(way); - } - - void relation(const osmium::Relation& relation) { - print_title("RELATION", relation); - print_meta(relation); - } - - void area(const osmium::Area& area) { - print_title("AREA", area); - print_meta(area); - } - - void changeset(const osmium::Changeset& changeset) { - print_title("CHANGESET", changeset); - m_out << m_prefix - << " id=" - << changeset.id() - << "\n"; - m_out << m_prefix - << " num_changes=" - << changeset.num_changes() - << "\n"; - m_out << m_prefix - << " uid=" - << changeset.uid() - << "\n"; - m_out << m_prefix - << " user=|" - << changeset.user() - << "|\n"; - m_out << m_prefix - << " created_at=" - << changeset.created_at().to_iso() - << "\n"; - m_out << m_prefix - << " closed_at=" - << changeset.closed_at().to_iso() - << "\n"; - m_out << m_prefix - << " bounds="; - - if (changeset.bounds()) { - m_out << '(' - << changeset.bounds().bottom_left().lon_without_check() - << ',' - << changeset.bounds().bottom_left().lat_without_check() - << ',' - << changeset.bounds().top_right().lon_without_check() - << ',' - << changeset.bounds().top_right().lat_without_check() - << ')'; - } else { - m_out << "(undefined)"; - } - - m_out << "\n"; - - Dump dump(m_out, m_with_size, m_prefix + " "); - osmium::apply(changeset.cbegin(), changeset.cend(), dump); - } - - }; // class Dump - - } // namespace handler - -} // namespace osmium - -#endif // OSMIUM_HANDLER_DUMP_HPP +#ifndef OSMIUM_HANDLER_DUMP_HPP +#define OSMIUM_HANDLER_DUMP_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace osmium { + + namespace handler { + + class Dump : public osmium::handler::Handler { + + std::ostream* m_out; + bool m_with_size; + std::string m_prefix; + + void print_title(const char* title, const osmium::memory::Item& item) { + *m_out << m_prefix + << title + << ":"; + + if (m_with_size) { + *m_out << " [" + << item.byte_size() + << "]"; + } + + *m_out << "\n"; + } + + void print_meta(const osmium::OSMObject& object) { + *m_out << m_prefix + << " id=" + << object.id() + << "\n"; + *m_out << m_prefix + << " version=" + << object.version() + << "\n"; + *m_out << m_prefix + << " uid=" + << object.uid() + << "\n"; + *m_out << m_prefix + << " user=|" + << object.user() + << "|\n"; + *m_out << m_prefix + << " changeset=" + << object.changeset() + << "\n"; + *m_out << m_prefix + << " timestamp=" + << object.timestamp().to_iso() + << "\n"; + *m_out << m_prefix + << " visible=" + << (object.visible() ? "yes" : "no") + << "\n"; + + Dump dump(*m_out, m_with_size, m_prefix + " "); + osmium::apply(object.cbegin(), object.cend(), dump); + } + + void print_location(const osmium::Node& node) { + const osmium::Location& location = node.location(); + + if (location) { + *m_out << m_prefix + << " lon=" + << std::fixed + << std::setprecision(7) + << location.lon_without_check() + << "\n"; + *m_out << m_prefix + << " lat=" + << location.lat_without_check() + << "\n"; + } else { + *m_out << m_prefix + << " lon=\n" + << m_prefix + << " lat=\n"; + } + } + + public: + + explicit Dump(std::ostream& out, bool with_size=true, const std::string& prefix="") : + m_out(&out), + m_with_size(with_size), + m_prefix(prefix) { + } + + void tag_list(const osmium::TagList& tags) { + print_title("TAGS", tags); + for (const auto& tag : tags) { + *m_out << m_prefix + << " k=|" + << tag.key() + << "| v=|" + << tag.value() + << "|" + << "\n"; + } + } + + void way_node_list(const osmium::WayNodeList& wnl) { + print_title("NODES", wnl); + for (const auto& node_ref : wnl) { + *m_out << m_prefix + << " ref=" + << node_ref.ref(); + if (node_ref.location()) { + *m_out << " pos=" + << node_ref.location(); + } + *m_out << "\n"; + } + } + + void relation_member_list(const osmium::RelationMemberList& rml) { + print_title("MEMBERS", rml); + for (const auto& member : rml) { + *m_out << m_prefix + << " type=" + << item_type_to_name(member.type()) + << " ref=" + << member.ref() + << " role=|" + << member.role() + << "|\n"; + if (member.full_member()) { + Dump dump(*m_out, m_with_size, m_prefix + " | "); + osmium::apply_item(member.get_object(), dump); + } + } + } + + void outer_ring(const osmium::OuterRing& ring) { + print_title("OUTER RING", ring); + for (const auto& node_ref : ring) { + *m_out << m_prefix + << " ref=" + << node_ref.ref(); + if (node_ref.location()) { + *m_out << " pos=" + << node_ref.location(); + } + *m_out << "\n"; + } + } + + void inner_ring(const osmium::InnerRing& ring) { + print_title("INNER RING", ring); + for (const auto& node_ref : ring) { + *m_out << m_prefix + << " ref=" + << node_ref.ref(); + if (node_ref.location()) { + *m_out << " pos=" + << node_ref.location(); + } + *m_out << "\n"; + } + } + + void node(const osmium::Node& node) { + print_title("NODE", node); + print_meta(node); + print_location(node); + } + + void way(const osmium::Way& way) { + print_title("WAY", way); + print_meta(way); + } + + void relation(const osmium::Relation& relation) { + print_title("RELATION", relation); + print_meta(relation); + } + + void area(const osmium::Area& area) { + print_title("AREA", area); + print_meta(area); + } + + void changeset(const osmium::Changeset& changeset) { + print_title("CHANGESET", changeset); + *m_out << m_prefix + << " id=" + << changeset.id() + << "\n"; + *m_out << m_prefix + << " num_changes=" + << changeset.num_changes() + << "\n"; + *m_out << m_prefix + << " uid=" + << changeset.uid() + << "\n"; + *m_out << m_prefix + << " user=|" + << changeset.user() + << "|\n"; + *m_out << m_prefix + << " created_at=" + << changeset.created_at().to_iso() + << "\n"; + *m_out << m_prefix + << " closed_at=" + << changeset.closed_at().to_iso() + << "\n"; + *m_out << m_prefix + << " bounds="; + + if (changeset.bounds()) { + *m_out << '(' + << changeset.bounds().bottom_left().lon_without_check() + << ',' + << changeset.bounds().bottom_left().lat_without_check() + << ',' + << changeset.bounds().top_right().lon_without_check() + << ',' + << changeset.bounds().top_right().lat_without_check() + << ')'; + } else { + *m_out << "(undefined)"; + } + + *m_out << "\n"; + + Dump dump(*m_out, m_with_size, m_prefix + " "); + osmium::apply(changeset.cbegin(), changeset.cend(), dump); + } + + }; // class Dump + + } // namespace handler + +} // namespace osmium + +#endif // OSMIUM_HANDLER_DUMP_HPP diff --git a/ThirdParty/osmium/handler/node_locations_for_ways.hpp b/ThirdParty/osmium/handler/node_locations_for_ways.hpp index 695eae010..8ece3d9f6 100644 --- a/ThirdParty/osmium/handler/node_locations_for_ways.hpp +++ b/ThirdParty/osmium/handler/node_locations_for_ways.hpp @@ -1,148 +1,170 @@ -#ifndef OSMIUM_HANDLER_NODE_LOCATIONS_FOR_WAYS_HPP -#define OSMIUM_HANDLER_NODE_LOCATIONS_FOR_WAYS_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace osmium { - - namespace handler { - - typedef osmium::index::map::Dummy dummy_type; - - /** - * Handler to retrieve locations from nodes and add them to ways. - * - * @tparam TStoragePosIDs Class that handles the actual storage of the node locations - * (for positive IDs). It must support the set(id, value) and - * get(id) methods. - * @tparam TStorageNegIDs Same but for negative IDs. - */ - template - class NodeLocationsForWays : public osmium::handler::Handler { - - /// Object that handles the actual storage of the node locations (with positive IDs). - TStoragePosIDs& m_storage_pos; - - /// Object that handles the actual storage of the node locations (with negative IDs). - TStorageNegIDs& m_storage_neg; - - bool m_ignore_errors {false}; - - bool m_must_sort {false}; - - // It is okay to have this static dummy instance, even when using several threads, - // because it is read-only. - static dummy_type& get_dummy() { - static dummy_type instance; - return instance; - } - - public: - - explicit NodeLocationsForWays(TStoragePosIDs& storage_pos, - TStorageNegIDs& storage_neg = get_dummy()) : - m_storage_pos(storage_pos), - m_storage_neg(storage_neg) { - } - - NodeLocationsForWays(const NodeLocationsForWays&) = delete; - NodeLocationsForWays& operator=(const NodeLocationsForWays&) = delete; - - ~NodeLocationsForWays() noexcept = default; - - void ignore_errors() { - m_ignore_errors = true; - } - - /** - * Store the location of the node in the storage. - */ - void node(const osmium::Node& node) { - m_must_sort = true; - const osmium::object_id_type id = node.id(); - if (id >= 0) { - m_storage_pos.set(id, node.location()); - } else { - m_storage_neg.set(-id, node.location()); - } - } - - /** - * Get location of node with given id. - */ - osmium::Location get_node_location(const osmium::object_id_type id) const { - return id >= 0 ? m_storage_pos.get(id) : m_storage_neg.get(-id); - } - - /** - * Retrieve locations of all nodes in the way from storage and add - * them to the way object. - */ - void way(osmium::Way& way) { - if (m_must_sort) { - m_storage_pos.sort(); - m_storage_neg.sort(); - m_must_sort = false; - } - bool error = false; - for (auto& node_ref : way.nodes()) { - try { - node_ref.location(get_node_location(node_ref.ref())); - if (!node_ref.location()) { - error = true; - } - } catch (osmium::not_found&) { - error = true; - } - } - if (error && !m_ignore_errors) { - throw osmium::not_found("not found"); - } - } - - }; // class NodeLocationsForWays - - } // namespace handler - -} // namespace osmium - -#endif // OSMIUM_HANDLER_NODE_LOCATIONS_FOR_WAYS_HPP +#ifndef OSMIUM_HANDLER_NODE_LOCATIONS_FOR_WAYS_HPP +#define OSMIUM_HANDLER_NODE_LOCATIONS_FOR_WAYS_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace osmium { + + namespace handler { + + typedef osmium::index::map::Dummy dummy_type; + + /** + * Handler to retrieve locations from nodes and add them to ways. + * + * @tparam TStoragePosIDs Class that handles the actual storage of the node locations + * (for positive IDs). It must support the set(id, value) and + * get(id) methods. + * @tparam TStorageNegIDs Same but for negative IDs. + */ + template + class NodeLocationsForWays : public osmium::handler::Handler { + + static_assert(std::is_base_of, TStoragePosIDs>::value, + "Index class must be derived from osmium::index::map::Map"); + + static_assert(std::is_base_of, TStorageNegIDs>::value, + "Index class must be derived from osmium::index::map::Map"); + + /// Object that handles the actual storage of the node locations (with positive IDs). + TStoragePosIDs& m_storage_pos; + + /// Object that handles the actual storage of the node locations (with negative IDs). + TStorageNegIDs& m_storage_neg; + + bool m_ignore_errors {false}; + + bool m_must_sort {false}; + + // It is okay to have this static dummy instance, even when using several threads, + // because it is read-only. + static dummy_type& get_dummy() { + static dummy_type instance; + return instance; + } + + public: + + explicit NodeLocationsForWays(TStoragePosIDs& storage_pos, + TStorageNegIDs& storage_neg = get_dummy()) : + m_storage_pos(storage_pos), + m_storage_neg(storage_neg) { + } + + NodeLocationsForWays(const NodeLocationsForWays&) = delete; + NodeLocationsForWays& operator=(const NodeLocationsForWays&) = delete; + + ~NodeLocationsForWays() noexcept = default; + + void ignore_errors() { + m_ignore_errors = true; + } + + /** + * Store the location of the node in the storage. + */ + void node(const osmium::Node& node) { + m_must_sort = true; + const osmium::object_id_type id = node.id(); + if (id >= 0) { + m_storage_pos.set(static_cast( id), node.location()); + } else { + m_storage_neg.set(static_cast(-id), node.location()); + } + } + + /** + * Get location of node with given id. + */ + osmium::Location get_node_location(const osmium::object_id_type id) const { + if (id >= 0) { + return m_storage_pos.get(static_cast( id)); + } else { + return m_storage_neg.get(static_cast(-id)); + } + } + + /** + * Retrieve locations of all nodes in the way from storage and add + * them to the way object. + */ + void way(osmium::Way& way) { + if (m_must_sort) { + m_storage_pos.sort(); + m_storage_neg.sort(); + m_must_sort = false; + } + bool error = false; + for (auto& node_ref : way.nodes()) { + try { + node_ref.set_location(get_node_location(node_ref.ref())); + if (!node_ref.location()) { + error = true; + } + } catch (osmium::not_found&) { + error = true; + } + } + if (error && !m_ignore_errors) { + throw osmium::not_found("location for one or more nodes not found in node location index"); + } + } + + /** + * Call clear on the location indexes. Makes the + * NodeLocationsForWays handler unusable. Used to explicitly free + * memory if thats needed. + */ + void clear() { + m_storage_pos.clear(); + m_storage_neg.clear(); + } + + }; // class NodeLocationsForWays + + } // namespace handler + +} // namespace osmium + +#endif // OSMIUM_HANDLER_NODE_LOCATIONS_FOR_WAYS_HPP diff --git a/ThirdParty/osmium/index/detail/mmap_vector_base.hpp b/ThirdParty/osmium/index/detail/mmap_vector_base.hpp index 7ff4af2ba..fc96b271a 100644 --- a/ThirdParty/osmium/index/detail/mmap_vector_base.hpp +++ b/ThirdParty/osmium/index/detail/mmap_vector_base.hpp @@ -1,183 +1,183 @@ -#ifndef OSMIUM_DETAIL_MMAP_VECTOR_BASE_HPP -#define OSMIUM_DETAIL_MMAP_VECTOR_BASE_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include - -#include - -namespace osmium { - - namespace detail { - - constexpr size_t mmap_vector_size_increment = 1024 * 1024; - - /** - * This is a base class for implementing classes that look like - * STL vector but use mmap internally. This class can not be used - * on it's own. Use the derived classes mmap_vector_anon or - * mmap_vector_file. - */ - template class TDerived> - class mmap_vector_base { - - protected: - - int m_fd; - size_t m_capacity; - size_t m_size; - T* m_data; - - explicit mmap_vector_base(int fd, size_t capacity, size_t size, T* data) : - m_fd(fd), - m_capacity(capacity), - m_size(size), - m_data(data) { - } - - explicit mmap_vector_base(int fd, size_t capacity, size_t size) : - m_fd(fd), - m_capacity(capacity), - m_size(size), - m_data(osmium::detail::typed_mmap::grow_and_map(capacity, m_fd)) { - } - - void data(T* data) { - m_data = data; - } - - public: - - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef T* pointer; - typedef const T* const_pointer; - typedef T* iterator; - typedef const T* const_iterator; - - ~mmap_vector_base() { - osmium::detail::typed_mmap::unmap(m_data, m_capacity); - } - - size_t capacity() const { - return m_capacity; - } - - size_t size() const { - return m_size; - } - - bool empty() const { - return m_size == 0; - } - - const T* data() const { - return m_data; - } - - T* data() { - return m_data; - } - - T& operator[](size_t n) { - return m_data[n]; - } - - T at(size_t n) const { - if (n >= m_size) { - throw std::out_of_range("out of range"); - } - return m_data[n]; - } - - void clear() { - m_size = 0; - } - - void shrink_to_fit() { - // XXX do something here - } - - void push_back(const T& value) { - if (m_size >= m_capacity) { - resize(m_size+1); - } - m_data[m_size] = value; - ++m_size; - } - - void resize(size_t new_size) { - if (new_size > this->capacity()) { - static_cast*>(this)->reserve(new_size + osmium::detail::mmap_vector_size_increment); - } - if (new_size > this->size()) { - new (this->data() + this->size()) T[new_size - this->size()]; - } - this->m_size = new_size; - } - - iterator begin() { - return m_data; - } - - iterator end() { - return m_data + m_size; - } - - const_iterator begin() const { - return m_data; - } - - const_iterator end() const { - return m_data + m_size; - } - - const_iterator cbegin() { - return m_data; - } - - const_iterator cend() { - return m_data + m_size; - } - - }; // class mmap_vector_base - - } // namespace detail - -} // namespace osmium - -#endif // OSMIUM_DETAIL_MMAP_VECTOR_BASE_HPP +#ifndef OSMIUM_DETAIL_MMAP_VECTOR_BASE_HPP +#define OSMIUM_DETAIL_MMAP_VECTOR_BASE_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include + +#include + +namespace osmium { + + namespace detail { + + constexpr size_t mmap_vector_size_increment = 1024 * 1024; + + /** + * This is a base class for implementing classes that look like + * STL vector but use mmap internally. This class can not be used + * on it's own. Use the derived classes mmap_vector_anon or + * mmap_vector_file. + */ + template class TDerived> + class mmap_vector_base { + + protected: + + int m_fd; + size_t m_capacity; + size_t m_size; + T* m_data; + + explicit mmap_vector_base(int fd, size_t capacity, size_t size, T* data) noexcept : + m_fd(fd), + m_capacity(capacity), + m_size(size), + m_data(data) { + } + + explicit mmap_vector_base(int fd, size_t capacity, size_t size) : + m_fd(fd), + m_capacity(capacity), + m_size(size), + m_data(osmium::detail::typed_mmap::grow_and_map(capacity, m_fd)) { + } + + void data(T* data) { + m_data = data; + } + + public: + + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T* pointer; + typedef const T* const_pointer; + typedef T* iterator; + typedef const T* const_iterator; + + ~mmap_vector_base() { + osmium::detail::typed_mmap::unmap(m_data, m_capacity); + } + + size_t capacity() const noexcept { + return m_capacity; + } + + size_t size() const noexcept { + return m_size; + } + + bool empty() const noexcept { + return m_size == 0; + } + + const T* data() const noexcept { + return m_data; + } + + T* data() noexcept { + return m_data; + } + + T& operator[](size_t n) { + return m_data[n]; + } + + T at(size_t n) const { + if (n >= m_size) { + throw std::out_of_range("out of range"); + } + return m_data[n]; + } + + void clear() noexcept { + m_size = 0; + } + + void shrink_to_fit() { + // XXX do something here + } + + void push_back(const T& value) { + if (m_size >= m_capacity) { + resize(m_size+1); + } + m_data[m_size] = value; + ++m_size; + } + + void resize(size_t new_size) { + if (new_size > capacity()) { + static_cast*>(this)->reserve(new_size + osmium::detail::mmap_vector_size_increment); + } + if (new_size > size()) { + new (data() + size()) T[new_size - size()]; + } + m_size = new_size; + } + + iterator begin() noexcept { + return m_data; + } + + iterator end() noexcept { + return m_data + m_size; + } + + const_iterator begin() const noexcept { + return m_data; + } + + const_iterator end() const noexcept { + return m_data + m_size; + } + + const_iterator cbegin() noexcept { + return m_data; + } + + const_iterator cend() noexcept { + return m_data + m_size; + } + + }; // class mmap_vector_base + + } // namespace detail + +} // namespace osmium + +#endif // OSMIUM_DETAIL_MMAP_VECTOR_BASE_HPP diff --git a/ThirdParty/osmium/index/detail/mmap_vector_file.hpp b/ThirdParty/osmium/index/detail/mmap_vector_file.hpp index fe2f98a9e..ca8f0ebfa 100644 --- a/ThirdParty/osmium/index/detail/mmap_vector_file.hpp +++ b/ThirdParty/osmium/index/detail/mmap_vector_file.hpp @@ -1,83 +1,82 @@ -#ifndef OSMIUM_DETAIL_MMAP_VECTOR_FILE_HPP -#define OSMIUM_DETAIL_MMAP_VECTOR_FILE_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include - -#include -#include -#include - -namespace osmium { - - namespace detail { - - /** - * This class looks and behaves like STL vector, but mmap's a file internally. - */ - template - class mmap_vector_file : public mmap_vector_base { - - public: - - explicit mmap_vector_file() : - mmap_vector_base( - osmium::detail::create_tmp_file(), - osmium::detail::mmap_vector_size_increment, - 0) { - } - - explicit mmap_vector_file(int fd) : - mmap_vector_base( - fd, - osmium::detail::typed_mmap::file_size(fd) == 0 ? osmium::detail::mmap_vector_size_increment : osmium::detail::typed_mmap::file_size(fd), - osmium::detail::typed_mmap::file_size(fd)) { - } - - void reserve(size_t new_capacity) { - if (new_capacity > this->capacity()) { - osmium::detail::typed_mmap::unmap(this->data(), this->capacity()); - osmium::detail::typed_mmap::grow_file(new_capacity, this->m_fd); - osmium::detail::typed_mmap::map(new_capacity, this->m_fd); - this->m_capacity = new_capacity; - } - } - - }; // class mmap_vector_file - - } // namespace detail - -} // namespace osmium - -#endif // OSMIUM_DETAIL_MMAP_VECTOR_FILE_HPP +#ifndef OSMIUM_DETAIL_MMAP_VECTOR_FILE_HPP +#define OSMIUM_DETAIL_MMAP_VECTOR_FILE_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include + +#include +#include +#include + +namespace osmium { + + namespace detail { + + /** + * This class looks and behaves like STL vector, but mmap's a file internally. + */ + template + class mmap_vector_file : public mmap_vector_base { + + public: + + explicit mmap_vector_file() : + mmap_vector_base( + osmium::detail::create_tmp_file(), + osmium::detail::mmap_vector_size_increment, + 0) { + } + + explicit mmap_vector_file(int fd) : + mmap_vector_base( + fd, + osmium::detail::typed_mmap::file_size(fd) == 0 ? osmium::detail::mmap_vector_size_increment : osmium::detail::typed_mmap::file_size(fd), + osmium::detail::typed_mmap::file_size(fd)) { + } + + void reserve(size_t new_capacity) { + if (new_capacity > this->capacity()) { + osmium::detail::typed_mmap::unmap(this->data(), this->capacity()); + this->data(osmium::detail::typed_mmap::grow_and_map(new_capacity, this->m_fd)); + this->m_capacity = new_capacity; + } + } + + }; // class mmap_vector_file + + } // namespace detail + +} // namespace osmium + +#endif // OSMIUM_DETAIL_MMAP_VECTOR_FILE_HPP diff --git a/ThirdParty/osmium/index/detail/tmpfile.hpp b/ThirdParty/osmium/index/detail/tmpfile.hpp index 50c9cc9a5..3d00c5017 100644 --- a/ThirdParty/osmium/index/detail/tmpfile.hpp +++ b/ThirdParty/osmium/index/detail/tmpfile.hpp @@ -44,8 +44,8 @@ namespace osmium { /** * Create and open a temporary file. It is removed after opening. * - * @return File descriptor of temporary file. - * @exception std::system_error if something went wrong. + * @returns File descriptor of temporary file. + * @throws std::system_error if something went wrong. */ inline int create_tmp_file() { FILE* file = ::tmpfile(); diff --git a/ThirdParty/osmium/index/detail/typed_mmap.hpp b/ThirdParty/osmium/index/detail/typed_mmap.hpp index d064da2be..8a952a4e0 100644 --- a/ThirdParty/osmium/index/detail/typed_mmap.hpp +++ b/ThirdParty/osmium/index/detail/typed_mmap.hpp @@ -38,18 +38,18 @@ DEALINGS IN THE SOFTWARE. #include #include -#ifndef WIN32 +#include + +#ifndef _WIN32 # include #else # include #endif -#include - -#ifdef _MSC_VER -# define ftruncate _chsize -#else +#ifndef _MSC_VER # include +#else +# define ftruncate _chsize #endif // for bsd systems @@ -57,6 +57,8 @@ DEALINGS IN THE SOFTWARE. # define MAP_ANONYMOUS MAP_ANON #endif +#include + namespace osmium { /** @@ -89,8 +91,8 @@ namespace osmium { * Note that no constructor is called for any of the objects in this memory! * * @param size Number of objects of type T that should fit into this memory - * @return Pointer to mapped memory - * @exception std::system_error If mmap(2) failed + * @returns Pointer to mapped memory + * @throws std::system_error If mmap(2) failed */ static T* map(size_t size) { void* addr = ::mmap(nullptr, sizeof(T) * size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); @@ -113,8 +115,8 @@ namespace osmium { * @param size Number of objects of type T that should fit into this memory * @param fd File descriptor * @param write True if data should be writable - * @return Pointer to mapped memory - * @exception std::system_error If mmap(2) failed + * @returns Pointer to mapped memory + * @throws std::system_error If mmap(2) failed */ static T* map(size_t size, int fd, bool write = false) { int prot = PROT_READ; @@ -141,7 +143,7 @@ namespace osmium { * @param data Pointer to current mapping (as returned by typed_mmap()) * @param old_size Number of objects currently stored in this memory * @param new_size Number of objects we want to have space for - * @exception std::system_error If mremap(2) call failed + * @throws std::system_error If mremap(2) call failed */ static T* remap(T* data, size_t old_size, size_t new_size) { void* addr = ::mremap(reinterpret_cast(data), sizeof(T) * old_size, sizeof(T) * new_size, MREMAP_MAYMOVE); @@ -162,7 +164,7 @@ namespace osmium { * * @param data Pointer to the data * @param size Number of objects of type T stored - * @exception std::system_error If munmap(2) call failed + * @throws std::system_error If munmap(2) call failed */ static void unmap(T* data, size_t size) { if (::munmap(reinterpret_cast(data), sizeof(T) * size) != 0) { @@ -174,19 +176,19 @@ namespace osmium { * Get number of objects of type T that would fit into a file. * * @param fd File descriptor - * @return Number of objects of type T in this file - * @exception std::system_error If fstat(2) call failed - * @exception std::length_error If size of the file isn't a multiple of sizeof(T) + * @returns Number of objects of type T in this file + * @throws std::system_error If fstat(2) call failed + * @throws std::length_error If size of the file isn't a multiple of sizeof(T) */ static size_t file_size(int fd) { struct stat s; if (fstat(fd, &s) < 0) { throw std::system_error(errno, std::system_category(), "fstat failed"); } - if (s.st_size % sizeof(T) != 0) { + if (static_cast(s.st_size) % sizeof(T) != 0) { throw std::length_error("file size has to be multiple of object size"); } - return s.st_size / sizeof(T); + return static_cast(s.st_size) / sizeof(T); } /** @@ -196,11 +198,11 @@ namespace osmium { * * @param new_size Number of objects of type T that should fit into this file * @param fd File descriptor - * @exception std::system_error If ftruncate(2) call failed + * @throws std::system_error If ftruncate(2) call failed */ static void grow_file(size_t new_size, int fd) { if (file_size(fd) < new_size) { - if (::ftruncate(fd, sizeof(T) * new_size) < 0) { + if (::ftruncate(fd, static_cast_with_assert(sizeof(T) * new_size)) < 0) { throw std::system_error(errno, std::system_category(), "ftruncate failed"); } } @@ -211,7 +213,7 @@ namespace osmium { * * @param size Number of objects of type T that should fit into this file * @param fd File descriptor - * @exception Errors thrown by grow_file() or map() + * @throws Errors thrown by grow_file() or map() */ static T* grow_and_map(size_t size, int fd) { grow_file(size, fd); diff --git a/ThirdParty/osmium/index/map.hpp b/ThirdParty/osmium/index/map.hpp index df865c727..92b880f47 100644 --- a/ThirdParty/osmium/index/map.hpp +++ b/ThirdParty/osmium/index/map.hpp @@ -1,156 +1,155 @@ -#ifndef OSMIUM_INDEX_MAP_HPP -#define OSMIUM_INDEX_MAP_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include - -#include // IWYU pragma: export - -namespace osmium { - - namespace index { - - /** - * @brief Key-value containers with unique integer values for a key - */ - namespace map { - - /** - * This abstract class defines an interface to storage classes - * intended for storing small pieces of data (such as coordinates) - * indexed by a positive integer (such as an object ID). The - * storage must be very space efficient and able to scale to billions - * of objects. - * - * Subclasses have different implementations that store the - * data in different ways in memory and/or on disk. Some storage - * classes are better suited when working with the whole planet, - * some are better for data extracts. - * - * Note that these classes are not required to track "empty" fields. - * When reading data you have to be sure you have put something in - * there before. - * - * A typical use for this and derived classes is storage of node - * locations indexed by node ID. These indexes will only work - * on 64 bit systems if used in this case. 32 bit systems just - * can't address that much memory! - * - * @tparam TId Id type, usually osmium::unsigned_object_id_type, - * must be an unsigned integral type. - * @tparam TValue Value type, usually osmium::Location or size_t. - * Copied by value, so should be "small" type. - */ - template - class Map { - - static_assert(std::is_integral::value && std::is_unsigned::value, - "TId template parameter for class Map must be unsigned integral type"); - - Map(const Map&) = delete; - Map& operator=(const Map&) = delete; - - protected: - - Map(Map&&) = default; - Map& operator=(Map&&) = default; - - public: - - /// The "key" type, usually osmium::unsigned_object_id_type. - typedef TId key_type; - - /// The "value" type, usually a Location or size_t. - typedef TValue value_type; - - Map() = default; - -// workaround for a bug in GCC 4.7 -#if __GNUC__ == 4 && __GNUC_MINOR__ < 8 - virtual ~Map() {} -#else - virtual ~Map() = default; -#endif - - virtual void reserve(const size_t) { - // default implementation is empty - } - - /// Set the field with id to value. - virtual void set(const TId id, const TValue value) = 0; - - /// Retrieve value by id. Does not check for overflow or empty fields. - virtual const TValue get(const TId id) const = 0; - - /** - * Get the approximate number of items in the storage. The storage - * might allocate memory in blocks, so this size might not be - * accurate. You can not use this to find out how much memory the - * storage uses. Use used_memory() for that. - */ - virtual size_t size() const = 0; - - /** - * Get the memory used for this storage in bytes. Note that this - * is not necessarily entirely accurate but an approximation. - * For storage classes that store the data in memory, this is - * the main memory used, for storage classes storing data on disk - * this is the memory used on disk. - */ - virtual size_t used_memory() const = 0; - - /** - * Clear memory used for this storage. After this you can not - * use the storage container any more. - */ - virtual void clear() = 0; - - /** - * Sort data in map. Call this after writing all data and - * before reading. Not all implementations need this. - */ - virtual void sort() { - // default implementation is empty - } - - }; // class Map - - } // namespace map - - } // namespace index - -} // namespace osmium - -#endif // OSMIUM_INDEX_MAP_HPP +#ifndef OSMIUM_INDEX_MAP_HPP +#define OSMIUM_INDEX_MAP_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include + +#include // IWYU pragma: export + +namespace osmium { + + namespace index { + + /** + * @brief Key-value containers with unique integer values for a key + */ + namespace map { + + /** + * This abstract class defines an interface to storage classes + * intended for storing small pieces of data (such as coordinates) + * indexed by a positive integer (such as an object ID). The + * storage must be very space efficient and able to scale to billions + * of objects. + * + * Subclasses have different implementations that store the + * data in different ways in memory and/or on disk. Some storage + * classes are better suited when working with the whole planet, + * some are better for data extracts. + * + * Note that these classes are not required to track "empty" fields. + * When reading data you have to be sure you have put something in + * there before. + * + * A typical use for this and derived classes is storage of node + * locations indexed by node ID. These indexes will only work + * on 64 bit systems if used in this case. 32 bit systems just + * can't address that much memory! + * + * @tparam TId Id type, usually osmium::unsigned_object_id_type, + * must be an unsigned integral type. + * @tparam TValue Value type, usually osmium::Location or size_t. + * Copied by value, so should be "small" type. + */ + template + class Map { + + static_assert(std::is_integral::value && std::is_unsigned::value, + "TId template parameter for class Map must be unsigned integral type"); + + Map(const Map&) = delete; + Map& operator=(const Map&) = delete; + + protected: + + Map(Map&&) = default; + Map& operator=(Map&&) = default; + + public: + + /// The "key" type, usually osmium::unsigned_object_id_type. + typedef TId key_type; + + /// The "value" type, usually a Location or size_t. + typedef TValue value_type; + + Map() = default; + + virtual ~Map() = default; + + virtual void reserve(const size_t) { + // default implementation is empty + } + + /// Set the field with id to value. + virtual void set(const TId id, const TValue value) = 0; + + /// Retrieve value by id. Does not check for overflow or empty fields. + virtual const TValue get(const TId id) const = 0; + + /** + * Get the approximate number of items in the storage. The storage + * might allocate memory in blocks, so this size might not be + * accurate. You can not use this to find out how much memory the + * storage uses. Use used_memory() for that. + */ + virtual size_t size() const = 0; + + /** + * Get the memory used for this storage in bytes. Note that this + * is not necessarily entirely accurate but an approximation. + * For storage classes that store the data in memory, this is + * the main memory used, for storage classes storing data on disk + * this is the memory used on disk. + */ + virtual size_t used_memory() const = 0; + + /** + * Clear memory used for this storage. After this you can not + * use the storage container any more. + */ + virtual void clear() = 0; + + /** + * Sort data in map. Call this after writing all data and + * before reading. Not all implementations need this. + */ + virtual void sort() { + // default implementation is empty + } + + virtual void dump_as_list(int /*fd*/) const { + std::runtime_error("can't dump as list"); + } + + }; // class Map + + } // namespace map + + } // namespace index + +} // namespace osmium + +#endif // OSMIUM_INDEX_MAP_HPP diff --git a/ThirdParty/osmium/index/map/sparse_table.hpp b/ThirdParty/osmium/index/map/sparse_table.hpp index 21eb6681d..704e33e21 100644 --- a/ThirdParty/osmium/index/map/sparse_table.hpp +++ b/ThirdParty/osmium/index/map/sparse_table.hpp @@ -1,140 +1,140 @@ -#ifndef OSMIUM_INDEX_MAP_SPARSE_TABLE_HPP -#define OSMIUM_INDEX_MAP_SPARSE_TABLE_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include - -#include - -#include -#include - -namespace osmium { - - namespace index { - - namespace map { - - /** - * The SparseTable index stores elements in a Google sparsetable, - * a data structure that can hold sparsly filled tables in a - * very space efficient way. It will resize automatically. - * - * Use this index if the ID space is only sparsly - * populated, such as when working with smaller OSM files (like - * country extracts). - * - * This will only work on 64 bit machines. - */ - template - class SparseTable : public osmium::index::map::Map { - - TId m_grow_size; - - google::sparsetable m_elements; - - static_assert(sizeof(typename google::sparsetable::size_type) >= 8, "google::sparsetable needs 64bit machine"); - - public: - - /** - * Constructor. - * - * @param grow_size The initial size of the index (ie number of - * elements that fit into the index). - * The storage will grow by at least this size - * every time it runs out of space. - */ - explicit SparseTable(const TId grow_size=10000) : - m_grow_size(grow_size), - m_elements(grow_size) { - } - - ~SparseTable() override final = default; - - void set(const TId id, const TValue value) override final { - if (id >= m_elements.size()) { - m_elements.resize(id + m_grow_size); - } - m_elements[id] = value; - } - - const TValue get(const TId id) const override final { - if (id >= m_elements.size()) { - not_found_error(id); - } - if (m_elements[id] == osmium::index::empty_value()) { - not_found_error(id); - } - return m_elements[id]; - } - - size_t size() const override final { - return m_elements.size(); - } - - size_t used_memory() const override final { - // unused elements use 1 bit, used elements sizeof(TValue) bytes - // http://google-sparsehash.googlecode.com/svn/trunk/doc/sparsetable.html - return (m_elements.size() / 8) + (m_elements.num_nonempty() * sizeof(TValue)); - } - - void clear() override final { - m_elements.clear(); - } - - void dump_as_list(const int fd) const { - std::vector> v; - int n=0; - for (const TValue value : m_elements) { - if (value != osmium::index::empty_value()) { - v.emplace_back(n, value); - } - ++n; - } - osmium::io::detail::reliable_write(fd, reinterpret_cast(v.data()), sizeof(std::pair) * v.size()); - } - - }; // class SparseTable - - } // namespace map - - } // namespace index - -} // namespace osmium - -#endif // OSMIUM_INDEX_BYID_SPARSE_TABLE_HPP +#ifndef OSMIUM_INDEX_MAP_SPARSE_TABLE_HPP +#define OSMIUM_INDEX_MAP_SPARSE_TABLE_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include +#include + +#include + +#include +#include + +namespace osmium { + + namespace index { + + namespace map { + + /** + * The SparseTable index stores elements in a Google sparsetable, + * a data structure that can hold sparsly filled tables in a + * very space efficient way. It will resize automatically. + * + * Use this index if the ID space is only sparsly + * populated, such as when working with smaller OSM files (like + * country extracts). + * + * This will only work on 64 bit machines. + */ + template + class SparseTable : public osmium::index::map::Map { + + TId m_grow_size; + + google::sparsetable m_elements; + + static_assert(sizeof(typename google::sparsetable::size_type) >= 8, "google::sparsetable needs 64bit machine"); + + public: + + /** + * Constructor. + * + * @param grow_size The initial size of the index (ie number of + * elements that fit into the index). + * The storage will grow by at least this size + * every time it runs out of space. + */ + explicit SparseTable(const TId grow_size=10000) : + m_grow_size(grow_size), + m_elements(grow_size) { + } + + ~SparseTable() override final = default; + + void set(const TId id, const TValue value) override final { + if (id >= m_elements.size()) { + m_elements.resize(id + m_grow_size); + } + m_elements[id] = value; + } + + const TValue get(const TId id) const override final { + if (id >= m_elements.size()) { + not_found_error(id); + } + if (m_elements[id] == osmium::index::empty_value()) { + not_found_error(id); + } + return m_elements[id]; + } + + size_t size() const override final { + return m_elements.size(); + } + + size_t used_memory() const override final { + // unused elements use 1 bit, used elements sizeof(TValue) bytes + // http://google-sparsehash.googlecode.com/svn/trunk/doc/sparsetable.html + return (m_elements.size() / 8) + (m_elements.num_nonempty() * sizeof(TValue)); + } + + void clear() override final { + m_elements.clear(); + } + + void dump_as_list(const int fd) const override final { + std::vector> v; + int n=0; + for (const TValue value : m_elements) { + if (value != osmium::index::empty_value()) { + v.emplace_back(n, value); + } + ++n; + } + osmium::io::detail::reliable_write(fd, reinterpret_cast(v.data()), sizeof(std::pair) * v.size()); + } + + }; // class SparseTable + + } // namespace map + + } // namespace index + +} // namespace osmium + +#endif // OSMIUM_INDEX_BYID_SPARSE_TABLE_HPP diff --git a/ThirdParty/osmium/index/map/stl_map.hpp b/ThirdParty/osmium/index/map/stl_map.hpp index 08458d55e..d2781a7e1 100644 --- a/ThirdParty/osmium/index/map/stl_map.hpp +++ b/ThirdParty/osmium/index/map/stl_map.hpp @@ -1,112 +1,112 @@ -#ifndef OSMIUM_INDEX_MAP_STL_MAP_HPP -#define OSMIUM_INDEX_MAP_STL_MAP_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace osmium { - - namespace index { - - namespace map { - - /** - * This implementation uses std::map internally. It uses rather a - * lot of memory, but might make sense for small maps. - */ - template - class StlMap : public osmium::index::map::Map { - - // This is a rough estimate for the memory needed for each - // element in the map (id + value + pointers to left, right, - // and parent plus some overhead for color of red-black-tree - // or similar). - static constexpr size_t element_size = sizeof(TId) + sizeof(TValue) + sizeof(void*) * 4; - - std::map m_elements; - - public: - - StlMap() = default; - - ~StlMap() override final = default; - - void set(const TId id, const TValue value) override final { - m_elements[id] = value; - } - - const TValue get(const TId id) const override final { - try { - return m_elements.at(id); - } catch (std::out_of_range&) { - not_found_error(id); - } - } - - size_t size() const override final { - return m_elements.size(); - } - - size_t used_memory() const override final { - return element_size * m_elements.size(); - } - - void clear() override final { - m_elements.clear(); - } - - void dump_as_list(const int fd) const { - typedef typename std::map::value_type t; - std::vector v; - std::copy(m_elements.begin(), m_elements.end(), std::back_inserter(v)); - osmium::io::detail::reliable_write(fd, reinterpret_cast(v.data()), sizeof(t) * v.size()); - } - - }; // class StlMap - - } // namespace map - - } // namespace index - -} // namespace osmium - -#endif // OSMIUM_INDEX_MAP_STL_MAP_HPP +#ifndef OSMIUM_INDEX_MAP_STL_MAP_HPP +#define OSMIUM_INDEX_MAP_STL_MAP_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace osmium { + + namespace index { + + namespace map { + + /** + * This implementation uses std::map internally. It uses rather a + * lot of memory, but might make sense for small maps. + */ + template + class StlMap : public osmium::index::map::Map { + + // This is a rough estimate for the memory needed for each + // element in the map (id + value + pointers to left, right, + // and parent plus some overhead for color of red-black-tree + // or similar). + static constexpr size_t element_size = sizeof(TId) + sizeof(TValue) + sizeof(void*) * 4; + + std::map m_elements; + + public: + + StlMap() = default; + + ~StlMap() override final = default; + + void set(const TId id, const TValue value) override final { + m_elements[id] = value; + } + + const TValue get(const TId id) const override final { + try { + return m_elements.at(id); + } catch (std::out_of_range&) { + not_found_error(id); + } + } + + size_t size() const override final { + return m_elements.size(); + } + + size_t used_memory() const override final { + return element_size * m_elements.size(); + } + + void clear() override final { + m_elements.clear(); + } + + void dump_as_list(const int fd) const override final { + typedef typename std::map::value_type t; + std::vector v; + std::copy(m_elements.begin(), m_elements.end(), std::back_inserter(v)); + osmium::io::detail::reliable_write(fd, reinterpret_cast(v.data()), sizeof(t) * v.size()); + } + + }; // class StlMap + + } // namespace map + + } // namespace index + +} // namespace osmium + +#endif // OSMIUM_INDEX_MAP_STL_MAP_HPP diff --git a/ThirdParty/osmium/index/map/vector.hpp b/ThirdParty/osmium/index/map/vector.hpp index 3e4890024..7e47ccfba 100644 --- a/ThirdParty/osmium/index/map/vector.hpp +++ b/ThirdParty/osmium/index/map/vector.hpp @@ -1,208 +1,208 @@ -#ifndef OSMIUM_INDEX_MAP_VECTOR_HPP -#define OSMIUM_INDEX_MAP_VECTOR_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include - -#include -#include - -namespace osmium { - - namespace index { - - namespace map { - - template - class VectorBasedDenseMap : public Map { - - TVector m_vector; - - public: - - VectorBasedDenseMap() : - m_vector() { - } - - explicit VectorBasedDenseMap(int fd) : - m_vector(fd) { - } - - ~VectorBasedDenseMap() {} - - void reserve(const size_t size) override final { - m_vector.reserve(size); - } - - void set(const TId id, const TValue value) override final { - if (size() <= id) { - m_vector.resize(id+1); - } - m_vector[id] = value; - } - - const TValue get(const TId id) const override final { - try { - const TValue& value = m_vector.at(id); - if (value == osmium::index::empty_value()) { - not_found_error(id); - } - return value; - } catch (std::out_of_range&) { - not_found_error(id); - } - } - - size_t size() const override final { - return m_vector.size(); - } - - size_t used_memory() const override final { - return sizeof(TValue) * size(); - } - - void clear() override final { - m_vector.clear(); - m_vector.shrink_to_fit(); - } - - }; // class VectorBasedDenseMap - - - template class TVector> - class VectorBasedSparseMap : public Map { - - public: - - typedef typename std::pair element_type; - typedef TVector vector_type; - typedef typename vector_type::iterator iterator; - typedef typename vector_type::const_iterator const_iterator; - - private: - - vector_type m_vector; - - public: - - VectorBasedSparseMap() : - m_vector() { - } - - VectorBasedSparseMap(int fd) : - m_vector(fd) { - } - - ~VectorBasedSparseMap() override final = default; - - void set(const TId id, const TValue value) override final { - m_vector.push_back(element_type(id, value)); - } - - const TValue get(const TId id) const override final { - const element_type element { - id, - osmium::index::empty_value() - }; - const auto result = std::lower_bound(m_vector.begin(), m_vector.end(), element, [](const element_type& a, const element_type& b) { - return a.first < b.first; - }); - if (result == m_vector.end() || result->first != id) { - not_found_error(id); - } else { - return result->second; - } - } - - size_t size() const override final { - return m_vector.size(); - } - - size_t byte_size() const { - return m_vector.size() * sizeof(element_type); - } - - size_t used_memory() const override final { - return sizeof(element_type) * size(); - } - - void clear() override final { - m_vector.clear(); - m_vector.shrink_to_fit(); - } - - void sort() override final { - std::sort(m_vector.begin(), m_vector.end()); - } - - void dump_as_list(int fd) const { - osmium::io::detail::reliable_write(fd, reinterpret_cast(m_vector.data()), byte_size()); - } - - iterator begin() { - return m_vector.begin(); - } - - iterator end() { - return m_vector.end(); - } - - const_iterator cbegin() const { - return m_vector.cbegin(); - } - - const_iterator cend() const { - return m_vector.cend(); - } - - const_iterator begin() const { - return m_vector.cbegin(); - } - - const_iterator end() const { - return m_vector.cend(); - } - - }; // class VectorBasedSparseMap - - } // namespace map - - } // namespace index - -} // namespace osmium - -#endif // OSMIUM_INDEX_MAP_VECTOR_HPP +#ifndef OSMIUM_INDEX_MAP_VECTOR_HPP +#define OSMIUM_INDEX_MAP_VECTOR_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include +#include + +#include +#include + +namespace osmium { + + namespace index { + + namespace map { + + template + class VectorBasedDenseMap : public Map { + + TVector m_vector; + + public: + + VectorBasedDenseMap() : + m_vector() { + } + + explicit VectorBasedDenseMap(int fd) : + m_vector(fd) { + } + + ~VectorBasedDenseMap() {} + + void reserve(const size_t size) override final { + m_vector.reserve(size); + } + + void set(const TId id, const TValue value) override final { + if (size() <= id) { + m_vector.resize(id+1); + } + m_vector[id] = value; + } + + const TValue get(const TId id) const override final { + try { + const TValue& value = m_vector.at(id); + if (value == osmium::index::empty_value()) { + not_found_error(id); + } + return value; + } catch (std::out_of_range&) { + not_found_error(id); + } + } + + size_t size() const override final { + return m_vector.size(); + } + + size_t used_memory() const override final { + return sizeof(TValue) * size(); + } + + void clear() override final { + m_vector.clear(); + m_vector.shrink_to_fit(); + } + + }; // class VectorBasedDenseMap + + + template class TVector> + class VectorBasedSparseMap : public Map { + + public: + + typedef typename std::pair element_type; + typedef TVector vector_type; + typedef typename vector_type::iterator iterator; + typedef typename vector_type::const_iterator const_iterator; + + private: + + vector_type m_vector; + + public: + + VectorBasedSparseMap() : + m_vector() { + } + + VectorBasedSparseMap(int fd) : + m_vector(fd) { + } + + ~VectorBasedSparseMap() override final = default; + + void set(const TId id, const TValue value) override final { + m_vector.push_back(element_type(id, value)); + } + + const TValue get(const TId id) const override final { + const element_type element { + id, + osmium::index::empty_value() + }; + const auto result = std::lower_bound(m_vector.begin(), m_vector.end(), element, [](const element_type& a, const element_type& b) { + return a.first < b.first; + }); + if (result == m_vector.end() || result->first != id) { + not_found_error(id); + } else { + return result->second; + } + } + + size_t size() const override final { + return m_vector.size(); + } + + size_t byte_size() const { + return m_vector.size() * sizeof(element_type); + } + + size_t used_memory() const override final { + return sizeof(element_type) * size(); + } + + void clear() override final { + m_vector.clear(); + m_vector.shrink_to_fit(); + } + + void sort() override final { + std::sort(m_vector.begin(), m_vector.end()); + } + + void dump_as_list(int fd) const override final { + osmium::io::detail::reliable_write(fd, reinterpret_cast(m_vector.data()), byte_size()); + } + + iterator begin() { + return m_vector.begin(); + } + + iterator end() { + return m_vector.end(); + } + + const_iterator cbegin() const { + return m_vector.cbegin(); + } + + const_iterator cend() const { + return m_vector.cend(); + } + + const_iterator begin() const { + return m_vector.cbegin(); + } + + const_iterator end() const { + return m_vector.cend(); + } + + }; // class VectorBasedSparseMap + + } // namespace map + + } // namespace index + +} // namespace osmium + +#endif // OSMIUM_INDEX_MAP_VECTOR_HPP diff --git a/ThirdParty/osmium/index/multimap.hpp b/ThirdParty/osmium/index/multimap.hpp index bf20dfb26..f76c65ddb 100644 --- a/ThirdParty/osmium/index/multimap.hpp +++ b/ThirdParty/osmium/index/multimap.hpp @@ -1,125 +1,129 @@ -#ifndef OSMIUM_INDEX_MULTIMAP_HPP -#define OSMIUM_INDEX_MULTIMAP_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include - -#include // IWYU pragma: export - -namespace osmium { - - namespace index { - - /** - * @brief Key-value containers with multiple values for an integer key - */ - namespace multimap { - - template - class Multimap { - - static_assert(std::is_integral::value && std::is_unsigned::value, - "TId template parameter for class Multimap must be unsigned integral type"); - - typedef typename std::pair element_type; - - Multimap(const Multimap&) = delete; - Multimap& operator=(const Multimap&) = delete; - - protected: - - Multimap(Multimap&&) = default; - Multimap& operator=(Multimap&&) = default; - - public: - - /// The "key" type, usually osmium::unsigned_object_id_type. - typedef TId key_type; - - /// The "value" type, usually a Location or size_t. - typedef TValue value_type; - - Multimap() = default; - - virtual ~Multimap() noexcept = default; - - /// Set the field with id to value. - virtual void set(const TId id, const TValue value) = 0; - - typedef element_type* iterator; - -// virtual std::pair get_all(const TId id) const = 0; - - /** - * Get the approximate number of items in the storage. The storage - * might allocate memory in blocks, so this size might not be - * accurate. You can not use this to find out how much memory the - * storage uses. Use used_memory() for that. - */ - virtual size_t size() const = 0; - - /** - * Get the memory used for this storage in bytes. Note that this - * is not necessarily entirely accurate but an approximation. - * For storage classes that store the data in memory, this is - * the main memory used, for storage classes storing data on disk - * this is the memory used on disk. - */ - virtual size_t used_memory() const = 0; - - /** - * Clear memory used for this storage. After this you can not - * use the storage container any more. - */ - virtual void clear() = 0; - - /** - * Sort data in map. Call this after writing all data and - * before reading. Not all implementations need this. - */ - virtual void sort() { - // default implementation is empty - } - - }; // class Multimap - - } // namespace map - - } // namespace index - -} // namespace osmium - -#endif // OSMIUM_INDEX_MULTIMAP_HPP +#ifndef OSMIUM_INDEX_MULTIMAP_HPP +#define OSMIUM_INDEX_MULTIMAP_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include + +#include // IWYU pragma: export + +namespace osmium { + + namespace index { + + /** + * @brief Key-value containers with multiple values for an integer key + */ + namespace multimap { + + template + class Multimap { + + static_assert(std::is_integral::value && std::is_unsigned::value, + "TId template parameter for class Multimap must be unsigned integral type"); + + typedef typename std::pair element_type; + + Multimap(const Multimap&) = delete; + Multimap& operator=(const Multimap&) = delete; + + protected: + + Multimap(Multimap&&) = default; + Multimap& operator=(Multimap&&) = default; + + public: + + /// The "key" type, usually osmium::unsigned_object_id_type. + typedef TId key_type; + + /// The "value" type, usually a Location or size_t. + typedef TValue value_type; + + Multimap() = default; + + virtual ~Multimap() noexcept = default; + + /// Set the field with id to value. + virtual void set(const TId id, const TValue value) = 0; + + typedef element_type* iterator; + +// virtual std::pair get_all(const TId id) const = 0; + + /** + * Get the approximate number of items in the storage. The storage + * might allocate memory in blocks, so this size might not be + * accurate. You can not use this to find out how much memory the + * storage uses. Use used_memory() for that. + */ + virtual size_t size() const = 0; + + /** + * Get the memory used for this storage in bytes. Note that this + * is not necessarily entirely accurate but an approximation. + * For storage classes that store the data in memory, this is + * the main memory used, for storage classes storing data on disk + * this is the memory used on disk. + */ + virtual size_t used_memory() const = 0; + + /** + * Clear memory used for this storage. After this you can not + * use the storage container any more. + */ + virtual void clear() = 0; + + /** + * Sort data in map. Call this after writing all data and + * before reading. Not all implementations need this. + */ + virtual void sort() { + // default implementation is empty + } + + virtual void dump_as_list(int /*fd*/) const { + std::runtime_error("can't dump as list"); + } + + }; // class Multimap + + } // namespace map + + } // namespace index + +} // namespace osmium + +#endif // OSMIUM_INDEX_MULTIMAP_HPP diff --git a/ThirdParty/osmium/index/multimap/hybrid.hpp b/ThirdParty/osmium/index/multimap/hybrid.hpp index 4214adc4e..abaf31e95 100644 --- a/ThirdParty/osmium/index/multimap/hybrid.hpp +++ b/ThirdParty/osmium/index/multimap/hybrid.hpp @@ -1,199 +1,199 @@ -#ifndef OSMIUM_INDEX_MULTIMAP_HYBRID_HPP -#define OSMIUM_INDEX_MULTIMAP_HYBRID_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include - -#include -#include -#include - -namespace osmium { - - namespace index { - - namespace multimap { - - template - class HybridIterator { - - typedef SparseMultimapMem main_map_type; - typedef StlMultimap extra_map_type; - - typedef typename std::pair element_type; - - typename main_map_type::iterator m_begin_main; - typename main_map_type::iterator m_end_main; - typename extra_map_type::iterator m_begin_extra; - typename extra_map_type::iterator m_end_extra; - - public: - - explicit HybridIterator(typename main_map_type::iterator begin_main, - typename main_map_type::iterator end_main, - typename extra_map_type::iterator begin_extra, - typename extra_map_type::iterator end_extra) : - m_begin_main(begin_main), - m_end_main(end_main), - m_begin_extra(begin_extra), - m_end_extra(end_extra) { - } - - HybridIterator& operator++() { - if (m_begin_main == m_end_main) { - ++m_begin_extra; - } else { - ++m_begin_main; - while (m_begin_main != m_end_main && m_begin_main->second == osmium::index::empty_value()) { // ignore removed elements - ++m_begin_main; - } - } - return *this; - } - - HybridIterator operator++(int) { - auto tmp(*this); - operator++(); - return tmp; - } - - bool operator==(const HybridIterator& rhs) const { - return m_begin_main == rhs.m_begin_main && - m_end_main == rhs.m_end_main && - m_begin_extra == rhs.m_begin_extra && - m_end_extra == rhs.m_end_extra; - } - - bool operator!=(const HybridIterator& rhs) const { - return ! operator==(rhs); - } - - const element_type& operator*() { - if (m_begin_main == m_end_main) { - return *m_begin_extra; - } else { - return *m_begin_main; - } - } - - const element_type* operator->() { - return &operator*(); - } - - }; - - template - class Hybrid : public Multimap { - - typedef SparseMultimapMem main_map_type; - typedef StlMultimap extra_map_type; - - main_map_type m_main; - extra_map_type m_extra; - - public: - - typedef HybridIterator iterator; - typedef const HybridIterator const_iterator; - - Hybrid() : - m_main(), - m_extra() { - } - - size_t size() const override final { - return m_main.size() + m_extra.size(); - } - - size_t used_memory() const override final { - return m_main.used_memory() + m_extra.used_memory(); - } - - void reserve(const size_t size) { - m_main.reserve(size); - } - - void unsorted_set(const TId id, const TValue value) { - m_main.set(id, value); - } - - void set(const TId id, const TValue value) override final { - m_extra.set(id, value); - } - - std::pair get_all(const TId id) { - auto result_main = m_main.get_all(id); - auto result_extra = m_extra.get_all(id); - return std::make_pair(iterator(result_main.first, result_main.second, result_extra.first, result_extra.second), - iterator(result_main.second, result_main.second, result_extra.second, result_extra.second)); - } - - void remove(const TId id, const TValue value) { - m_main.remove(id, value); - m_extra.remove(id, value); - } - - void consolidate() { - m_main.erase_removed(); - for (const auto& element : m_extra) { - m_main.set(element.first, element.second); - } - m_extra.clear(); - m_main.sort(); - } - - void dump_as_list(int fd) { - consolidate(); - m_main.dump_as_list(fd); - } - - void clear() override final { - m_main.clear(); - m_extra.clear(); - } - - void sort() override final { - m_main.sort(); - } - - }; // Hybrid - - } // namespace multimap - - } // namespace index - -} // namespace osmium - -#endif // OSMIUM_INDEX_MULTIMAP_HYBRID_HPP +#ifndef OSMIUM_INDEX_MULTIMAP_HYBRID_HPP +#define OSMIUM_INDEX_MULTIMAP_HYBRID_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include + +#include +#include +#include + +namespace osmium { + + namespace index { + + namespace multimap { + + template + class HybridIterator { + + typedef SparseMultimapMem main_map_type; + typedef StlMultimap extra_map_type; + + typedef typename std::pair element_type; + + typename main_map_type::iterator m_begin_main; + typename main_map_type::iterator m_end_main; + typename extra_map_type::iterator m_begin_extra; + typename extra_map_type::iterator m_end_extra; + + public: + + explicit HybridIterator(typename main_map_type::iterator begin_main, + typename main_map_type::iterator end_main, + typename extra_map_type::iterator begin_extra, + typename extra_map_type::iterator end_extra) : + m_begin_main(begin_main), + m_end_main(end_main), + m_begin_extra(begin_extra), + m_end_extra(end_extra) { + } + + HybridIterator& operator++() { + if (m_begin_main == m_end_main) { + ++m_begin_extra; + } else { + ++m_begin_main; + while (m_begin_main != m_end_main && m_begin_main->second == osmium::index::empty_value()) { // ignore removed elements + ++m_begin_main; + } + } + return *this; + } + + HybridIterator operator++(int) { + auto tmp(*this); + operator++(); + return tmp; + } + + bool operator==(const HybridIterator& rhs) const { + return m_begin_main == rhs.m_begin_main && + m_end_main == rhs.m_end_main && + m_begin_extra == rhs.m_begin_extra && + m_end_extra == rhs.m_end_extra; + } + + bool operator!=(const HybridIterator& rhs) const { + return ! operator==(rhs); + } + + const element_type& operator*() { + if (m_begin_main == m_end_main) { + return *m_begin_extra; + } else { + return *m_begin_main; + } + } + + const element_type* operator->() { + return &operator*(); + } + + }; // class HybridIterator + + template + class Hybrid : public Multimap { + + typedef SparseMultimapMem main_map_type; + typedef StlMultimap extra_map_type; + + main_map_type m_main; + extra_map_type m_extra; + + public: + + typedef HybridIterator iterator; + typedef const HybridIterator const_iterator; + + Hybrid() : + m_main(), + m_extra() { + } + + size_t size() const override final { + return m_main.size() + m_extra.size(); + } + + size_t used_memory() const override final { + return m_main.used_memory() + m_extra.used_memory(); + } + + void reserve(const size_t size) { + m_main.reserve(size); + } + + void unsorted_set(const TId id, const TValue value) { + m_main.set(id, value); + } + + void set(const TId id, const TValue value) override final { + m_extra.set(id, value); + } + + std::pair get_all(const TId id) { + auto result_main = m_main.get_all(id); + auto result_extra = m_extra.get_all(id); + return std::make_pair(iterator(result_main.first, result_main.second, result_extra.first, result_extra.second), + iterator(result_main.second, result_main.second, result_extra.second, result_extra.second)); + } + + void remove(const TId id, const TValue value) { + m_main.remove(id, value); + m_extra.remove(id, value); + } + + void consolidate() { + m_main.erase_removed(); + for (const auto& element : m_extra) { + m_main.set(element.first, element.second); + } + m_extra.clear(); + m_main.sort(); + } + + void dump_as_list(int fd) override final { + consolidate(); + m_main.dump_as_list(fd); + } + + void clear() override final { + m_main.clear(); + m_extra.clear(); + } + + void sort() override final { + m_main.sort(); + } + + }; // class Hybrid + + } // namespace multimap + + } // namespace index + +} // namespace osmium + +#endif // OSMIUM_INDEX_MULTIMAP_HYBRID_HPP diff --git a/ThirdParty/osmium/index/multimap/stl_multimap.hpp b/ThirdParty/osmium/index/multimap/stl_multimap.hpp index cd19c1560..3df07abff 100644 --- a/ThirdParty/osmium/index/multimap/stl_multimap.hpp +++ b/ThirdParty/osmium/index/multimap/stl_multimap.hpp @@ -1,151 +1,151 @@ -#ifndef OSMIUM_INDEX_MULTIMAP_STL_MULTIMAP_HPP -#define OSMIUM_INDEX_MULTIMAP_STL_MULTIMAP_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include -#include - -#include -#include - -namespace osmium { - - namespace index { - - namespace multimap { - - /** - * This implementation uses std::multimap internally. It uses rather a - * lot of memory, but might make sense for small maps. - */ - template - class StlMultimap : public osmium::index::multimap::Multimap { - - // This is a rough estimate for the memory needed for each - // element in the map (id + value + pointers to left, right, - // and parent plus some overhead for color of red-black-tree - // or similar). - static constexpr size_t element_size = sizeof(TId) + sizeof(TValue) + sizeof(void*) * 4; - - public: - - typedef typename std::multimap collection_type; - typedef typename collection_type::iterator iterator; - typedef typename collection_type::const_iterator const_iterator; - typedef typename collection_type::value_type value_type; - - typedef typename std::pair element_type; - - private: - - collection_type m_elements; - - public: - - StlMultimap() = default; - - ~StlMultimap() noexcept override final = default; - - void unsorted_set(const TId id, const TValue value) { - m_elements.emplace(id, value); - } - - void set(const TId id, const TValue value) override final { - m_elements.emplace(id, value); - } - - std::pair get_all(const TId id) { - return m_elements.equal_range(id); - } - - std::pair get_all(const TId id) const { - return m_elements.equal_range(id); - } - - void remove(const TId id, const TValue value) { - std::pair r = get_all(id); - for (iterator it = r.first; it != r.second; ++it) { - if (it->second == value) { - m_elements.erase(it); - return; - } - } - } - - iterator begin() { - return m_elements.begin(); - } - - iterator end() { - return m_elements.end(); - } - - size_t size() const override final { - return m_elements.size(); - } - - size_t used_memory() const override final { - return element_size * m_elements.size(); - } - - void clear() override final { - m_elements.clear(); - } - - void consolidate() { - // intentionally left blank - } - - void dump_as_list(const int fd) const { - std::vector v; - for (const auto& element : m_elements) { - v.emplace_back(element.first, element.second); - } -// std::copy(m_elements.cbegin(), m_elements.cend(), std::back_inserter(v)); - std::sort(v.begin(), v.end()); - osmium::io::detail::reliable_write(fd, reinterpret_cast(v.data()), sizeof(element_type) * v.size()); - } - - }; // class StlMultimap - - } // namespace multimap - - } // namespace index - -} // namespace osmium - -#endif // OSMIUM_INDEX_MULTIMAP_STL_MULTIMAP_HPP +#ifndef OSMIUM_INDEX_MULTIMAP_STL_MULTIMAP_HPP +#define OSMIUM_INDEX_MULTIMAP_STL_MULTIMAP_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include +#include +#include + +#include +#include + +namespace osmium { + + namespace index { + + namespace multimap { + + /** + * This implementation uses std::multimap internally. It uses rather a + * lot of memory, but might make sense for small maps. + */ + template + class StlMultimap : public osmium::index::multimap::Multimap { + + // This is a rough estimate for the memory needed for each + // element in the map (id + value + pointers to left, right, + // and parent plus some overhead for color of red-black-tree + // or similar). + static constexpr size_t element_size = sizeof(TId) + sizeof(TValue) + sizeof(void*) * 4; + + public: + + typedef typename std::multimap collection_type; + typedef typename collection_type::iterator iterator; + typedef typename collection_type::const_iterator const_iterator; + typedef typename collection_type::value_type value_type; + + typedef typename std::pair element_type; + + private: + + collection_type m_elements; + + public: + + StlMultimap() = default; + + ~StlMultimap() noexcept override final = default; + + void unsorted_set(const TId id, const TValue value) { + m_elements.emplace(id, value); + } + + void set(const TId id, const TValue value) override final { + m_elements.emplace(id, value); + } + + std::pair get_all(const TId id) { + return m_elements.equal_range(id); + } + + std::pair get_all(const TId id) const { + return m_elements.equal_range(id); + } + + void remove(const TId id, const TValue value) { + std::pair r = get_all(id); + for (iterator it = r.first; it != r.second; ++it) { + if (it->second == value) { + m_elements.erase(it); + return; + } + } + } + + iterator begin() { + return m_elements.begin(); + } + + iterator end() { + return m_elements.end(); + } + + size_t size() const override final { + return m_elements.size(); + } + + size_t used_memory() const override final { + return element_size * m_elements.size(); + } + + void clear() override final { + m_elements.clear(); + } + + void consolidate() { + // intentionally left blank + } + + void dump_as_list(const int fd) const override final { + std::vector v; + for (const auto& element : m_elements) { + v.emplace_back(element.first, element.second); + } +// std::copy(m_elements.cbegin(), m_elements.cend(), std::back_inserter(v)); + std::sort(v.begin(), v.end()); + osmium::io::detail::reliable_write(fd, reinterpret_cast(v.data()), sizeof(element_type) * v.size()); + } + + }; // class StlMultimap + + } // namespace multimap + + } // namespace index + +} // namespace osmium + +#endif // OSMIUM_INDEX_MULTIMAP_STL_MULTIMAP_HPP diff --git a/ThirdParty/osmium/index/multimap/vector.hpp b/ThirdParty/osmium/index/multimap/vector.hpp index 1a548a814..b9dae43e5 100644 --- a/ThirdParty/osmium/index/multimap/vector.hpp +++ b/ThirdParty/osmium/index/multimap/vector.hpp @@ -1,141 +1,151 @@ -#ifndef OSMIUM_INDEX_MULTIMAP_VECTOR_HPP -#define OSMIUM_INDEX_MULTIMAP_VECTOR_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include - -#include -#include - -namespace osmium { - - namespace index { - - namespace multimap { - - template class TVector> - class VectorBasedSparseMultimap : public Multimap { - - public: - - typedef typename std::pair element_type; - typedef TVector vector_type; - typedef typename vector_type::iterator iterator; - typedef typename vector_type::const_iterator const_iterator; - - private: - - vector_type m_vector; - - static bool is_removed(element_type& element) { - return element.second == osmium::index::empty_value(); - } - - public: - - void set(const TId id, const TValue value) override final { - m_vector.push_back(element_type(id, value)); - } - - void unsorted_set(const TId id, const TValue value) { - m_vector.push_back(element_type(id, value)); - } - - std::pair get_all(const TId id) { - const element_type element { - id, - osmium::index::empty_value() - }; - return std::equal_range(m_vector.begin(), m_vector.end(), element, [](const element_type& a, const element_type& b) { - return a.first < b.first; - }); - } - - size_t size() const override final { - return m_vector.size(); - } - - size_t byte_size() const { - return m_vector.size() * sizeof(element_type); - } - - size_t used_memory() const override final { - return sizeof(element_type) * size(); - } - - void clear() override final { - m_vector.clear(); - m_vector.shrink_to_fit(); - } - - void sort() override final { - std::sort(m_vector.begin(), m_vector.end()); - } - - void remove(const TId id, const TValue value) { - auto r = get_all(id); - for (auto it = r.first; it != r.second; ++it) { - if (it->second == value) { - it->second = 0; - return; - } - } - } - - void consolidate() { - std::sort(m_vector.begin(), m_vector.end()); - } - - void erase_removed() { - m_vector.erase( - std::remove_if(m_vector.begin(), m_vector.end(), is_removed), - m_vector.end() - ); - } - - void dump_as_list(int fd) const { - osmium::io::detail::reliable_write(fd, reinterpret_cast(m_vector.data()), byte_size()); - } - - }; // class VectorBasedSparseMultimap - - } // namespace multimap - - } // namespace index - -} // namespace osmium - -#endif // OSMIUM_INDEX_MULTIMAP_VECTOR_HPP +#ifndef OSMIUM_INDEX_MULTIMAP_VECTOR_HPP +#define OSMIUM_INDEX_MULTIMAP_VECTOR_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include + +#include +#include + +namespace osmium { + + namespace index { + + namespace multimap { + + template class TVector> + class VectorBasedSparseMultimap : public Multimap { + + public: + + typedef typename std::pair element_type; + typedef TVector vector_type; + typedef typename vector_type::iterator iterator; + typedef typename vector_type::const_iterator const_iterator; + + private: + + vector_type m_vector; + + static bool is_removed(element_type& element) { + return element.second == osmium::index::empty_value(); + } + + public: + + void set(const TId id, const TValue value) override final { + m_vector.push_back(element_type(id, value)); + } + + void unsorted_set(const TId id, const TValue value) { + m_vector.push_back(element_type(id, value)); + } + + std::pair get_all(const TId id) { + const element_type element { + id, + osmium::index::empty_value() + }; + return std::equal_range(m_vector.begin(), m_vector.end(), element, [](const element_type& a, const element_type& b) { + return a.first < b.first; + }); + } + + std::pair get_all(const TId id) const { + const element_type element { + id, + osmium::index::empty_value() + }; + return std::equal_range(m_vector.cbegin(), m_vector.cend(), element, [](const element_type& a, const element_type& b) { + return a.first < b.first; + }); + } + + size_t size() const override final { + return m_vector.size(); + } + + size_t byte_size() const { + return m_vector.size() * sizeof(element_type); + } + + size_t used_memory() const override final { + return sizeof(element_type) * size(); + } + + void clear() override final { + m_vector.clear(); + m_vector.shrink_to_fit(); + } + + void sort() override final { + std::sort(m_vector.begin(), m_vector.end()); + } + + void remove(const TId id, const TValue value) { + auto r = get_all(id); + for (auto it = r.first; it != r.second; ++it) { + if (it->second == value) { + it->second = 0; + return; + } + } + } + + void consolidate() { + std::sort(m_vector.begin(), m_vector.end()); + } + + void erase_removed() { + m_vector.erase( + std::remove_if(m_vector.begin(), m_vector.end(), is_removed), + m_vector.end() + ); + } + + void dump_as_list(int fd) const override final { + osmium::io::detail::reliable_write(fd, reinterpret_cast(m_vector.data()), byte_size()); + } + + }; // class VectorBasedSparseMultimap + + } // namespace multimap + + } // namespace index + +} // namespace osmium + +#endif // OSMIUM_INDEX_MULTIMAP_VECTOR_HPP diff --git a/ThirdParty/osmium/io/bzip2_compression.hpp b/ThirdParty/osmium/io/bzip2_compression.hpp index 1b6552528..cbfaf9a5f 100644 --- a/ThirdParty/osmium/io/bzip2_compression.hpp +++ b/ThirdParty/osmium/io/bzip2_compression.hpp @@ -40,22 +40,50 @@ DEALINGS IN THE SOFTWARE. #include #include + #ifndef _MSC_VER # include #endif #include #include +#include #include namespace osmium { + /** + * Exception thrown when there are problems compressing or + * decompressing bzip2 files. + */ + struct bzip2_error : public std::runtime_error { + + int bzip2_error_code; + int system_errno; + + bzip2_error(const std::string& what, int error_code) : + std::runtime_error(what), + bzip2_error_code(error_code), + system_errno(error_code == BZ_IO_ERROR ? errno : 0) { + } + + }; // struct bzip2_error + namespace io { namespace detail { - OSMIUM_NORETURN inline void throw_bzip2_error(const std::string& msg, int error) { - throw std::runtime_error("bzip2 error: " + msg + ": " + std::to_string(error)); + OSMIUM_NORETURN inline void throw_bzip2_error(BZFILE* bzfile, const char* msg, int bzlib_error=0) { + std::string error("bzip2 error: "); + error += msg; + error += ": "; + int errnum = bzlib_error; + if (bzlib_error) { + error += std::to_string(bzlib_error); + } else { + error += ::BZ2_bzerror(bzfile, &errnum); + } + throw osmium::bzip2_error(error, errnum); } } // namespace detail @@ -74,19 +102,19 @@ namespace osmium { m_bzerror(BZ_OK), m_bzfile(::BZ2_bzWriteOpen(&m_bzerror, m_file, 6, 0, 0)) { if (!m_bzfile) { - detail::throw_bzip2_error("write open failed", m_bzerror); + detail::throw_bzip2_error(m_bzfile, "write open failed", m_bzerror); } } ~Bzip2Compressor() override final { - this->close(); + close(); } void write(const std::string& data) override final { int error; - ::BZ2_bzWrite(&error, m_bzfile, const_cast(data.data()), data.size()); + ::BZ2_bzWrite(&error, m_bzfile, const_cast(data.data()), static_cast_with_assert(data.size())); if (error != BZ_OK && error != BZ_STREAM_END) { - detail::throw_bzip2_error("write failed", error); + detail::throw_bzip2_error(m_bzfile, "write failed", error); } } @@ -99,7 +127,7 @@ namespace osmium { fclose(m_file); } if (error != BZ_OK) { - detail::throw_bzip2_error("write close failed", error); + detail::throw_bzip2_error(m_bzfile, "write close failed", error); } } } @@ -121,12 +149,12 @@ namespace osmium { m_bzerror(BZ_OK), m_bzfile(::BZ2_bzReadOpen(&m_bzerror, m_file, 0, 0, nullptr, 0)) { if (!m_bzfile) { - detail::throw_bzip2_error("read open failed", m_bzerror); + detail::throw_bzip2_error(m_bzfile, "read open failed", m_bzerror); } } ~Bzip2Decompressor() override final { - this->close(); + close(); } std::string read() override final { @@ -135,9 +163,9 @@ namespace osmium { } std::string buffer(osmium::io::Decompressor::input_buffer_size, '\0'); int error; - int nread = ::BZ2_bzRead(&error, m_bzfile, const_cast(buffer.data()), buffer.size()); + int nread = ::BZ2_bzRead(&error, m_bzfile, const_cast(buffer.data()), static_cast_with_assert(buffer.size())); if (error != BZ_OK && error != BZ_STREAM_END) { - detail::throw_bzip2_error("read failed", error); + detail::throw_bzip2_error(m_bzfile, "read failed", error); } if (error == BZ_STREAM_END) { void* unused; @@ -145,16 +173,16 @@ namespace osmium { if (! feof(m_file)) { ::BZ2_bzReadGetUnused(&error, m_bzfile, &unused, &nunused); if (error != BZ_OK) { - detail::throw_bzip2_error("get unused failed", error); + detail::throw_bzip2_error(m_bzfile, "get unused failed", error); } std::string unused_data(static_cast(unused), static_cast(nunused)); ::BZ2_bzReadClose(&error, m_bzfile); if (error != BZ_OK) { - detail::throw_bzip2_error("read close failed", error); + detail::throw_bzip2_error(m_bzfile, "read close failed", error); } - m_bzfile = ::BZ2_bzReadOpen(&error, m_file, 0, 0, const_cast(static_cast(unused_data.data())), unused_data.size()); + m_bzfile = ::BZ2_bzReadOpen(&error, m_file, 0, 0, const_cast(static_cast(unused_data.data())), static_cast_with_assert(unused_data.size())); if (error != BZ_OK) { - detail::throw_bzip2_error("read open failed", error); + detail::throw_bzip2_error(m_bzfile, "read open failed", error); } } else { m_stream_end = true; @@ -173,18 +201,71 @@ namespace osmium { fclose(m_file); } if (error != BZ_OK) { - detail::throw_bzip2_error("read close failed", error); + detail::throw_bzip2_error(m_bzfile, "read close failed", error); } } } }; // class Bzip2Decompressor + class Bzip2BufferDecompressor : public Decompressor { + + const char* m_buffer; + size_t m_buffer_size; + bz_stream m_bzstream; + + public: + + Bzip2BufferDecompressor(const char* buffer, size_t size) : + m_buffer(buffer), + m_buffer_size(size), + m_bzstream() { + m_bzstream.next_in = const_cast(buffer); + m_bzstream.avail_in = static_cast_with_assert(size); + int result = BZ2_bzDecompressInit(&m_bzstream, 0, 0); + if (result != BZ_OK) { + std::string message("bzip2 error: decompression init failed: "); + throw bzip2_error(message, result); + } + } + + ~Bzip2BufferDecompressor() override final { + BZ2_bzDecompressEnd(&m_bzstream); + } + + std::string read() override final { + if (!m_buffer) { + return std::string(); + } + + const size_t buffer_size = 10240; + std::string output(buffer_size, '\0'); + m_bzstream.next_out = const_cast(output.data()); + m_bzstream.avail_out = buffer_size; + int result = BZ2_bzDecompress(&m_bzstream); + + if (result != BZ_OK) { + m_buffer = nullptr; + m_buffer_size = 0; + } + + if (result != BZ_OK && result != BZ_STREAM_END) { + std::string message("bzip2 error: decompress failed: "); + throw bzip2_error(message, result); + } + + output.resize(static_cast(m_bzstream.next_out - output.data())); + return output; + } + + }; // class Bzip2BufferDecompressor + namespace { const bool registered_bzip2_compression = osmium::io::CompressionFactory::instance().register_compression(osmium::io::file_compression::bzip2, [](int fd) { return new osmium::io::Bzip2Compressor(fd); }, - [](int fd) { return new osmium::io::Bzip2Decompressor(fd); } + [](int fd) { return new osmium::io::Bzip2Decompressor(fd); }, + [](const char* buffer, size_t size) { return new osmium::io::Bzip2BufferDecompressor(buffer, size); } ); } // anonymous namespace diff --git a/ThirdParty/osmium/io/compression.hpp b/ThirdParty/osmium/io/compression.hpp index 5ac242ab0..59776408b 100644 --- a/ThirdParty/osmium/io/compression.hpp +++ b/ThirdParty/osmium/io/compression.hpp @@ -40,13 +40,14 @@ DEALINGS IN THE SOFTWARE. #include #include #include -#ifndef _MSC_VER -#include -#else -#include -#endif #include +#ifndef _MSC_VER +# include +#else +# include +#endif + #include #include #include @@ -89,7 +90,8 @@ namespace osmium { virtual std::string read() = 0; - virtual void close() = 0; + virtual void close() { + } }; // class Decompressor @@ -105,11 +107,12 @@ namespace osmium { public: typedef std::function create_compressor_type; - typedef std::function create_decompressor_type; + typedef std::function create_decompressor_type_fd; + typedef std::function create_decompressor_type_buffer; private: - typedef std::map> compression_map_type; + typedef std::map> compression_map_type; compression_map_type m_callbacks; @@ -135,8 +138,13 @@ namespace osmium { return factory; } - bool register_compression(osmium::io::file_compression compression, create_compressor_type create_compressor, create_decompressor_type create_decompressor) { - compression_map_type::value_type cc(compression, std::make_pair(create_compressor, create_decompressor)); + bool register_compression( + osmium::io::file_compression compression, + create_compressor_type create_compressor, + create_decompressor_type_fd create_decompressor_fd, + create_decompressor_type_buffer create_decompressor_buffer) { + + compression_map_type::value_type cc(compression, std::make_tuple(create_compressor, create_decompressor_fd, create_decompressor_buffer)); return m_callbacks.insert(cc).second; } @@ -144,7 +152,7 @@ namespace osmium { auto it = m_callbacks.find(compression); if (it != m_callbacks.end()) { - return std::unique_ptr((it->second.first)(fd)); + return std::unique_ptr(std::get<0>(it->second)(fd)); } error(compression); @@ -154,7 +162,17 @@ namespace osmium { auto it = m_callbacks.find(compression); if (it != m_callbacks.end()) { - return std::unique_ptr((it->second.second)(fd)); + return std::unique_ptr(std::get<1>(it->second)(fd)); + } + + error(compression); + } + + std::unique_ptr create_decompressor(osmium::io::file_compression compression, const char* buffer, size_t size) { + auto it = m_callbacks.find(compression); + + if (it != m_callbacks.end()) { + return std::unique_ptr(std::get<2>(it->second)(buffer, size)); } error(compression); @@ -174,7 +192,7 @@ namespace osmium { } ~NoCompressor() override final { - this->close(); + close(); } void write(const std::string& data) override final { @@ -193,26 +211,46 @@ namespace osmium { class NoDecompressor : public Decompressor { int m_fd; + const char *m_buffer; + size_t m_buffer_size; public: NoDecompressor(int fd) : Decompressor(), - m_fd(fd) { + m_fd(fd), + m_buffer(nullptr), + m_buffer_size(0) { + } + + NoDecompressor(const char* buffer, size_t size) : + Decompressor(), + m_fd(-1), + m_buffer(buffer), + m_buffer_size(size) { } ~NoDecompressor() override final { - this->close(); + close(); } std::string read() override final { - std::string buffer(osmium::io::Decompressor::input_buffer_size, '\0'); - ssize_t nread = ::read(m_fd, const_cast(buffer.data()), buffer.size()); - if (nread < 0) { - throw std::system_error(errno, std::system_category(), "Read failed"); + if (m_buffer) { + if (m_buffer_size == 0) { + return std::string(); + } + size_t size = m_buffer_size; + m_buffer_size = 0; + return std::string(m_buffer, size); + } else { + std::string buffer(osmium::io::Decompressor::input_buffer_size, '\0'); + ssize_t nread = ::read(m_fd, const_cast(buffer.data()), buffer.size()); + if (nread < 0) { + throw std::system_error(errno, std::system_category(), "Read failed"); + } + buffer.resize(static_cast(nread)); + return buffer; } - buffer.resize(static_cast(nread)); - return buffer; } void close() override final { @@ -228,7 +266,8 @@ namespace osmium { const bool registered_no_compression = osmium::io::CompressionFactory::instance().register_compression(osmium::io::file_compression::none, [](int fd) { return new osmium::io::NoCompressor(fd); }, - [](int fd) { return new osmium::io::NoDecompressor(fd); } + [](int fd) { return new osmium::io::NoDecompressor(fd); }, + [](const char* buffer, size_t size) { return new osmium::io::NoDecompressor(buffer, size); } ); } // anonymous namespace diff --git a/ThirdParty/osmium/io/detail/input_format.hpp b/ThirdParty/osmium/io/detail/input_format.hpp index 13e5ca7d7..f88561b11 100644 --- a/ThirdParty/osmium/io/detail/input_format.hpp +++ b/ThirdParty/osmium/io/detail/input_format.hpp @@ -76,7 +76,7 @@ namespace osmium { m_file(file), m_read_which_entities(read_which_entities), m_input_queue(input_queue) { - m_header.has_multiple_object_versions(m_file.has_multiple_object_versions()); + m_header.set_has_multiple_object_versions(m_file.has_multiple_object_versions()); } InputFormat(const InputFormat&) = delete; diff --git a/ThirdParty/osmium/io/detail/opl_output_format.hpp b/ThirdParty/osmium/io/detail/opl_output_format.hpp index e96d7345c..482aecca5 100644 --- a/ThirdParty/osmium/io/detail/opl_output_format.hpp +++ b/ThirdParty/osmium/io/detail/opl_output_format.hpp @@ -48,12 +48,22 @@ DEALINGS IN THE SOFTWARE. #include +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmissing-noreturn" +# pragma clang diagnostic ignored "-Wsign-conversion" +#endif + #if BOOST_VERSION >= 104800 # include #else # include #endif +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + #include #include #include @@ -95,10 +105,13 @@ namespace osmium { template void output_formatted(const char* format, TArgs&&... args) { +#ifndef NDEBUG + int len = +#endif #ifndef _MSC_VER - int len = snprintf(m_tmp_buffer, tmp_buffer_size, format, std::forward(args)...); + snprintf(m_tmp_buffer, tmp_buffer_size, format, std::forward(args)...); #else - int len = _snprintf(m_tmp_buffer, tmp_buffer_size, format, std::forward(args)...); + _snprintf(m_tmp_buffer, tmp_buffer_size, format, std::forward(args)...); #endif assert(len > 0 && static_cast(len) < tmp_buffer_size); m_out += m_tmp_buffer; @@ -269,7 +282,7 @@ namespace osmium { } void write_buffer(osmium::memory::Buffer&& buffer) override final { - OPLOutputBlock output_block(std::move(buffer)); + osmium::thread::SharedPtrWrapper output_block(std::move(buffer)); m_output_queue.push(osmium::thread::Pool::instance().submit(std::move(output_block))); while (m_output_queue.size() > 10) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); // XXX @@ -287,10 +300,13 @@ namespace osmium { namespace { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" const bool registered_opl_output = osmium::io::detail::OutputFormatFactory::instance().register_output_format(osmium::io::file_format::opl, [](const osmium::io::File& file, data_queue_type& output_queue) { return new osmium::io::detail::OPLOutputFormat(file, output_queue); }); +#pragma GCC diagnostic pop } // anonymous namespace diff --git a/ThirdParty/osmium/io/detail/pbf.hpp b/ThirdParty/osmium/io/detail/pbf.hpp index cb44bb039..cdd48912e 100644 --- a/ThirdParty/osmium/io/detail/pbf.hpp +++ b/ThirdParty/osmium/io/detail/pbf.hpp @@ -40,7 +40,7 @@ DEALINGS IN THE SOFTWARE. #include // needed for htonl and ntohl -#ifndef WIN32 +#ifndef _WIN32 # include #else # include @@ -50,6 +50,9 @@ DEALINGS IN THE SOFTWARE. namespace osmium { +// avoid g++ false positive +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreturn-type" inline item_type osmpbf_membertype_to_item_type(const OSMPBF::Relation::MemberType mt) { switch (mt) { case OSMPBF::Relation::NODE: @@ -60,6 +63,7 @@ namespace osmium { return item_type::relation; } } +#pragma GCC diagnostic pop inline OSMPBF::Relation::MemberType item_type_to_osmpbf_membertype(const item_type type) { switch (type) { diff --git a/ThirdParty/osmium/io/detail/pbf_input_format.hpp b/ThirdParty/osmium/io/detail/pbf_input_format.hpp index 36430bea5..bdfa1622d 100644 --- a/ThirdParty/osmium/io/detail/pbf_input_format.hpp +++ b/ThirdParty/osmium/io/detail/pbf_input_format.hpp @@ -33,7 +33,6 @@ DEALINGS IN THE SOFTWARE. */ - #include #include #include @@ -53,6 +52,7 @@ DEALINGS IN THE SOFTWARE. #include #include // IWYU pragma: export #include +#include #include #include #include @@ -65,9 +65,26 @@ DEALINGS IN THE SOFTWARE. #include #include #include +#include namespace osmium { + /** + * Exception thrown when there was a problem with parsing the PBF format of + * a file. + */ + struct pbf_error : public io_error { + + pbf_error(const std::string& what) : + io_error(std::string("PBF error: ") + what) { + } + + pbf_error(const char* what) : + io_error(std::string("PBF error: ") + what) { + } + + }; // struct pbf_error + namespace io { class File; @@ -76,10 +93,10 @@ namespace osmium { class PBFPrimitiveBlockParser { - static constexpr size_t initial_buffer_size = 10 * 1024; + static constexpr size_t initial_buffer_size = 2 * 1024 * 1024; const void* m_data; - const size_t m_size; + const int m_size; const OSMPBF::StringTable* m_stringtable; int64_t m_lon_offset; @@ -99,7 +116,7 @@ namespace osmium { public: - explicit PBFPrimitiveBlockParser(const void* data, const size_t size, osmium::osm_entity_bits::type read_types) : + explicit PBFPrimitiveBlockParser(const void* data, const int size, osmium::osm_entity_bits::type read_types) : m_data(data), m_size(size), m_stringtable(nullptr), @@ -116,7 +133,7 @@ namespace osmium { osmium::memory::Buffer operator()() { OSMPBF::PrimitiveBlock pbf_primitive_block; if (!pbf_primitive_block.ParseFromArray(m_data, m_size)) { - throw std::runtime_error("Failed to parse PrimitiveBlock."); + throw osmium::pbf_error("failed to parse PrimitiveBlock"); } m_stringtable = &pbf_primitive_block.stringtable(); @@ -137,7 +154,7 @@ namespace osmium { } else if (group.nodes_size() != 0) { if (m_read_types & osmium::osm_entity_bits::node) parse_node_group(group); } else { - throw std::runtime_error("Group of unknown type."); + throw osmium::pbf_error("group of unknown type"); } } @@ -150,19 +167,19 @@ namespace osmium { void parse_attributes(TBuilder& builder, const TPBFObject& pbf_object) { auto& object = builder.object(); - object.id(pbf_object.id()); + object.set_id(pbf_object.id()); if (pbf_object.has_info()) { - object.version(pbf_object.info().version()) - .changeset(pbf_object.info().changeset()) - .timestamp(pbf_object.info().timestamp() * m_date_factor) - .uid_from_signed(pbf_object.info().uid()); + object.set_version(static_cast_with_assert(pbf_object.info().version())) + .set_changeset(static_cast_with_assert(pbf_object.info().changeset())) + .set_timestamp(pbf_object.info().timestamp() * m_date_factor) + .set_uid_from_signed(pbf_object.info().uid()); if (pbf_object.info().has_visible()) { - object.visible(pbf_object.info().visible()); + object.set_visible(pbf_object.info().visible()); } - builder.add_user(m_stringtable->s(pbf_object.info().user_sid()).data()); + builder.add_user(m_stringtable->s(static_cast_with_assert(pbf_object.info().user_sid()))); } else { - builder.add_user(""); + builder.add_user("", 1); } } @@ -173,7 +190,7 @@ namespace osmium { parse_attributes(builder, pbf_node); if (builder.object().visible()) { - builder.object().location(osmium::Location( + builder.object().set_location(osmium::Location( (pbf_node.lon() * m_granularity + m_lon_offset) / (OSMPBF::lonlat_resolution / osmium::Location::coordinate_precision), (pbf_node.lat() * m_granularity + m_lat_offset) / (OSMPBF::lonlat_resolution / osmium::Location::coordinate_precision))); } @@ -181,8 +198,8 @@ namespace osmium { if (pbf_node.keys_size() > 0) { osmium::builder::TagListBuilder tl_builder(m_buffer, &builder); for (int tag=0; tag < pbf_node.keys_size(); ++tag) { - tl_builder.add_tag(m_stringtable->s(static_cast(pbf_node.keys(tag))).data(), - m_stringtable->s(static_cast(pbf_node.vals(tag))).data()); + tl_builder.add_tag(m_stringtable->s(static_cast(pbf_node.keys(tag))), + m_stringtable->s(static_cast(pbf_node.vals(tag)))); } } @@ -208,8 +225,8 @@ namespace osmium { if (pbf_way.keys_size() > 0) { osmium::builder::TagListBuilder tl_builder(m_buffer, &builder); for (int tag=0; tag < pbf_way.keys_size(); ++tag) { - tl_builder.add_tag(m_stringtable->s(static_cast(pbf_way.keys(tag))).data(), - m_stringtable->s(static_cast(pbf_way.vals(tag))).data()); + tl_builder.add_tag(m_stringtable->s(static_cast(pbf_way.keys(tag))), + m_stringtable->s(static_cast(pbf_way.vals(tag)))); } } @@ -228,15 +245,15 @@ namespace osmium { int64_t ref = 0; for (int n=0; n < pbf_relation.types_size(); ++n) { ref += pbf_relation.memids(n); - rml_builder.add_member(osmpbf_membertype_to_item_type(pbf_relation.types(n)), ref, m_stringtable->s(pbf_relation.roles_sid(n)).data()); + rml_builder.add_member(osmpbf_membertype_to_item_type(pbf_relation.types(n)), ref, m_stringtable->s(pbf_relation.roles_sid(n))); } } if (pbf_relation.keys_size() > 0) { osmium::builder::TagListBuilder tl_builder(m_buffer, &builder); for (int tag=0; tag < pbf_relation.keys_size(); ++tag) { - tl_builder.add_tag(m_stringtable->s(static_cast(pbf_relation.keys(tag))).data(), - m_stringtable->s(static_cast(pbf_relation.vals(tag))).data()); + tl_builder.add_tag(m_stringtable->s(static_cast(pbf_relation.keys(tag))), + m_stringtable->s(static_cast(pbf_relation.vals(tag)))); } } @@ -262,8 +279,8 @@ namespace osmium { break; } - tl_builder.add_tag(m_stringtable->s(tag_key_pos).data(), - m_stringtable->s(dense.keys_vals(n)).data()); + tl_builder.add_tag(m_stringtable->s(tag_key_pos), + m_stringtable->s(dense.keys_vals(n))); ++n; } @@ -307,23 +324,23 @@ namespace osmium { osmium::builder::NodeBuilder builder(m_buffer); osmium::Node& node = builder.object(); - node.id(last_dense_id); + node.set_id(last_dense_id); if (dense.has_denseinfo()) { auto v = dense.denseinfo().version(i); assert(v > 0); - node.version(static_cast(v)); - node.changeset(last_dense_changeset); - node.timestamp(last_dense_timestamp * m_date_factor); - node.uid_from_signed(last_dense_uid); - node.visible(visible); - builder.add_user(m_stringtable->s(last_dense_user_sid).data()); + node.set_version(static_cast(v)); + node.set_changeset(static_cast(last_dense_changeset)); + node.set_timestamp(last_dense_timestamp * m_date_factor); + node.set_uid_from_signed(static_cast(last_dense_uid)); + node.set_visible(visible); + builder.add_user(m_stringtable->s(static_cast(last_dense_user_sid))); } else { - builder.add_user(""); + builder.add_user("", 1); } if (visible) { - builder.object().location(osmium::Location( + builder.object().set_location(osmium::Location( (last_dense_longitude * m_granularity + m_lon_offset) / (OSMPBF::lonlat_resolution / osmium::Location::coordinate_precision), (last_dense_latitude * m_granularity + m_lat_offset) / (OSMPBF::lonlat_resolution / osmium::Location::coordinate_precision))); } @@ -362,7 +379,7 @@ namespace osmium { return true; } - }; + }; // class InputQueueReader template class BlobParser { @@ -380,13 +397,10 @@ namespace osmium { m_blob_num(blob_num), m_input_queue_reader(input_queue_reader) { if (size < 0 || size > OSMPBF::max_uncompressed_blob_size) { - std::ostringstream errmsg; - errmsg << "invalid blob size: " << size; - throw std::runtime_error(errmsg.str()); + throw osmium::pbf_error(std::string("invalid blob size: " + std::to_string(size))); } - if (! input_queue_reader(m_input_buffer.get(), size)) { - // EOF - throw std::runtime_error("read error (EOF)"); + if (! input_queue_reader(m_input_buffer.get(), static_cast(size))) { + throw osmium::pbf_error("truncated data (EOF encountered)"); } } @@ -395,7 +409,7 @@ namespace osmium { void doit() { OSMPBF::Blob pbf_blob; if (!pbf_blob.ParseFromArray(m_input_buffer.get(), m_size)) { - throw std::runtime_error("failed to parse blob"); + throw osmium::pbf_error("failed to parse blob"); } if (pbf_blob.has_raw()) { @@ -410,16 +424,16 @@ namespace osmium { static_cast(this)->handle_blob(unpack_buffer); return; } else if (pbf_blob.has_lzma_data()) { - throw std::runtime_error("lzma blobs not implemented"); + throw osmium::pbf_error("lzma blobs not implemented"); } else { - throw std::runtime_error("Blob contains no data"); + throw osmium::pbf_error("blob contains no data"); } } osmium::memory::Buffer operator()() { OSMPBF::Blob pbf_blob; if (!pbf_blob.ParseFromArray(m_input_buffer.get(), m_size)) { - throw std::runtime_error("failed to parse blob"); + throw osmium::pbf_error("failed to parse blob"); } if (pbf_blob.has_raw()) { @@ -432,9 +446,9 @@ namespace osmium { std::string unpack_buffer { osmium::io::detail::zlib_uncompress(pbf_blob.zlib_data(), static_cast(raw_size)) }; return static_cast(this)->handle_blob(unpack_buffer); } else if (pbf_blob.has_lzma_data()) { - throw std::runtime_error("lzma blobs not implemented"); + throw osmium::pbf_error("lzma blobs not implemented"); } else { - throw std::runtime_error("Blob contains no data"); + throw osmium::pbf_error("blob contains no data"); } } @@ -446,8 +460,8 @@ namespace osmium { void handle_blob(const std::string& data) { OSMPBF::HeaderBlock pbf_header_block; - if (!pbf_header_block.ParseFromArray(data.data(), data.size())) { - throw std::runtime_error("Failed to parse HeaderBlock."); + if (!pbf_header_block.ParseFromArray(data.data(), static_cast_with_assert(data.size()))) { + throw osmium::pbf_error("failed to parse HeaderBlock"); } for (int i=0; i < pbf_header_block.required_features_size(); ++i) { @@ -459,13 +473,16 @@ namespace osmium { continue; } if (feature == "HistoricalInformation") { - m_header.has_multiple_object_versions(true); + m_header.set_has_multiple_object_versions(true); continue; } - std::ostringstream errmsg; - errmsg << "Required feature not supported: " << feature; - throw std::runtime_error(errmsg.str()); + throw osmium::pbf_error(std::string("required feature not supported: ") + feature); + } + + for (int i=0; i < pbf_header_block.optional_features_size(); ++i) { + const std::string& feature = pbf_header_block.optional_features(i); + m_header.set("pbf_optional_feature_" + std::to_string(i), feature); } if (pbf_header_block.has_writingprogram()) { @@ -510,7 +527,7 @@ namespace osmium { osmium::osm_entity_bits::type m_read_types; osmium::memory::Buffer handle_blob(const std::string& data) { - PBFPrimitiveBlockParser parser(data.data(), data.size(), m_read_types); + PBFPrimitiveBlockParser parser(data.data(), static_cast_with_assert(data.size()), m_read_types); return std::move(parser()); } @@ -545,9 +562,9 @@ namespace osmium { * the expected type) and a size field. * * @param expected_type Expected type of data ("OSMHeader" or "OSMData"). - * @return Size of the data read from BlobHeader (0 on EOF). + * @returns Size of the data read from BlobHeader (0 on EOF). */ - size_t read_blob_header(const char* expected_type) { + int read_blob_header(const char* expected_type) { uint32_t size_in_network_byte_order; if (! m_input_queue_reader(reinterpret_cast(&size_in_network_byte_order), sizeof(size_in_network_byte_order))) { @@ -556,29 +573,29 @@ namespace osmium { uint32_t size = ntohl(size_in_network_byte_order); if (size > static_cast(OSMPBF::max_blob_header_size)) { - throw std::runtime_error("Invalid BlobHeader size"); + throw osmium::pbf_error("invalid BlobHeader size (> max_blob_header_size)"); } unsigned char blob_header_buffer[OSMPBF::max_blob_header_size]; if (! m_input_queue_reader(blob_header_buffer, size)) { - throw std::runtime_error("Read error."); + throw osmium::pbf_error("read error"); } if (!m_blob_header.ParseFromArray(blob_header_buffer, static_cast(size))) { - throw std::runtime_error("Failed to parse BlobHeader."); + throw osmium::pbf_error("failed to parse BlobHeader"); } if (std::strcmp(m_blob_header.type().c_str(), expected_type)) { - throw std::runtime_error("Blob does not have expected type (OSMHeader in first Blob, OSMData in following Blobs)."); + throw osmium::pbf_error("blob does not have expected type (OSMHeader in first blob, OSMData in following blobs)"); } - return static_cast(m_blob_header.datasize()); + return m_blob_header.datasize(); } void parse_osm_data(osmium::osm_entity_bits::type read_types) { osmium::thread::set_thread_name("_osmium_pbf_in"); int n=0; - while (size_t size = read_blob_header("OSMData")) { + while (int size = read_blob_header("OSMData")) { DataBlobParser data_blob_parser(size, n, m_input_queue_reader, read_types); if (m_use_thread_pool) { @@ -627,7 +644,7 @@ namespace osmium { GOOGLE_PROTOBUF_VERIFY_VERSION; // handle OSMHeader - size_t size = read_blob_header("OSMHeader"); + int size = read_blob_header("OSMHeader"); { HeaderBlobParser header_blob_parser(size, m_input_queue_reader, m_header); diff --git a/ThirdParty/osmium/io/detail/pbf_output_format.hpp b/ThirdParty/osmium/io/detail/pbf_output_format.hpp index d24062c20..5ddff98ea 100644 --- a/ThirdParty/osmium/io/detail/pbf_output_format.hpp +++ b/ThirdParty/osmium/io/detail/pbf_output_format.hpp @@ -128,6 +128,7 @@ More complete outlines of real .osm.pbf files can be created using the osmpbf-ou #include #include #include +#include #include namespace osmium { @@ -153,7 +154,7 @@ namespace osmium { std::string content; msg.SerializeToString(&content); - pbf_blob.set_raw_size(content.size()); + pbf_blob.set_raw_size(static_cast_with_assert<::google::protobuf::int32>(content.size())); if (use_compression) { pbf_blob.set_zlib_data(osmium::io::detail::zlib_compress(content)); @@ -167,12 +168,12 @@ namespace osmium { OSMPBF::BlobHeader pbf_blob_header; pbf_blob_header.set_type(type); - pbf_blob_header.set_datasize(blob_data.size()); + pbf_blob_header.set_datasize(static_cast_with_assert<::google::protobuf::int32>(blob_data.size())); std::string blob_header_data; pbf_blob_header.SerializeToString(&blob_header_data); - uint32_t sz = htonl(blob_header_data.size()); + uint32_t sz = htonl(static_cast_with_assert(blob_header_data.size())); // write to output: the 4-byte BlobHeader-Size followed by the BlobHeader followed by the Blob std::string output; @@ -236,7 +237,7 @@ namespace osmium { * enough space for the string table (which typically * needs about 0.1 to 0.3% of the block size). */ - static constexpr int buffer_fill_percent = 95; + static constexpr int64_t buffer_fill_percent = 95; /** * protobuf-struct of a HeaderBlock @@ -313,7 +314,7 @@ namespace osmium { * called once for each object. */ uint16_t primitive_block_contents; - uint32_t primitive_block_size; + int primitive_block_size; // StringTable management StringTable string_table; @@ -329,7 +330,7 @@ namespace osmium { Delta m_delta_timestamp; Delta m_delta_changeset; Delta m_delta_uid; - Delta m_delta_user_sid; + Delta<::google::protobuf::int32> m_delta_user_sid; bool debug; @@ -365,10 +366,8 @@ namespace osmium { for (int i=0, l=dense->keys_vals_size(); i 0 to real string ids auto sid = dense->keys_vals(i); - assert(sid >= 0); - assert(sid < std::numeric_limits::max()); if (sid > 0) { - dense->set_keys_vals(i, string_table.map_string_id(static_cast(sid))); + dense->set_keys_vals(i, string_table.map_string_id(sid)); } } @@ -380,9 +379,7 @@ namespace osmium { // iterate over all username string-ids for (int i=0, l=denseinfo->user_sid_size(); i 0 to real string ids - auto usid = denseinfo->user_sid(i); - assert(usid < std::numeric_limits::max()); - auto user_sid = string_table.map_string_id(static_cast(usid)); + auto user_sid = string_table.map_string_id(denseinfo->user_sid(i)); // delta encode the string-id denseinfo->set_user_sid(i, m_delta_user_sid.update(user_sid)); @@ -411,7 +408,7 @@ namespace osmium { // iterate over all relation members, mapping the interim string-ids // of the role to real string ids - for (int mi=0, ml=relation->roles_sid_size(); miroles_sid_size(); ++mi) { relation->set_roles_sid(mi, string_table.map_string_id(relation->roles_sid(mi))); } } @@ -447,14 +444,14 @@ namespace osmium { * convert a double lat or lon value to an int, respecting the current blocks granularity */ int64_t lonlat2int(double lonlat) { - return round(lonlat * OSMPBF::lonlat_resolution / location_granularity()); + return static_cast(std::round(lonlat * OSMPBF::lonlat_resolution / location_granularity())); } /** * convert a timestamp to an int, respecting the current blocks granularity */ int64_t timestamp2int(time_t timestamp) { - return round(timestamp * (static_cast(1000) / date_granularity())); + return static_cast(std::round(timestamp * (1000.0 / date_granularity()))); } /** @@ -570,7 +567,7 @@ namespace osmium { void check_block_contents_counter() { if (primitive_block_contents >= max_block_contents) { store_primitive_block(); - } else if (primitive_block_size > (static_cast(OSMPBF::max_uncompressed_blob_size) * buffer_fill_percent / 100)) { + } else if (primitive_block_size > OSMPBF::max_uncompressed_blob_size * buffer_fill_percent / 100) { if (debug && has_debug_level(1)) { std::cerr << "storing primitive_block with only " << primitive_block_contents << " items, because its ByteSize (" << primitive_block_size << ") reached " << (static_cast(primitive_block_size) / static_cast(OSMPBF::max_uncompressed_blob_size) * 100.0) << "% of the maximum blob-size" << std::endl; @@ -650,7 +647,7 @@ namespace osmium { denseinfo->add_changeset(m_delta_changeset.update(node.changeset())); // copy the user id, delta encoded - denseinfo->add_uid(m_delta_uid.update(node.uid())); + denseinfo->add_uid(static_cast<::google::protobuf::int32>(m_delta_uid.update(node.uid()))); // record the user-name to the interim stringtable and copy the // interim string-id to the pbf-object @@ -808,7 +805,7 @@ namespace osmium { // when the resulting file will carry history information, add // HistoricalInformation as required feature - if (this->m_file.has_multiple_object_versions()) { + if (m_file.has_multiple_object_versions()) { pbf_header_block.add_required_features("HistoricalInformation"); } diff --git a/ThirdParty/osmium/io/detail/pbf_stringtable.hpp b/ThirdParty/osmium/io/detail/pbf_stringtable.hpp index b1bd5cdc1..6f6c54c89 100644 --- a/ThirdParty/osmium/io/detail/pbf_stringtable.hpp +++ b/ThirdParty/osmium/io/detail/pbf_stringtable.hpp @@ -34,15 +34,17 @@ DEALINGS IN THE SOFTWARE. */ #include +#include #include #include -#include #include #include #include #include +#include + namespace osmium { namespace io { @@ -83,12 +85,14 @@ namespace osmium { * IDs means less used space in the resulting file. */ struct string_info { + /// number of occurrences of this string uint16_t count; /// an intermediate-id string_id_type interim_id; - }; + + }; // struct string_info /** * Interim StringTable, storing all strings that should be written to @@ -123,8 +127,7 @@ namespace osmium { string_info& info = m_strings[string]; if (info.interim_id == 0) { ++m_size; - assert(m_size < std::numeric_limits::max()); - info.interim_id = static_cast(m_size); + info.interim_id = static_cast_with_assert(m_size); } else { info.count++; } @@ -176,6 +179,11 @@ namespace osmium { return m_id2id_map[interim_id]; } + template + string_id_type map_string_id(const T interim_id) const { + return map_string_id(static_cast_with_assert(interim_id)); + } + /** * Clear the stringtable, preparing for the next block. */ diff --git a/ThirdParty/osmium/io/detail/read_thread.hpp b/ThirdParty/osmium/io/detail/read_thread.hpp index eb8461261..0a5254686 100644 --- a/ThirdParty/osmium/io/detail/read_thread.hpp +++ b/ThirdParty/osmium/io/detail/read_thread.hpp @@ -74,10 +74,11 @@ namespace osmium { while (!m_done) { std::string data {m_decompressor->read()}; if (data.empty()) { - m_done = true; + m_queue.push(std::move(data)); + break; } m_queue.push(std::move(data)); - while (m_queue.size() > 10) { + while (m_queue.size() > 10 && !m_done) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } diff --git a/ThirdParty/osmium/io/detail/read_write.hpp b/ThirdParty/osmium/io/detail/read_write.hpp index 305e63b11..a949296f2 100644 --- a/ThirdParty/osmium/io/detail/read_write.hpp +++ b/ThirdParty/osmium/io/detail/read_write.hpp @@ -37,13 +37,12 @@ DEALINGS IN THE SOFTWARE. #include #include #include -//#include -//#include #include + #ifndef _MSC_VER -#include +# include #else -#include +# include typedef int ssize_t; #endif @@ -61,11 +60,11 @@ namespace osmium { /** * Open file for writing. If the file exists, it is truncated, if * not, it is created. If the file name is empty or "-", no file - * is open and the stdout file descriptor (1) is returned. + * is opened and the stdout file descriptor (1) is returned. * * @param filename Name of file to be opened. * @param allow_overwrite If the file exists, should it be overwritten? - * @return File descriptor of open file. + * @returns File descriptor of open file. * @throws system_error if the file can't be opened. */ inline int open_for_writing(const std::string& filename, osmium::io::overwrite allow_overwrite = osmium::io::overwrite::no) { @@ -78,7 +77,7 @@ namespace osmium { } else { flags |= O_EXCL; } -#ifdef WIN32 +#ifdef _WIN32 flags |= O_BINARY; #endif int fd = ::open(filename.c_str(), flags, 0666); @@ -91,9 +90,10 @@ namespace osmium { /** * Open file for reading. If the file name is empty or "-", no file - * is open and the stdin file descriptor (0) is returned. + * is opened and the stdin file descriptor (0) is returned. * - * @return File descriptor of open file. + * @param filename Name of file to be opened. + * @returns File descriptor of open file. * @throws system_error if the file can't be opened. */ inline int open_for_reading(const std::string& filename) { @@ -101,7 +101,7 @@ namespace osmium { return 0; // stdin } else { int flags = O_RDONLY; -#ifdef WIN32 +#ifdef _WIN32 flags |= O_BINARY; #endif int fd = ::open(filename.c_str(), flags); @@ -112,39 +112,15 @@ namespace osmium { } } - /** - * Reads the given number of bytes into the input buffer. - * This is basically just a wrapper around read(2). - * - * @param fd File descriptor. - * @param input_buffer Buffer with data of at least size. - * @param size Number of bytes to be read. - * @return True when read was successful, false on EOF. - * @exception std::system_error On error. - */ - inline bool reliable_read(const int fd, unsigned char* input_buffer, const size_t size) { - size_t offset = 0; - while (offset < size) { - ssize_t length = ::read(fd, input_buffer + offset, size - offset); - if (length < 0) { - throw std::system_error(errno, std::system_category(), "Read failed"); - } - if (length == 0) { - return false; - } - offset += static_cast(length); - } - return true; - } - /** * Writes the given number of bytes from the output_buffer to the file descriptor. - * This is just a wrapper around write(2). + * This is just a wrapper around write(2), because write(2) can write less than + * the given number of bytes. * * @param fd File descriptor. - * @param output_buffer Buffer where data is written. Must be at least size bytes long. - * @param size Number of bytes to be read. - * @exception std::system_error On error. + * @param output_buffer Buffer with data to be written. Must be at least size bytes long. + * @param size Number of bytes to write. + * @throws std::system_error On error. */ inline void reliable_write(const int fd, const unsigned char* output_buffer, const size_t size) { size_t offset = 0; @@ -157,6 +133,16 @@ namespace osmium { } while (offset < size); } + /** + * Writes the given number of bytes from the output_buffer to the file descriptor. + * This is just a wrapper around write(2), because write(2) can write less than + * the given number of bytes. + * + * @param fd File descriptor. + * @param output_buffer Buffer with data to be written. Must be at least size bytes long. + * @param size Number of bytes to write. + * @throws std::system_error On error. + */ inline void reliable_write(const int fd, const char* output_buffer, const size_t size) { reliable_write(fd, reinterpret_cast(output_buffer), size); } diff --git a/ThirdParty/osmium/io/detail/xml_input_format.hpp b/ThirdParty/osmium/io/detail/xml_input_format.hpp index 461a947cd..1daf5d0f1 100644 --- a/ThirdParty/osmium/io/detail/xml_input_format.hpp +++ b/ThirdParty/osmium/io/detail/xml_input_format.hpp @@ -69,9 +69,15 @@ DEALINGS IN THE SOFTWARE. #include #include #include +#include namespace osmium { + /** + * Exception thrown when the XML parser failed. The exception contains + * information about the place where the error happened and the type of + * error. + */ struct xml_error : public io_error { unsigned long line; @@ -120,6 +126,8 @@ namespace osmium { * Once the header is fully parsed this exception will be thrown if * the caller is not interested in anything else except the header. * It will break off the parsing at this point. + * + * This exception is never seen by user code, it is caught internally. */ class ParserIsDone : std::exception { }; @@ -140,7 +148,7 @@ namespace osmium { ignored_relation, ignored_changeset, in_object - }; + }; // enum class context context m_context; context m_last_context; @@ -168,14 +176,81 @@ namespace osmium { osmium::thread::Queue& m_queue; std::promise& m_header_promise; - bool m_promise_fulfilled; - osmium::osm_entity_bits::type m_read_types; size_t m_max_queue_size; std::atomic& m_done; + /** + * A C++ wrapper for the Expat parser that makes sure no memory is leaked. + */ + template + class ExpatXMLParser { + + XML_Parser m_parser; + + static void XMLCALL start_element_wrapper(void* data, const XML_Char* element, const XML_Char** attrs) { + static_cast(data)->start_element(element, attrs); + } + + static void XMLCALL end_element_wrapper(void* data, const XML_Char* element) { + static_cast(data)->end_element(element); + } + + public: + + ExpatXMLParser(T* callback_object) : + m_parser(XML_ParserCreate(nullptr)) { + if (!m_parser) { + throw osmium::io_error("Internal error: Can not create parser"); + } + XML_SetUserData(m_parser, callback_object); + XML_SetElementHandler(m_parser, start_element_wrapper, end_element_wrapper); + } + + ExpatXMLParser(const ExpatXMLParser&) = delete; + ExpatXMLParser(ExpatXMLParser&&) = delete; + + ExpatXMLParser& operator=(const ExpatXMLParser&) = delete; + ExpatXMLParser& operator=(ExpatXMLParser&&) = delete; + + ~ExpatXMLParser() { + XML_ParserFree(m_parser); + } + + void operator()(const std::string& data, bool last) { + if (XML_Parse(m_parser, data.data(), static_cast_with_assert(data.size()), last) == XML_STATUS_ERROR) { + throw osmium::xml_error(m_parser); + } + } + + }; // class ExpatXMLParser + + /** + * A helper class that makes sure a promise is kept. It stores + * a reference to some piece of data and to a promise and, on + * destruction, sets the value of the promise from the data. + */ + template + class PromiseKeeper { + + T& m_data; + std::promise& m_promise; + + public: + + PromiseKeeper(T& data, std::promise& promise) : + m_data(data), + m_promise(promise) { + } + + ~PromiseKeeper() { + m_promise.set_value(m_data); + } + + }; // class PromiseKeeper + public: explicit XMLParser(osmium::thread::Queue& input_queue, osmium::thread::Queue& queue, std::promise& header_promise, osmium::osm_entity_bits::type read_types, std::atomic& done) : @@ -194,7 +269,6 @@ namespace osmium { m_input_queue(input_queue), m_queue(queue), m_header_promise(header_promise), - m_promise_fulfilled(false), m_read_types(read_types), m_max_queue_size(100), m_done(done) { @@ -222,7 +296,6 @@ namespace osmium { m_input_queue(other.m_input_queue), m_queue(other.m_queue), m_header_promise(other.m_header_promise), - m_promise_fulfilled(false), m_read_types(other.m_read_types), m_max_queue_size(100), m_done(other.m_done) { @@ -237,70 +310,45 @@ namespace osmium { ~XMLParser() = default; bool operator()() { - XML_Parser parser = XML_ParserCreate(nullptr); - if (!parser) { - throw osmium::io_error("Internal error: Can not create parser"); - } - - XML_SetUserData(parser, this); - - XML_SetElementHandler(parser, start_element_wrapper, end_element_wrapper); - - try { - int done; - do { - std::string data; - m_input_queue.wait_and_pop(data); - done = data.empty(); - try { - if (XML_Parse(parser, data.data(), data.size(), done) == XML_STATUS_ERROR) { - throw osmium::xml_error(parser); - } - } catch (ParserIsDone&) { - throw; - } catch (...) { - m_queue.push(osmium::memory::Buffer()); // empty buffer to signify eof - if (!m_promise_fulfilled) { - m_promise_fulfilled = true; - m_header_promise.set_value(m_header); - } - throw; - } - } while (!done && !m_done); - header_is_done(); // make sure we'll always fulfill the promise - if (m_buffer.committed() > 0) { - m_queue.push(std::move(m_buffer)); + ExpatXMLParser parser(this); + PromiseKeeper promise_keeper(m_header, m_header_promise); + bool last; + do { + std::string data; + m_input_queue.wait_and_pop(data); + last = data.empty(); + try { + parser(data, last); + } catch (ParserIsDone&) { + return true; + } catch (...) { + m_queue.push(osmium::memory::Buffer()); // empty buffer to signify eof + throw; } - m_queue.push(osmium::memory::Buffer()); // empty buffer to signify eof - } catch (ParserIsDone&) { - // intentionally left blank + } while (!last && !m_done); + if (m_buffer.committed() > 0) { + m_queue.push(std::move(m_buffer)); } - XML_ParserFree(parser); + m_queue.push(osmium::memory::Buffer()); // empty buffer to signify eof return true; } private: - static void XMLCALL start_element_wrapper(void* data, const XML_Char* element, const XML_Char** attrs) { - static_cast(data)->start_element(element, attrs); - } - - static void XMLCALL end_element_wrapper(void* data, const XML_Char* element) { - static_cast(data)->end_element(element); - } - const char* init_object(osmium::OSMObject& object, const XML_Char** attrs) { static const char* empty = ""; const char* user = empty; if (m_in_delete_section) { - object.visible(false); + object.set_visible(false); } + + osmium::Location location; for (int count = 0; attrs[count]; count += 2) { if (!strcmp(attrs[count], "lon")) { - static_cast(object).location().lon(std::atof(attrs[count+1])); // XXX doesn't detect garbage after the number + location.set_lon(std::atof(attrs[count+1])); // XXX doesn't detect garbage after the number } else if (!strcmp(attrs[count], "lat")) { - static_cast(object).location().lat(std::atof(attrs[count+1])); // XXX doesn't detect garbage after the number + location.set_lat(std::atof(attrs[count+1])); // XXX doesn't detect garbage after the number } else if (!strcmp(attrs[count], "user")) { user = attrs[count+1]; } else { @@ -308,6 +356,10 @@ namespace osmium { } } + if (location && object.type() == osmium::item_type::node) { + static_cast(object).set_location(location); + } + return user; } @@ -320,13 +372,13 @@ namespace osmium { osmium::Location max; for (int count = 0; attrs[count]; count += 2) { if (!strcmp(attrs[count], "min_lon")) { - min.lon(atof(attrs[count+1])); + min.set_lon(atof(attrs[count+1])); } else if (!strcmp(attrs[count], "min_lat")) { - min.lat(atof(attrs[count+1])); + min.set_lat(atof(attrs[count+1])); } else if (!strcmp(attrs[count], "max_lon")) { - max.lon(atof(attrs[count+1])); + max.set_lon(atof(attrs[count+1])); } else if (!strcmp(attrs[count], "max_lat")) { - max.lat(atof(attrs[count+1])); + max.set_lat(atof(attrs[count+1])); } else if (!strcmp(attrs[count], "user")) { user = attrs[count+1]; } else { @@ -350,8 +402,7 @@ namespace osmium { for (int count = 0; attrs[count]; count += 2) { if (attrs[count][0] == 'k' && attrs[count][1] == 0) { key = attrs[count+1]; - } - if (attrs[count][0] == 'v' && attrs[count][1] == 0) { + } else if (attrs[count][0] == 'v' && attrs[count][1] == 0) { value = attrs[count+1]; } } @@ -363,12 +414,8 @@ namespace osmium { } void header_is_done() { - if (!m_promise_fulfilled) { - m_header_promise.set_value(m_header); - m_promise_fulfilled = true; - if (m_read_types == osmium::osm_entity_bits::nothing) { - throw ParserIsDone(); - } + if (m_read_types == osmium::osm_entity_bits::nothing) { + throw ParserIsDone(); } } @@ -377,7 +424,7 @@ namespace osmium { case context::root: if (!strcmp(element, "osm") || !strcmp(element, "osmChange")) { if (!strcmp(element, "osmChange")) { - m_header.has_multiple_object_versions(true); + m_header.set_has_multiple_object_versions(true); } for (int count = 0; attrs[count]; count += 2) { if (!strcmp(attrs[count], "version")) { @@ -438,13 +485,13 @@ namespace osmium { osmium::Location max; for (int count = 0; attrs[count]; count += 2) { if (!strcmp(attrs[count], "minlon")) { - min.lon(atof(attrs[count+1])); + min.set_lon(atof(attrs[count+1])); } else if (!strcmp(attrs[count], "minlat")) { - min.lat(atof(attrs[count+1])); + min.set_lat(atof(attrs[count+1])); } else if (!strcmp(attrs[count], "maxlon")) { - max.lon(atof(attrs[count+1])); + max.set_lon(atof(attrs[count+1])); } else if (!strcmp(attrs[count], "maxlat")) { - max.lat(atof(attrs[count+1])); + max.set_lat(atof(attrs[count+1])); } } osmium::Box box; @@ -610,7 +657,7 @@ namespace osmium { } } - }; // XMLParser + }; // class XMLParser class XMLInputFormat : public osmium::io::detail::InputFormat { @@ -639,7 +686,11 @@ namespace osmium { } ~XMLInputFormat() { - m_done = true; + try { + close(); + } catch (...) { + // ignore any exceptions at this point because destructor should not throw + } } virtual osmium::io::Header header() override final { @@ -657,6 +708,11 @@ namespace osmium { return buffer; } + void close() { + m_done = true; + m_parser_task.close(); + } + }; // class XMLInputFormat namespace { diff --git a/ThirdParty/osmium/io/detail/xml_output_format.hpp b/ThirdParty/osmium/io/detail/xml_output_format.hpp index fc9e1e630..3e451bd1c 100644 --- a/ThirdParty/osmium/io/detail/xml_output_format.hpp +++ b/ThirdParty/osmium/io/detail/xml_output_format.hpp @@ -96,10 +96,13 @@ namespace osmium { void oprintf(std::string& out, const char* format, T value) { char buffer[tmp_buffer_size+1]; size_t max_size = sizeof(buffer)/sizeof(char); +#ifndef NDEBUG + int len = +#endif #ifndef _MSC_VER - int len = snprintf(buffer, max_size, format, value); + snprintf(buffer, max_size, format, value); #else - int len = _snprintf(buffer, max_size, format, value); + _snprintf(buffer, max_size, format, value); #endif assert(len > 0 && static_cast(len) < max_size); out += buffer; @@ -115,7 +118,7 @@ namespace osmium { op_create = 1, op_modify = 2, op_delete = 3 - }; + }; // enum class operation osmium::memory::Buffer m_input_buffer; @@ -257,9 +260,9 @@ namespace osmium { if (node.location()) { m_out += " lat=\""; - osmium::Location::coordinate2string(std::back_inserter(m_out), node.location().lat_without_check()); + osmium::util::double2string(std::back_inserter(m_out), node.location().lat_without_check(), 7); m_out += "\" lon=\""; - osmium::Location::coordinate2string(std::back_inserter(m_out), node.location().lon_without_check()); + osmium::util::double2string(std::back_inserter(m_out), node.location().lon_without_check(), 7); m_out += "\""; } @@ -402,7 +405,7 @@ namespace osmium { } void write_buffer(osmium::memory::Buffer&& buffer) override final { - XMLOutputBlock output_block(std::move(buffer), m_write_visible_flag, m_file.is_true("xml_change_format")); + osmium::thread::SharedPtrWrapper output_block(std::move(buffer), m_write_visible_flag, m_file.is_true("xml_change_format")); m_output_queue.push(osmium::thread::Pool::instance().submit(std::move(output_block))); while (m_output_queue.size() > 10) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); // XXX diff --git a/ThirdParty/osmium/io/detail/zlib.hpp b/ThirdParty/osmium/io/detail/zlib.hpp index 932c04835..7e1deca80 100644 --- a/ThirdParty/osmium/io/detail/zlib.hpp +++ b/ThirdParty/osmium/io/detail/zlib.hpp @@ -50,7 +50,7 @@ namespace osmium { * Compress data using zlib. * * @param input Data to compress. - * @return Compressed data. + * @returns Compressed data. */ inline std::string zlib_compress(const std::string& input) { unsigned long output_size = ::compressBound(input.size()); @@ -74,7 +74,7 @@ namespace osmium { * * @param input Compressed input data. * @param raw_size Size of uncompressed data. - * @return Uncompressed data. + * @returns Uncompressed data. */ inline std::string zlib_uncompress(const std::string& input, unsigned long raw_size) { std::string output(raw_size, '\0'); diff --git a/ThirdParty/osmium/io/file.hpp b/ThirdParty/osmium/io/file.hpp index 3aa76f77a..908ada70a 100644 --- a/ThirdParty/osmium/io/file.hpp +++ b/ThirdParty/osmium/io/file.hpp @@ -1,319 +1,358 @@ -#ifndef OSMIUM_IO_FILE_HPP -#define OSMIUM_IO_FILE_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace osmium { - - struct io_error : public std::runtime_error { - - io_error(const std::string& what) : - std::runtime_error(what) { - } - - io_error(const char* what) : - std::runtime_error(what) { - } - - }; // struct io_error - - /** - * @brief Everything related to input and output of OSM data. - */ - namespace io { - - namespace detail { - - inline std::vector split(const std::string& in, const char delim) { - std::vector result; - std::stringstream ss(in); - std::string item; - while (std::getline(ss, item, delim)) { - result.push_back(item); - } - return result; - } - - } // namespace detail - - /** - * This class describes an OSM file in one of several different formats. - * - * If the filename is empty or "-", this means stdin or stdout is used. - */ - class File : public osmium::util::Options { - - private: - - std::string m_filename; - - std::string m_format_string; - - file_format m_file_format {file_format::unknown}; - - file_compression m_file_compression {file_compression::none}; - - bool m_has_multiple_object_versions {false}; - - public: - - /** - * Create File using type and encoding from filename or given - * format specification. - * - * @param filename Filename including suffix. The type and encoding - * of the file will be taken from the suffix. - * An empty filename or "-" means stdin or stdout. - * @param format File format as string. See the description of the - * parse_format() function for details. - */ - explicit File(const std::string& filename = "", const std::string& format = "") : - Options(), - m_filename(filename), - m_format_string(format) { - - // stdin/stdout - if (filename == "" || filename == "-") { - m_filename = ""; - default_settings_for_stdinout(); - } - - // filename is actually a URL - std::string protocol = m_filename.substr(0, m_filename.find_first_of(':')); - if (protocol == "http" || protocol == "https") { - default_settings_for_url(); - } - - detect_format_from_suffix(m_filename); - - if (format != "") { - parse_format(format); - } - } - - File(const File& other) = default; - File& operator=(const File& other) = default; - - File(File&& other) = default; - File& operator=(File&& other) = default; - - ~File() = default; - - void parse_format(const std::string& format) { - std::vector options = detail::split(format, ','); - - // if the first item in the format list doesn't contain - // an equals sign, it is a format - if (!options.empty() && options[0].find_first_of('=') == std::string::npos) { - detect_format_from_suffix(options[0]); - options.erase(options.begin()); - } - - for (auto& option : options) { - size_t pos = option.find_first_of('='); - if (pos == std::string::npos) { - set(option, true); - } else { - std::string value = option.substr(pos+1); - option.erase(pos); - set(option, value); - } - } - - if (get("history") == "true") { - m_has_multiple_object_versions = true; - } else if (get("history") == "false") { - m_has_multiple_object_versions = false; - } - } - - void detect_format_from_suffix(const std::string& name) { - std::vector suffixes = detail::split(name, '.'); - - if (suffixes.empty()) return; - - // if the last suffix is one of a known set of compressions, - // set that compression - if (suffixes.back() == "gz") { - m_file_compression = file_compression::gzip; - suffixes.pop_back(); - } else if (suffixes.back() == "bz2") { - m_file_compression = file_compression::bzip2; - suffixes.pop_back(); - } - - if (suffixes.empty()) return; - - // if the last suffix is one of a known set of formats, - // set that format - if (suffixes.back() == "pbf") { - m_file_format = file_format::pbf; - suffixes.pop_back(); - } else if (suffixes.back() == "xml") { - m_file_format = file_format::xml; - suffixes.pop_back(); - } else if (suffixes.back() == "opl") { - m_file_format = file_format::opl; - suffixes.pop_back(); - } - - if (suffixes.empty()) return; - - if (suffixes.back() == "osm") { - if (m_file_format == file_format::unknown) m_file_format = file_format::xml; - suffixes.pop_back(); - } else if (suffixes.back() == "osh") { - if (m_file_format == file_format::unknown) m_file_format = file_format::xml; - m_has_multiple_object_versions = true; - suffixes.pop_back(); - } else if (suffixes.back() == "osc") { - if (m_file_format == file_format::unknown) m_file_format = file_format::xml; - m_has_multiple_object_versions = true; - set("xml_change_format", true); - suffixes.pop_back(); - } - } - - /** - * Check file format etc. for consistency and throw exception if there - * is a problem. - * - * @throws std::runtime_error - */ - void check() const { - if (m_file_format == file_format::unknown) { - std::string msg = "Could not detect file format"; - if (!m_format_string.empty()) { - msg += " from format string '"; - msg += m_format_string; - msg += "'"; - } - if (m_filename.empty()) { - msg += " for stdin/stdout"; - } else { - msg += " for filename '"; - msg += m_filename; - msg += "'"; - } - msg += "."; - throw std::runtime_error(msg); - } - } - - /** - * Set default settings for type and encoding when the filename is - * empty or "-". If you want to have a different default setting - * override this in a subclass. - */ - void default_settings_for_stdinout() { - m_file_format = file_format::unknown; - m_file_compression = file_compression::none; - } - - /** - * Set default settings for type and encoding when the filename is - * a normal file. If you want to have a different default setting - * override this in a subclass. - */ - void default_settings_for_file() { - m_file_format = file_format::unknown; - m_file_compression = file_compression::none; - } - - /** - * Set default settings for type and encoding when the filename is a URL. - * If you want to have a different default setting override this in a - * subclass. - */ - void default_settings_for_url() { - m_file_format = file_format::xml; - m_file_compression = file_compression::none; - } - - file_format format() const { - return m_file_format; - } - - File& format(file_format format) { - m_file_format = format; - return *this; - } - - file_compression compression() const { - return m_file_compression; - } - - File& compression(file_compression compression) { - m_file_compression = compression; - return *this; - } - - bool has_multiple_object_versions() const { - return m_has_multiple_object_versions; - } - - File& has_multiple_object_versions(bool value) { - m_has_multiple_object_versions = value; - return *this; - } - - File& filename(const std::string& filename) { - if (filename == "-") { - m_filename = ""; - } else { - m_filename = filename; - } - return *this; - } - - const std::string& filename() const { - return m_filename; - } - - }; // class File - - } // namespace io - -} // namespace osmium - -#endif // OSMIUM_IO_FILE_HPP +#ifndef OSMIUM_IO_FILE_HPP +#define OSMIUM_IO_FILE_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace osmium { + + /** + * Exception thrown when some kind of input/output operation failed. + */ + struct io_error : public std::runtime_error { + + io_error(const std::string& what) : + std::runtime_error(what) { + } + + io_error(const char* what) : + std::runtime_error(what) { + } + + }; // struct io_error + + /** + * @brief Everything related to input and output of OSM data. + */ + namespace io { + + namespace detail { + + inline std::vector split(const std::string& in, const char delim) { + std::vector result; + std::stringstream ss(in); + std::string item; + while (std::getline(ss, item, delim)) { + result.push_back(item); + } + return result; + } + + } // namespace detail + + /** + * This class describes an OSM file in one of several different formats. + * + * If the filename is empty or "-", this means stdin or stdout is used. + */ + class File : public osmium::util::Options { + + private: + + std::string m_filename; + + const char* m_buffer; + size_t m_buffer_size; + + std::string m_format_string; + + file_format m_file_format {file_format::unknown}; + + file_compression m_file_compression {file_compression::none}; + + bool m_has_multiple_object_versions {false}; + + public: + + /** + * Create File using type and encoding from filename or given + * format specification. + * + * @param filename Filename including suffix. The type and encoding + * of the file will be taken from the suffix. + * An empty filename or "-" means stdin or stdout. + * @param format File format as string. See the description of the + * parse_format() function for details. + */ + explicit File(const std::string& filename = "", const std::string& format = "") : + Options(), + m_filename(filename), + m_buffer(nullptr), + m_buffer_size(0), + m_format_string(format) { + + // stdin/stdout + if (filename == "" || filename == "-") { + m_filename = ""; + default_settings_for_stdinout(); + } + + // filename is actually a URL + std::string protocol = m_filename.substr(0, m_filename.find_first_of(':')); + if (protocol == "http" || protocol == "https") { + default_settings_for_url(); + } + + detect_format_from_suffix(m_filename); + + if (format != "") { + parse_format(format); + } + } + + /** + * Create File using buffer pointer and size and type and encoding + * from given format specification. + * + * @param buffer Pointer to buffer with data. + * @param size Size of buffer. + * @param format File format as string. See the description of the + * parse_format() function for details. + */ + explicit File(const char* buffer, size_t size, const std::string& format = "") : + Options(), + m_filename(), + m_buffer(buffer), + m_buffer_size(size), + m_format_string(format) { + + default_settings_for_stdinout(); + + if (format != "") { + parse_format(format); + } + } + + File(const File& other) = default; + File& operator=(const File& other) = default; + + File(File&& other) = default; + File& operator=(File&& other) = default; + + ~File() = default; + + const char* buffer() const noexcept { + return m_buffer; + } + + size_t buffer_size() const noexcept { + return m_buffer_size; + } + + void parse_format(const std::string& format) { + std::vector options = detail::split(format, ','); + + // if the first item in the format list doesn't contain + // an equals sign, it is a format + if (!options.empty() && options[0].find_first_of('=') == std::string::npos) { + detect_format_from_suffix(options[0]); + options.erase(options.begin()); + } + + for (auto& option : options) { + size_t pos = option.find_first_of('='); + if (pos == std::string::npos) { + set(option, true); + } else { + std::string value = option.substr(pos+1); + option.erase(pos); + set(option, value); + } + } + + if (get("history") == "true") { + m_has_multiple_object_versions = true; + } else if (get("history") == "false") { + m_has_multiple_object_versions = false; + } + } + + void detect_format_from_suffix(const std::string& name) { + std::vector suffixes = detail::split(name, '.'); + + if (suffixes.empty()) return; + + // if the last suffix is one of a known set of compressions, + // set that compression + if (suffixes.back() == "gz") { + m_file_compression = file_compression::gzip; + suffixes.pop_back(); + } else if (suffixes.back() == "bz2") { + m_file_compression = file_compression::bzip2; + suffixes.pop_back(); + } + + if (suffixes.empty()) return; + + // if the last suffix is one of a known set of formats, + // set that format + if (suffixes.back() == "pbf") { + m_file_format = file_format::pbf; + suffixes.pop_back(); + } else if (suffixes.back() == "xml") { + m_file_format = file_format::xml; + suffixes.pop_back(); + } else if (suffixes.back() == "opl") { + m_file_format = file_format::opl; + suffixes.pop_back(); + } + + if (suffixes.empty()) return; + + if (suffixes.back() == "osm") { + if (m_file_format == file_format::unknown) m_file_format = file_format::xml; + suffixes.pop_back(); + } else if (suffixes.back() == "osh") { + if (m_file_format == file_format::unknown) m_file_format = file_format::xml; + m_has_multiple_object_versions = true; + suffixes.pop_back(); + } else if (suffixes.back() == "osc") { + if (m_file_format == file_format::unknown) m_file_format = file_format::xml; + m_has_multiple_object_versions = true; + set("xml_change_format", true); + suffixes.pop_back(); + } + } + + /** + * Check file format etc. for consistency and throw exception if there + * is a problem. + * + * @throws std::runtime_error + */ + void check() const { + if (m_file_format == file_format::unknown) { + std::string msg = "Could not detect file format"; + if (!m_format_string.empty()) { + msg += " from format string '"; + msg += m_format_string; + msg += "'"; + } + if (m_filename.empty()) { + msg += " for stdin/stdout"; + } else { + msg += " for filename '"; + msg += m_filename; + msg += "'"; + } + msg += "."; + throw std::runtime_error(msg); + } + } + + /** + * Set default settings for type and encoding when the filename is + * empty or "-". If you want to have a different default setting + * override this in a subclass. + */ + void default_settings_for_stdinout() { + m_file_format = file_format::unknown; + m_file_compression = file_compression::none; + } + + /** + * Set default settings for type and encoding when the filename is + * a normal file. If you want to have a different default setting + * override this in a subclass. + */ + void default_settings_for_file() { + m_file_format = file_format::unknown; + m_file_compression = file_compression::none; + } + + /** + * Set default settings for type and encoding when the filename is a URL. + * If you want to have a different default setting override this in a + * subclass. + */ + void default_settings_for_url() { + m_file_format = file_format::xml; + m_file_compression = file_compression::none; + } + + file_format format() const noexcept { + return m_file_format; + } + + File& set_format(file_format format) noexcept { + m_file_format = format; + return *this; + } + + file_compression compression() const noexcept { + return m_file_compression; + } + + File& set_compression(file_compression compression) noexcept { + m_file_compression = compression; + return *this; + } + + bool has_multiple_object_versions() const noexcept { + return m_has_multiple_object_versions; + } + + File& set_has_multiple_object_versions(bool value) noexcept { + m_has_multiple_object_versions = value; + return *this; + } + + File& filename(const std::string& filename) { + if (filename == "-") { + m_filename = ""; + } else { + m_filename = filename; + } + return *this; + } + + const std::string& filename() const noexcept { + return m_filename; + } + + }; // class File + + } // namespace io + +} // namespace osmium + +#endif // OSMIUM_IO_FILE_HPP diff --git a/ThirdParty/osmium/io/file_compression.hpp b/ThirdParty/osmium/io/file_compression.hpp index 8de416d38..c71871553 100644 --- a/ThirdParty/osmium/io/file_compression.hpp +++ b/ThirdParty/osmium/io/file_compression.hpp @@ -45,6 +45,9 @@ namespace osmium { bzip2 = 2 }; +// avoid g++ false positive +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreturn-type" inline const char* as_string(file_compression compression) { switch (compression) { case file_compression::none: @@ -55,6 +58,7 @@ namespace osmium { return "bzip2"; } } +#pragma GCC diagnostic pop template inline std::basic_ostream& operator<<(std::basic_ostream& out, const file_compression compression) { diff --git a/ThirdParty/osmium/io/file_format.hpp b/ThirdParty/osmium/io/file_format.hpp index 649e965bf..5a4aa5c01 100644 --- a/ThirdParty/osmium/io/file_format.hpp +++ b/ThirdParty/osmium/io/file_format.hpp @@ -47,6 +47,9 @@ namespace osmium { json = 4 }; +// avoid g++ false positive +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreturn-type" inline const char* as_string(file_format format) { switch (format) { case file_format::unknown: @@ -61,6 +64,7 @@ namespace osmium { return "JSON"; } } +#pragma GCC diagnostic pop template inline std::basic_ostream& operator<<(std::basic_ostream& out, const file_format format) { diff --git a/ThirdParty/osmium/io/gzip_compression.hpp b/ThirdParty/osmium/io/gzip_compression.hpp index f9afed06c..db99acb9a 100644 --- a/ThirdParty/osmium/io/gzip_compression.hpp +++ b/ThirdParty/osmium/io/gzip_compression.hpp @@ -38,15 +38,52 @@ DEALINGS IN THE SOFTWARE. #include #include +#include #include #include #include +#include +#include namespace osmium { + /** + * Exception thrown when there are problems compressing or + * decompressing gzip files. + */ + struct gzip_error : public std::runtime_error { + + int gzip_error_code; + int system_errno; + + gzip_error(const std::string& what, int error_code) : + std::runtime_error(what), + gzip_error_code(error_code), + system_errno(error_code == Z_ERRNO ? errno : 0) { + } + + }; // struct gzip_error + namespace io { + namespace detail { + + OSMIUM_NORETURN inline void throw_gzip_error(gzFile gzfile, const char* msg, int zlib_error=0) { + std::string error("gzip error: "); + error += msg; + error += ": "; + int errnum = zlib_error; + if (zlib_error) { + error += std::to_string(zlib_error); + } else { + error += ::gzerror(gzfile, &errnum); + } + throw osmium::gzip_error(error, errnum); + } + + } // namespace detail + class GzipCompressor : public Compressor { gzFile m_gzfile; @@ -57,22 +94,30 @@ namespace osmium { Compressor(), m_gzfile(::gzdopen(fd, "w")) { if (!m_gzfile) { - throw std::runtime_error("initialization of gzip compression failed"); + detail::throw_gzip_error(m_gzfile, "write initialization failed"); } } ~GzipCompressor() override final { - this->close(); + close(); } void write(const std::string& data) override final { - ::gzwrite(m_gzfile, data.data(), data.size()); + if (!data.empty()) { + int nwrite = ::gzwrite(m_gzfile, data.data(), static_cast_with_assert(data.size())); + if (nwrite == 0) { + detail::throw_gzip_error(m_gzfile, "write failed"); + } + } } void close() override final { if (m_gzfile) { - ::gzclose(m_gzfile); + int result = ::gzclose(m_gzfile); m_gzfile = nullptr; + if (result != Z_OK) { + detail::throw_gzip_error(m_gzfile, "write close failed", result); + } } } @@ -88,20 +133,19 @@ namespace osmium { Decompressor(), m_gzfile(::gzdopen(fd, "r")) { if (!m_gzfile) { - throw std::runtime_error("initialization of gzip compression failed"); + detail::throw_gzip_error(m_gzfile, "read initialization failed"); } } ~GzipDecompressor() override final { - this->close(); + close(); } std::string read() override final { std::string buffer(osmium::io::Decompressor::input_buffer_size, '\0'); - int nread = ::gzread(m_gzfile, const_cast(buffer.data()), buffer.size()); + int nread = ::gzread(m_gzfile, const_cast(buffer.data()), static_cast_with_assert(buffer.size())); if (nread < 0) { - throw std::runtime_error("gzip read failed"); // XXX better error detection and reporting -// throw std::system_error(errno, std::system_category(), "Read failed"); + detail::throw_gzip_error(m_gzfile, "read failed"); } buffer.resize(static_cast(nread)); return buffer; @@ -109,18 +153,80 @@ namespace osmium { void close() override final { if (m_gzfile) { - ::gzclose(m_gzfile); + int result = ::gzclose(m_gzfile); m_gzfile = nullptr; + if (result != Z_OK) { + detail::throw_gzip_error(m_gzfile, "read close failed", result); + } } } }; // class GzipDecompressor + class GzipBufferDecompressor : public Decompressor { + + const char* m_buffer; + size_t m_buffer_size; + z_stream m_zstream; + + public: + + GzipBufferDecompressor(const char* buffer, size_t size) : + m_buffer(buffer), + m_buffer_size(size), + m_zstream() { + m_zstream.next_in = reinterpret_cast(const_cast(buffer)); + m_zstream.avail_in = static_cast_with_assert(size); + int result = inflateInit2(&m_zstream, MAX_WBITS | 32); + if (result != Z_OK) { + std::string message("gzip error: decompression init failed: "); + if (m_zstream.msg) { + message.append(m_zstream.msg); + } + throw osmium::gzip_error(message, result); + } + } + + ~GzipBufferDecompressor() override final { + inflateEnd(&m_zstream); + } + + std::string read() override final { + if (!m_buffer) { + return std::string(); + } + + const size_t buffer_size = 10240; + std::string output(buffer_size, '\0'); + m_zstream.next_out = reinterpret_cast(const_cast(output.data())); + m_zstream.avail_out = buffer_size; + int result = inflate(&m_zstream, Z_SYNC_FLUSH); + + if (result != Z_OK) { + m_buffer = nullptr; + m_buffer_size = 0; + } + + if (result != Z_OK && result != Z_STREAM_END) { + std::string message("gzip error: inflate failed: "); + if (m_zstream.msg) { + message.append(m_zstream.msg); + } + throw osmium::gzip_error(message, result); + } + + output.resize(static_cast(m_zstream.next_out - reinterpret_cast(output.data()))); + return output; + } + + }; // class GzipBufferDecompressor + namespace { const bool registered_gzip_compression = osmium::io::CompressionFactory::instance().register_compression(osmium::io::file_compression::gzip, [](int fd) { return new osmium::io::GzipCompressor(fd); }, - [](int fd) { return new osmium::io::GzipDecompressor(fd); } + [](int fd) { return new osmium::io::GzipDecompressor(fd); }, + [](const char* buffer, size_t size) { return new osmium::io::GzipBufferDecompressor(buffer, size); } ); } // anonymous namespace diff --git a/ThirdParty/osmium/io/header.hpp b/ThirdParty/osmium/io/header.hpp index c3294756a..0fdbf77fc 100644 --- a/ThirdParty/osmium/io/header.hpp +++ b/ThirdParty/osmium/io/header.hpp @@ -73,15 +73,15 @@ namespace osmium { ~Header() = default; - std::vector& boxes() { + std::vector& boxes() noexcept { return m_boxes; } - const std::vector& boxes() const { + const std::vector& boxes() const noexcept { return m_boxes; } - Header& boxes(const std::vector& boxes) { + Header& boxes(const std::vector& boxes) noexcept { m_boxes = boxes; return *this; } @@ -104,12 +104,12 @@ namespace osmium { return *this; } - bool has_multiple_object_versions() const { + bool has_multiple_object_versions() const noexcept { return m_has_multiple_object_versions; } - Header& has_multiple_object_versions(bool h) { - m_has_multiple_object_versions = h; + Header& set_has_multiple_object_versions(bool value) noexcept { + m_has_multiple_object_versions = value; return *this; } diff --git a/ThirdParty/osmium/io/input_iterator.hpp b/ThirdParty/osmium/io/input_iterator.hpp index 06be82dc4..a2e3b83b3 100644 --- a/ThirdParty/osmium/io/input_iterator.hpp +++ b/ThirdParty/osmium/io/input_iterator.hpp @@ -89,7 +89,7 @@ namespace osmium { } // end iterator - InputIterator() : + InputIterator() noexcept : m_source(nullptr) { } @@ -110,13 +110,13 @@ namespace osmium { return tmp; } - bool operator==(const InputIterator& rhs) const { + bool operator==(const InputIterator& rhs) const noexcept { return m_source == rhs.m_source && m_buffer == rhs.m_buffer && m_iter == rhs.m_iter; } - bool operator!=(const InputIterator& rhs) const { + bool operator!=(const InputIterator& rhs) const noexcept { return !(*this == rhs); } diff --git a/ThirdParty/osmium/io/output_iterator.hpp b/ThirdParty/osmium/io/output_iterator.hpp index d83b10c54..e6a9cc096 100644 --- a/ThirdParty/osmium/io/output_iterator.hpp +++ b/ThirdParty/osmium/io/output_iterator.hpp @@ -1,114 +1,116 @@ -#ifndef OSMIUM_IO_OUTPUT_ITERATOR_HPP -#define OSMIUM_IO_OUTPUT_ITERATOR_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include - -#include -#include - -namespace osmium { - - namespace memory { - class Item; - } // namespace memory - - namespace io { - - template - class OutputIterator : public std::iterator { - - struct buffer_wrapper { - osmium::memory::Buffer buffer; - - buffer_wrapper(size_t buffer_size) : - buffer(buffer_size, osmium::memory::Buffer::auto_grow::no) { - } - }; - - static constexpr size_t default_buffer_size = 10 * 1024 * 1024; - - TDest& m_destination; - - std::shared_ptr m_buffer_wrapper; - - public: - - explicit OutputIterator(TDest& destination, const size_t buffer_size = default_buffer_size) : - m_destination(destination), - m_buffer_wrapper(std::make_shared(buffer_size)) { - } - - void flush() { - osmium::memory::Buffer buffer(m_buffer_wrapper->buffer.capacity(), osmium::memory::Buffer::auto_grow::no); - std::swap(m_buffer_wrapper->buffer, buffer); - m_destination(std::move(buffer)); - } - - OutputIterator& operator=(const osmium::memory::Item& item) { - try { - m_buffer_wrapper->buffer.push_back(item); - } catch (osmium::memory::BufferIsFull&) { - flush(); - m_buffer_wrapper->buffer.push_back(item); - } - return *this; - } - - OutputIterator& operator=(const osmium::DiffObject& diff) { - return this->operator=(diff.curr()); - } - - OutputIterator& operator*() { - return *this; - } - - OutputIterator& operator++() { - return *this; - } - - OutputIterator& operator++(int) { - return *this; - } - - }; // class OutputIterator - - } // namespace io - -} // namespace osmium - -#endif // OSMIUM_IO_OUTPUT_ITERATOR_HPP +#ifndef OSMIUM_IO_OUTPUT_ITERATOR_HPP +#define OSMIUM_IO_OUTPUT_ITERATOR_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include +#include + +#include +#include + +namespace osmium { + + namespace memory { + class Item; + } // namespace memory + + namespace io { + + template + class OutputIterator : public std::iterator { + + struct buffer_wrapper { + + osmium::memory::Buffer buffer; + + buffer_wrapper(size_t buffer_size) : + buffer(buffer_size, osmium::memory::Buffer::auto_grow::no) { + } + + }; // struct buffer_wrapper + + static constexpr size_t default_buffer_size = 10 * 1024 * 1024; + + TDest* m_destination; + + std::shared_ptr m_buffer_wrapper; + + public: + + explicit OutputIterator(TDest& destination, const size_t buffer_size = default_buffer_size) : + m_destination(&destination), + m_buffer_wrapper(std::make_shared(buffer_size)) { + } + + void flush() { + osmium::memory::Buffer buffer(m_buffer_wrapper->buffer.capacity(), osmium::memory::Buffer::auto_grow::no); + std::swap(m_buffer_wrapper->buffer, buffer); + (*m_destination)(std::move(buffer)); + } + + OutputIterator& operator=(const osmium::memory::Item& item) { + try { + m_buffer_wrapper->buffer.push_back(item); + } catch (osmium::buffer_is_full&) { + flush(); + m_buffer_wrapper->buffer.push_back(item); + } + return *this; + } + + OutputIterator& operator=(const osmium::DiffObject& diff) { + return this->operator=(diff.curr()); + } + + OutputIterator& operator*() { + return *this; + } + + OutputIterator& operator++() { + return *this; + } + + OutputIterator& operator++(int) { + return *this; + } + + }; // class OutputIterator + + } // namespace io + +} // namespace osmium + +#endif // OSMIUM_IO_OUTPUT_ITERATOR_HPP diff --git a/ThirdParty/osmium/io/reader.hpp b/ThirdParty/osmium/io/reader.hpp index 8acac94b5..29c2b24ae 100644 --- a/ThirdParty/osmium/io/reader.hpp +++ b/ThirdParty/osmium/io/reader.hpp @@ -41,15 +41,16 @@ DEALINGS IN THE SOFTWARE. #include #include #include -#ifndef _WIN32 -#include -#endif -#ifndef _MSC_VER -#include -#else -#endif #include +#ifndef _WIN32 +# include +#endif + +#ifndef _MSC_VER +# include +#endif + #include #include #include @@ -95,7 +96,7 @@ namespace osmium { * * @param command Command to execute in the child. * @param filename Filename to give to command as argument. - * @return File descriptor of pipe in the parent. + * @returns File descriptor of pipe in the parent. * @throws std::system_error if a system call fails. */ static int execute(const std::string& command, const std::string& filename, int* childpid) { @@ -140,7 +141,7 @@ namespace osmium { * are opened by executing the "curl" program (which must be installed) * and reading from its output. * - * @return File descriptor of open file or pipe. + * @returns File descriptor of open file or pipe. * @throws std::system_error if a system call fails. */ static int open_input_file_or_url(const std::string& filename, int* childpid) { @@ -173,7 +174,9 @@ namespace osmium { m_input_done(false), m_childpid(0), m_input_queue(), - m_decompressor(osmium::io::CompressionFactory::instance().create_decompressor(file.compression(), open_input_file_or_url(m_file.filename(), &m_childpid))), + m_decompressor(m_file.buffer() ? + osmium::io::CompressionFactory::instance().create_decompressor(file.compression(), m_file.buffer(), m_file.buffer_size()) : + osmium::io::CompressionFactory::instance().create_decompressor(file.compression(), open_input_file_or_url(m_file.filename(), &m_childpid))), m_read_task(m_input_queue, m_decompressor.get(), m_input_done), m_input(osmium::io::detail::InputFormatFactory::instance().create_input(m_file, m_read_which_entities, m_input_queue)) { } @@ -190,7 +193,11 @@ namespace osmium { Reader& operator=(const Reader&) = delete; ~Reader() { - close(); + try { + close(); + } + catch (...) { + } } /** @@ -233,7 +240,10 @@ namespace osmium { /** * Reads the next buffer from the input. An invalid buffer signals - * end-of-file. Do not call read() after the end-of-file. + * end-of-file. After end-of-file all read() calls will return an + * invalid buffer. An invalid buffer is also always returned if + * osmium::osm_entity_bits::nothing was set when the Reader was + * constructed. * * @returns Buffer. * @throws Some form of std::runtime_error if there is an error. @@ -243,12 +253,25 @@ namespace osmium { // it in this (the main) thread. m_read_task.check_for_exception(); - if (m_read_which_entities == osmium::osm_entity_bits::nothing) { + if (m_read_which_entities == osmium::osm_entity_bits::nothing || m_input_done) { // If the caller didn't want anything but the header, it will // always get an empty buffer here. return osmium::memory::Buffer(); } - return m_input->read(); + + osmium::memory::Buffer buffer = m_input->read(); + if (!buffer) { + m_input_done = true; + } + return buffer; + } + + /** + * Has the end of file been reached? This is set after the last + * data has been read. It is also set by calling close(). + */ + bool eof() { + return m_input_done; } }; // class Reader diff --git a/ThirdParty/osmium/io/writer.hpp b/ThirdParty/osmium/io/writer.hpp index c5ff05cf2..da685c9cb 100644 --- a/ThirdParty/osmium/io/writer.hpp +++ b/ThirdParty/osmium/io/writer.hpp @@ -90,6 +90,7 @@ namespace osmium { m_output(osmium::io::detail::OutputFormatFactory::instance().create_output(m_file, m_output_queue)), m_compressor(osmium::io::CompressionFactory::instance().create_compressor(file.compression(), osmium::io::detail::open_for_writing(m_file.filename(), allow_overwrite))), m_write_task(m_output_queue, m_compressor.get()) { + assert(!m_file.buffer()); m_output->write_header(header); } @@ -121,7 +122,7 @@ namespace osmium { } /** - * Flush writes to output file and close it. If you do not + * Flush writes to output file and closes it. If you do not * call this, the destructor of Writer will also do the same * thing. But because this call might thrown an exception, * it is better to call close() explicitly. diff --git a/ThirdParty/osmium/memory/buffer.hpp b/ThirdParty/osmium/memory/buffer.hpp index a8a9c7441..fe040caf1 100644 --- a/ThirdParty/osmium/memory/buffer.hpp +++ b/ThirdParty/osmium/memory/buffer.hpp @@ -49,17 +49,24 @@ DEALINGS IN THE SOFTWARE. namespace osmium { + /** + * Exception thrown by the osmium::memory::Buffer class when somebody tries + * to write data into a buffer and it doesn't fit. Buffers with internal + * memory management will not throw this exception, but increase their size. + */ + struct buffer_is_full : public std::runtime_error { + + buffer_is_full() : + std::runtime_error("Osmium buffer is full") { + } + + }; // struct buffer_is_full + /** * @brief Memory management of items in buffers and iterators over this data. */ namespace memory { - /** - * Exception thrown by the Buffer class when somebody tries to write data - * into the buffer and it doesn't fit. - */ - class BufferIsFull : public std::exception {}; - /** * A memory area for storing OSM objects and other items. Each item stored * has a type and a length. See the Item class for details. @@ -80,7 +87,7 @@ namespace osmium { * create a Buffer object and have it manage the memory internally. It will * dynamically allocate memory and free it again after use. * - * By default, if a buffer gets full it will throw a BufferIsFull exception. + * By default, if a buffer gets full it will throw a buffer_is_full exception. * You can use the set_full_callback() method to set a callback functor * which will be called instead of throwing an exception. */ @@ -91,7 +98,7 @@ namespace osmium { enum class auto_grow : bool { yes = true, no = false - }; + }; // enum class auto_grow private: @@ -112,7 +119,7 @@ namespace osmium { * buffer, ie an empty hull of a buffer that has no actual memory * associated with it. It can be used to signify end-of-input. */ - Buffer() : + Buffer() noexcept : m_memory(), m_data(nullptr), m_capacity(0), @@ -126,7 +133,7 @@ namespace osmium { * * @param data A pointer to some already initialized data. * @param size The size of the initialized data. - * @exception std::invalid_argument When the size isn't a multiple of the alignment. + * @throws std::invalid_argument When the size isn't a multiple of the alignment. */ explicit Buffer(unsigned char* data, size_t size) : m_memory(), @@ -146,7 +153,7 @@ namespace osmium { * @param data A pointer to some (possibly initialized) data. * @param capacity The size of the memory for this buffer. * @param committed The size of the initialized data. If this is 0, the buffer startes out empty. - * @exception std::invalid_argument When the capacity or committed isn't a multiple of the alignment. + * @throws std::invalid_argument When the capacity or committed isn't a multiple of the alignment. */ explicit Buffer(unsigned char* data, size_t capacity, size_t committed) : m_memory(), @@ -193,21 +200,21 @@ namespace osmium { /** * Return a pointer to data inside the buffer. */ - unsigned char* data() const { + unsigned char* data() const noexcept { return m_data; } /** * Returns the capacity of the buffer, ie how many bytes it can contain. */ - size_t capacity() const { + size_t capacity() const noexcept { return m_capacity; } /** * Returns the number of bytes already filled in this buffer. */ - size_t committed() const { + size_t committed() const noexcept { return m_committed; } @@ -215,7 +222,7 @@ namespace osmium { * Returns the number of bytes currently filled in this buffer that * are not yet committed. */ - size_t written() const { + size_t written() const noexcept { return m_written; } @@ -223,13 +230,13 @@ namespace osmium { * This tests if the current state of the buffer is aligned * properly. Can be used for asserts. */ - bool is_aligned() const { + bool is_aligned() const noexcept { return (m_written % align_bytes == 0) && (m_committed % align_bytes == 0); } /** * Set functor to be called whenever the buffer is full - * instead of throwing BufferIsFull. + * instead of throwing buffer_is_full. */ void set_full_callback(std::function full) { m_full = full; @@ -260,7 +267,7 @@ namespace osmium { /** * Mark currently written bytes in the buffer as committed. * - * @return Last number of committed bytes before this commit. + * @returns Last number of committed bytes before this commit. */ size_t commit() { assert(is_aligned()); @@ -280,7 +287,7 @@ namespace osmium { /** * Clear the buffer. * - * @return Number of bytes in the buffer before it was cleared. + * @returns Number of bytes in the buffer before it was cleared. */ size_t clear() { const size_t committed = m_committed; @@ -293,7 +300,7 @@ namespace osmium { * Get the data in the buffer at the given offset. * * @tparam T Type we want to the data to be interpreted as. - * @return Reference of given type pointing to the data in the buffer. + * @returns Reference of given type pointing to the data in the buffer. */ template T& get(const size_t offset) const { @@ -317,13 +324,13 @@ namespace osmium { * * If no callback is defined and this buffer uses internal * memory management, the buffers capacity is grown, so that * the new data will fit. - * * Else the BufferIsFull exception is thrown. + * * Else the buffer_is_full exception is thrown. * * @param size Number of bytes to reserve. - * @return Pointer to reserved space. Note that this pointer is + * @returns Pointer to reserved space. Note that this pointer is * only guaranteed to be valid until the next call to * reserve_space(). - * @throw BufferIsFull Might be thrown if the buffer is full. + * @throws osmium::buffer_is_full Might be thrown if the buffer is full. */ unsigned char* reserve_space(const size_t size) { if (m_written + size > m_capacity) { @@ -337,7 +344,7 @@ namespace osmium { } grow(new_capacity); } else { - throw BufferIsFull(); + throw osmium::buffer_is_full(); } } unsigned char* data = &m_data[m_written]; @@ -354,7 +361,7 @@ namespace osmium { * * @tparam T Class of the item to be copied. * @param item Reference to the item to be copied. - * @return Reference to newly copied data in the buffer. + * @returns Reference to newly copied data in the buffer. */ template T& add_item(const T& item) { @@ -483,6 +490,10 @@ namespace osmium { */ template void purge_removed(TCallbackClass* callback) { + if (begin() == end()) { + return; + } + iterator it_write = begin(); iterator next; @@ -490,29 +501,29 @@ namespace osmium { next = std::next(it_read); if (!it_read->removed()) { if (it_read != it_write) { - assert(it_read->data() >= data()); - assert(it_write->data() >= data()); - size_t old_offset = static_cast(it_read->data() - data()); - size_t new_offset = static_cast(it_write->data() - data()); + assert(it_read.data() >= data()); + assert(it_write.data() >= data()); + size_t old_offset = static_cast(it_read.data() - data()); + size_t new_offset = static_cast(it_write.data() - data()); callback->moving_in_buffer(old_offset, new_offset); - std::memmove(it_write->data(), it_read->data(), it_read->padded_size()); + std::memmove(it_write.data(), it_read.data(), it_read->padded_size()); } - ++it_write; + it_write.advance_once(); } } - assert(it_write->data() >= data()); - m_written = static_cast(it_write->data() - data()); + assert(it_write.data() >= data()); + m_written = static_cast(it_write.data() - data()); m_committed = m_written; } }; // class Buffer - inline bool operator==(const Buffer& lhs, const Buffer& rhs) { + inline bool operator==(const Buffer& lhs, const Buffer& rhs) noexcept { return lhs.data() == rhs.data() && lhs.capacity() == rhs.capacity() && lhs.committed() == rhs.committed(); } - inline bool operator!=(const Buffer& lhs, const Buffer& rhs) { + inline bool operator!=(const Buffer& lhs, const Buffer& rhs) noexcept { return ! (lhs == rhs); } diff --git a/ThirdParty/osmium/memory/collection.hpp b/ThirdParty/osmium/memory/collection.hpp index c6256b175..b25dd64ec 100644 --- a/ThirdParty/osmium/memory/collection.hpp +++ b/ThirdParty/osmium/memory/collection.hpp @@ -1,153 +1,153 @@ -#ifndef OSMIUM_MEMORY_COLLECTION_HPP -#define OSMIUM_MEMORY_COLLECTION_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include - -#include - -namespace osmium { - - namespace memory { - - template - class CollectionIterator : public std::iterator { - - // This data_type is either 'unsigned char*' or 'const unsigned char*' depending - // on whether TMember is const. This allows this class to be used as an iterator and - // as a const_iterator. - typedef typename std::conditional::value, const unsigned char*, unsigned char*>::type data_type; - - data_type m_data; - - public: - - CollectionIterator() : - m_data(nullptr) { - } - - CollectionIterator(data_type data) : - m_data(data) { - } - - CollectionIterator& operator++() { - m_data = reinterpret_cast(m_data)->next(); - return *static_cast*>(this); - } - - CollectionIterator operator++(int) { - CollectionIterator tmp(*this); - operator++(); - return tmp; - } - - bool operator==(const CollectionIterator& rhs) const { - return m_data == rhs.m_data; - } - - bool operator!=(const CollectionIterator& rhs) const { - return m_data != rhs.m_data; - } - - unsigned char* data() const { - return m_data; - } - - TMember& operator*() const { - return *reinterpret_cast(m_data); - } - - TMember* operator->() const { - return reinterpret_cast(m_data); - } - - template - friend std::basic_ostream& operator<<(std::basic_ostream& out, const CollectionIterator& iter) { - return out << static_cast(iter.m_data); - } - - }; // class CollectionIterator - - template - class Collection : public Item { - - public: - - typedef CollectionIterator iterator; - typedef CollectionIterator const_iterator; - typedef TMember value_type; - - static constexpr osmium::item_type itemtype = TCollectionItemType; - - Collection() : - Item(sizeof(Collection), TCollectionItemType) { - } - - bool empty() const { - return sizeof(Collection) == byte_size(); - } - - iterator begin() { - return iterator(data() + sizeof(Collection)); - } - - iterator end() { - return iterator(data() + byte_size()); - } - - const_iterator cbegin() const { - return const_iterator(data() + sizeof(Collection)); - } - - const_iterator cend() const { - return const_iterator(data() + byte_size()); - } - - const_iterator begin() const { - return cbegin(); - } - - const_iterator end() const { - return cend(); - } - - }; // class Collection - - } // namespace memory - -} // namespace osmium - -#endif // OSMIUM_MEMORY_COLLECTION_HPP +#ifndef OSMIUM_MEMORY_COLLECTION_HPP +#define OSMIUM_MEMORY_COLLECTION_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include + +#include + +namespace osmium { + + namespace memory { + + template + class CollectionIterator : public std::iterator { + + // This data_type is either 'unsigned char*' or 'const unsigned char*' depending + // on whether TMember is const. This allows this class to be used as an iterator and + // as a const_iterator. + typedef typename std::conditional::value, const unsigned char*, unsigned char*>::type data_type; + + data_type m_data; + + public: + + CollectionIterator() noexcept : + m_data(nullptr) { + } + + CollectionIterator(data_type data) noexcept : + m_data(data) { + } + + CollectionIterator& operator++() { + m_data = reinterpret_cast(m_data)->next(); + return *static_cast*>(this); + } + + CollectionIterator operator++(int) { + CollectionIterator tmp(*this); + operator++(); + return tmp; + } + + bool operator==(const CollectionIterator& rhs) const noexcept { + return m_data == rhs.m_data; + } + + bool operator!=(const CollectionIterator& rhs) const noexcept { + return m_data != rhs.m_data; + } + + unsigned char* data() const noexcept { + return m_data; + } + + TMember& operator*() const { + return *reinterpret_cast(m_data); + } + + TMember* operator->() const { + return reinterpret_cast(m_data); + } + + template + friend std::basic_ostream& operator<<(std::basic_ostream& out, const CollectionIterator& iter) { + return out << static_cast(iter.m_data); + } + + }; // class CollectionIterator + + template + class Collection : public Item { + + public: + + typedef CollectionIterator iterator; + typedef CollectionIterator const_iterator; + typedef TMember value_type; + + static constexpr osmium::item_type itemtype = TCollectionItemType; + + Collection() : + Item(sizeof(Collection), TCollectionItemType) { + } + + bool empty() const { + return sizeof(Collection) == byte_size(); + } + + iterator begin() { + return iterator(data() + sizeof(Collection)); + } + + iterator end() { + return iterator(data() + byte_size()); + } + + const_iterator cbegin() const { + return const_iterator(data() + sizeof(Collection)); + } + + const_iterator cend() const { + return const_iterator(data() + byte_size()); + } + + const_iterator begin() const { + return cbegin(); + } + + const_iterator end() const { + return cend(); + } + + }; // class Collection + + } // namespace memory + +} // namespace osmium + +#endif // OSMIUM_MEMORY_COLLECTION_HPP diff --git a/ThirdParty/osmium/memory/item.hpp b/ThirdParty/osmium/memory/item.hpp index 73e653efe..20bb75a7a 100644 --- a/ThirdParty/osmium/memory/item.hpp +++ b/ThirdParty/osmium/memory/item.hpp @@ -52,11 +52,11 @@ namespace osmium { // align datastructures to this many bytes constexpr item_size_type align_bytes = 8; - inline size_t padded_length(size_t length) { + inline size_t padded_length(size_t length) noexcept { return (length + align_bytes - 1) & ~(align_bytes - 1); } - inline item_size_type padded_length(item_size_type length) { + inline item_size_type padded_length(item_size_type length) noexcept { return (length + align_bytes - 1) & ~(align_bytes - 1); } @@ -85,15 +85,15 @@ namespace osmium { public: - unsigned char* data() { + unsigned char* data() noexcept { return reinterpret_cast(this); } - const unsigned char* data() const { + const unsigned char* data() const noexcept { return reinterpret_cast(this); } - }; + }; // class ItemHelper } // namespace detail @@ -112,22 +112,14 @@ namespace osmium { friend class osmium::builder::Builder; - unsigned char* next() { - return data() + padded_size(); - } - - const unsigned char* next() const { - return data() + padded_size(); - } - - Item& add_size(const item_size_type size) { + Item& add_size(const item_size_type size) noexcept { m_size += size; return *this; } protected: - explicit Item(item_size_type size=0, item_type type=item_type()) : + explicit Item(item_size_type size=0, item_type type=item_type()) noexcept : m_size(size), m_type(type), m_removed(false) { @@ -139,14 +131,22 @@ namespace osmium { Item& operator=(const Item&) = delete; Item& operator=(Item&&) = delete; - Item& type(const item_type item_type) { + Item& set_type(const item_type item_type) noexcept { m_type = item_type; return *this; } public: - item_size_type byte_size() const { + unsigned char* next() noexcept { + return data() + padded_size(); + } + + const unsigned char* next() const noexcept { + return data() + padded_size(); + } + + item_size_type byte_size() const noexcept { return m_size; } @@ -154,15 +154,15 @@ namespace osmium { return padded_length(m_size); } - item_type type() const { + item_type type() const noexcept { return m_type; } - bool removed() const { + bool removed() const noexcept { return m_removed; } - void removed(bool removed) { + void set_removed(bool removed) noexcept { m_removed = removed; } diff --git a/ThirdParty/osmium/memory/item_iterator.hpp b/ThirdParty/osmium/memory/item_iterator.hpp index 64899b333..34ed60083 100644 --- a/ThirdParty/osmium/memory/item_iterator.hpp +++ b/ThirdParty/osmium/memory/item_iterator.hpp @@ -1,181 +1,234 @@ -#ifndef OSMIUM_ITEM_ITERATOR_HPP -#define OSMIUM_ITEM_ITERATOR_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include - -#include -#include -#include - -namespace osmium { - - namespace memory { - - namespace detail { - - template - inline bool type_is_compatible(osmium::item_type) { - return true; - } - - template <> - inline bool type_is_compatible(osmium::item_type t) { - return t == osmium::item_type::node; - } - - template <> - inline bool type_is_compatible(osmium::item_type t) { - return t == osmium::item_type::way; - } - - template <> - inline bool type_is_compatible(osmium::item_type t) { - return t == osmium::item_type::relation; - } - - template <> - inline bool type_is_compatible(osmium::item_type t) { - return t == osmium::item_type::area; - } - - template <> - inline bool type_is_compatible(osmium::item_type t) { - return t == osmium::item_type::changeset; - } - - template <> - inline bool type_is_compatible(osmium::item_type t) { - return t == osmium::item_type::node || t == osmium::item_type::way || t == osmium::item_type::relation || t == osmium::item_type::area; - } - - template <> - inline bool type_is_compatible(osmium::item_type t) { - return t == osmium::item_type::node || t == osmium::item_type::way || t == osmium::item_type::relation || t == osmium::item_type::area || t == osmium::item_type::changeset; - } - - } // namespace detail - - template - class ItemIterator : public std::iterator { - - static_assert(std::is_base_of::value, "TMember must derive from osmium::memory::Item"); - - // This data_type is either 'unsigned char*' or 'const unsigned char*' depending - // on whether TMember is const. This allows this class to be used as an iterator and - // as a const_iterator. - typedef typename std::conditional::value, const unsigned char*, unsigned char*>::type data_type; - - data_type m_data; - data_type m_end; - - void advance_to_next_item_of_right_type() { - while (m_data != m_end && - !detail::type_is_compatible::type>(reinterpret_cast(m_data)->type())) { - m_data = reinterpret_cast(m_data)->next(); - } - } - - public: - - ItemIterator() : - m_data(nullptr), - m_end(nullptr) { - } - - ItemIterator(data_type data, data_type end) : - m_data(data), - m_end(end) { - advance_to_next_item_of_right_type(); - } - - ItemIterator& operator++() { - assert(m_data); - assert(m_data != m_end); - m_data = reinterpret_cast(m_data)->next(); - advance_to_next_item_of_right_type(); - return *static_cast*>(this); - } - - ItemIterator operator++(int) { - ItemIterator tmp(*this); - operator++(); - return tmp; - } - - bool operator==(const ItemIterator& rhs) const { - return m_data == rhs.m_data && m_end == rhs.m_end; - } - - bool operator!=(const ItemIterator& rhs) const { - return !(*this == rhs); - } - - unsigned char* data() const { - assert(m_data); - assert(m_data != m_end); - return m_data; - } - - TMember& operator*() const { - assert(m_data); - assert(m_data != m_end); - return *reinterpret_cast(m_data); - } - - TMember* operator->() const { - assert(m_data); - assert(m_data != m_end); - return reinterpret_cast(m_data); - } - - explicit operator bool() const { - return m_data != nullptr; - } - - template - friend std::basic_ostream& operator<<(std::basic_ostream& out, const ItemIterator& iter) { - return out << static_cast(iter.m_data); - } - - }; // class ItemIterator - - } // namespace memory - -} // namespace osmium - -#endif // OSMIUM_ITEM_ITERATOR_HPP +#ifndef OSMIUM_ITEM_ITERATOR_HPP +#define OSMIUM_ITEM_ITERATOR_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include +#include + +#include +#include + +namespace osmium { + + class Node; + class Way; + class Relation; + class Area; + class Changeset; + class OSMObject; + class OSMEntity; + class TagList; + class WayNodeList; + class RelationMemberList; + class InnerRing; + class OuterRing; + + namespace memory { + + namespace detail { + + template + inline bool type_is_compatible(osmium::item_type) noexcept { + return true; + } + + template <> + inline bool type_is_compatible(osmium::item_type t) noexcept { + return t == osmium::item_type::node; + } + + template <> + inline bool type_is_compatible(osmium::item_type t) noexcept { + return t == osmium::item_type::way; + } + + template <> + inline bool type_is_compatible(osmium::item_type t) noexcept { + return t == osmium::item_type::relation; + } + + template <> + inline bool type_is_compatible(osmium::item_type t) noexcept { + return t == osmium::item_type::area; + } + + template <> + inline bool type_is_compatible(osmium::item_type t) noexcept { + return t == osmium::item_type::changeset; + } + + template <> + inline bool type_is_compatible(osmium::item_type t) noexcept { + return t == osmium::item_type::node || t == osmium::item_type::way || t == osmium::item_type::relation || t == osmium::item_type::area; + } + + template <> + inline bool type_is_compatible(osmium::item_type t) noexcept { + return t == osmium::item_type::node || t == osmium::item_type::way || t == osmium::item_type::relation || t == osmium::item_type::area || t == osmium::item_type::changeset; + } + + template <> + inline bool type_is_compatible(osmium::item_type t) noexcept { + return t == osmium::item_type::tag_list; + } + + template <> + inline bool type_is_compatible(osmium::item_type t) noexcept { + return t == osmium::item_type::way_node_list; + } + + template <> + inline bool type_is_compatible(osmium::item_type t) noexcept { + return t == osmium::item_type::relation_member_list || t == osmium::item_type::relation_member_list_with_full_members; + } + + template <> + inline bool type_is_compatible(osmium::item_type t) noexcept { + return t == osmium::item_type::outer_ring; + } + + template <> + inline bool type_is_compatible(osmium::item_type t) noexcept { + return t == osmium::item_type::inner_ring; + } + + } // namespace detail + + template + class ItemIterator : public std::iterator { + + static_assert(std::is_base_of::value, "TMember must derive from osmium::memory::Item"); + + // This data_type is either 'unsigned char*' or 'const unsigned char*' depending + // on whether TMember is const. This allows this class to be used as an iterator and + // as a const_iterator. + typedef typename std::conditional::value, const unsigned char*, unsigned char*>::type data_type; + + data_type m_data; + data_type m_end; + + void advance_to_next_item_of_right_type() { + while (m_data != m_end && + !detail::type_is_compatible::type>(reinterpret_cast(m_data)->type())) { + m_data = reinterpret_cast(m_data)->next(); + } + } + + public: + + ItemIterator() noexcept : + m_data(nullptr), + m_end(nullptr) { + } + + ItemIterator(data_type data, data_type end) : + m_data(data), + m_end(end) { + advance_to_next_item_of_right_type(); + } + + template + ItemIterator cast() const { + return ItemIterator(m_data, m_end); + } + + ItemIterator& operator++() { + assert(m_data); + assert(m_data != m_end); + m_data = reinterpret_cast(m_data)->next(); + advance_to_next_item_of_right_type(); + return *static_cast*>(this); + } + + /** + * Like operator++() but will NOT skip items of unwanted + * types. Do not use this unless you know what you are + * doing. + */ + ItemIterator& advance_once() { + assert(m_data); + assert(m_data != m_end); + m_data = reinterpret_cast(m_data)->next(); + return *static_cast*>(this); + } + + ItemIterator operator++(int) { + ItemIterator tmp(*this); + operator++(); + return tmp; + } + + bool operator==(const ItemIterator& rhs) const { + return m_data == rhs.m_data && m_end == rhs.m_end; + } + + bool operator!=(const ItemIterator& rhs) const { + return !(*this == rhs); + } + + unsigned char* data() const { + assert(m_data); + return m_data; + } + + TMember& operator*() const { + assert(m_data); + assert(m_data != m_end); + return *reinterpret_cast(m_data); + } + + TMember* operator->() const { + assert(m_data); + assert(m_data != m_end); + return reinterpret_cast(m_data); + } + + explicit operator bool() const { + return m_data != nullptr; + } + + template + friend std::basic_ostream& operator<<(std::basic_ostream& out, const ItemIterator& iter) { + return out << static_cast(iter.m_data); + } + + }; // class ItemIterator + + } // namespace memory + +} // namespace osmium + +#endif // OSMIUM_ITEM_ITERATOR_HPP diff --git a/ThirdParty/osmium/object_pointer_collection.hpp b/ThirdParty/osmium/object_pointer_collection.hpp index 08ea46e01..22029a149 100644 --- a/ThirdParty/osmium/object_pointer_collection.hpp +++ b/ThirdParty/osmium/object_pointer_collection.hpp @@ -1,112 +1,112 @@ -#ifndef OSMIUM_OBJECT_POINTER_COLLECTION_HPP -#define OSMIUM_OBJECT_POINTER_COLLECTION_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include - -#include - -#include -#include -#include - -// IWYU pragma: no_forward_declare osmium::OSMObject -// IWYU pragma: no_forward_declare osmium::memory::Item - -namespace osmium { - - /** - * A collection of pointers to OSM objects. The pointers can be easily - * and quickly sorted or otherwise manipulated, while the objects - * themselves or the buffers they are in, do not have to be changed. - * - * An iterator is provided that can iterate over the pointers but looks - * like it is iterating over the underlying OSM objects. - * - * This class implements the visitor pattern which makes it easy to - * populate the collection from a buffer of OSM objects: - * - * osmium::ObjectPointerCollection objects; - * osmium::memory::Buffer buffer = reader.read(); - * osmium::apply(buffer, objects); - * - */ - class ObjectPointerCollection : public osmium::handler::Handler { - - std::vector m_objects; - - public: - - typedef boost::indirect_iterator::iterator, osmium::OSMObject> iterator; - typedef boost::indirect_iterator::const_iterator, const osmium::OSMObject> const_iterator; - - ObjectPointerCollection() : - m_objects() { - } - - void osm_object(osmium::OSMObject& object) { - m_objects.push_back(&object); - } - - /** - * Sort objects according to the given order functor. - */ - template - void sort(TCompare&& compare) { - std::sort(m_objects.begin(), m_objects.end(), std::forward(compare)); - } - - iterator begin() { - return iterator { m_objects.begin() }; - } - - iterator end() { - return iterator { m_objects.end() }; - } - - const_iterator cbegin() const { - return const_iterator { m_objects.cbegin() }; - } - - const_iterator cend() const { - return const_iterator { m_objects.cend() }; - } - - }; // class ObjectPointerCollection - -} // namespace osmium - -#endif // OSMIUM_OBJECT_POINTER_COLLECTION_HPP +#ifndef OSMIUM_OBJECT_POINTER_COLLECTION_HPP +#define OSMIUM_OBJECT_POINTER_COLLECTION_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include + +#include + +#include +#include +#include + +// IWYU pragma: no_forward_declare osmium::OSMObject +// IWYU pragma: no_forward_declare osmium::memory::Item + +namespace osmium { + + /** + * A collection of pointers to OSM objects. The pointers can be easily + * and quickly sorted or otherwise manipulated, while the objects + * themselves or the buffers they are in, do not have to be changed. + * + * An iterator is provided that can iterate over the pointers but looks + * like it is iterating over the underlying OSM objects. + * + * This class implements the visitor pattern which makes it easy to + * populate the collection from a buffer of OSM objects: + * + * osmium::ObjectPointerCollection objects; + * osmium::memory::Buffer buffer = reader.read(); + * osmium::apply(buffer, objects); + * + */ + class ObjectPointerCollection : public osmium::handler::Handler { + + std::vector m_objects; + + public: + + typedef boost::indirect_iterator::iterator, osmium::OSMObject> iterator; + typedef boost::indirect_iterator::const_iterator, const osmium::OSMObject> const_iterator; + + ObjectPointerCollection() noexcept : + m_objects() { + } + + void osm_object(osmium::OSMObject& object) { + m_objects.push_back(&object); + } + + /** + * Sort objects according to the given order functor. + */ + template + void sort(TCompare&& compare) { + std::sort(m_objects.begin(), m_objects.end(), std::forward(compare)); + } + + iterator begin() { + return iterator { m_objects.begin() }; + } + + iterator end() { + return iterator { m_objects.end() }; + } + + const_iterator cbegin() const { + return const_iterator { m_objects.cbegin() }; + } + + const_iterator cend() const { + return const_iterator { m_objects.cend() }; + } + + }; // class ObjectPointerCollection + +} // namespace osmium + +#endif // OSMIUM_OBJECT_POINTER_COLLECTION_HPP diff --git a/ThirdParty/osmium/osm/area.hpp b/ThirdParty/osmium/osm/area.hpp index 5d8233de9..a388de2e9 100644 --- a/ThirdParty/osmium/osm/area.hpp +++ b/ThirdParty/osmium/osm/area.hpp @@ -33,6 +33,7 @@ DEALINGS IN THE SOFTWARE. */ +#include #include #include @@ -123,7 +124,7 @@ namespace osmium { * Was this area created from a way? (In contrast to areas * created from a relation and their members.) */ - bool from_way() const { + bool from_way() const noexcept { return (positive_id() & 0x1) == 0; } @@ -148,7 +149,19 @@ namespace osmium { case osmium::item_type::inner_ring: ++counter.second; break; - default: + case osmium::item_type::tag_list: + // ignore tags + break; + case osmium::item_type::undefined: + case osmium::item_type::node: + case osmium::item_type::way: + case osmium::item_type::relation: + case osmium::item_type::area: + case osmium::item_type::changeset: + case osmium::item_type::way_node_list: + case osmium::item_type::relation_member_list: + case osmium::item_type::relation_member_list_with_full_members: + assert(false && "Children of Area can only be outer/inner_ring and tag_list."); break; } } @@ -163,6 +176,14 @@ namespace osmium { return num_rings().first > 1; } + osmium::memory::ItemIterator inner_ring_cbegin(const osmium::memory::ItemIterator& it) const { + return it.cast(); + } + + osmium::memory::ItemIterator inner_ring_cend(const osmium::memory::ItemIterator& it) const { + return std::next(it).cast(); + } + }; // class Area static_assert(sizeof(Area) % osmium::memory::align_bytes == 0, "Class osmium::Area has wrong size to be aligned properly!"); diff --git a/ThirdParty/osmium/osm/box.hpp b/ThirdParty/osmium/osm/box.hpp index fea0c70cd..2b761fefc 100644 --- a/ThirdParty/osmium/osm/box.hpp +++ b/ThirdParty/osmium/osm/box.hpp @@ -54,7 +54,7 @@ namespace osmium { * Create undefined Box. Use the extend() function * to add actual bounds. */ - constexpr Box() : + constexpr Box() noexcept : m_bottom_left(), m_top_right() { } @@ -83,16 +83,16 @@ namespace osmium { if (location) { if (m_bottom_left) { if (location.x() < m_bottom_left.x()) { - m_bottom_left.x(location.x()); + m_bottom_left.set_x(location.x()); } if (location.x() > m_top_right.x()) { - m_top_right.x(location.x()); + m_top_right.set_x(location.x()); } if (location.y() < m_bottom_left.y()) { - m_bottom_left.y(location.y()); + m_bottom_left.set_y(location.y()); } if (location.y() > m_top_right.y()) { - m_top_right.y(location.y()); + m_top_right.set_y(location.y()); } } else { m_bottom_left = location; diff --git a/ThirdParty/osmium/osm/changeset.hpp b/ThirdParty/osmium/osm/changeset.hpp index e04267cb1..2b79fb5cf 100644 --- a/ThirdParty/osmium/osm/changeset.hpp +++ b/ThirdParty/osmium/osm/changeset.hpp @@ -52,8 +52,11 @@ namespace osmium { } /** - * An OSM Changeset is of a group of changes made by a single user over a - * short period of time. + * \brief An OSM Changeset, a group of changes made by a single user over + * a short period of time. + * + * You can not create Changeset objects directly. Use the ChangesetBuilder + * class to create Changesets in a Buffer. */ class Changeset : public osmium::OSMEntity { @@ -71,7 +74,7 @@ namespace osmium { OSMEntity(sizeof(Changeset), osmium::item_type::changeset) { } - void user_size(string_size_type size) { + void set_user_size(string_size_type size) { m_user_size = size; } @@ -83,30 +86,6 @@ namespace osmium { return data() + osmium::memory::padded_length(sizeof(Changeset) + m_user_size); } - template - T& subitem_of_type() { - for (iterator it = begin(); it != end(); ++it) { - if (it->type() == T::itemtype) { - return reinterpret_cast(*it); - } - } - - static T subitem; - return subitem; - } - - template - const T& subitem_of_type() const { - for (const_iterator it = cbegin(); it != cend(); ++it) { - if (it->type() == T::itemtype) { - return reinterpret_cast(*it); - } - } - - static const T subitem; - return subitem; - } - public: /// Get ID of this changeset @@ -117,9 +96,10 @@ namespace osmium { /** * Set ID of this changeset * - * @return Reference to changeset to make calls chainable. + * @param id The id. + * @returns Reference to changeset to make calls chainable. */ - Changeset& id(changeset_id_type id) noexcept { + Changeset& set_id(changeset_id_type id) noexcept { m_id = id; return *this; } @@ -127,10 +107,11 @@ namespace osmium { /** * Set ID of this changeset. * - * @return Reference to object to make calls chainable. + * @param id The id. + * @returns Reference to object to make calls chainable. */ - Changeset& id(const char* id) { - return this->id(osmium::string_to_changeset_id(id)); + Changeset& set_id(const char* id) { + return set_id(osmium::string_to_changeset_id(id)); } /// Get user id. @@ -141,31 +122,34 @@ namespace osmium { /** * Set user id. * - * @return Reference to changeset to make calls chainable. + * @param uid The user id. + * @returns Reference to changeset to make calls chainable. */ - Changeset& uid(user_id_type uid) noexcept { + Changeset& set_uid(user_id_type uid) noexcept { m_uid = uid; return *this; } /** - * Set user id. - * Sets uid to 0 (anonymous) if the given uid is smaller than 0. + * Set user id to given uid or to 0 (anonymous user) if the given + * uid is smaller than 0. * - * @return Reference to changeset to make calls chainable. + * @param uid The user id. + * @returns Reference to changeset to make calls chainable. */ - Changeset& uid_from_signed(signed_user_id_type uid) noexcept { + Changeset& set_uid_from_signed(signed_user_id_type uid) noexcept { m_uid = uid < 0 ? 0 : static_cast(uid); return *this; } /** - * Set user id. + * Set user id to given uid or to 0 (anonymous user) if the given + * uid is smaller than 0. * - * @return Reference to changeset to make calls chainable. + * @returns Reference to changeset to make calls chainable. */ - Changeset& uid(const char* uid) { - return this->uid_from_signed(string_to_user_id(uid)); + Changeset& set_uid(const char* uid) { + return set_uid_from_signed(string_to_user_id(uid)); } /// Is this user anonymous? @@ -181,17 +165,19 @@ namespace osmium { /** * Get timestamp when this changeset was closed. * - * This will return the empty Timestamp when the - * changeset is not yet closed. + * @returns Timestamp. Will return the empty Timestamp when the + * changeset is not yet closed. */ osmium::Timestamp closed_at() const noexcept { return m_closed_at; } + /// Is this changeset open? bool open() const noexcept { return m_closed_at == osmium::Timestamp(); } + /// Is this changeset closed? bool closed() const noexcept { return !open(); } @@ -200,9 +186,9 @@ namespace osmium { * Set the timestamp when this changeset was created. * * @param timestamp Timestamp - * @return Reference to changeset to make calls chainable. + * @returns Reference to changeset to make calls chainable. */ - Changeset& created_at(const osmium::Timestamp timestamp) { + Changeset& set_created_at(const osmium::Timestamp timestamp) { m_created_at = timestamp; return *this; } @@ -211,30 +197,43 @@ namespace osmium { * Set the timestamp when this changeset was closed. * * @param timestamp Timestamp - * @return Reference to changeset to make calls chainable. + * @returns Reference to changeset to make calls chainable. */ - Changeset& closed_at(const osmium::Timestamp timestamp) { + Changeset& set_closed_at(const osmium::Timestamp timestamp) { m_closed_at = timestamp; return *this; } + /// Get the number of changes in this changeset num_changes_type num_changes() const noexcept { return m_num_changes; } - Changeset& num_changes(num_changes_type num_changes) noexcept { + /// Set the number of changes in this changeset + Changeset& set_num_changes(num_changes_type num_changes) noexcept { m_num_changes = num_changes; return *this; } - Changeset& num_changes(const char* num_changes) noexcept { - return this->num_changes(osmium::string_to_num_changes(num_changes)); + /// Set the number of changes in this changeset + Changeset& set_num_changes(const char* num_changes) noexcept { + return set_num_changes(osmium::string_to_num_changes(num_changes)); } + /** + * Get the bounding box of this changeset. + * + * @returns Bounding box. Can be empty. + */ osmium::Box& bounds() noexcept { return m_bounds; } + /** + * Get the bounding box of this changeset. + * + * @returns Bounding box. Can be empty. + */ const osmium::Box& bounds() const noexcept { return m_bounds; } @@ -244,33 +243,29 @@ namespace osmium { return reinterpret_cast(data() + sizeof(Changeset)); } - /// Get the list of tags. - TagList& tags() { - return subitem_of_type(); - } - /// Get the list of tags. const TagList& tags() const { - return subitem_of_type(); + return osmium::detail::subitem_of_type(cbegin(), cend()); } /** * Set named attribute. * - * @param attr Name of the attribute (must be one of "id", "version", "changeset", "timestamp", "uid", "visible") + * @param attr Name of the attribute (must be one of "id", "version", + * "changeset", "timestamp", "uid", "visible") * @param value Value of the attribute */ void set_attribute(const char* attr, const char* value) { if (!strcmp(attr, "id")) { - id(value); + set_id(value); } else if (!strcmp(attr, "num_changes")) { - num_changes(value); + set_num_changes(value); } else if (!strcmp(attr, "created_at")) { - created_at(osmium::Timestamp(value)); + set_created_at(osmium::Timestamp(value)); } else if (!strcmp(attr, "closed_at")) { - closed_at(osmium::Timestamp(value)); + set_closed_at(osmium::Timestamp(value)); } else if (!strcmp(attr, "uid")) { - uid(value); + set_uid(value); } } @@ -303,7 +298,8 @@ namespace osmium { }; // class Changeset - static_assert(sizeof(Changeset) % osmium::memory::align_bytes == 0, "Class osmium::Changeset has wrong size to be aligned properly!"); + static_assert(sizeof(Changeset) % osmium::memory::align_bytes == 0, + "Class osmium::Changeset has wrong size to be aligned properly!"); /** * Changesets are equal if their IDs are equal. diff --git a/ThirdParty/osmium/osm/diff_object.hpp b/ThirdParty/osmium/osm/diff_object.hpp index d3d9c2123..4aecb8cfd 100644 --- a/ThirdParty/osmium/osm/diff_object.hpp +++ b/ThirdParty/osmium/osm/diff_object.hpp @@ -1,156 +1,156 @@ -#ifndef OSMIUM_OSM_DIFF_OBJECT_HPP -#define OSMIUM_OSM_DIFF_OBJECT_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include - -namespace osmium { - - class Node; - class Way; - class Relation; - - class DiffObject { - - protected: - - osmium::OSMObject* m_prev; - osmium::OSMObject* m_curr; - osmium::OSMObject* m_next; - - public: - - DiffObject() : - m_prev(nullptr), - m_curr(nullptr), - m_next(nullptr) { - } - - explicit DiffObject(osmium::OSMObject& prev, osmium::OSMObject& curr, osmium::OSMObject& next) : - m_prev(&prev), - m_curr(&curr), - m_next(&next) { - } - - DiffObject(const DiffObject& other) = default; - DiffObject& operator=(const DiffObject& other) = default; - - DiffObject(DiffObject&& other) = default; - DiffObject& operator=(DiffObject&& other) = default; - - const osmium::OSMObject& prev() const { - return *m_prev; - } - - const osmium::OSMObject& curr() const { - return *m_curr; - } - - const osmium::OSMObject& next() const { - return *m_next; - } - - bool first() const { - return m_prev == m_curr; - } - - bool last() const { - return m_curr == m_next; - } - - osmium::item_type type() const { - return m_curr->type(); - } - - osmium::object_id_type id() const { - return m_curr->id(); - } - - osmium::object_version_type version() const { - return m_curr->version(); - } - - osmium::changeset_id_type changeset() const { - return m_curr->changeset(); - } - - const osmium::Timestamp start_time() const { - return m_curr->timestamp(); - } - - const osmium::Timestamp end_time() const { - return last() ? osmium::Timestamp() : m_next->timestamp(); - } - - }; // class DiffObject - - template - class DiffObjectDerived : public DiffObject { - - public: - - DiffObjectDerived(T& prev, T& curr, T& next) : - DiffObject(prev, curr, next) { - } - - DiffObjectDerived(const DiffObjectDerived& other) = default; - DiffObjectDerived& operator=(const DiffObjectDerived& other) = default; - - DiffObjectDerived(DiffObjectDerived&& other) = default; - DiffObjectDerived& operator=(DiffObjectDerived&& other) = default; - - const T& prev() const { - return *static_cast(m_prev); - } - - const T& curr() const { - return *static_cast(m_curr); - } - - const T& next() const { - return *static_cast(m_next); - } - - }; // class DiffObjectDerived - - typedef DiffObjectDerived DiffNode; - typedef DiffObjectDerived DiffWay; - typedef DiffObjectDerived DiffRelation; - -} // namespace osmium - -#endif // OSMIUM_OSM_DIFF_OBJECT_HPP +#ifndef OSMIUM_OSM_DIFF_OBJECT_HPP +#define OSMIUM_OSM_DIFF_OBJECT_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include +#include + +namespace osmium { + + class Node; + class Way; + class Relation; + + class DiffObject { + + protected: + + osmium::OSMObject* m_prev; + osmium::OSMObject* m_curr; + osmium::OSMObject* m_next; + + public: + + DiffObject() noexcept : + m_prev(nullptr), + m_curr(nullptr), + m_next(nullptr) { + } + + explicit DiffObject(osmium::OSMObject& prev, osmium::OSMObject& curr, osmium::OSMObject& next) noexcept : + m_prev(&prev), + m_curr(&curr), + m_next(&next) { + } + + DiffObject(const DiffObject& other) = default; + DiffObject& operator=(const DiffObject& other) = default; + + DiffObject(DiffObject&& other) = default; + DiffObject& operator=(DiffObject&& other) = default; + + const osmium::OSMObject& prev() const noexcept { + return *m_prev; + } + + const osmium::OSMObject& curr() const noexcept { + return *m_curr; + } + + const osmium::OSMObject& next() const noexcept { + return *m_next; + } + + bool first() const noexcept { + return m_prev == m_curr; + } + + bool last() const noexcept { + return m_curr == m_next; + } + + osmium::item_type type() const noexcept { + return m_curr->type(); + } + + osmium::object_id_type id() const noexcept { + return m_curr->id(); + } + + osmium::object_version_type version() const noexcept { + return m_curr->version(); + } + + osmium::changeset_id_type changeset() const noexcept { + return m_curr->changeset(); + } + + const osmium::Timestamp start_time() const noexcept { + return m_curr->timestamp(); + } + + const osmium::Timestamp end_time() const noexcept { + return last() ? osmium::Timestamp() : m_next->timestamp(); + } + + }; // class DiffObject + + template + class DiffObjectDerived : public DiffObject { + + public: + + DiffObjectDerived(T& prev, T& curr, T& next) noexcept : + DiffObject(prev, curr, next) { + } + + DiffObjectDerived(const DiffObjectDerived& other) = default; + DiffObjectDerived& operator=(const DiffObjectDerived& other) = default; + + DiffObjectDerived(DiffObjectDerived&& other) = default; + DiffObjectDerived& operator=(DiffObjectDerived&& other) = default; + + const T& prev() const noexcept { + return *static_cast(m_prev); + } + + const T& curr() const noexcept { + return *static_cast(m_curr); + } + + const T& next() const noexcept { + return *static_cast(m_next); + } + + }; // class DiffObjectDerived + + typedef DiffObjectDerived DiffNode; + typedef DiffObjectDerived DiffWay; + typedef DiffObjectDerived DiffRelation; + +} // namespace osmium + +#endif // OSMIUM_OSM_DIFF_OBJECT_HPP diff --git a/ThirdParty/osmium/osm/entity.hpp b/ThirdParty/osmium/osm/entity.hpp index 9d068f587..e37ed4c94 100644 --- a/ThirdParty/osmium/osm/entity.hpp +++ b/ThirdParty/osmium/osm/entity.hpp @@ -1,55 +1,74 @@ -#ifndef OSMIUM_OSM_ENTITY_HPP -#define OSMIUM_OSM_ENTITY_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include - -namespace osmium { - - /** - * OSMEntity is the parent class for the OSMObject class and the Changeset class. - */ - class OSMEntity : public osmium::memory::Item { - - public: - - explicit OSMEntity(osmium::memory::item_size_type size, osmium::item_type type) : - Item(size, type) { - } - - }; // class OSMEntity - -} // namespace osmium - -#endif // OSMIUM_OSM_ENTITY_HPP +#ifndef OSMIUM_OSM_ENTITY_HPP +#define OSMIUM_OSM_ENTITY_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include + +namespace osmium { + + namespace detail { + + template + inline TSubitem& subitem_of_type(TIter it, TIter end) { + for (; it != end; ++it) { + if (it->type() == TSubitem::itemtype) { + return reinterpret_cast(*it); + } + } + + // If no subitem of the TSubitem type was found, + // return a default constructed one. + static TSubitem subitem; + return subitem; + } + + } // namespace detail + + /** + * \brief OSMEntity is the abstract base class for the OSMObject and + * Changeset classes. + */ + class OSMEntity : public osmium::memory::Item { + + public: + + explicit OSMEntity(osmium::memory::item_size_type size, osmium::item_type type) : + Item(size, type) { + } + + }; // class OSMEntity + +} // namespace osmium + +#endif // OSMIUM_OSM_ENTITY_HPP diff --git a/ThirdParty/osmium/osm/entity_bits.hpp b/ThirdParty/osmium/osm/entity_bits.hpp index d6e4a8b75..96d44ab2e 100644 --- a/ThirdParty/osmium/osm/entity_bits.hpp +++ b/ThirdParty/osmium/osm/entity_bits.hpp @@ -68,20 +68,20 @@ namespace osmium { }; // enum type - inline type operator|(const type lhs, const type rhs) { + inline type operator|(const type lhs, const type rhs) noexcept { return static_cast(static_cast(lhs) | static_cast (rhs)); } - inline type& operator|=(type& lhs, const type rhs) { + inline type& operator|=(type& lhs, const type rhs) noexcept { lhs = lhs | rhs; return lhs; } - inline type operator&(const type lhs, const type rhs) { + inline type operator&(const type lhs, const type rhs) noexcept { return static_cast(static_cast(lhs) & static_cast (rhs)); } - inline type operator&=(type& lhs, const type rhs) { + inline type operator&=(type& lhs, const type rhs) noexcept { lhs = lhs & rhs; return lhs; } diff --git a/ThirdParty/osmium/osm/item_type.hpp b/ThirdParty/osmium/osm/item_type.hpp index 90075d331..d277e06c8 100644 --- a/ThirdParty/osmium/osm/item_type.hpp +++ b/ThirdParty/osmium/osm/item_type.hpp @@ -56,7 +56,7 @@ namespace osmium { }; // enum class item_type - inline item_type char_to_item_type(const char c) { + inline item_type char_to_item_type(const char c) noexcept { switch (c) { case 'X': return item_type::undefined; @@ -87,7 +87,10 @@ namespace osmium { } } - inline char item_type_to_char(const item_type type) { +// avoid g++ false positive +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreturn-type" + inline char item_type_to_char(const item_type type) noexcept { switch (type) { case item_type::undefined: return 'X'; @@ -116,7 +119,7 @@ namespace osmium { } } - inline const char* item_type_to_name(const item_type type) { + inline const char* item_type_to_name(const item_type type) noexcept { switch (type) { case item_type::undefined: return "undefined"; @@ -144,12 +147,19 @@ namespace osmium { return "inner_ring"; } } +#pragma GCC diagnostic pop template inline std::basic_ostream& operator<<(std::basic_ostream& out, const item_type item_type) { return out << item_type_to_char(item_type); } + /** + * This exception is thrown when a visitor encounters an unknown item type. + * Under usual circumstance this should not happen. If it does happen, it + * probably means the buffer contains different kinds of objects than were + * expected or that there is some kind of data corruption. + */ struct unknown_type : public std::runtime_error { unknown_type() : diff --git a/ThirdParty/osmium/osm/location.hpp b/ThirdParty/osmium/osm/location.hpp index 8884583ad..cabecd50f 100644 --- a/ThirdParty/osmium/osm/location.hpp +++ b/ThirdParty/osmium/osm/location.hpp @@ -33,19 +33,16 @@ DEALINGS IN THE SOFTWARE. */ -#include -#include #include #include -#include #include -#include #include #include #include #include +#include namespace osmium { @@ -86,7 +83,7 @@ namespace osmium { public: - /// this value is used for a coordinate to mark it as undefined + // this value is used for a coordinate to mark it as undefined // MSVC doesn't declare std::numeric_limits::max() as // constexpr, so we hard code this for the time being. // static constexpr int32_t undefined_coordinate = std::numeric_limits::max(); @@ -105,7 +102,7 @@ namespace osmium { /** * Create undefined Location. */ - explicit constexpr Location() : + explicit constexpr Location() noexcept : m_x(undefined_coordinate), m_y(undefined_coordinate) { } @@ -115,7 +112,7 @@ namespace osmium { * Note that these coordinates are coordinate_precision * times larger than the real coordinates. */ - constexpr Location(const int32_t x, const int32_t y) : + constexpr Location(const int32_t x, const int32_t y) noexcept : m_x(x), m_y(y) { } @@ -125,7 +122,7 @@ namespace osmium { * Note that these coordinates are coordinate_precision * times larger than the real coordinates. */ - constexpr Location(const int64_t x, const int64_t y) : + constexpr Location(const int64_t x, const int64_t y) noexcept : m_x(static_cast(x)), m_y(static_cast(y)) { } @@ -171,12 +168,12 @@ namespace osmium { return m_y; } - Location& x(const int32_t x) noexcept { + Location& set_x(const int32_t x) noexcept { m_x = x; return *this; } - Location& y(const int32_t y) noexcept { + Location& set_y(const int32_t y) noexcept { m_y = y; return *this; } @@ -219,44 +216,21 @@ namespace osmium { return fix_to_double(m_y); } - Location& lon(double lon) noexcept { + Location& set_lon(double lon) noexcept { m_x = double_to_fix(lon); return *this; } - Location& lat(double lat) noexcept { + Location& set_lat(double lat) noexcept { m_y = double_to_fix(lat); return *this; } - static constexpr int coordinate_length = - 1 + /* sign */ - 3 + /* before . */ - 1 + /* . */ - 7 + /* after . */ - 1; /* null byte */ - - template - static T coordinate2string(T iterator, double value) { - char buffer[coordinate_length]; - -#ifndef _MSC_VER - int len = snprintf(buffer, coordinate_length, "%.7f", value); -#else - int len = _snprintf(buffer, coordinate_length, "%.7f", value); -#endif - assert(len > 0 && len < coordinate_length); - while (buffer[len-1] == '0') --len; - if (buffer[len-1] == '.') --len; - - return std::copy_n(buffer, len, iterator); - } - template T as_string(T iterator, const char separator) const { - iterator = coordinate2string(iterator, lon()); + iterator = osmium::util::double2string(iterator, lon(), 7); *iterator++ = separator; - return coordinate2string(iterator, lat()); + return osmium::util::double2string(iterator, lat(), 7); } }; // class Location @@ -268,7 +242,7 @@ namespace osmium { return lhs.x() == rhs.x() && lhs.y() == rhs.y(); } - inline OSMIUM_CONSTEXPR bool operator!=(const Location& lhs, const Location& rhs) { + inline OSMIUM_CONSTEXPR bool operator!=(const Location& lhs, const Location& rhs) noexcept { return ! (lhs == rhs); } @@ -281,15 +255,15 @@ namespace osmium { return (lhs.x() == rhs.x() && lhs.y() < rhs.y()) || lhs.x() < rhs.x(); } - inline OSMIUM_CONSTEXPR bool operator>(const Location& lhs, const Location& rhs) { + inline OSMIUM_CONSTEXPR bool operator>(const Location& lhs, const Location& rhs) noexcept { return rhs < lhs; } - inline OSMIUM_CONSTEXPR bool operator<=(const Location& lhs, const Location& rhs) { + inline OSMIUM_CONSTEXPR bool operator<=(const Location& lhs, const Location& rhs) noexcept { return ! (rhs < lhs); } - inline OSMIUM_CONSTEXPR bool operator>=(const Location& lhs, const Location& rhs) { + inline OSMIUM_CONSTEXPR bool operator>=(const Location& lhs, const Location& rhs) noexcept { return ! (lhs < rhs); } diff --git a/ThirdParty/osmium/osm/node.hpp b/ThirdParty/osmium/osm/node.hpp index e1bc2d0eb..50146c568 100644 --- a/ThirdParty/osmium/osm/node.hpp +++ b/ThirdParty/osmium/osm/node.hpp @@ -58,15 +58,11 @@ namespace osmium { static constexpr osmium::item_type itemtype = osmium::item_type::node; - const osmium::Location location() const { + osmium::Location location() const noexcept { return m_location; } - osmium::Location& location() { - return m_location; - } - - Node& location(const osmium::Location& location) { + Node& set_location(const osmium::Location& location) { m_location = location; return *this; } diff --git a/ThirdParty/osmium/osm/node_ref.hpp b/ThirdParty/osmium/osm/node_ref.hpp index 5e10b0ab6..ed50b9e66 100644 --- a/ThirdParty/osmium/osm/node_ref.hpp +++ b/ThirdParty/osmium/osm/node_ref.hpp @@ -54,20 +54,27 @@ namespace osmium { public: - NodeRef(const osmium::object_id_type ref=0, const osmium::Location& location=Location()) : + NodeRef(const osmium::object_id_type ref=0, const osmium::Location& location=Location()) noexcept : m_ref(ref), m_location(location) { } - osmium::object_id_type ref() const { + osmium::object_id_type ref() const noexcept { return m_ref; } - osmium::unsigned_object_id_type positive_ref() const { + osmium::unsigned_object_id_type positive_ref() const noexcept { return static_cast(std::abs(m_ref)); } - osmium::Location location() const { + /** + * Get reference to location in this NodeRef. Can be used to update it. + */ + osmium::Location& location() noexcept { + return m_location; + } + + osmium::Location location() const noexcept { return m_location; } @@ -79,33 +86,47 @@ namespace osmium { return m_location.lat(); } - void location(const osmium::Location& location) { + int32_t x() const noexcept { + return m_location.x(); + } + + int32_t y() const noexcept { + return m_location.y(); + } + + NodeRef& set_ref(const osmium::object_id_type ref) noexcept { + m_ref = ref; + return *this; + } + + NodeRef& set_location(const osmium::Location& location) noexcept { m_location = location; + return *this; } }; // class NodeRef - inline bool operator==(const NodeRef& lhs, const NodeRef& rhs) { + inline bool operator==(const NodeRef& lhs, const NodeRef& rhs) noexcept { return lhs.ref() == rhs.ref(); } - inline bool operator!=(const NodeRef& lhs, const NodeRef& rhs) { + inline bool operator!=(const NodeRef& lhs, const NodeRef& rhs) noexcept { return ! (lhs == rhs); } - inline bool operator<(const NodeRef& lhs, const NodeRef& rhs) { + inline bool operator<(const NodeRef& lhs, const NodeRef& rhs) noexcept { return lhs.ref() < rhs.ref(); } - inline bool operator>(const NodeRef& lhs, const NodeRef& rhs) { + inline bool operator>(const NodeRef& lhs, const NodeRef& rhs) noexcept { return rhs < lhs; } - inline bool operator<=(const NodeRef& lhs, const NodeRef& rhs) { + inline bool operator<=(const NodeRef& lhs, const NodeRef& rhs) noexcept { return ! (rhs < lhs); } - inline bool operator>=(const NodeRef& lhs, const NodeRef& rhs) { + inline bool operator>=(const NodeRef& lhs, const NodeRef& rhs) noexcept { return ! (lhs < rhs); } @@ -122,7 +143,7 @@ namespace osmium { */ struct location_equal { - bool operator()(const NodeRef& lhs, const NodeRef& rhs) const { + bool operator()(const NodeRef& lhs, const NodeRef& rhs) const noexcept { return lhs.location() == rhs.location(); } @@ -137,7 +158,7 @@ namespace osmium { */ struct location_less { - bool operator()(const NodeRef& lhs, const NodeRef& rhs) const { + bool operator()(const NodeRef& lhs, const NodeRef& rhs) const noexcept { return lhs.location() < rhs.location(); } diff --git a/ThirdParty/osmium/osm/node_ref_list.hpp b/ThirdParty/osmium/osm/node_ref_list.hpp index 5ece86b06..321c952f4 100644 --- a/ThirdParty/osmium/osm/node_ref_list.hpp +++ b/ThirdParty/osmium/osm/node_ref_list.hpp @@ -1,135 +1,135 @@ -#ifndef OSMIUM_OSM_NODE_REF_LIST_HPP -#define OSMIUM_OSM_NODE_REF_LIST_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include - -#include -#include -#include - -namespace osmium { - - /** - * A vector of NodeRef objects. Usually this is not instatiated directly, - * but one of its subclasses are used. - */ - template - class NodeRefList : public osmium::memory::Item { - - public: - - static constexpr osmium::item_type itemtype = TItemType; - - NodeRefList(): - osmium::memory::Item(sizeof(NodeRefList), TItemType) { - } - - bool empty() const { - return sizeof(NodeRefList) == byte_size(); - } - - size_t size() const noexcept { - assert((osmium::memory::Item::byte_size() - sizeof(NodeRefList)) % sizeof(NodeRef) == 0); - return (osmium::memory::Item::byte_size() - sizeof(NodeRefList)) / sizeof(NodeRef); - } - - const NodeRef& operator[](size_t n) const { - const NodeRef* node_ref = &*(this->cbegin()); - return node_ref[n]; - } - - const NodeRef& front() const { - return operator[](0); - } - - const NodeRef& back() const { - return operator[](size()-1); - } - - bool is_closed() const { - return front().ref() == back().ref(); - } - - bool ends_have_same_id() const { - return front().ref() == back().ref(); - } - - bool ends_have_same_location() const { - return front().location() == back().location(); - } - - typedef NodeRef* iterator; - typedef const NodeRef* const_iterator; - typedef std::reverse_iterator const_reverse_iterator; - - iterator begin() { - return iterator(data() + sizeof(NodeRefList)); - } - - iterator end() { - return iterator(data() + byte_size()); - } - - const_iterator cbegin() const { - return const_iterator(data() + sizeof(NodeRefList)); - } - - const_iterator cend() const { - return const_iterator(data() + byte_size()); - } - - const_iterator begin() const { - return cbegin(); - } - - const_iterator end() const { - return cend(); - } - - const_reverse_iterator crbegin() const { - return const_reverse_iterator(this->cend()); - } - - const_reverse_iterator crend() const { - return const_reverse_iterator(this->cbegin()); - } - - }; // class NodeRefList - -} // namespace osmium - -#endif // OSMIUM_OSM_NODE_REF_LIST_HPP +#ifndef OSMIUM_OSM_NODE_REF_LIST_HPP +#define OSMIUM_OSM_NODE_REF_LIST_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include + +#include +#include +#include + +namespace osmium { + + /** + * A vector of NodeRef objects. Usually this is not instatiated directly, + * but one of its subclasses are used. + */ + template + class NodeRefList : public osmium::memory::Item { + + public: + + static constexpr osmium::item_type itemtype = TItemType; + + NodeRefList() noexcept : + osmium::memory::Item(sizeof(NodeRefList), TItemType) { + } + + bool empty() const noexcept { + return sizeof(NodeRefList) == byte_size(); + } + + size_t size() const noexcept { + assert((osmium::memory::Item::byte_size() - sizeof(NodeRefList)) % sizeof(NodeRef) == 0); + return (osmium::memory::Item::byte_size() - sizeof(NodeRefList)) / sizeof(NodeRef); + } + + const NodeRef& operator[](size_t n) const { + const NodeRef* node_ref = &*(cbegin()); + return node_ref[n]; + } + + const NodeRef& front() const { + return operator[](0); + } + + const NodeRef& back() const { + return operator[](size()-1); + } + + bool is_closed() const { + return front().ref() == back().ref(); + } + + bool ends_have_same_id() const { + return front().ref() == back().ref(); + } + + bool ends_have_same_location() const { + return front().location() == back().location(); + } + + typedef NodeRef* iterator; + typedef const NodeRef* const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + iterator begin() { + return iterator(data() + sizeof(NodeRefList)); + } + + iterator end() { + return iterator(data() + byte_size()); + } + + const_iterator cbegin() const { + return const_iterator(data() + sizeof(NodeRefList)); + } + + const_iterator cend() const { + return const_iterator(data() + byte_size()); + } + + const_iterator begin() const { + return cbegin(); + } + + const_iterator end() const { + return cend(); + } + + const_reverse_iterator crbegin() const { + return const_reverse_iterator(cend()); + } + + const_reverse_iterator crend() const { + return const_reverse_iterator(cbegin()); + } + + }; // class NodeRefList + +} // namespace osmium + +#endif // OSMIUM_OSM_NODE_REF_LIST_HPP diff --git a/ThirdParty/osmium/osm/object.hpp b/ThirdParty/osmium/osm/object.hpp index 1ef379892..9c4d60341 100644 --- a/ThirdParty/osmium/osm/object.hpp +++ b/ThirdParty/osmium/osm/object.hpp @@ -41,6 +41,7 @@ DEALINGS IN THE SOFTWARE. #include #include +#include #include #include #include @@ -62,19 +63,19 @@ namespace osmium { user_id_type m_uid; changeset_id_type m_changeset; - size_t sizeof_object() const { + size_t sizeof_object() const noexcept { return sizeof(OSMObject) + (type() == item_type::node ? sizeof(osmium::Location) : 0) + sizeof(string_size_type); } - unsigned char* user_position() { + unsigned char* user_position() noexcept { return data() + sizeof_object() - sizeof(string_size_type); } - const unsigned char* user_position() const { + const unsigned char* user_position() const noexcept { return data() + sizeof_object() - sizeof(string_size_type); } - string_size_type user_size() const { + string_size_type user_size() const noexcept { return *reinterpret_cast(user_position()); } @@ -98,52 +99,28 @@ namespace osmium { m_changeset(0) { } - void user_size(string_size_type size) { + void set_user_size(string_size_type size) { *reinterpret_cast(user_position()) = size; } - template - T& subitem_of_type() { - for (iterator it = begin(); it != end(); ++it) { - if (it->type() == T::itemtype) { - return reinterpret_cast(*it); - } - } - - static T subitem; - return subitem; - } - - template - const T& subitem_of_type() const { - for (const_iterator it = cbegin(); it != cend(); ++it) { - if (it->type() == T::itemtype) { - return reinterpret_cast(*it); - } - } - - static const T subitem; - return subitem; - } - public: /// Get ID of this object. - object_id_type id() const { + object_id_type id() const noexcept { return m_id; } /// Get absolute value of the ID of this object. - unsigned_object_id_type positive_id() const { + unsigned_object_id_type positive_id() const noexcept { return static_cast(std::abs(m_id)); } /** * Set ID of this object. * - * @return Reference to object to make calls chainable. + * @returns Reference to object to make calls chainable. */ - OSMObject& id(object_id_type id) { + OSMObject& set_id(object_id_type id) noexcept { m_id = id; return *this; } @@ -151,28 +128,28 @@ namespace osmium { /** * Set ID of this object. * - * @return Reference to object to make calls chainable. + * @returns Reference to object to make calls chainable. */ - OSMObject& id(const char* id) { - return this->id(osmium::string_to_object_id(id)); + OSMObject& set_id(const char* id) { + return set_id(osmium::string_to_object_id(id)); } /// Is this object marked as deleted? - bool deleted() const { + bool deleted() const noexcept { return m_deleted; } /// Is this object marked visible (ie not deleted)? - bool visible() const { + bool visible() const noexcept { return !deleted(); } /** * Mark this object as deleted (or not). * - * @return Reference to object to make calls chainable. + * @returns Reference to object to make calls chainable. */ - OSMObject& deleted(bool deleted) { + OSMObject& set_deleted(bool deleted) noexcept { m_deleted = deleted; return *this; } @@ -180,9 +157,9 @@ namespace osmium { /** * Mark this object as visible (ie not deleted) (or not). * - * @return Reference to object to make calls chainable. + * @returns Reference to object to make calls chainable. */ - OSMObject& visible(bool visible) { + OSMObject& set_visible(bool visible) noexcept { m_deleted = !visible; return *this; } @@ -191,13 +168,13 @@ namespace osmium { * Mark this object as visible (ie not deleted) or deleted. * * @param visible Either "true" or "false" - * @return Reference to object to make calls chainable. + * @returns Reference to object to make calls chainable. */ - OSMObject& visible(const char* visible) { + OSMObject& set_visible(const char* visible) { if (!strcmp("true", visible)) { - this->visible(true); + set_visible(true); } else if (!strcmp("false", visible)) { - this->visible(false); + set_visible(false); } else { throw std::invalid_argument("Unknown value for visible attribute (allowed is 'true' or 'false')"); } @@ -205,16 +182,16 @@ namespace osmium { } /// Get version of this object. - object_version_type version() const { + object_version_type version() const noexcept { return m_version; } /** * Set object version. * - * @return Reference to object to make calls chainable. + * @returns Reference to object to make calls chainable. */ - OSMObject& version(object_version_type version) { + OSMObject& set_version(object_version_type version) noexcept { m_version = version; return *this; } @@ -222,23 +199,23 @@ namespace osmium { /** * Set object version. * - * @return Reference to object to make calls chainable. + * @returns Reference to object to make calls chainable. */ - OSMObject& version(const char* version) { - return this->version(string_to_object_version(version)); + OSMObject& set_version(const char* version) { + return set_version(string_to_object_version(version)); } /// Get changeset id of this object. - changeset_id_type changeset() const { + changeset_id_type changeset() const noexcept { return m_changeset; } /** * Set changeset id of this object. * - * @return Reference to object to make calls chainable. + * @returns Reference to object to make calls chainable. */ - OSMObject& changeset(changeset_id_type changeset) { + OSMObject& set_changeset(changeset_id_type changeset) noexcept { m_changeset = changeset; return *this; } @@ -246,23 +223,23 @@ namespace osmium { /** * Set changeset id of this object. * - * @return Reference to object to make calls chainable. + * @returns Reference to object to make calls chainable. */ - OSMObject& changeset(const char* changeset) { - return this->changeset(string_to_changeset_id(changeset)); + OSMObject& set_changeset(const char* changeset) { + return set_changeset(string_to_changeset_id(changeset)); } /// Get user id of this object. - user_id_type uid() const { + user_id_type uid() const noexcept { return m_uid; } /** * Set user id of this object. * - * @return Reference to object to make calls chainable. + * @returns Reference to object to make calls chainable. */ - OSMObject& uid(user_id_type uid) { + OSMObject& set_uid(user_id_type uid) noexcept { m_uid = uid; return *this; } @@ -271,9 +248,9 @@ namespace osmium { * Set user id of this object. * Sets uid to 0 (anonymous) if the given uid is smaller than 0. * - * @return Reference to object to make calls chainable. + * @returns Reference to object to make calls chainable. */ - OSMObject& uid_from_signed(signed_user_id_type uid) { + OSMObject& set_uid_from_signed(signed_user_id_type uid) noexcept { m_uid = uid < 0 ? 0 : static_cast(uid); return *this; } @@ -281,19 +258,19 @@ namespace osmium { /** * Set user id of this object. * - * @return Reference to object to make calls chainable. + * @returns Reference to object to make calls chainable. */ - OSMObject& uid(const char* uid) { - return this->uid_from_signed(string_to_user_id(uid)); + OSMObject& set_uid(const char* uid) { + return set_uid_from_signed(string_to_user_id(uid)); } /// Is this user anonymous? - bool user_is_anonymous() const { + bool user_is_anonymous() const noexcept { return m_uid == 0; } /// Get timestamp when this object last changed. - osmium::Timestamp timestamp() const { + osmium::Timestamp timestamp() const noexcept { return m_timestamp; } @@ -301,26 +278,21 @@ namespace osmium { * Set the timestamp when this object last changed. * * @param timestamp Timestamp - * @return Reference to object to make calls chainable. + * @returns Reference to object to make calls chainable. */ - OSMObject& timestamp(const osmium::Timestamp timestamp) { + OSMObject& set_timestamp(const osmium::Timestamp timestamp) noexcept { m_timestamp = timestamp; return *this; } /// Get user name for this object. - const char* user() const { + const char* user() const noexcept { return reinterpret_cast(data() + sizeof_object()); } - /// Get the list of tags for this object. - TagList& tags() { - return subitem_of_type(); - } - /// Get the list of tags for this object. const TagList& tags() const { - return subitem_of_type(); + return osmium::detail::subitem_of_type(cbegin(), cend()); } /** @@ -341,17 +313,17 @@ namespace osmium { */ void set_attribute(const char* attr, const char* value) { if (!strcmp(attr, "id")) { - id(value); + set_id(value); } else if (!strcmp(attr, "version")) { - version(value); + set_version(value); } else if (!strcmp(attr, "changeset")) { - changeset(value); + set_changeset(value); } else if (!strcmp(attr, "timestamp")) { - timestamp(osmium::Timestamp(value)); + set_timestamp(osmium::Timestamp(value)); } else if (!strcmp(attr, "uid")) { - uid(value); + set_uid(value); } else if (!strcmp(attr, "visible")) { - visible(value); + set_visible(value); } } @@ -363,7 +335,7 @@ namespace osmium { } iterator end() { - return iterator(data() + padded_size()); + return iterator(next()); } const_iterator cbegin() const { @@ -371,7 +343,7 @@ namespace osmium { } const_iterator cend() const { - return const_iterator(data() + padded_size()); + return const_iterator(next()); } const_iterator begin() const { @@ -382,6 +354,42 @@ namespace osmium { return cend(); } + template + using t_iterator = osmium::memory::ItemIterator; + + template + using t_const_iterator = osmium::memory::ItemIterator; + + template + t_iterator begin() { + return t_iterator(subitems_position(), next()); + } + + template + t_iterator end() { + return t_iterator(next(), next()); + } + + template + t_const_iterator cbegin() const { + return t_const_iterator(subitems_position(), next()); + } + + template + t_const_iterator cend() const { + return t_const_iterator(next(), next()); + } + + template + t_const_iterator begin() const { + return cbegin(); + } + + template + t_const_iterator end() const { + return cend(); + } + }; // class OSMObject static_assert(sizeof(OSMObject) % osmium::memory::align_bytes == 0, "Class osmium::OSMObject has wrong size to be aligned properly!"); @@ -389,13 +397,13 @@ namespace osmium { /** * OSMObjects are equal if their type, id, and version are equal. */ - inline bool operator==(const OSMObject& lhs, const OSMObject& rhs) { + inline bool operator==(const OSMObject& lhs, const OSMObject& rhs) noexcept { return lhs.type() == rhs.type() && lhs.id() == rhs.id() && lhs.version() == rhs.version(); } - inline bool operator!=(const OSMObject& lhs, const OSMObject& rhs) { + inline bool operator!=(const OSMObject& lhs, const OSMObject& rhs) noexcept { return ! (lhs == rhs); } @@ -404,7 +412,7 @@ namespace osmium { * Note that we use the absolute value of the id for a * better ordering of objects with negative id. */ - inline bool operator<(const OSMObject& lhs, const OSMObject& rhs) { + inline bool operator<(const OSMObject& lhs, const OSMObject& rhs) noexcept { if (lhs.type() != rhs.type()) { return lhs.type() < rhs.type(); } @@ -412,15 +420,15 @@ namespace osmium { lhs.positive_id() < rhs.positive_id(); } - inline bool operator>(const OSMObject& lhs, const OSMObject& rhs) { + inline bool operator>(const OSMObject& lhs, const OSMObject& rhs) noexcept { return rhs < lhs; } - inline bool operator<=(const OSMObject& lhs, const OSMObject& rhs) { + inline bool operator<=(const OSMObject& lhs, const OSMObject& rhs) noexcept { return ! (rhs < lhs); } - inline bool operator>=(const OSMObject& lhs, const OSMObject& rhs) { + inline bool operator>=(const OSMObject& lhs, const OSMObject& rhs) noexcept { return ! (lhs < rhs); } diff --git a/ThirdParty/osmium/osm/object_comparisons.hpp b/ThirdParty/osmium/osm/object_comparisons.hpp index 5c2bf6cc6..db11b0d4c 100644 --- a/ThirdParty/osmium/osm/object_comparisons.hpp +++ b/ThirdParty/osmium/osm/object_comparisons.hpp @@ -1,110 +1,110 @@ -#ifndef OSMIUM_OSM_OBJECT_COMPARISONS_HPP -#define OSMIUM_OSM_OBJECT_COMPARISONS_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include - -namespace osmium { - - /** - * Function object class for comparing OSM objects for equality by type, id, and version. - */ - struct object_equal_type_id_version { - - bool operator()(const osmium::OSMObject& lhs, const osmium::OSMObject& rhs) const { - return lhs == rhs; - } - - bool operator()(const osmium::OSMObject* lhs, const osmium::OSMObject* rhs) const { - return *lhs == *rhs; - } - - }; // struct object_equal_type_id_version - - /** - * Function object class for comparing OSM objects for equality by type and id, - * ignoring the version. - */ - struct object_equal_type_id { - - bool operator()(const osmium::OSMObject& lhs, const osmium::OSMObject& rhs) const { - return lhs.type() == rhs.type() && - lhs.id() == rhs.id(); - } - - bool operator()(const osmium::OSMObject* lhs, const osmium::OSMObject* rhs) const { - return operator()(*lhs, *rhs); - } - - }; // struct object_equal_type_id - - /** - * Function object class for ordering OSM objects by type, id, and version. - */ - struct object_order_type_id_version { - - bool operator()(const osmium::OSMObject& lhs, const osmium::OSMObject& rhs) const { - return lhs < rhs; - } - - bool operator()(const osmium::OSMObject* lhs, const osmium::OSMObject* rhs) const { - return *lhs < *rhs; - } - - }; // struct object_order_type_id_version - - /** - * Function object class for ordering OSM objects by type, id, and reverse version, - * ie objects are ordered by type and id, but later versions of an object are - * ordered before earlier versions of the same object. - */ - struct object_order_type_id_reverse_version { - - bool operator()(const osmium::OSMObject& lhs, const osmium::OSMObject& rhs) const { - if (lhs.type() != rhs.type()) { - return lhs.type() < rhs.type(); - } - return (lhs.id() == rhs.id() && lhs.version() > rhs.version()) || - lhs.positive_id() < rhs.positive_id(); - } - - bool operator()(const osmium::OSMObject* lhs, const osmium::OSMObject* rhs) const { - return operator()(*lhs, *rhs); - } - - }; // struct object_order_type_id_reverse_version - -} // namespace osmium - -#endif // OSMIUM_OSM_OBJECT_COMPARISONS_HPP +#ifndef OSMIUM_OSM_OBJECT_COMPARISONS_HPP +#define OSMIUM_OSM_OBJECT_COMPARISONS_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include + +namespace osmium { + + /** + * Function object class for comparing OSM objects for equality by type, id, and version. + */ + struct object_equal_type_id_version { + + bool operator()(const osmium::OSMObject& lhs, const osmium::OSMObject& rhs) const noexcept { + return lhs == rhs; + } + + bool operator()(const osmium::OSMObject* lhs, const osmium::OSMObject* rhs) const noexcept { + return *lhs == *rhs; + } + + }; // struct object_equal_type_id_version + + /** + * Function object class for comparing OSM objects for equality by type and id, + * ignoring the version. + */ + struct object_equal_type_id { + + bool operator()(const osmium::OSMObject& lhs, const osmium::OSMObject& rhs) const noexcept { + return lhs.type() == rhs.type() && + lhs.id() == rhs.id(); + } + + bool operator()(const osmium::OSMObject* lhs, const osmium::OSMObject* rhs) const noexcept { + return operator()(*lhs, *rhs); + } + + }; // struct object_equal_type_id + + /** + * Function object class for ordering OSM objects by type, id, and version. + */ + struct object_order_type_id_version { + + bool operator()(const osmium::OSMObject& lhs, const osmium::OSMObject& rhs) const noexcept { + return lhs < rhs; + } + + bool operator()(const osmium::OSMObject* lhs, const osmium::OSMObject* rhs) const noexcept { + return *lhs < *rhs; + } + + }; // struct object_order_type_id_version + + /** + * Function object class for ordering OSM objects by type, id, and reverse version, + * ie objects are ordered by type and id, but later versions of an object are + * ordered before earlier versions of the same object. + */ + struct object_order_type_id_reverse_version { + + bool operator()(const osmium::OSMObject& lhs, const osmium::OSMObject& rhs) const noexcept { + if (lhs.type() != rhs.type()) { + return lhs.type() < rhs.type(); + } + return (lhs.id() == rhs.id() && lhs.version() > rhs.version()) || + lhs.positive_id() < rhs.positive_id(); + } + + bool operator()(const osmium::OSMObject* lhs, const osmium::OSMObject* rhs) const noexcept { + return operator()(*lhs, *rhs); + } + + }; // struct object_order_type_id_reverse_version + +} // namespace osmium + +#endif // OSMIUM_OSM_OBJECT_COMPARISONS_HPP diff --git a/ThirdParty/osmium/osm/relation.hpp b/ThirdParty/osmium/osm/relation.hpp index 7974e7aad..f5d040100 100644 --- a/ThirdParty/osmium/osm/relation.hpp +++ b/ThirdParty/osmium/osm/relation.hpp @@ -93,7 +93,7 @@ namespace osmium { } } - void set_role_size(string_size_type size) { + void set_role_size(string_size_type size) noexcept { m_role_size = size; } @@ -101,34 +101,34 @@ namespace osmium { static constexpr item_type collection_type = item_type::relation_member_list; - RelationMember(const object_id_type ref=0, const item_type type=item_type(), const bool full=false) : + RelationMember(const object_id_type ref=0, const item_type type=item_type(), const bool full=false) noexcept : m_ref(ref), m_type(type), m_flags(full ? 1 : 0) { } - object_id_type ref() const { + object_id_type ref() const noexcept { return m_ref; } - RelationMember& ref(object_id_type ref) { + RelationMember& ref(object_id_type ref) noexcept { m_ref = ref; return *this; } - unsigned_object_id_type positive_ref() const { + unsigned_object_id_type positive_ref() const noexcept { return static_cast(std::abs(m_ref)); } - item_type type() const { + item_type type() const noexcept { return m_type; } - bool full_member() const { + bool full_member() const noexcept { return m_flags == 1; } - const char* role() const { + const char* role() const noexcept { return reinterpret_cast(data() + sizeof(RelationMember)); } @@ -164,7 +164,7 @@ namespace osmium { friend class osmium::builder::ObjectBuilder; - Relation() : + Relation() noexcept : OSMObject(sizeof(Relation), osmium::item_type::relation) { } @@ -173,11 +173,11 @@ namespace osmium { static constexpr osmium::item_type itemtype = osmium::item_type::relation; RelationMemberList& members() { - return subitem_of_type(); + return osmium::detail::subitem_of_type(begin(), end()); } const RelationMemberList& members() const { - return subitem_of_type(); + return osmium::detail::subitem_of_type(cbegin(), cend()); } }; // class Relation diff --git a/ThirdParty/osmium/osm/segment.hpp b/ThirdParty/osmium/osm/segment.hpp index b08679165..205036ec6 100644 --- a/ThirdParty/osmium/osm/segment.hpp +++ b/ThirdParty/osmium/osm/segment.hpp @@ -51,7 +51,7 @@ namespace osmium { public: - explicit constexpr Segment(const osmium::Location& location1, const osmium::Location& location2) : + explicit constexpr Segment(const osmium::Location& location1, const osmium::Location& location2) noexcept : m_first(location1), m_second(location2) { } @@ -65,12 +65,12 @@ namespace osmium { ~Segment() = default; /// Return first Location of Segment. - OSMIUM_CONSTEXPR osmium::Location first() const { + OSMIUM_CONSTEXPR osmium::Location first() const noexcept { return m_first; } /// Return second Location of Segment. - OSMIUM_CONSTEXPR osmium::Location second() const { + OSMIUM_CONSTEXPR osmium::Location second() const noexcept { return m_second; } @@ -84,11 +84,11 @@ namespace osmium { }; // class Segment /// Segments are equal if both their locations are equal - inline OSMIUM_CONSTEXPR bool operator==(const Segment& lhs, const Segment& rhs) { + inline OSMIUM_CONSTEXPR bool operator==(const Segment& lhs, const Segment& rhs) noexcept { return lhs.first() == rhs.first() && lhs.second() == rhs.second(); } - inline OSMIUM_CONSTEXPR bool operator!=(const Segment& lhs, const Segment& rhs) { + inline OSMIUM_CONSTEXPR bool operator!=(const Segment& lhs, const Segment& rhs) noexcept { return ! (lhs == rhs); } diff --git a/ThirdParty/osmium/osm/tag.hpp b/ThirdParty/osmium/osm/tag.hpp index df994a134..fe80de34f 100644 --- a/ThirdParty/osmium/osm/tag.hpp +++ b/ThirdParty/osmium/osm/tag.hpp @@ -76,7 +76,7 @@ namespace osmium { static constexpr item_type collection_type = item_type::tag_list; - const char* key() const { + const char* key() const noexcept { return reinterpret_cast(data()); } diff --git a/ThirdParty/osmium/osm/timestamp.hpp b/ThirdParty/osmium/osm/timestamp.hpp index 7e25f83e8..662b61f5b 100644 --- a/ThirdParty/osmium/osm/timestamp.hpp +++ b/ThirdParty/osmium/osm/timestamp.hpp @@ -67,13 +67,13 @@ namespace osmium { public: - constexpr Timestamp() : + constexpr Timestamp() noexcept : m_timestamp(0) { } // Not "explicit" so that conversions from time_t work // like in node.timestamp(123); - constexpr Timestamp(time_t timestamp) : + constexpr Timestamp(time_t timestamp) noexcept : m_timestamp(static_cast(timestamp)) { } @@ -82,7 +82,7 @@ namespace osmium { * Throws std::invalid_argument, if the timestamp can not be parsed. */ explicit Timestamp(const char* timestamp) { -#ifndef WIN32 +#ifndef _WIN32 struct tm tm { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -105,14 +105,24 @@ namespace osmium { #endif } - constexpr time_t seconds_since_epoch() const { + constexpr time_t seconds_since_epoch() const noexcept { return static_cast(m_timestamp); } - constexpr operator time_t() const { + constexpr operator time_t() const noexcept { return static_cast(m_timestamp); } + template + void operator+=(T time_difference) noexcept { + m_timestamp += time_difference; + } + + template + void operator-=(T time_difference) noexcept { + m_timestamp -= time_difference; + } + /** * Return UTC Unix time as string in ISO date/time format. */ @@ -140,11 +150,11 @@ namespace osmium { }; // class Timestamp - inline OSMIUM_CONSTEXPR Timestamp start_of_time() { + inline OSMIUM_CONSTEXPR Timestamp start_of_time() noexcept { return Timestamp(1); } - inline OSMIUM_CONSTEXPR Timestamp end_of_time() { + inline OSMIUM_CONSTEXPR Timestamp end_of_time() noexcept { return Timestamp(std::numeric_limits::max()); } diff --git a/ThirdParty/osmium/osm/undirected_segment.hpp b/ThirdParty/osmium/osm/undirected_segment.hpp index 8805162ec..487e7bf32 100644 --- a/ThirdParty/osmium/osm/undirected_segment.hpp +++ b/ThirdParty/osmium/osm/undirected_segment.hpp @@ -71,19 +71,19 @@ namespace osmium { * segment. The first() location is checked first() and only if they have the * same first() location the second() location is taken into account. */ - inline bool operator<(const UndirectedSegment& lhs, const UndirectedSegment& rhs) { + inline bool operator<(const UndirectedSegment& lhs, const UndirectedSegment& rhs) noexcept { return (lhs.first() == rhs.first() && lhs.second() < rhs.second()) || lhs.first() < rhs.first(); } - inline bool operator>(const UndirectedSegment& lhs, const UndirectedSegment& rhs) { + inline bool operator>(const UndirectedSegment& lhs, const UndirectedSegment& rhs) noexcept { return rhs < lhs; } - inline bool operator<=(const UndirectedSegment& lhs, const UndirectedSegment& rhs) { + inline bool operator<=(const UndirectedSegment& lhs, const UndirectedSegment& rhs) noexcept { return ! (rhs < lhs); } - inline bool operator>=(const UndirectedSegment& lhs, const UndirectedSegment& rhs) { + inline bool operator>=(const UndirectedSegment& lhs, const UndirectedSegment& rhs) noexcept { return ! (lhs < rhs); } diff --git a/ThirdParty/osmium/osm/way.hpp b/ThirdParty/osmium/osm/way.hpp index c55698c21..a30cf911f 100644 --- a/ThirdParty/osmium/osm/way.hpp +++ b/ThirdParty/osmium/osm/way.hpp @@ -1,115 +1,115 @@ -#ifndef OSMIUM_OSM_WAY_HPP -#define OSMIUM_OSM_WAY_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include -#include -#include - -namespace osmium { - - namespace builder { - template class ObjectBuilder; - } - - /** - * List of node references (id and location) in a way. - */ - class WayNodeList : public NodeRefList { - - public: - - WayNodeList(): - NodeRefList() { - } - - }; // class WayNodeList - - static_assert(sizeof(WayNodeList) % osmium::memory::align_bytes == 0, "Class osmium::WayNodeList has wrong size to be aligned properly!"); - - class Way : public OSMObject { - - friend class osmium::builder::ObjectBuilder; - - Way() : - OSMObject(sizeof(Way), osmium::item_type::way) { - } - - public: - - WayNodeList& nodes() { - return subitem_of_type(); - } - - const WayNodeList& nodes() const { - return subitem_of_type(); - } - - /** - * Update all nodes in a way with the ID of the given NodeRef with the - * location of the given NodeRef. - */ - void update_node_location(const NodeRef& new_node_ref) { - for (auto& node_ref : nodes()) { - if (node_ref.ref() == new_node_ref.ref()) { - node_ref.location(new_node_ref.location()); - } - } - } - - /** - * Do the nodes in this way form a closed ring? - */ - bool is_closed() const { - return nodes().is_closed(); - } - - bool ends_have_same_id() const { - return nodes().ends_have_same_id(); - } - - bool ends_have_same_location() const { - return nodes().ends_have_same_location(); - } - - }; // class Way - - static_assert(sizeof(Way) % osmium::memory::align_bytes == 0, "Class osmium::Way has wrong size to be aligned properly!"); - -} // namespace osmium - -#endif // OSMIUM_OSM_WAY_HPP +#ifndef OSMIUM_OSM_WAY_HPP +#define OSMIUM_OSM_WAY_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include +#include +#include +#include + +namespace osmium { + + namespace builder { + template class ObjectBuilder; + } + + /** + * List of node references (id and location) in a way. + */ + class WayNodeList : public NodeRefList { + + public: + + WayNodeList(): + NodeRefList() { + } + + }; // class WayNodeList + + static_assert(sizeof(WayNodeList) % osmium::memory::align_bytes == 0, "Class osmium::WayNodeList has wrong size to be aligned properly!"); + + class Way : public OSMObject { + + friend class osmium::builder::ObjectBuilder; + + Way() noexcept : + OSMObject(sizeof(Way), osmium::item_type::way) { + } + + public: + + WayNodeList& nodes() { + return osmium::detail::subitem_of_type(begin(), end()); + } + + const WayNodeList& nodes() const { + return osmium::detail::subitem_of_type(cbegin(), cend()); + } + + /** + * Update all nodes in a way with the ID of the given NodeRef with the + * location of the given NodeRef. + */ + void update_node_location(const NodeRef& new_node_ref) { + for (auto& node_ref : nodes()) { + if (node_ref.ref() == new_node_ref.ref()) { + node_ref.set_location(new_node_ref.location()); + } + } + } + + /** + * Do the nodes in this way form a closed ring? + */ + bool is_closed() const { + return nodes().is_closed(); + } + + bool ends_have_same_id() const { + return nodes().ends_have_same_id(); + } + + bool ends_have_same_location() const { + return nodes().ends_have_same_location(); + } + + }; // class Way + + static_assert(sizeof(Way) % osmium::memory::align_bytes == 0, "Class osmium::Way has wrong size to be aligned properly!"); + +} // namespace osmium + +#endif // OSMIUM_OSM_WAY_HPP diff --git a/ThirdParty/osmium/relations/collector.hpp b/ThirdParty/osmium/relations/collector.hpp index cc7a5964e..8d3bb9150 100644 --- a/ThirdParty/osmium/relations/collector.hpp +++ b/ThirdParty/osmium/relations/collector.hpp @@ -1,535 +1,542 @@ -#ifndef OSMIUM_RELATIONS_COLLECTOR_HPP -#define OSMIUM_RELATIONS_COLLECTOR_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include // IWYU pragma: keep -#include -#include -#include -#include - -#include -#include - -namespace osmium { - - class Node; - class Way; - - /** - * @brief Code related to the assembly of OSM relations - */ - namespace relations { - - /** - * The Collector class collects members of a relation. This is a generic - * base class that can be used to assemble all kinds of relations. It has numerous - * hooks you can implement in derived classes to customize its behaviour. - * - * The collector provides two handlers (HandlerPass1 and HandlerPass2) for a first - * and second pass through an input file, respectively. In the first pass all - * relations we are interested in are stored in RelationMeta objects in the - * m_relations vector. All members we are interested in are stored in MemberMeta - * objects in the m_member_meta vectors. - * The MemberMeta objects also store the information where the relations containing - * those members are to be found. - * - * Later the m_member_meta vectors are sorted according to the - * member ids so that a binary search (with std::equal_range) can be used in the second - * pass to find the parent relations for each node, way, or relation coming along. - * The member objects are stored together with their relation and once a relation - * is complete the complete_relation() method is called which you must overwrite in - * a derived class of Collector. - * - * @tparam TCollector Derived class of this class. - * - * @tparam TNodes Are we interested in member nodes? - * - * @tparam TWays Are we interested in member ways? - * - * @tparam TRelations Are we interested in member relations? - */ - template - class Collector { - - /** - * This is the handler class for the first pass of the Collector. - */ - class HandlerPass1 : public osmium::handler::Handler { - - TCollector& m_collector; - - public: - - HandlerPass1(TCollector& collector) : - m_collector(collector) { - } - - void relation(const osmium::Relation& relation) { - if (m_collector.keep_relation(relation)) { - m_collector.add_relation(relation); - } - } - - }; // class HandlerPass1 - - /** - * This is the handler class for the second pass of the Collector. - */ - class HandlerPass2 : public osmium::handler::Handler { - - TCollector& m_collector; - - /** - * This variable is initialized with the number of different - * kinds of OSM objects we are interested in. If we only need - * way members (for instance for the multipolygon collector) - * it is intialized with 1 for instance. If node and way - * members are needed, it is initialized with 2. - * - * In the after_* methods of this handler, it is decremented - * and once it reaches 0, we know we have all members available - * that we are ever going to get. - */ - int m_want_types; - - /** - * Find this object in the member vectors and add it to all - * relations that need it. - * - * @returns true if the member was added to at least one - * relation and false otherwise - */ - bool find_and_add_object(const osmium::OSMObject& object) { - auto& mmv = m_collector.member_meta(object.type()); - auto range = std::equal_range(mmv.begin(), mmv.end(), MemberMeta(object.id())); - - if (range.first == range.second) { - // nothing found - return false; - } - - { - const size_t member_offset = m_collector.members_buffer().committed(); - m_collector.members_buffer().add_item(object); - m_collector.members_buffer().commit(); - - for (auto it = range.first; it != range.second; ++it) { - it->buffer_offset(member_offset); - } - } - - for (auto it = range.first; it != range.second; ++it) { - MemberMeta& member_meta = *it; - assert(member_meta.member_id() == object.id()); - assert(member_meta.relation_pos() < m_collector.m_relations.size()); - RelationMeta& relation_meta = m_collector.m_relations[member_meta.relation_pos()]; -// std::cerr << " => " << member_meta.member_pos() << " < " << m_collector.get_relation(relation_meta).members().size() << " (id=" << m_collector.get_relation(relation_meta).id() << ")\n"; - assert(member_meta.member_pos() < m_collector.get_relation(relation_meta).members().size()); -// std::cerr << " add way " << member_meta.member_id() << " to rel " << m_collector.get_relation(relation_meta).id() << " at pos " << member_meta.member_pos() << "\n"; - relation_meta.got_one_member(); - if (relation_meta.has_all_members()) { - const size_t relation_offset = member_meta.relation_pos(); - m_collector.complete_relation(relation_meta); - m_collector.m_relations[relation_offset] = RelationMeta(); - m_collector.possibly_purge_removed_members(); - } - } - - return true; - } - - public: - - HandlerPass2(TCollector& collector) : - m_collector(collector), - m_want_types((TNodes?1:0) + (TWays?1:0) + (TRelations?1:0)) { - } - - void node(const osmium::Node& node) { - if (TNodes) { - if (! find_and_add_object(node)) { - m_collector.node_not_in_any_relation(node); - } - } - } - - void way(const osmium::Way& way) { - if (TWays) { - if (! find_and_add_object(way)) { - m_collector.way_not_in_any_relation(way); - } - } - } - - void relation(const osmium::Relation& relation) { - if (TRelations) { - if (! find_and_add_object(relation)) { - m_collector.relation_not_in_any_relation(relation); - } - } - } - - void flush() { - m_collector.flush(); - } - - }; // class HandlerPass2 - - HandlerPass2 m_handler_pass2; - - // All relations we are interested in will be kept in this buffer - osmium::memory::Buffer m_relations_buffer; - - // All members we are interested in will be kept in this buffer - osmium::memory::Buffer m_members_buffer; - - /// Vector with all relations we are interested in - std::vector m_relations; - - /** - * One vector each for nodes, ways, and relations containing all - * mappings from member ids to their relations. - */ - std::vector m_member_meta[3]; - - int m_count_complete = 0; - - typedef std::function callback_func_type; - callback_func_type m_callback; - - static constexpr size_t initial_buffer_size = 1024 * 1024; - - public: - - /** - * Create an Collector. - */ - Collector() : - m_handler_pass2(*static_cast(this)), - m_relations_buffer(initial_buffer_size, osmium::memory::Buffer::auto_grow::yes), - m_members_buffer(initial_buffer_size, osmium::memory::Buffer::auto_grow::yes), - m_relations(), - m_member_meta() { - } - - protected: - - std::vector& member_meta(const item_type type) { - return m_member_meta[static_cast(type) - 1]; - } - - callback_func_type callback() { - return m_callback; - } - - const std::vector& relations() const { - return m_relations; - } - - /** - * This method is called from the first pass handler for every - * relation in the input, to check whether it should be kept. - * - * Overwrite this method in a child class to only add relations - * you are interested in, for instance depending on the type tag. - * Storing relations takes a lot of memory, so it makes sense to - * filter this as much as possible. - */ - bool keep_relation(const osmium::Relation& /*relation*/) const { - return true; - } - - /** - * This method is called for every member of every relation that - * should be kept. It should decide if the member is interesting or - * not and return true or false to signal that. Only interesting - * members are later added to the relation. - * - * Overwrite this method in a child class. In the MultiPolygonCollector - * this is for instance used to only keep members of type way and - * ignore all others. - */ - bool keep_member(const osmium::relations::RelationMeta& /*relation_meta*/, const osmium::RelationMember& /*member*/) const { - return true; - } - - /** - * This method is called for all nodes that are not a member of - * any relation. - * - * Overwrite this method in a child class if you are interested - * in this. - */ - void node_not_in_any_relation(const osmium::Node& /*node*/) { - } - - /** - * This method is called for all ways that are not a member of - * any relation. - * - * Overwrite this method in a child class if you are interested - * in this. - */ - void way_not_in_any_relation(const osmium::Way& /*way*/) { - } - - /** - * This method is called for all relations that are not a member of - * any relation. - * - * Overwrite this method in a child class if you are interested - * in this. - */ - void relation_not_in_any_relation(const osmium::Relation& /*relation*/) { - } - - /** - * This method is called from the 2nd pass handler when all objects - * of types we are interested in have been seen. - * - * Overwrite this method in a child class if you are interested - * in this. - * - * Note that even after this call members might be missing if they - * were not in the input file! The derived class has to handle this - * case. - */ - void flush() { - } - - /** - * This removes all relations that have already been assembled - * from the m_relations vector. - */ - void clean_assembled_relations() { - m_relations.erase( - std::remove_if(m_relations.begin(), m_relations.end(), has_all_members()), - m_relations.end() - ); - } - - const osmium::Relation& get_relation(size_t offset) const { - return m_relations_buffer.get(offset); - } - - /** - * Get the relation from a relation_meta. - */ - const osmium::Relation& get_relation(const RelationMeta& relation_meta) const { - return get_relation(relation_meta.relation_offset()); - } - - osmium::OSMObject& get_member(size_t offset) const { - return m_members_buffer.get(offset); - } - - /** - * Tell the Collector that you are interested in this relation - * and want it kept until all members have been assembled and - * it is handed back to you. - * - * The relation is copied and stored in a buffer inside the - * collector. - */ - void add_relation(const osmium::Relation& relation) { - const size_t offset = m_relations_buffer.committed(); - m_relations_buffer.add_item(relation); - - RelationMeta relation_meta(offset); - - int n=0; - for (auto& member : m_relations_buffer.get(offset).members()) { - if (static_cast(this)->keep_member(relation_meta, member)) { - member_meta(member.type()).emplace_back(member.ref(), m_relations.size(), n); - relation_meta.increment_need_members(); - } else { - member.ref(0); // set member id to zero to indicate we are not interested - } - ++n; - } - - assert(offset == m_relations_buffer.committed()); - if (relation_meta.has_all_members()) { - m_relations_buffer.rollback(); - } else { - m_relations_buffer.commit(); - m_relations.push_back(std::move(relation_meta)); -// std::cerr << "added relation id=" << relation.id() << "\n"; - } - } - - /** - * Sort the vectors with the member infos so that we can do binary - * search on them. - */ - void sort_member_meta() { -/* std::cerr << "relations: " << m_relations.size() << "\n"; - std::cerr << "node members: " << m_member_meta[0].size() << "\n"; - std::cerr << "way members: " << m_member_meta[1].size() << "\n"; - std::cerr << "relation members: " << m_member_meta[2].size() << "\n";*/ - std::sort(m_member_meta[0].begin(), m_member_meta[0].end()); - std::sort(m_member_meta[1].begin(), m_member_meta[1].end()); - std::sort(m_member_meta[2].begin(), m_member_meta[2].end()); - } - - public: - - uint64_t used_memory() const { - const uint64_t nmembers = m_member_meta[0].capacity() + m_member_meta[1].capacity() + m_member_meta[2].capacity(); - const uint64_t members = nmembers * sizeof(MemberMeta); - const uint64_t relations = m_relations.capacity() * sizeof(RelationMeta); - const uint64_t relations_buffer_capacity = m_relations_buffer.capacity(); - const uint64_t members_buffer_capacity = m_members_buffer.capacity(); - - std::cout << " nR = m_relations.capacity() ........... = " << std::setw(12) << m_relations.capacity() << "\n"; - std::cout << " nMN = m_member_meta[NODE].capacity() ... = " << std::setw(12) << m_member_meta[0].capacity() << "\n"; - std::cout << " nMW = m_member_meta[WAY].capacity() .... = " << std::setw(12) << m_member_meta[1].capacity() << "\n"; - std::cout << " nMR = m_member_meta[RELATION].capacity() = " << std::setw(12) << m_member_meta[2].capacity() << "\n"; - std::cout << " nM = m_member_meta[*].capacity() ...... = " << std::setw(12) << nmembers << "\n"; - - std::cout << " sRM = sizeof(RelationMeta) ............. = " << std::setw(12) << sizeof(RelationMeta) << "\n"; - std::cout << " sMM = sizeof(MemberMeta) ............... = " << std::setw(12) << sizeof(MemberMeta) << "\n\n"; - - std::cout << " nR * sRM ............................... = " << std::setw(12) << relations << "\n"; - std::cout << " nM * sMM ............................... = " << std::setw(12) << members << "\n"; - std::cout << " relations_buffer_capacity .............. = " << std::setw(12) << relations_buffer_capacity << "\n"; - std::cout << " members_buffer_capacity ................ = " << std::setw(12) << members_buffer_capacity << "\n"; - - const uint64_t total = relations + members + relations_buffer_capacity + members_buffer_capacity; - - std::cout << " total .................................. = " << std::setw(12) << total << "\n"; - std::cout << " =======================================================\n"; - - return relations_buffer_capacity + members_buffer_capacity + relations + members; - } - - /** - * Return reference to second pass handler. - */ - HandlerPass2& handler(const callback_func_type& callback = nullptr) { - m_callback = callback; - return m_handler_pass2; - } - - osmium::memory::Buffer& members_buffer() { - return m_members_buffer; - } - - size_t get_offset(osmium::item_type type, osmium::object_id_type id) { - const auto& mmv = member_meta(type); - const auto range = std::equal_range(mmv.cbegin(), mmv.cend(), MemberMeta(id)); - assert(range.first != range.second); - return range.first->buffer_offset(); - } - - template - void read_relations(TIter begin, TIter end) { - HandlerPass1 handler(*static_cast(this)); - osmium::apply(begin, end, handler); - sort_member_meta(); - } - - template - void read_relations(TSource& source) { - read_relations(std::begin(source), std::end(source)); - source.close(); - } - - void moving_in_buffer(size_t old_offset, size_t new_offset) { - const osmium::OSMObject& object = m_members_buffer.get(old_offset); - auto& mmv = member_meta(object.type()); - auto range = std::equal_range(mmv.begin(), mmv.end(), osmium::relations::MemberMeta(object.id())); - for (auto it = range.first; it != range.second; ++it) { - assert(it->buffer_offset() == old_offset); - it->buffer_offset(new_offset); - } - } - - /** - * Decide whether to purge removed members and then do it. - * - * Currently the purging is done every thousand calls. - * This could probably be improved upon. - */ - void possibly_purge_removed_members() { - ++m_count_complete; - if (m_count_complete > 10000) { // XXX - const size_t size_before = m_members_buffer.committed(); - m_members_buffer.purge_removed(this); - const size_t size_after = m_members_buffer.committed(); - double percent = size_before - size_after; - percent /= size_before; - percent *= 100; - std::cerr << "PURGE (size before=" << size_before << " after=" << size_after << " purged=" << (size_before - size_after) << " / " << static_cast(percent) << "%)\n"; - m_count_complete = 0; - } - } - - /** - * Get a vector with pointers to all Relations that could not - * be completed, because members were missing in the input - * data. - * - * Note that these pointers point into memory allocated and - * owned by the Collector object. - */ - std::vector get_incomplete_relations() const { - std::vector relations; - for (const auto& relation_meta : m_relations) { - if (!relation_meta.has_all_members()) { - relations.push_back(&get_relation(relation_meta)); - } - } - return relations; - } - - }; // class Collector - - } // namespace relations - -} // namespace osmium - -#endif // OSMIUM_RELATIONS_COLLECTOR_HPP +#ifndef OSMIUM_RELATIONS_COLLECTOR_HPP +#define OSMIUM_RELATIONS_COLLECTOR_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include // IWYU pragma: keep +#include +#include +#include +#include + +#include +#include + +namespace osmium { + + class Node; + class Way; + + /** + * @brief Code related to the assembly of OSM relations + */ + namespace relations { + + /** + * The Collector class collects members of a relation. This is a generic + * base class that can be used to assemble all kinds of relations. It has numerous + * hooks you can implement in derived classes to customize its behaviour. + * + * The collector provides two handlers (HandlerPass1 and HandlerPass2) for a first + * and second pass through an input file, respectively. In the first pass all + * relations we are interested in are stored in RelationMeta objects in the + * m_relations vector. All members we are interested in are stored in MemberMeta + * objects in the m_member_meta vectors. + * The MemberMeta objects also store the information where the relations containing + * those members are to be found. + * + * Later the m_member_meta vectors are sorted according to the + * member ids so that a binary search (with std::equal_range) can be used in the second + * pass to find the parent relations for each node, way, or relation coming along. + * The member objects are stored together with their relation and once a relation + * is complete the complete_relation() method is called which you must overwrite in + * a derived class of Collector. + * + * @tparam TCollector Derived class of this class. + * + * @tparam TNodes Are we interested in member nodes? + * + * @tparam TWays Are we interested in member ways? + * + * @tparam TRelations Are we interested in member relations? + */ + template + class Collector { + + /** + * This is the handler class for the first pass of the Collector. + */ + class HandlerPass1 : public osmium::handler::Handler { + + TCollector& m_collector; + + public: + + HandlerPass1(TCollector& collector) noexcept : + m_collector(collector) { + } + + void relation(const osmium::Relation& relation) { + if (m_collector.keep_relation(relation)) { + m_collector.add_relation(relation); + } + } + + }; // class HandlerPass1 + + /** + * This is the handler class for the second pass of the Collector. + */ + class HandlerPass2 : public osmium::handler::Handler { + + TCollector& m_collector; + + /** + * This variable is initialized with the number of different + * kinds of OSM objects we are interested in. If we only need + * way members (for instance for the multipolygon collector) + * it is intialized with 1 for instance. If node and way + * members are needed, it is initialized with 2. + * + * In the after_* methods of this handler, it is decremented + * and once it reaches 0, we know we have all members available + * that we are ever going to get. + */ + int m_want_types; + + /** + * Find this object in the member vectors and add it to all + * relations that need it. + * + * @returns true if the member was added to at least one + * relation and false otherwise + */ + bool find_and_add_object(const osmium::OSMObject& object) { + auto& mmv = m_collector.member_meta(object.type()); + auto range = std::equal_range(mmv.begin(), mmv.end(), MemberMeta(object.id())); + + if (osmium::relations::count_not_removed(range.first, range.second) == 0) { + // nothing found + return false; + } + + { + m_collector.members_buffer().add_item(object); + const size_t member_offset = m_collector.members_buffer().commit(); + + for (auto it = range.first; it != range.second; ++it) { + it->set_buffer_offset(member_offset); + } + } + + for (auto it = range.first; it != range.second; ++it) { + MemberMeta& member_meta = *it; + if (member_meta.removed()) { + break; + } + assert(member_meta.member_id() == object.id()); + assert(member_meta.relation_pos() < m_collector.m_relations.size()); + RelationMeta& relation_meta = m_collector.m_relations[member_meta.relation_pos()]; +// std::cerr << " => " << member_meta.member_pos() << " < " << m_collector.get_relation(relation_meta).members().size() << " (id=" << m_collector.get_relation(relation_meta).id() << ")\n"; + assert(member_meta.member_pos() < m_collector.get_relation(relation_meta).members().size()); +// std::cerr << " add way " << member_meta.member_id() << " to rel " << m_collector.get_relation(relation_meta).id() << " at pos " << member_meta.member_pos() << "\n"; + relation_meta.got_one_member(); + if (relation_meta.has_all_members()) { + const size_t relation_offset = member_meta.relation_pos(); + m_collector.complete_relation(relation_meta); + m_collector.m_relations[relation_offset] = RelationMeta(); + m_collector.possibly_purge_removed_members(); + } + } + + // Remove MemberMetas that were marked as removed. + mmv.erase(std::remove_if(mmv.begin(), mmv.end(), [](MemberMeta& mm) { + return mm.removed(); + }), mmv.end()); + + return true; + } + + public: + + HandlerPass2(TCollector& collector) noexcept : + m_collector(collector), + m_want_types((TNodes?1:0) + (TWays?1:0) + (TRelations?1:0)) { + } + + void node(const osmium::Node& node) { + if (TNodes) { + if (! find_and_add_object(node)) { + m_collector.node_not_in_any_relation(node); + } + } + } + + void way(const osmium::Way& way) { + if (TWays) { + if (! find_and_add_object(way)) { + m_collector.way_not_in_any_relation(way); + } + } + } + + void relation(const osmium::Relation& relation) { + if (TRelations) { + if (! find_and_add_object(relation)) { + m_collector.relation_not_in_any_relation(relation); + } + } + } + + void flush() { + m_collector.flush(); + } + + }; // class HandlerPass2 + + HandlerPass2 m_handler_pass2; + + // All relations we are interested in will be kept in this buffer + osmium::memory::Buffer m_relations_buffer; + + // All members we are interested in will be kept in this buffer + osmium::memory::Buffer m_members_buffer; + + /// Vector with all relations we are interested in + std::vector m_relations; + + /** + * One vector each for nodes, ways, and relations containing all + * mappings from member ids to their relations. + */ + std::vector m_member_meta[3]; + + int m_count_complete = 0; + + typedef std::function callback_func_type; + callback_func_type m_callback; + + static constexpr size_t initial_buffer_size = 1024 * 1024; + + public: + + /** + * Create an Collector. + */ + Collector() : + m_handler_pass2(*static_cast(this)), + m_relations_buffer(initial_buffer_size, osmium::memory::Buffer::auto_grow::yes), + m_members_buffer(initial_buffer_size, osmium::memory::Buffer::auto_grow::yes), + m_relations(), + m_member_meta() { + } + + protected: + + std::vector& member_meta(const item_type type) { + return m_member_meta[static_cast(type) - 1]; + } + + callback_func_type callback() { + return m_callback; + } + + const std::vector& relations() const { + return m_relations; + } + + /** + * This method is called from the first pass handler for every + * relation in the input, to check whether it should be kept. + * + * Overwrite this method in a child class to only add relations + * you are interested in, for instance depending on the type tag. + * Storing relations takes a lot of memory, so it makes sense to + * filter this as much as possible. + */ + bool keep_relation(const osmium::Relation& /*relation*/) const { + return true; + } + + /** + * This method is called for every member of every relation that + * should be kept. It should decide if the member is interesting or + * not and return true or false to signal that. Only interesting + * members are later added to the relation. + * + * Overwrite this method in a child class. In the MultiPolygonCollector + * this is for instance used to only keep members of type way and + * ignore all others. + */ + bool keep_member(const osmium::relations::RelationMeta& /*relation_meta*/, const osmium::RelationMember& /*member*/) const { + return true; + } + + /** + * This method is called for all nodes that are not a member of + * any relation. + * + * Overwrite this method in a child class if you are interested + * in this. + */ + void node_not_in_any_relation(const osmium::Node& /*node*/) { + } + + /** + * This method is called for all ways that are not a member of + * any relation. + * + * Overwrite this method in a child class if you are interested + * in this. + */ + void way_not_in_any_relation(const osmium::Way& /*way*/) { + } + + /** + * This method is called for all relations that are not a member of + * any relation. + * + * Overwrite this method in a child class if you are interested + * in this. + */ + void relation_not_in_any_relation(const osmium::Relation& /*relation*/) { + } + + /** + * This method is called from the 2nd pass handler when all objects + * of types we are interested in have been seen. + * + * Overwrite this method in a child class if you are interested + * in this. + * + * Note that even after this call members might be missing if they + * were not in the input file! The derived class has to handle this + * case. + */ + void flush() { + } + + /** + * This removes all relations that have already been assembled + * from the m_relations vector. + */ + void clean_assembled_relations() { + m_relations.erase( + std::remove_if(m_relations.begin(), m_relations.end(), has_all_members()), + m_relations.end() + ); + } + + const osmium::Relation& get_relation(size_t offset) const { + return m_relations_buffer.get(offset); + } + + /** + * Get the relation from a relation_meta. + */ + const osmium::Relation& get_relation(const RelationMeta& relation_meta) const { + return get_relation(relation_meta.relation_offset()); + } + + osmium::OSMObject& get_member(size_t offset) const { + return m_members_buffer.get(offset); + } + + /** + * Tell the Collector that you are interested in this relation + * and want it kept until all members have been assembled and + * it is handed back to you. + * + * The relation is copied and stored in a buffer inside the + * collector. + */ + void add_relation(const osmium::Relation& relation) { + const size_t offset = m_relations_buffer.committed(); + m_relations_buffer.add_item(relation); + + RelationMeta relation_meta(offset); + + int n=0; + for (auto& member : m_relations_buffer.get(offset).members()) { + if (static_cast(this)->keep_member(relation_meta, member)) { + member_meta(member.type()).emplace_back(member.ref(), m_relations.size(), n); + relation_meta.increment_need_members(); + } else { + member.ref(0); // set member id to zero to indicate we are not interested + } + ++n; + } + + assert(offset == m_relations_buffer.committed()); + if (relation_meta.has_all_members()) { + m_relations_buffer.rollback(); + } else { + m_relations_buffer.commit(); + m_relations.push_back(std::move(relation_meta)); +// std::cerr << "added relation id=" << relation.id() << "\n"; + } + } + + /** + * Sort the vectors with the member infos so that we can do binary + * search on them. + */ + void sort_member_meta() { +/* std::cerr << "relations: " << m_relations.size() << "\n"; + std::cerr << "node members: " << m_member_meta[0].size() << "\n"; + std::cerr << "way members: " << m_member_meta[1].size() << "\n"; + std::cerr << "relation members: " << m_member_meta[2].size() << "\n";*/ + std::sort(m_member_meta[0].begin(), m_member_meta[0].end()); + std::sort(m_member_meta[1].begin(), m_member_meta[1].end()); + std::sort(m_member_meta[2].begin(), m_member_meta[2].end()); + } + + public: + + uint64_t used_memory() const { + const uint64_t nmembers = m_member_meta[0].capacity() + m_member_meta[1].capacity() + m_member_meta[2].capacity(); + const uint64_t members = nmembers * sizeof(MemberMeta); + const uint64_t relations = m_relations.capacity() * sizeof(RelationMeta); + const uint64_t relations_buffer_capacity = m_relations_buffer.capacity(); + const uint64_t members_buffer_capacity = m_members_buffer.capacity(); + + std::cout << " nR = m_relations.capacity() ........... = " << std::setw(12) << m_relations.capacity() << "\n"; + std::cout << " nMN = m_member_meta[NODE].capacity() ... = " << std::setw(12) << m_member_meta[0].capacity() << "\n"; + std::cout << " nMW = m_member_meta[WAY].capacity() .... = " << std::setw(12) << m_member_meta[1].capacity() << "\n"; + std::cout << " nMR = m_member_meta[RELATION].capacity() = " << std::setw(12) << m_member_meta[2].capacity() << "\n"; + std::cout << " nM = m_member_meta[*].capacity() ...... = " << std::setw(12) << nmembers << "\n"; + + std::cout << " sRM = sizeof(RelationMeta) ............. = " << std::setw(12) << sizeof(RelationMeta) << "\n"; + std::cout << " sMM = sizeof(MemberMeta) ............... = " << std::setw(12) << sizeof(MemberMeta) << "\n\n"; + + std::cout << " nR * sRM ............................... = " << std::setw(12) << relations << "\n"; + std::cout << " nM * sMM ............................... = " << std::setw(12) << members << "\n"; + std::cout << " relations_buffer_capacity .............. = " << std::setw(12) << relations_buffer_capacity << "\n"; + std::cout << " members_buffer_capacity ................ = " << std::setw(12) << members_buffer_capacity << "\n"; + + const uint64_t total = relations + members + relations_buffer_capacity + members_buffer_capacity; + + std::cout << " total .................................. = " << std::setw(12) << total << "\n"; + std::cout << " =======================================================\n"; + + return relations_buffer_capacity + members_buffer_capacity + relations + members; + } + + /** + * Return reference to second pass handler. + */ + HandlerPass2& handler(const callback_func_type& callback = nullptr) { + m_callback = callback; + return m_handler_pass2; + } + + osmium::memory::Buffer& members_buffer() { + return m_members_buffer; + } + + size_t get_offset(osmium::item_type type, osmium::object_id_type id) { + const auto& mmv = member_meta(type); + const auto range = std::equal_range(mmv.cbegin(), mmv.cend(), MemberMeta(id)); + assert(range.first != range.second); + return range.first->buffer_offset(); + } + + template + void read_relations(TIter begin, TIter end) { + HandlerPass1 handler(*static_cast(this)); + osmium::apply(begin, end, handler); + sort_member_meta(); + } + + template + void read_relations(TSource& source) { + read_relations(std::begin(source), std::end(source)); + source.close(); + } + + void moving_in_buffer(size_t old_offset, size_t new_offset) { + const osmium::OSMObject& object = m_members_buffer.get(old_offset); + auto& mmv = member_meta(object.type()); + auto range = std::equal_range(mmv.begin(), mmv.end(), osmium::relations::MemberMeta(object.id())); + for (auto it = range.first; it != range.second; ++it) { + assert(it->buffer_offset() == old_offset); + it->set_buffer_offset(new_offset); + } + } + + /** + * Decide whether to purge removed members and then do it. + * + * Currently the purging is done every thousand calls. + * This could probably be improved upon. + */ + void possibly_purge_removed_members() { + ++m_count_complete; + if (m_count_complete > 10000) { // XXX + const size_t size_before = m_members_buffer.committed(); + m_members_buffer.purge_removed(this); + const size_t size_after = m_members_buffer.committed(); + double percent = size_before - size_after; + percent /= size_before; + percent *= 100; + std::cerr << "PURGE (size before=" << size_before << " after=" << size_after << " purged=" << (size_before - size_after) << " / " << static_cast(percent) << "%)\n"; + m_count_complete = 0; + } + } + + /** + * Get a vector with pointers to all Relations that could not + * be completed, because members were missing in the input + * data. + * + * Note that these pointers point into memory allocated and + * owned by the Collector object. + */ + std::vector get_incomplete_relations() const { + std::vector relations; + for (const auto& relation_meta : m_relations) { + if (!relation_meta.has_all_members()) { + relations.push_back(&get_relation(relation_meta)); + } + } + return relations; + } + + }; // class Collector + + } // namespace relations + +} // namespace osmium + +#endif // OSMIUM_RELATIONS_COLLECTOR_HPP diff --git a/ThirdParty/osmium/relations/detail/member_meta.hpp b/ThirdParty/osmium/relations/detail/member_meta.hpp index f6105e559..5463a1cb8 100644 --- a/ThirdParty/osmium/relations/detail/member_meta.hpp +++ b/ThirdParty/osmium/relations/detail/member_meta.hpp @@ -1,131 +1,158 @@ -#ifndef OSMIUM_RELATIONS_DETAIL_MEMBER_META_HPP -#define OSMIUM_RELATIONS_DETAIL_MEMBER_META_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include - -#include - -namespace osmium { - - namespace relations { - - /** - * Helper class for the Collector class. - * - * Stores an object ID and information where the object should be - * stored. - */ - class MemberMeta { - - /** - * Object ID of this relation member. Can be a node, way, or relation ID. - * It depends on the vector in which this object is stored which kind of - * object is referenced here. - */ - osmium::object_id_type m_member_id; - - /** - * Position of the relation this member is a part of in the - * m_relations vector. - */ - size_t m_relation_pos; - - /** - * Position of this member in the list of members of the - * relation this member is a part of. - */ - size_t m_member_pos; - - /** - * Offset in the buffer where the object is stored. - */ - size_t m_buffer_offset { 0 }; - - public: - - /** - * Create new MemberMeta. The variant with zeros for relation_pos and - * member_pos is used to create dummy MemberMeta that can be compared - * to the MemberMeta in the vectors using the equal_range algorithm. - */ - explicit MemberMeta(osmium::object_id_type member_id, size_t relation_pos=0, size_t member_pos=0) : - m_member_id(member_id), - m_relation_pos(relation_pos), - m_member_pos(member_pos) { - } - - osmium::object_id_type member_id() const { - return m_member_id; - } - - size_t relation_pos() const { - return m_relation_pos; - } - - size_t member_pos() const { - return m_member_pos; - } - - size_t buffer_offset() const { - return m_buffer_offset; - } - - void buffer_offset(size_t offset) { - m_buffer_offset = offset; - } - - }; // class MemberMeta - - /** - * Compares two MemberMeta objects by only looking at the member id. - * Used to sort a vector of MemberMeta objects and to later find - * them using binary search. - */ - inline bool operator<(const MemberMeta& a, const MemberMeta& b) { - return a.member_id() < b.member_id(); - } - - template - inline std::basic_ostream& operator<<(std::basic_ostream& out, const MemberMeta& mm) { - out << "MemberMeta(member_id=" << mm.member_id() << " relation_pos=" << mm.relation_pos() << " member_pos=" << mm.member_pos() << " buffer_offset=" << mm.buffer_offset() << ")"; - return out; - } - - } // namespace relations - -} // namespace osmium - -#endif // OSMIUM_RELATIONS_DETAIL_MEMBER_META_HPP +#ifndef OSMIUM_RELATIONS_DETAIL_MEMBER_META_HPP +#define OSMIUM_RELATIONS_DETAIL_MEMBER_META_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include +#include + +#include + +namespace osmium { + + namespace relations { + + /** + * Helper class for the Collector class. + * + * Stores an object ID and information where the object should be + * stored. + */ + class MemberMeta { + + /** + * Object ID of this relation member. Can be a node, way, or relation ID. + * It depends on the vector in which this object is stored which kind of + * object is referenced here. + */ + osmium::object_id_type m_member_id; + + /** + * Position of the relation this member is a part of in the + * m_relations vector. + */ + size_t m_relation_pos; + + /** + * Position of this member in the list of members of the + * relation this member is a part of. + */ + size_t m_member_pos; + + /** + * Offset in the buffer where the object is stored. + */ + size_t m_buffer_offset { 0 }; + + bool m_removed = false; + + public: + + /** + * Create new MemberMeta. The variant with zeros for relation_pos and + * member_pos is used to create dummy MemberMeta that can be compared + * to the MemberMeta in the vectors using the equal_range algorithm. + */ + explicit MemberMeta(osmium::object_id_type member_id, size_t relation_pos=0, size_t member_pos=0) noexcept : + m_member_id(member_id), + m_relation_pos(relation_pos), + m_member_pos(member_pos) { + } + + osmium::object_id_type member_id() const noexcept { + return m_member_id; + } + + size_t relation_pos() const noexcept { + return m_relation_pos; + } + + size_t member_pos() const noexcept { + return m_member_pos; + } + + size_t buffer_offset() const noexcept { + return m_buffer_offset; + } + + void set_buffer_offset(size_t offset) noexcept { + m_buffer_offset = offset; + } + + bool removed() const noexcept { + return m_removed; + } + + void remove() noexcept { + m_removed = true; + } + + }; // class MemberMeta + + /** + * Compares two MemberMeta objects by only looking at the member id. + * Used to sort a vector of MemberMeta objects and to later find + * them using binary search. + */ + inline bool operator<(const MemberMeta& a, const MemberMeta& b) noexcept { + return a.member_id() < b.member_id(); + } + + template + inline std::basic_ostream& operator<<(std::basic_ostream& out, const MemberMeta& mm) { + out << "MemberMeta(member_id=" << mm.member_id() << " relation_pos=" << mm.relation_pos() << " member_pos=" << mm.member_pos() << " buffer_offset=" << mm.buffer_offset() << ")"; + return out; + } + + /** + * Count the number of MemberMeta objects in the iterator range + * that are not marked as removed. + * + * @tparam TIter Iterator that dereferences to a MemberMeta + * @param begin Begin of iterator range + * @param end End of iterator range + */ + template + inline typename std::iterator_traits::difference_type count_not_removed(TIter begin, TIter end) { + return std::count_if(begin, end, [](MemberMeta& mm) { + return !mm.removed(); + }); + } + + } // namespace relations + +} // namespace osmium + +#endif // OSMIUM_RELATIONS_DETAIL_MEMBER_META_HPP diff --git a/ThirdParty/osmium/relations/detail/relation_meta.hpp b/ThirdParty/osmium/relations/detail/relation_meta.hpp index a9b184ea6..77ca0c130 100644 --- a/ThirdParty/osmium/relations/detail/relation_meta.hpp +++ b/ThirdParty/osmium/relations/detail/relation_meta.hpp @@ -1,136 +1,136 @@ -#ifndef OSMIUM_RELATIONS_DETAIL_RELATION_META_HPP -#define OSMIUM_RELATIONS_DETAIL_RELATION_META_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include - -namespace osmium { - - namespace relations { - - /** - * Helper class for the Collector class. - * - * Stores information needed to collect all members of a relation. This - * includes the offset of the relation in a buffer plus the information - * needed to add members to this relation. - */ - class RelationMeta { - - /// The relation we are assembling. - size_t m_relation_offset; - - /** - * The number of members still needed before the relation is complete. - * This will be set to the number of members we are interested in and - * then count down for every member we find. When it is 0, the relation - * is complete. - */ - int m_need_members = 0; - - public: - - /** - * Initialize an empty RelationMeta. This is needed to zero out relations - * that have been completed. - */ - RelationMeta() : - m_relation_offset(0) { - } - - explicit RelationMeta(size_t relation_offset) : - m_relation_offset(relation_offset) { - } - - /** - * Get offset of relation in buffer. - */ - size_t relation_offset() const { - return m_relation_offset; - } - - /** - * Increment the m_need_members counter. - */ - void increment_need_members() { - ++m_need_members; - } - - /** - * This decrements the "members needed" counter. - */ - void got_one_member() { - assert(m_need_members > 0); - --m_need_members; - } - - /** - * Returns true if all members for this relation are available. - */ - bool has_all_members() const { - return m_need_members == 0; - } - - }; // class RelationMeta - - template - inline std::basic_ostream& operator<<(std::basic_ostream& out, const RelationMeta& rm) { - out << "RelationMeta(relation_offset=" << rm.relation_offset() << " has_all_members=" << rm.has_all_members() << ")"; - return out; - } - - /** - * Function object to check if a relation is complete. - */ - struct has_all_members { - - typedef RelationMeta& argument_type; - typedef bool result_type; - - /** - * @return true if this relation is complete, false otherwise. - */ - bool operator()(RelationMeta& relation_info) const { - return relation_info.has_all_members(); - } - - }; // struct has_all_members - - } // namespace relations - -} // namespace osmium - -#endif // OSMIUM_RELATIONS_DETAIL_RELATION_META_HPP +#ifndef OSMIUM_RELATIONS_DETAIL_RELATION_META_HPP +#define OSMIUM_RELATIONS_DETAIL_RELATION_META_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include + +namespace osmium { + + namespace relations { + + /** + * Helper class for the Collector class. + * + * Stores information needed to collect all members of a relation. This + * includes the offset of the relation in a buffer plus the information + * needed to add members to this relation. + */ + class RelationMeta { + + /// The relation we are assembling. + size_t m_relation_offset; + + /** + * The number of members still needed before the relation is + * complete. This will be set to the number of members we are + * interested in and then count down for every member we find. + * When it is 0, the relation is complete. + */ + int m_need_members = 0; + + public: + + /** + * Initialize an empty RelationMeta. This is needed to zero out + * relations that have been completed. + */ + RelationMeta() noexcept : + m_relation_offset(0) { + } + + explicit RelationMeta(size_t relation_offset) noexcept : + m_relation_offset(relation_offset) { + } + + /** + * Get offset of relation in buffer. + */ + size_t relation_offset() const noexcept { + return m_relation_offset; + } + + /** + * Increment the m_need_members counter. + */ + void increment_need_members() noexcept { + ++m_need_members; + } + + /** + * This decrements the "members needed" counter. + */ + void got_one_member() { + assert(m_need_members > 0); + --m_need_members; + } + + /** + * Returns true if all members for this relation are available. + */ + bool has_all_members() const noexcept { + return m_need_members == 0; + } + + }; // class RelationMeta + + template + inline std::basic_ostream& operator<<(std::basic_ostream& out, const RelationMeta& rm) { + out << "RelationMeta(relation_offset=" << rm.relation_offset() << " has_all_members=" << rm.has_all_members() << ")"; + return out; + } + + /** + * Function object to check if a relation is complete. + */ + struct has_all_members { + + typedef RelationMeta& argument_type; + typedef bool result_type; + + /** + * @returns true if this relation is complete, false otherwise. + */ + bool operator()(RelationMeta& relation_info) const { + return relation_info.has_all_members(); + } + + }; // struct has_all_members + + } // namespace relations + +} // namespace osmium + +#endif // OSMIUM_RELATIONS_DETAIL_RELATION_META_HPP diff --git a/ThirdParty/osmium/tags/filter.hpp b/ThirdParty/osmium/tags/filter.hpp index a55dcf718..0a0fd3b56 100644 --- a/ThirdParty/osmium/tags/filter.hpp +++ b/ThirdParty/osmium/tags/filter.hpp @@ -51,27 +51,27 @@ namespace osmium { bool operator()(const TKey& rule_key, const char* tag_key) { return rule_key == tag_key; } - }; + }; // struct match_key struct match_key_prefix { bool operator()(const std::string& rule_key, const char* tag_key) { return rule_key.compare(0, std::string::npos, tag_key, 0, rule_key.size()) == 0; } - }; + }; // struct match_key_prefix template struct match_value { bool operator()(const TValue& rule_value, const char* tag_value) { return rule_value == tag_value; } - }; + }; // struct match_value template <> struct match_value { bool operator()(const bool, const char*) { return true; } - }; + }; // struct match_value template , class TValueComp=match_value> class Filter { @@ -99,7 +99,7 @@ namespace osmium { result(r) { } - }; + }; // struct Rule std::vector m_rules; bool m_default_result; @@ -135,7 +135,7 @@ namespace osmium { return m_default_result; } - }; // Filter + }; // class Filter typedef Filter KeyValueFilter; typedef Filter KeyFilter; diff --git a/ThirdParty/osmium/tags/regex_filter.hpp b/ThirdParty/osmium/tags/regex_filter.hpp index 1f30cba7a..ae2703a30 100644 --- a/ThirdParty/osmium/tags/regex_filter.hpp +++ b/ThirdParty/osmium/tags/regex_filter.hpp @@ -1,58 +1,58 @@ -#ifndef OSMIUM_TAGS_REGEX_FILTER_HPP -#define OSMIUM_TAGS_REGEX_FILTER_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include - -#include - -namespace osmium { - - namespace tags { - - template <> - struct match_value { - bool operator()(const std::regex& rule_value, const char* tag_value) { - return std::regex_match(tag_value, rule_value); - } - }; - - typedef Filter RegexFilter; - - } // namespace tags - -} // namespace osmium - -#endif // OSMIUM_TAGS_REGEX_FILTER_HPP +#ifndef OSMIUM_TAGS_REGEX_FILTER_HPP +#define OSMIUM_TAGS_REGEX_FILTER_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include + +#include + +namespace osmium { + + namespace tags { + + template <> + struct match_value { + bool operator()(const std::regex& rule_value, const char* tag_value) { + return std::regex_match(tag_value, rule_value); + } + }; // struct match_value + + typedef Filter RegexFilter; + + } // namespace tags + +} // namespace osmium + +#endif // OSMIUM_TAGS_REGEX_FILTER_HPP diff --git a/ThirdParty/osmium/thread/function_wrapper.hpp b/ThirdParty/osmium/thread/function_wrapper.hpp index ad0d14d49..22043ffb5 100644 --- a/ThirdParty/osmium/thread/function_wrapper.hpp +++ b/ThirdParty/osmium/thread/function_wrapper.hpp @@ -1,104 +1,104 @@ -#ifndef OSMIUM_THREAD_FUNCTION_WRAPPER_HPP -#define OSMIUM_THREAD_FUNCTION_WRAPPER_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include - -namespace osmium { - - namespace thread { - - class function_wrapper { - - struct impl_base { - virtual void call() = 0; - virtual ~impl_base() { - } - }; - - std::unique_ptr impl; - - template - struct impl_type : impl_base { - F m_functor; - - impl_type(F&& functor) : - m_functor(std::move(functor)) { - } - - void call() { - m_functor(); - } - }; - - public: - - // Constructor must not be "explicit" for wrapper - // to work seemlessly. - template - function_wrapper(F&& f) : - impl(new impl_type(std::move(f))) { - } - - void operator()() { - impl->call(); - } - - function_wrapper() = default; - - function_wrapper(function_wrapper&& other) : - impl(std::move(other.impl)) { - } - - function_wrapper& operator=(function_wrapper&& other) { - impl = std::move(other.impl); - return *this; - } - - function_wrapper(const function_wrapper&) = delete; - function_wrapper(function_wrapper&) = delete; - function_wrapper& operator=(const function_wrapper&) = delete; - - explicit operator bool() const { - return static_cast(impl); - } - - }; // class function_wrapper - - } // namespace thread - -} // namespace osmium - -#endif // OSMIUM_THREAD_FUNCTION_WRAPPER_HPP +#ifndef OSMIUM_THREAD_FUNCTION_WRAPPER_HPP +#define OSMIUM_THREAD_FUNCTION_WRAPPER_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include + +namespace osmium { + + namespace thread { + + class function_wrapper { + + struct impl_base { + virtual void call() = 0; + virtual ~impl_base() { + } + }; // struct impl_base + + std::unique_ptr impl; + + template + struct impl_type : impl_base { + F m_functor; + + impl_type(F&& functor) : + m_functor(std::move(functor)) { + } + + void call() { + m_functor(); + } + }; // struct impl_type + + public: + + // Constructor must not be "explicit" for wrapper + // to work seemlessly. + template + function_wrapper(F&& f) : + impl(new impl_type(std::move(f))) { + } + + void operator()() { + impl->call(); + } + + function_wrapper() = default; + + function_wrapper(function_wrapper&& other) : + impl(std::move(other.impl)) { + } + + function_wrapper& operator=(function_wrapper&& other) { + impl = std::move(other.impl); + return *this; + } + + function_wrapper(const function_wrapper&) = delete; + function_wrapper(function_wrapper&) = delete; + function_wrapper& operator=(const function_wrapper&) = delete; + + explicit operator bool() const { + return static_cast(impl); + } + + }; // class function_wrapper + + } // namespace thread + +} // namespace osmium + +#endif // OSMIUM_THREAD_FUNCTION_WRAPPER_HPP diff --git a/ThirdParty/osmium/thread/pool.hpp b/ThirdParty/osmium/thread/pool.hpp index 2e6d6356f..58fd53edd 100644 --- a/ThirdParty/osmium/thread/pool.hpp +++ b/ThirdParty/osmium/thread/pool.hpp @@ -1,180 +1,204 @@ -#ifndef OSMIUM_THREAD_POOL_HPP -#define OSMIUM_THREAD_POOL_HPP - -/* - -This file is part of Osmium (http://osmcode.org/libosmium). - -Copyright 2013,2014 Jochen Topf and others (see README). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace osmium { - - /** - * @brief Threading-related low-level code - */ - namespace thread { - - /** - * Thread pool. - */ - class Pool { - - // This class makes sure pool threads are joined when the pool is destructed - class thread_joiner { - - std::vector& m_threads; - - public: - - explicit thread_joiner(std::vector& threads) : - m_threads(threads) { - } - - ~thread_joiner() { - for (auto& thread : m_threads) { - if (thread.joinable()) { - thread.join(); - } - } - } - - }; // class thread_joiner - - std::atomic m_done; - osmium::thread::Queue m_work_queue; - std::vector m_threads; - thread_joiner m_joiner; - int m_num_threads; - - void worker_thread() { - osmium::thread::set_thread_name("_osmium_worker"); - while (!m_done) { - function_wrapper task; - m_work_queue.wait_and_pop_with_timeout(task); - if (task) { - task(); - } - } - } - - /** - * Create thread pool with the given number of threads. If - * num_threads is 0, the number of threads is read from - * the environment variable OSMIUM_POOL_THREADS. The default - * value in that case is -2. - * - * If the number of threads is a negative number, it will be - * set to the actual number of cores on the system plus the - * given number, ie it will leave a number of cores unused. - * - * In all cases the minimum number of threads in the pool is 1. - */ - explicit Pool(int num_threads) : - m_done(false), - m_work_queue(), - m_threads(), - m_joiner(m_threads), - m_num_threads(num_threads) { - - if (m_num_threads == 0) { - const char* env_threads = getenv("OSMIUM_POOL_THREADS"); - if (env_threads) { - m_num_threads = std::atoi(env_threads); - } else { - m_num_threads = -2; - } - } - - if (m_num_threads <= 0) { - m_num_threads = std::max(1, static_cast(std::thread::hardware_concurrency()) + m_num_threads); - } - - try { - for (int i=0; i < m_num_threads; ++i) { - m_threads.push_back(std::thread(&Pool::worker_thread, this)); - } - } catch (...) { - m_done = true; - throw; - } - } - - public: - - static constexpr int default_num_threads = 0; - - static Pool& instance() { - static Pool pool(default_num_threads); - return pool; - } - - ~Pool() { - m_done = true; - } - - size_t queue_size() const { - return m_work_queue.size(); - } - - bool queue_empty() const { - return m_work_queue.empty(); - } - - template - std::future::type> submit(TFunction f) { - - typedef typename std::result_of::type result_type; - - std::packaged_task task(std::move(f)); - std::future future_result(task.get_future()); - m_work_queue.push(std::move(task)); - - return future_result; - } - - }; // class Pool - - } // namespace thread - -} // namespace osmium - -#endif // OSMIUM_THREAD_POOL_HPP +#ifndef OSMIUM_THREAD_POOL_HPP +#define OSMIUM_THREAD_POOL_HPP + +/* + +This file is part of Osmium (http://osmcode.org/libosmium). + +Copyright 2013,2014 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace osmium { + + /** + * @brief Threading-related low-level code + */ + namespace thread { + + /** + * Thread pool. + */ + class Pool { + + // This class makes sure pool threads are joined when the pool is destructed + class thread_joiner { + + std::vector& m_threads; + + public: + + explicit thread_joiner(std::vector& threads) : + m_threads(threads) { + } + + ~thread_joiner() { + for (auto& thread : m_threads) { + if (thread.joinable()) { + thread.join(); + } + } + } + + }; // class thread_joiner + + std::atomic m_done; + osmium::thread::Queue m_work_queue; + std::vector m_threads; + thread_joiner m_joiner; + int m_num_threads; + + void worker_thread() { + osmium::thread::set_thread_name("_osmium_worker"); + while (!m_done) { + function_wrapper task; + m_work_queue.wait_and_pop_with_timeout(task); + if (task) { + task(); + } + } + } + + /** + * Create thread pool with the given number of threads. If + * num_threads is 0, the number of threads is read from + * the environment variable OSMIUM_POOL_THREADS. The default + * value in that case is -2. + * + * If the number of threads is a negative number, it will be + * set to the actual number of cores on the system plus the + * given number, ie it will leave a number of cores unused. + * + * In all cases the minimum number of threads in the pool is 1. + */ + explicit Pool(int num_threads) : + m_done(false), + m_work_queue(), + m_threads(), + m_joiner(m_threads), + m_num_threads(num_threads) { + + if (m_num_threads == 0) { + const char* env_threads = getenv("OSMIUM_POOL_THREADS"); + if (env_threads) { + m_num_threads = std::atoi(env_threads); + } else { + m_num_threads = -2; + } + } + + if (m_num_threads <= 0) { + m_num_threads = std::max(1, static_cast(std::thread::hardware_concurrency()) + m_num_threads); + } + + try { + for (int i=0; i < m_num_threads; ++i) { + m_threads.push_back(std::thread(&Pool::worker_thread, this)); + } + } catch (...) { + m_done = true; + throw; + } + } + + public: + + static constexpr int default_num_threads = 0; + + static Pool& instance() { + static Pool pool(default_num_threads); + return pool; + } + + ~Pool() { + m_done = true; + } + + size_t queue_size() const { + return m_work_queue.size(); + } + + bool queue_empty() const { + return m_work_queue.empty(); + } + + template + std::future::type> submit(TFunction f) { + + typedef typename std::result_of::type result_type; + + std::packaged_task task(std::move(f)); + std::future future_result(task.get_future()); + m_work_queue.push(std::move(task)); + + return future_result; + } + + }; // class Pool + + /** + * Wrapper for classes that can't be copied but need to be copyable for + * putting them in the pool. + */ + template + class SharedPtrWrapper { + + std::shared_ptr m_task; + + public: + + typedef typename std::result_of::type result_type; + + template + SharedPtrWrapper(TArgs&&... args) : + m_task(std::make_shared(std::forward(args)...)) { + } + + result_type operator()() { + return m_task->operator()(); + } + + }; // class SharedPtrWrapper + + } // namespace thread + +} // namespace osmium + +#endif // OSMIUM_THREAD_POOL_HPP diff --git a/ThirdParty/osmium/util/compatibility.hpp b/ThirdParty/osmium/util/compatibility.hpp index dfd854cc3..48a6db017 100644 --- a/ThirdParty/osmium/util/compatibility.hpp +++ b/ThirdParty/osmium/util/compatibility.hpp @@ -1,5 +1,5 @@ -#ifndef OSMIUM_CONFIG_CONSTEXPR_HPP -#define OSMIUM_CONFIG_CONSTEXPR_HPP +#ifndef OSMIUM_UTIL_COMPATIBILITY_HPP +#define OSMIUM_UTIL_COMPATIBILITY_HPP /* @@ -44,4 +44,4 @@ DEALINGS IN THE SOFTWARE. # define OSMIUM_NORETURN [[noreturn]] #endif -#endif // OSMIUM_CONFIG_CONSTEXPR_HPP +#endif // OSMIUM_UTIL_COMPATIBILITY_HPP diff --git a/ThirdParty/osmium/util/verbose_output.hpp b/ThirdParty/osmium/util/verbose_output.hpp index 9925ceee4..8709441af 100644 --- a/ThirdParty/osmium/util/verbose_output.hpp +++ b/ThirdParty/osmium/util/verbose_output.hpp @@ -87,7 +87,7 @@ namespace osmium { public: - explicit VerboseOutput(bool verbose=false) : + explicit VerboseOutput(bool verbose=false) noexcept : m_start(time(NULL)), m_verbose(verbose), m_newline(true) {