fixing line endings
This commit is contained in:
		
							parent
							
								
									9d1e21b5ad
								
							
						
					
					
						commit
						dc75469e78
					
				
							
								
								
									
										767
									
								
								ThirdParty/osmium/area/assembler.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										767
									
								
								ThirdParty/osmium/area/assembler.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,767 @@ | |||||||
|  | #ifndef OSMIUM_AREA_ASSEMBLER_HPP | ||||||
|  | #define OSMIUM_AREA_ASSEMBLER_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2014 Jochen Topf <jochen@topf.org> 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 <algorithm> | ||||||
|  | #include <iostream> | ||||||
|  | #include <iterator> | ||||||
|  | #include <list> | ||||||
|  | #include <map> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <osmium/builder/osm_object_builder.hpp> | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/osm/area.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/relation.hpp> | ||||||
|  | #include <osmium/tags/filter.hpp> | ||||||
|  | 
 | ||||||
|  | #include <osmium/area/detail/proto_ring.hpp> | ||||||
|  | #include <osmium/area/detail/node_ref_segment.hpp> | ||||||
|  | #include <osmium/area/detail/segment_list.hpp> | ||||||
|  | #include <osmium/area/problem_reporter.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace area { | ||||||
|  | 
 | ||||||
|  |         using osmium::area::detail::ProtoRing; | ||||||
|  | 
 | ||||||
|  |         struct AssemblerConfig { | ||||||
|  | 
 | ||||||
|  |             osmium::area::ProblemReporter* problem_reporter; | ||||||
|  | 
 | ||||||
|  |             // Enables debug output to stderr
 | ||||||
|  |             bool debug; | ||||||
|  | 
 | ||||||
|  |             explicit AssemblerConfig(osmium::area::ProblemReporter* pr = nullptr, bool d=false) : | ||||||
|  |                 problem_reporter(pr), | ||||||
|  |                 debug(d) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Enable or disable debug output to stderr. This is for Osmium | ||||||
|  |              * developers only. | ||||||
|  |              */ | ||||||
|  |             void enable_debug_output(bool d=true) { | ||||||
|  |                 debug = d; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // struct AssemblerConfig
 | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Assembles area objects from multipolygon relations and their | ||||||
|  |          * members. This is called by the MultipolygonCollector object | ||||||
|  |          * after all members have been collected. | ||||||
|  |          */ | ||||||
|  |         class Assembler { | ||||||
|  | 
 | ||||||
|  |             const AssemblerConfig m_config; | ||||||
|  | 
 | ||||||
|  |             // The way segments
 | ||||||
|  |             osmium::area::detail::SegmentList m_segment_list; | ||||||
|  | 
 | ||||||
|  |             // The rings we are building from the way segments
 | ||||||
|  |             std::list<ProtoRing> m_rings {}; | ||||||
|  | 
 | ||||||
|  |             std::vector<ProtoRing*> m_outer_rings {}; | ||||||
|  |             std::vector<ProtoRing*> m_inner_rings {}; | ||||||
|  | 
 | ||||||
|  |             int m_inner_outer_mismatches { 0 }; | ||||||
|  | 
 | ||||||
|  |             bool debug() const { | ||||||
|  |                 return m_config.debug; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Checks whether the given NodeRefs have the same location. | ||||||
|  |              * Uses the actual location for the test, not the id. If both | ||||||
|  |              * have the same location, but not the same id, a problem | ||||||
|  |              * point will be added to the list of problem points. | ||||||
|  |              */ | ||||||
|  |             bool has_same_location(const osmium::NodeRef& nr1, const osmium::NodeRef& nr2) { | ||||||
|  |                 if (nr1.location() != nr2.location()) { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |                 if (nr1.ref() != nr2.ref()) { | ||||||
|  |                     if (m_config.problem_reporter) { | ||||||
|  |                         m_config.problem_reporter->report_duplicate_node(nr1.ref(), nr2.ref(), nr1.location()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void add_tags_to_area(osmium::builder::AreaBuilder& builder, const osmium::Way& way) const { | ||||||
|  |                 osmium::builder::TagListBuilder tl_builder(builder.buffer(), &builder); | ||||||
|  |                 for (const osmium::Tag& tag : way.tags()) { | ||||||
|  |                     tl_builder.add_tag(tag.key(), tag.value()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void add_common_tags(osmium::builder::TagListBuilder& tl_builder, std::set<const osmium::Way*>& ways) const { | ||||||
|  |                 std::map<std::string, size_t> counter; | ||||||
|  |                 for (const osmium::Way* way : ways) { | ||||||
|  |                     for (const auto& tag : way->tags()) { | ||||||
|  |                         std::string kv {tag.key()}; | ||||||
|  |                         kv.append(1, '\0'); | ||||||
|  |                         kv.append(tag.value()); | ||||||
|  |                         ++counter[kv]; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 size_t num_ways = ways.size(); | ||||||
|  |                 for (const auto& t_c : counter) { | ||||||
|  |                     if (debug()) { | ||||||
|  |                         std::cerr << "        tag " << t_c.first << " is used " << t_c.second << " times in " << num_ways << " ways\n"; | ||||||
|  |                     } | ||||||
|  |                     if (t_c.second == num_ways) { | ||||||
|  |                         size_t len = std::strlen(t_c.first.c_str()); | ||||||
|  |                         tl_builder.add_tag(t_c.first.c_str(), t_c.first.c_str() + len + 1); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             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); | ||||||
|  | 
 | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "  found " << count << " tags on relation (without ignored ones)\n"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if (count > 0) { | ||||||
|  |                     if (debug()) { | ||||||
|  |                         std::cerr << "    use tags from relation\n"; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     // write out all tags except type=*
 | ||||||
|  |                     osmium::builder::TagListBuilder tl_builder(builder.buffer(), &builder); | ||||||
|  |                     for (const osmium::Tag& tag : relation.tags()) { | ||||||
|  |                         if (strcmp(tag.key(), "type")) { | ||||||
|  |                             tl_builder.add_tag(tag.key(), tag.value()); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     if (debug()) { | ||||||
|  |                         std::cerr << "    use tags from outer ways\n"; | ||||||
|  |                     } | ||||||
|  |                     std::set<const osmium::Way*> ways; | ||||||
|  |                     for (const auto& ring : m_outer_rings) { | ||||||
|  |                         ring->get_ways(ways); | ||||||
|  |                     } | ||||||
|  |                     if (ways.size() == 1) { | ||||||
|  |                         if (debug()) { | ||||||
|  |                             std::cerr << "      only one outer way\n"; | ||||||
|  |                         } | ||||||
|  |                         osmium::builder::TagListBuilder tl_builder(builder.buffer(), &builder); | ||||||
|  |                         for (const osmium::Tag& tag : (*ways.begin())->tags()) { | ||||||
|  |                             tl_builder.add_tag(tag.key(), tag.value()); | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|  |                         if (debug()) { | ||||||
|  |                             std::cerr << "      multiple outer ways, get common tags\n"; | ||||||
|  |                         } | ||||||
|  |                         osmium::builder::TagListBuilder tl_builder(builder.buffer(), &builder); | ||||||
|  |                         add_common_tags(tl_builder, ways); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Go through all the rings and find rings that are not closed. | ||||||
|  |              * Problems are reported through the problem reporter. | ||||||
|  |              * | ||||||
|  |              * @returns true if any rings were not closed, false otherwise | ||||||
|  |              */ | ||||||
|  |             bool check_for_open_rings() { | ||||||
|  |                 bool open_rings = false; | ||||||
|  | 
 | ||||||
|  |                 for (const auto& ring : m_rings) { | ||||||
|  |                     if (!ring.closed()) { | ||||||
|  |                         open_rings = true; | ||||||
|  |                         if (m_config.problem_reporter) { | ||||||
|  |                             m_config.problem_reporter->report_ring_not_closed(ring.get_segment_front().first().location(), ring.get_segment_back().second().location()); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 return open_rings; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Check whether there are any rings that can be combined with the | ||||||
|  |              * given ring to one larger ring by appending the other ring to | ||||||
|  |              * the end of this ring. | ||||||
|  |              * If the rings can be combined they are and the function returns | ||||||
|  |              * true. | ||||||
|  |              */ | ||||||
|  |             bool possibly_combine_rings_back(ProtoRing& ring) { | ||||||
|  |                 const osmium::NodeRef& nr = ring.get_segment_back().second(); | ||||||
|  | 
 | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "      possibly_combine_rings_back()\n"; | ||||||
|  |                 } | ||||||
|  |                 for (auto it = m_rings.begin(); it != m_rings.end(); ++it) { | ||||||
|  |                     if (&*it != &ring && !it->closed()) { | ||||||
|  |                         if (has_same_location(nr, it->get_segment_front().first())) { | ||||||
|  |                             if (debug()) { | ||||||
|  |                                 std::cerr << "      ring.last=it->first\n"; | ||||||
|  |                             } | ||||||
|  |                             ring.merge_ring(*it, debug()); | ||||||
|  |                             m_rings.erase(it); | ||||||
|  |                             return true; | ||||||
|  |                         } | ||||||
|  |                         if (has_same_location(nr, it->get_segment_back().second())) { | ||||||
|  |                             if (debug()) { | ||||||
|  |                                 std::cerr << "      ring.last=it->last\n"; | ||||||
|  |                             } | ||||||
|  |                             ring.merge_ring_reverse(*it, debug()); | ||||||
|  |                             m_rings.erase(it); | ||||||
|  |                             return true; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Check whether there are any rings that can be combined with the | ||||||
|  |              * given ring to one larger ring by prepending the other ring to | ||||||
|  |              * the start of this ring. | ||||||
|  |              * If the rings can be combined they are and the function returns | ||||||
|  |              * true. | ||||||
|  |              */ | ||||||
|  |             bool possibly_combine_rings_front(ProtoRing& ring) { | ||||||
|  |                 const osmium::NodeRef& nr = ring.get_segment_front().first(); | ||||||
|  | 
 | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "      possibly_combine_rings_front()\n"; | ||||||
|  |                 } | ||||||
|  |                 for (auto it = m_rings.begin(); it != m_rings.end(); ++it) { | ||||||
|  |                     if (&*it != &ring && !it->closed()) { | ||||||
|  |                         if (has_same_location(nr, it->get_segment_back().second())) { | ||||||
|  |                             if (debug()) { | ||||||
|  |                                 std::cerr << "      ring.first=it->last\n"; | ||||||
|  |                             } | ||||||
|  |                             ring.swap_segments(*it); | ||||||
|  |                             ring.merge_ring(*it, debug()); | ||||||
|  |                             m_rings.erase(it); | ||||||
|  |                             return true; | ||||||
|  |                         } | ||||||
|  |                         if (has_same_location(nr, it->get_segment_front().first())) { | ||||||
|  |                             if (debug()) { | ||||||
|  |                                 std::cerr << "      ring.first=it->first\n"; | ||||||
|  |                             } | ||||||
|  |                             ring.reverse(); | ||||||
|  |                             ring.merge_ring(*it, debug()); | ||||||
|  |                             m_rings.erase(it); | ||||||
|  |                             return true; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void split_off_subring(osmium::area::detail::ProtoRing& ring, osmium::area::detail::ProtoRing::segments_type::iterator it, osmium::area::detail::ProtoRing::segments_type::iterator it_begin, osmium::area::detail::ProtoRing::segments_type::iterator it_end) { | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "        subring found at: " << *it << "\n"; | ||||||
|  |                 } | ||||||
|  |                 ProtoRing new_ring(it_begin, it_end); | ||||||
|  |                 ring.remove_segments(it_begin, it_end); | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "        split into two rings:\n"; | ||||||
|  |                     std::cerr << "          " << new_ring << "\n"; | ||||||
|  |                     std::cerr << "          " << ring << "\n"; | ||||||
|  |                 } | ||||||
|  |                 m_rings.push_back(std::move(new_ring)); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool has_closed_subring_back(ProtoRing& ring, const NodeRef& nr) { | ||||||
|  |                 if (ring.segments().size() < 3) { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "      has_closed_subring_back()\n"; | ||||||
|  |                 } | ||||||
|  |                 auto end = ring.segments().end(); | ||||||
|  |                 for (auto it = ring.segments().begin() + 1; it != end - 1; ++it) { | ||||||
|  |                     if (has_same_location(nr, it->first())) { | ||||||
|  |                         split_off_subring(ring, it, it, end); | ||||||
|  |                         return true; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool has_closed_subring_front(ProtoRing& ring, const NodeRef& nr) { | ||||||
|  |                 if (ring.segments().size() < 3) { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "      has_closed_subring_front()\n"; | ||||||
|  |                 } | ||||||
|  |                 auto end = ring.segments().end(); | ||||||
|  |                 for (auto it = ring.segments().begin() + 1; it != end - 1; ++it) { | ||||||
|  |                     if (has_same_location(nr, it->second())) { | ||||||
|  |                         split_off_subring(ring, it, ring.segments().begin(), it+1); | ||||||
|  |                         return true; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool check_for_closed_subring(ProtoRing& ring) { | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "      check_for_closed_subring()\n"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 osmium::area::detail::ProtoRing::segments_type segments(ring.segments().size()); | ||||||
|  |                 std::copy(ring.segments().begin(), ring.segments().end(), segments.begin()); | ||||||
|  |                 std::sort(segments.begin(), segments.end()); | ||||||
|  |                 auto it = std::adjacent_find(segments.begin(), segments.end(), [this](const osmium::area::detail::NodeRefSegment& s1, const osmium::area::detail::NodeRefSegment& s2) { | ||||||
|  |                     return has_same_location(s1.first(), s2.first()); | ||||||
|  |                 }); | ||||||
|  |                 if (it == segments.end()) { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |                 auto r1 = std::find_first_of(ring.segments().begin(), ring.segments().end(), it, it+1); | ||||||
|  |                 assert(r1 != ring.segments().end()); | ||||||
|  |                 auto r2 = std::find_first_of(ring.segments().begin(), ring.segments().end(), it+1, it+2); | ||||||
|  |                 assert(r2 != ring.segments().end()); | ||||||
|  | 
 | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "      found subring in ring " << ring << " at " << it->first() << "\n"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 auto m = std::minmax(r1, r2); | ||||||
|  | 
 | ||||||
|  |                 ProtoRing new_ring(m.first, m.second); | ||||||
|  |                 ring.remove_segments(m.first, m.second); | ||||||
|  | 
 | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "        split ring1=" << new_ring << "\n"; | ||||||
|  |                     std::cerr << "        split ring2=" << ring << "\n"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 m_rings.emplace_back(new_ring); | ||||||
|  | 
 | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void combine_rings_front(const osmium::area::detail::NodeRefSegment& segment, ProtoRing& ring) { | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << " => match at front of ring\n"; | ||||||
|  |                 } | ||||||
|  |                 ring.add_segment_front(segment); | ||||||
|  |                 has_closed_subring_front(ring, segment.first()); | ||||||
|  |                 if (possibly_combine_rings_front(ring)) { | ||||||
|  |                     check_for_closed_subring(ring); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void combine_rings_back(const osmium::area::detail::NodeRefSegment& segment, ProtoRing& ring) { | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << " => match at back of ring\n"; | ||||||
|  |                 } | ||||||
|  |                 ring.add_segment_back(segment); | ||||||
|  |                 has_closed_subring_back(ring, segment.second()); | ||||||
|  |                 if (possibly_combine_rings_back(ring)) { | ||||||
|  |                     check_for_closed_subring(ring); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Append each outer ring together with its inner rings to the | ||||||
|  |              * area in the buffer. | ||||||
|  |              */ | ||||||
|  |             void add_rings_to_area(osmium::builder::AreaBuilder& builder) const { | ||||||
|  |                 for (const ProtoRing* ring : m_outer_rings) { | ||||||
|  |                     if (debug()) { | ||||||
|  |                         std::cerr << "    ring " << *ring << " is outer\n"; | ||||||
|  |                     } | ||||||
|  |                     { | ||||||
|  |                         osmium::builder::OuterRingBuilder ring_builder(builder.buffer(), &builder); | ||||||
|  |                         ring_builder.add_node_ref(ring->get_segment_front().first()); | ||||||
|  |                         for (const auto& segment : ring->segments()) { | ||||||
|  |                             ring_builder.add_node_ref(segment.second()); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     for (ProtoRing* inner : ring->inner_rings()) { | ||||||
|  |                         osmium::builder::InnerRingBuilder ring_builder(builder.buffer(), &builder); | ||||||
|  |                         ring_builder.add_node_ref(inner->get_segment_front().first()); | ||||||
|  |                         for (const auto& segment : inner->segments()) { | ||||||
|  |                             ring_builder.add_node_ref(segment.second()); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool add_to_existing_ring(osmium::area::detail::NodeRefSegment segment) { | ||||||
|  |                 int n=0; | ||||||
|  |                 for (auto& ring : m_rings) { | ||||||
|  |                     if (debug()) { | ||||||
|  |                         std::cerr << "    check against ring " << n << " " << ring; | ||||||
|  |                     } | ||||||
|  |                     if (ring.closed()) { | ||||||
|  |                         if (debug()) { | ||||||
|  |                             std::cerr << " => ring CLOSED\n"; | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|  |                         if (has_same_location(ring.get_segment_back().second(), segment.first())) { | ||||||
|  |                             combine_rings_back(segment, ring); | ||||||
|  |                             return true; | ||||||
|  |                         } | ||||||
|  |                         if (has_same_location(ring.get_segment_back().second(), segment.second())) { | ||||||
|  |                             segment.swap_locations(); | ||||||
|  |                             combine_rings_back(segment, ring); | ||||||
|  |                             return true; | ||||||
|  |                         } | ||||||
|  |                         if (has_same_location(ring.get_segment_front().first(), segment.first())) { | ||||||
|  |                             segment.swap_locations(); | ||||||
|  |                             combine_rings_front(segment, ring); | ||||||
|  |                             return true; | ||||||
|  |                         } | ||||||
|  |                         if (has_same_location(ring.get_segment_front().first(), segment.second())) { | ||||||
|  |                             combine_rings_front(segment, ring); | ||||||
|  |                             return true; | ||||||
|  |                         } | ||||||
|  |                         if (debug()) { | ||||||
|  |                             std::cerr << " => no match\n"; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     ++n; | ||||||
|  |                 } | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void check_inner_outer(ProtoRing& ring) { | ||||||
|  |                 const osmium::NodeRef& min_node = ring.min_node(); | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "    check_inner_outer min_node=" << min_node << "\n"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 int count = 0; | ||||||
|  |                 int above = 0; | ||||||
|  | 
 | ||||||
|  |                 for (auto it = m_segment_list.begin(); it != m_segment_list.end() && it->first().location().x() <= min_node.location().x(); ++it) { | ||||||
|  |                     if (!ring.contains(*it)) { | ||||||
|  |                         if (debug()) { | ||||||
|  |                             std::cerr << "      segments for count: " << *it; | ||||||
|  |                         } | ||||||
|  |                         if (it->to_left_of(min_node.location())) { | ||||||
|  |                             ++count; | ||||||
|  |                             if (debug()) { | ||||||
|  |                                 std::cerr << " counted\n"; | ||||||
|  |                             } | ||||||
|  |                         } else { | ||||||
|  |                             if (debug()) { | ||||||
|  |                                 std::cerr << " not counted\n"; | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         if (it->first().location() == min_node.location()) { | ||||||
|  |                             if (it->second().location().y() > min_node.location().y()) { | ||||||
|  |                                 ++above; | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         if (it->second().location() == min_node.location()) { | ||||||
|  |                             if (it->first().location().y() > min_node.location().y()) { | ||||||
|  |                                 ++above; | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "      count=" << count << " above=" << above << "\n"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 count += above % 2; | ||||||
|  | 
 | ||||||
|  |                 if (count % 2) { | ||||||
|  |                     ring.set_inner(); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void check_inner_outer_roles() { | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "    check_inner_outer_roles\n"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 for (const auto ringptr : m_outer_rings) { | ||||||
|  |                     for (const auto segment : ringptr->segments()) { | ||||||
|  |                         if (!segment.role_outer()) { | ||||||
|  |                             ++m_inner_outer_mismatches; | ||||||
|  |                             if (debug()) { | ||||||
|  |                                 std::cerr << "      segment " << segment << " from way " << segment.way()->id() << " should have role 'outer'\n"; | ||||||
|  |                             } | ||||||
|  |                             if (m_config.problem_reporter) { | ||||||
|  |                                 m_config.problem_reporter->report_role_should_be_outer(segment.way()->id(), segment.first().location(), segment.second().location()); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 for (const auto ringptr : m_inner_rings) { | ||||||
|  |                     for (const auto segment : ringptr->segments()) { | ||||||
|  |                         if (!segment.role_inner()) { | ||||||
|  |                             ++m_inner_outer_mismatches; | ||||||
|  |                             if (debug()) { | ||||||
|  |                                 std::cerr << "      segment " << segment << " from way " << segment.way()->id() << " should have role 'inner'\n"; | ||||||
|  |                             } | ||||||
|  |                             if (m_config.problem_reporter) { | ||||||
|  |                                 m_config.problem_reporter->report_role_should_be_inner(segment.way()->id(), segment.first().location(), segment.second().location()); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Create rings from segments. | ||||||
|  |              */ | ||||||
|  |             bool create_rings() { | ||||||
|  |                 m_segment_list.sort(); | ||||||
|  |                 m_segment_list.erase_duplicate_segments(); | ||||||
|  | 
 | ||||||
|  |                 // Now we look for segments crossing each other. If there are
 | ||||||
|  |                 // any, the multipolygon is invalid.
 | ||||||
|  |                 // In the future this could be improved by trying to fix those
 | ||||||
|  |                 // cases.
 | ||||||
|  |                 if (m_segment_list.find_intersections(m_config.problem_reporter)) { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 // Now iterator over all segments and add them to rings. Each segment
 | ||||||
|  |                 // is tacked on to either end of an existing ring if possible, or a
 | ||||||
|  |                 // new ring is started with it.
 | ||||||
|  |                 for (const auto& segment : m_segment_list) { | ||||||
|  |                     if (debug()) { | ||||||
|  |                         std::cerr << "  checking segment " << segment << "\n"; | ||||||
|  |                     } | ||||||
|  |                     if (!add_to_existing_ring(segment)) { | ||||||
|  |                         if (debug()) { | ||||||
|  |                             std::cerr << "    new ring for segment " << segment << "\n"; | ||||||
|  |                         } | ||||||
|  |                         m_rings.emplace_back(segment); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "  Rings:\n"; | ||||||
|  |                     for (const auto& ring : m_rings) { | ||||||
|  |                         std::cerr << "    " << ring; | ||||||
|  |                         if (ring.closed()) { | ||||||
|  |                             std::cerr << " (closed)"; | ||||||
|  |                         } | ||||||
|  |                         std::cerr << "\n"; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if (check_for_open_rings()) { | ||||||
|  |                     if (debug()) { | ||||||
|  |                         std::cerr << "  not all rings are closed\n"; | ||||||
|  |                     } | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "  Find inner/outer...\n"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if (m_rings.size() == 1) { | ||||||
|  |                     m_outer_rings.push_back(&m_rings.front()); | ||||||
|  |                 } else { | ||||||
|  |                     for (auto& ring : m_rings) { | ||||||
|  |                         check_inner_outer(ring); | ||||||
|  |                         if (ring.outer()) { | ||||||
|  |                             if (!ring.is_cw()) { | ||||||
|  |                                 ring.reverse(); | ||||||
|  |                             } | ||||||
|  |                             m_outer_rings.push_back(&ring); | ||||||
|  |                         } else { | ||||||
|  |                             if (ring.is_cw()) { | ||||||
|  |                                 ring.reverse(); | ||||||
|  |                             } | ||||||
|  |                             m_inner_rings.push_back(&ring); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (m_outer_rings.size() == 1) { | ||||||
|  |                         for (auto inner : m_inner_rings) { | ||||||
|  |                             m_outer_rings.front()->add_inner_ring(inner); | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|  |                         // sort outer rings by size, smallest first
 | ||||||
|  |                         std::sort(m_outer_rings.begin(), m_outer_rings.end(), [](ProtoRing* a, ProtoRing* b) { | ||||||
|  |                             return a->area() < b->area(); | ||||||
|  |                         }); | ||||||
|  |                         for (auto inner : m_inner_rings) { | ||||||
|  |                             for (auto outer : m_outer_rings) { | ||||||
|  |                                 if (inner->is_in(outer)) { | ||||||
|  |                                     outer->add_inner_ring(inner); | ||||||
|  |                                     break; | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 check_inner_outer_roles(); | ||||||
|  | 
 | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             typedef osmium::area::AssemblerConfig config_type; | ||||||
|  | 
 | ||||||
|  |             explicit Assembler(const config_type& config) : | ||||||
|  |                 m_config(config), | ||||||
|  |                 m_segment_list(config.debug) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             ~Assembler() = default; | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Assemble an area from the given way. | ||||||
|  |              * The resulting area is put into the out_buffer. | ||||||
|  |              */ | ||||||
|  |             void operator()(const osmium::Way& way, osmium::memory::Buffer& out_buffer) { | ||||||
|  |                 if (m_config.problem_reporter) { | ||||||
|  |                     m_config.problem_reporter->set_object(osmium::item_type::way, way.id()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if (!way.ends_have_same_id()) { | ||||||
|  |                     if (m_config.problem_reporter) { | ||||||
|  |                         m_config.problem_reporter->report_duplicate_node(way.nodes().front().ref(), way.nodes().back().ref(), way.nodes().front().location()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 m_segment_list.extract_segments_from_way(way, "outer"); | ||||||
|  | 
 | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "\nBuild way id()=" << way.id() << " segments.size()=" << m_segment_list.size() << "\n"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 // Now create the Area object and add the attributes and tags
 | ||||||
|  |                 // from the relation.
 | ||||||
|  |                 { | ||||||
|  |                     osmium::builder::AreaBuilder builder(out_buffer); | ||||||
|  |                     builder.initialize_from_object(way); | ||||||
|  | 
 | ||||||
|  |                     if (create_rings()) { | ||||||
|  |                         add_tags_to_area(builder, way); | ||||||
|  |                         add_rings_to_area(builder); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 out_buffer.commit(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Assemble an area from the given relation and its members. | ||||||
|  |              * All members are to be found in the in_buffer at the offsets | ||||||
|  |              * given by the members parameter. | ||||||
|  |              * The resulting area is put into the out_buffer. | ||||||
|  |              */ | ||||||
|  |             void operator()(const osmium::Relation& relation, const std::vector<size_t>& members, const osmium::memory::Buffer& in_buffer, osmium::memory::Buffer& out_buffer) { | ||||||
|  |                 if (m_config.problem_reporter) { | ||||||
|  |                     m_config.problem_reporter->set_object(osmium::item_type::relation, relation.id()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 m_segment_list.extract_segments_from_ways(relation, members, in_buffer); | ||||||
|  | 
 | ||||||
|  |                 if (debug()) { | ||||||
|  |                     std::cerr << "\nBuild relation id()=" << relation.id() << " members.size()=" << members.size() << " segments.size()=" << m_segment_list.size() << "\n"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 size_t area_offset = out_buffer.committed(); | ||||||
|  | 
 | ||||||
|  |                 // Now create the Area object and add the attributes and tags
 | ||||||
|  |                 // from the relation.
 | ||||||
|  |                 { | ||||||
|  |                     osmium::builder::AreaBuilder builder(out_buffer); | ||||||
|  |                     builder.initialize_from_object(relation); | ||||||
|  | 
 | ||||||
|  |                     if (create_rings()) { | ||||||
|  |                         add_tags_to_area(builder, relation); | ||||||
|  |                         add_rings_to_area(builder); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 out_buffer.commit(); | ||||||
|  | 
 | ||||||
|  |                 const osmium::TagList& area_tags = out_buffer.get<osmium::Area>(area_offset).tags(); // tags of the area we just built
 | ||||||
|  | 
 | ||||||
|  |                 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<const osmium::Way>(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); | ||||||
|  |                                 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()); | ||||||
|  | 
 | ||||||
|  |                                     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); | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         ++memit; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class Assembler
 | ||||||
|  | 
 | ||||||
|  |     } // namespace area
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_AREA_ASSEMBLER_HPP
 | ||||||
							
								
								
									
										242
									
								
								ThirdParty/osmium/area/detail/node_ref_segment.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								ThirdParty/osmium/area/detail/node_ref_segment.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,242 @@ | |||||||
|  | #ifndef OSMIUM_AREA_DETAIL_NODE_REF_SEGMENT_HPP | ||||||
|  | #define OSMIUM_AREA_DETAIL_NODE_REF_SEGMENT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2014 Jochen Topf <jochen@topf.org> 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 <algorithm> | ||||||
|  | #include <cstdint> | ||||||
|  | #include <cstring> | ||||||
|  | #include <iosfwd> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/node_ref.hpp> | ||||||
|  | #include <osmium/util/operators.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     class Way; | ||||||
|  | 
 | ||||||
|  |     namespace area { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * @brief Namespace for Osmium internal use | ||||||
|  |          */ | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * This helper class for the Assembler class models a segment. | ||||||
|  |              * Segments are the connection between | ||||||
|  |              * two nodes and they all have their smaller coordinate at the | ||||||
|  |              * beginning of the segment. Smaller, in this case, means smaller x | ||||||
|  |              * coordinate, and if they are the same smaller y coordinate. | ||||||
|  |              */ | ||||||
|  |             class NodeRefSegment : osmium::totally_ordered<NodeRefSegment> { | ||||||
|  | 
 | ||||||
|  |                 osmium::NodeRef m_first; | ||||||
|  |                 osmium::NodeRef m_second; | ||||||
|  | 
 | ||||||
|  |                 /// Role of the member this segment was from.
 | ||||||
|  |                 const char* m_role; | ||||||
|  | 
 | ||||||
|  |                 /// Way this segment was from.
 | ||||||
|  |                 const osmium::Way* m_way; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 void swap_locations() { | ||||||
|  |                     using std::swap; | ||||||
|  |                     swap(m_first, m_second); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 explicit NodeRefSegment() : | ||||||
|  |                     m_first(), | ||||||
|  |                     m_second(), | ||||||
|  |                     m_role(nullptr), | ||||||
|  |                     m_way(nullptr) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 explicit NodeRefSegment(const osmium::NodeRef& nr1, const osmium::NodeRef& nr2, const char* role, const osmium::Way* way) : | ||||||
|  |                     m_first(nr1), | ||||||
|  |                     m_second(nr2), | ||||||
|  |                     m_role(role), | ||||||
|  |                     m_way(way) { | ||||||
|  |                     if (nr2.location() < nr1.location()) { | ||||||
|  |                         swap_locations(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 NodeRefSegment(const NodeRefSegment&) = default; | ||||||
|  |                 NodeRefSegment(NodeRefSegment&&) = default; | ||||||
|  | 
 | ||||||
|  |                 NodeRefSegment& operator=(const NodeRefSegment&) = default; | ||||||
|  |                 NodeRefSegment& operator=(NodeRefSegment&&) = default; | ||||||
|  | 
 | ||||||
|  |                 ~NodeRefSegment() = default; | ||||||
|  | 
 | ||||||
|  |                 /// Return first NodeRef of Segment according to sorting order (bottom left to top right).
 | ||||||
|  |                 const osmium::NodeRef& first() const { | ||||||
|  |                     return m_first; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /// Return second NodeRef of Segment according to sorting order (bottom left to top right).
 | ||||||
|  |                 const osmium::NodeRef& second() const { | ||||||
|  |                     return m_second; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 bool to_left_of(const osmium::Location location) const { | ||||||
|  |     //                std::cerr << "segment " << first() << "--" << second() << " to_left_of(" << location << "\n";
 | ||||||
|  | 
 | ||||||
|  |                     if (first().location() == location || second().location() == location) { | ||||||
|  |                         return false; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     const std::pair<osmium::Location, osmium::Location> mm = std::minmax(first().location(), second().location(), [](const osmium::Location a, const osmium::Location b) { | ||||||
|  |                         return a.y() < b.y(); | ||||||
|  |                     }); | ||||||
|  | 
 | ||||||
|  |                     if (mm.first.y() >= location.y() || mm.second.y() < location.y() || first().location().x() > location.x()) { | ||||||
|  |     //                    std::cerr << "  false\n";
 | ||||||
|  |                         return false; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     int64_t ax = mm.first.x(); | ||||||
|  |                     int64_t bx = mm.second.x(); | ||||||
|  |                     int64_t lx = location.x(); | ||||||
|  |                     int64_t ay = mm.first.y(); | ||||||
|  |                     int64_t by = mm.second.y(); | ||||||
|  |                     int64_t ly = location.y(); | ||||||
|  |                     return ((bx - ax)*(ly - ay) - (by - ay)*(lx - ax)) <= 0; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 bool role_outer() const { | ||||||
|  |                     return !strcmp(m_role, "outer"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 bool role_inner() const { | ||||||
|  |                     return !strcmp(m_role, "inner"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 const osmium::Way* way() const { | ||||||
|  |                     return m_way; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class NodeRefSegment
 | ||||||
|  | 
 | ||||||
|  |             /// NodeRefSegments are equal if both their locations are equal
 | ||||||
|  |             inline bool operator==(const NodeRefSegment& lhs, const NodeRefSegment& rhs) { | ||||||
|  |                 return lhs.first().location() == rhs.first().location() && lhs.second().location() == rhs.second().location(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * NodeRefSegments are "smaller" if they are to the left and down of another | ||||||
|  |              * 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) { | ||||||
|  |                 return (lhs.first().location() == rhs.first().location() && lhs.second().location() < rhs.second().location()) || lhs.first().location() < rhs.first().location(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <typename TChar, typename TTraits> | ||||||
|  |             inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const NodeRefSegment& segment) { | ||||||
|  |                 return out << segment.first() << "--" << segment.second(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             inline bool outside_x_range(const NodeRefSegment& s1, const NodeRefSegment& s2) { | ||||||
|  |                 if (s1.first().location().x() > s2.second().location().x()) { | ||||||
|  |                     return true; | ||||||
|  |                 } | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             inline bool y_range_overlap(const NodeRefSegment& s1, const NodeRefSegment& s2) { | ||||||
|  |                 auto m1 = std::minmax(s1.first().location().y(), s1.second().location().y()); | ||||||
|  |                 auto m2 = std::minmax(s2.first().location().y(), s2.second().location().y()); | ||||||
|  |                 if (m1.first > m2.second || m2.first > m1.second) { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |             * 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() || | ||||||
|  |                     s1.second().location() == s2.first().location()  || | ||||||
|  |                     s1.second().location() == s2.second().location()) { | ||||||
|  |                     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())); | ||||||
|  | 
 | ||||||
|  |                 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())); | ||||||
|  | 
 | ||||||
|  |                     double nume_b = ((s1.second().lon() - s1.first().lon())*(s1.first().lat() - s2.first().lat())) - | ||||||
|  |                                     ((s1.second().lat() - s1.first().lat())*(s1.first().lon() - s2.first().lon())); | ||||||
|  | 
 | ||||||
|  |                     if ((denom > 0 && nume_a >= 0 && nume_a <= denom && nume_b >= 0 && nume_b <= denom) || | ||||||
|  |                         (denom < 0 && nume_a <= 0 && nume_a >= denom && nume_b <= 0 && nume_b >= denom)) { | ||||||
|  |                         double ua = nume_a / denom; | ||||||
|  |                         double ix = s1.first().lon() + ua*(s1.second().lon() - s1.first().lon()); | ||||||
|  |                         double iy = s1.first().lat() + ua*(s1.second().lat() - s1.first().lat()); | ||||||
|  |                         return osmium::Location(ix, iy); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 return osmium::Location(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     } // namespace area
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_AREA_DETAIL_NODE_REF_SEGMENT_HPP
 | ||||||
							
								
								
									
										274
									
								
								ThirdParty/osmium/area/detail/proto_ring.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								ThirdParty/osmium/area/detail/proto_ring.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,274 @@ | |||||||
|  | #ifndef OSMIUM_AREA_DETAIL_PROTO_RING_HPP | ||||||
|  | #define OSMIUM_AREA_DETAIL_PROTO_RING_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2014 Jochen Topf <jochen@topf.org> 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 <algorithm> | ||||||
|  | #include <cassert> | ||||||
|  | #include <iostream> | ||||||
|  | #include <list> | ||||||
|  | #include <set> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <osmium/osm/node_ref.hpp> | ||||||
|  | #include <osmium/area/detail/node_ref_segment.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace area { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * A ring in the process of being built by the Assembler object. | ||||||
|  |              */ | ||||||
|  |             class ProtoRing { | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 typedef std::vector<NodeRefSegment> segments_type; | ||||||
|  | 
 | ||||||
|  |             private: | ||||||
|  | 
 | ||||||
|  |                 // segments in this ring
 | ||||||
|  |                 segments_type m_segments; | ||||||
|  | 
 | ||||||
|  |                 bool m_outer {true}; | ||||||
|  | 
 | ||||||
|  |                 // if this is an outer ring, these point to it's inner rings (if any)
 | ||||||
|  |                 std::vector<ProtoRing*> m_inner {}; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 explicit ProtoRing(const NodeRefSegment& segment) : | ||||||
|  |                     m_segments() { | ||||||
|  |                     add_segment_back(segment); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 explicit ProtoRing(segments_type::const_iterator sbegin, segments_type::const_iterator send) : | ||||||
|  |                     m_segments(static_cast<size_t>(std::distance(sbegin, send))) { | ||||||
|  |                     std::copy(sbegin, send, m_segments.begin()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 bool outer() const { | ||||||
|  |                     return m_outer; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void set_inner() { | ||||||
|  |                     m_outer = false; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 segments_type& segments() { | ||||||
|  |                     return m_segments; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 const segments_type& segments() const { | ||||||
|  |                     return m_segments; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void remove_segments(segments_type::iterator sbegin, segments_type::iterator send) { | ||||||
|  |                     m_segments.erase(sbegin, send); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void add_segment_front(const NodeRefSegment& segment) { | ||||||
|  |                     m_segments.insert(m_segments.begin(), segment); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void add_segment_back(const NodeRefSegment& segment) { | ||||||
|  |                     m_segments.push_back(segment); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 const NodeRefSegment& get_segment_front() const { | ||||||
|  |                     return m_segments.front(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 NodeRefSegment& get_segment_front() { | ||||||
|  |                     return m_segments.front(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 const NodeRefSegment& get_segment_back() const { | ||||||
|  |                     return m_segments.back(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 NodeRefSegment& get_segment_back() { | ||||||
|  |                     return m_segments.back(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 bool closed() const { | ||||||
|  |                     return m_segments.front().first().location() == m_segments.back().second().location(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 int64_t sum() const { | ||||||
|  |                     int64_t sum = 0; | ||||||
|  | 
 | ||||||
|  |                     for (const auto& segment : m_segments) { | ||||||
|  |                         sum += static_cast<int64_t>(segment.first().location().x()) * static_cast<int64_t>(segment.second().location().y()) - | ||||||
|  |                                static_cast<int64_t>(segment.second().location().x()) * static_cast<int64_t>(segment.first().location().y()); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     return sum; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 bool is_cw() const { | ||||||
|  |                     return sum() <= 0; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 int64_t area() const { | ||||||
|  |                     return std::abs(sum()) / 2; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void swap_segments(ProtoRing& other) { | ||||||
|  |                     std::swap(m_segments, other.m_segments); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void add_inner_ring(ProtoRing* ring) { | ||||||
|  |                     m_inner.push_back(ring); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 const std::vector<ProtoRing*> inner_rings() const { | ||||||
|  |                     return m_inner; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void print(std::ostream& out) const { | ||||||
|  |                     out << "["; | ||||||
|  |                     bool first = true; | ||||||
|  |                     for (const auto& segment : m_segments) { | ||||||
|  |                         if (first) { | ||||||
|  |                             out << segment.first().ref(); | ||||||
|  |                         } | ||||||
|  |                         out << ',' << segment.second().ref(); | ||||||
|  |                         first = false; | ||||||
|  |                     } | ||||||
|  |                     out << "]"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void reverse() { | ||||||
|  |                     std::for_each(m_segments.begin(), m_segments.end(), [](NodeRefSegment& segment) { | ||||||
|  |                         segment.swap_locations(); | ||||||
|  |                     }); | ||||||
|  |                     std::reverse(m_segments.begin(), m_segments.end()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Merge other ring to end of this ring. | ||||||
|  |                  */ | ||||||
|  |                 void merge_ring(const ProtoRing& other, bool debug) { | ||||||
|  |                     if (debug) { | ||||||
|  |                         std::cerr << "        MERGE rings "; | ||||||
|  |                         print(std::cerr); | ||||||
|  |                         std::cerr << " to "; | ||||||
|  |                         other.print(std::cerr); | ||||||
|  |                         std::cerr << "\n"; | ||||||
|  |                     } | ||||||
|  |                     m_segments.insert(m_segments.end(), other.m_segments.begin(), other.m_segments.end()); | ||||||
|  |                     if (debug) { | ||||||
|  |                         std::cerr << "          result ring: "; | ||||||
|  |                         print(std::cerr); | ||||||
|  |                         std::cerr << "\n"; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void merge_ring_reverse(const ProtoRing& other, bool debug) { | ||||||
|  |                     if (debug) { | ||||||
|  |                         std::cerr << "        MERGE rings (reverse) "; | ||||||
|  |                         print(std::cerr); | ||||||
|  |                         std::cerr << " to "; | ||||||
|  |                         other.print(std::cerr); | ||||||
|  |                         std::cerr << "\n"; | ||||||
|  |                     } | ||||||
|  |                     size_t n = m_segments.size(); | ||||||
|  |                     m_segments.resize(n + other.m_segments.size()); | ||||||
|  |                     std::transform(other.m_segments.rbegin(), other.m_segments.rend(), m_segments.begin() + static_cast<segments_type::difference_type>(n), [](NodeRefSegment segment) { | ||||||
|  |                         segment.swap_locations(); | ||||||
|  |                         return segment; | ||||||
|  |                     }); | ||||||
|  |                     if (debug) { | ||||||
|  |                         std::cerr << "          result ring: "; | ||||||
|  |                         print(std::cerr); | ||||||
|  |                         std::cerr << "\n"; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 const NodeRef& min_node() const { | ||||||
|  |                     auto it = std::min_element(m_segments.begin(), m_segments.end()); | ||||||
|  |                     if (location_less()(it->first(), it->second())) { | ||||||
|  |                         return it->first(); | ||||||
|  |                     } else { | ||||||
|  |                         return it->second(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 bool is_in(ProtoRing* outer) { | ||||||
|  |                     osmium::Location testpoint = segments().front().first().location(); | ||||||
|  |                     bool is_in = false; | ||||||
|  | 
 | ||||||
|  |                     for (size_t i = 0, j = outer->segments().size()-1; i < outer->segments().size(); j = i++) { | ||||||
|  |                         if (((outer->segments()[i].first().location().y() > testpoint.y()) != (outer->segments()[j].first().location().y() > testpoint.y())) && | ||||||
|  |                             (testpoint.x() < (outer->segments()[j].first().location().x() - outer->segments()[i].first().location().x()) * (testpoint.y() - outer->segments()[i].first().location().y()) / (outer->segments()[j].first().location().y() - outer->segments()[i].first().location().y()) + outer->segments()[i].first().location().x()) ) { | ||||||
|  |                             is_in = !is_in; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     return is_in; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void get_ways(std::set<const osmium::Way*>& ways) { | ||||||
|  |                     for (const auto& segment : m_segments) { | ||||||
|  |                         ways.insert(segment.way()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 bool contains(const NodeRefSegment& segment) const { | ||||||
|  |                     for (const auto& s : m_segments) { | ||||||
|  |                         if (s == segment || (s.first() == segment.second() && s.second() == segment.first())) { | ||||||
|  |                             return true; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class ProtoRing
 | ||||||
|  | 
 | ||||||
|  |             template <typename TChar, typename TTraits> | ||||||
|  |             inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const ProtoRing& ring) { | ||||||
|  |                 ring.print(out); | ||||||
|  |                 return out; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     } // namespace area
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_AREA_DETAIL_PROTO_RING_HPP
 | ||||||
							
								
								
									
										216
									
								
								ThirdParty/osmium/area/detail/segment_list.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								ThirdParty/osmium/area/detail/segment_list.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,216 @@ | |||||||
|  | #ifndef OSMIUM_AREA_DETAIL_SEGMENT_LIST_HPP | ||||||
|  | #define OSMIUM_AREA_DETAIL_SEGMENT_LIST_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2014 Jochen Topf <jochen@topf.org> 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 <algorithm> | ||||||
|  | #include <cassert> | ||||||
|  | #include <iostream> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <osmium/area/problem_reporter.hpp> | ||||||
|  | #include <osmium/area/detail/node_ref_segment.hpp> | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/osm/relation.hpp> | ||||||
|  | #include <osmium/osm/way.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace area { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * This is a helper class for the area assembler. It models | ||||||
|  |              * a list of segments. | ||||||
|  |              */ | ||||||
|  |             class SegmentList { | ||||||
|  | 
 | ||||||
|  |                 typedef std::vector<NodeRefSegment> slist_type; | ||||||
|  | 
 | ||||||
|  |                 slist_type m_segments {}; | ||||||
|  | 
 | ||||||
|  |                 bool m_debug; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 explicit SegmentList(bool debug) : | ||||||
|  |                     m_debug(debug) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 ~SegmentList() = default; | ||||||
|  | 
 | ||||||
|  |                 SegmentList(const SegmentList& other) = delete; | ||||||
|  |                 SegmentList(SegmentList&& other) = delete; | ||||||
|  | 
 | ||||||
|  |                 SegmentList& operator=(const SegmentList& other) = delete; | ||||||
|  |                 SegmentList& operator=(SegmentList&& other) = delete; | ||||||
|  | 
 | ||||||
|  |                 /// The number of segments in the list.
 | ||||||
|  |                 size_t size() const { | ||||||
|  |                     return m_segments.size(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 bool empty() const { | ||||||
|  |                     return m_segments.empty(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 typedef slist_type::const_iterator const_iterator; | ||||||
|  | 
 | ||||||
|  |                 const_iterator begin() const { | ||||||
|  |                     return m_segments.begin(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 const_iterator end() const { | ||||||
|  |                     return m_segments.end(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Enable or disable debug output to stderr. This is for Osmium | ||||||
|  |                  * developers only. | ||||||
|  |                  */ | ||||||
|  |                 void enable_debug_output(bool debug=true) { | ||||||
|  |                     m_debug = debug; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /// Clear the list of segments. All segments are removed.
 | ||||||
|  |                 void clear() { | ||||||
|  |                     m_segments.clear(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /// Sort the list of segments.
 | ||||||
|  |                 void sort() { | ||||||
|  |                     std::sort(m_segments.begin(), m_segments.end()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Extract segments from given way and add them to the list. | ||||||
|  |                  * | ||||||
|  |                  * Segments connecting two nodes with the same location (ie same | ||||||
|  |                  * node or different node with same location) are removed. | ||||||
|  |                  * | ||||||
|  |                  * XXX should two nodes with same location be reported? | ||||||
|  |                  */ | ||||||
|  |                 void extract_segments_from_way(const osmium::Way& way, const char* role) { | ||||||
|  |                     osmium::NodeRef last_nr; | ||||||
|  |                     for (const osmium::NodeRef& nr : way.nodes()) { | ||||||
|  |                         if (last_nr.location() && last_nr.location() != nr.location()) { | ||||||
|  |                             m_segments.emplace_back(last_nr, nr, role, &way); | ||||||
|  |                         } | ||||||
|  |                         last_nr = nr; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Extract all segments from all ways that make up this | ||||||
|  |                  * multipolygon relation and add them to the list. | ||||||
|  |                  */ | ||||||
|  |                 void extract_segments_from_ways(const osmium::Relation& relation, const std::vector<size_t>& members, const osmium::memory::Buffer& in_buffer) { | ||||||
|  |                     auto member_it = relation.members().begin(); | ||||||
|  |                     for (size_t offset : members) { | ||||||
|  |                         const osmium::Way& way = in_buffer.get<const osmium::Way>(offset); | ||||||
|  |                         extract_segments_from_way(way, member_it->role()); | ||||||
|  |                         ++member_it; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Find duplicate segments (ie same start and end point) in the | ||||||
|  |                  * list and remove them. This will always remove pairs of the same | ||||||
|  |                  * segment. So if there are three, for instance, two will be | ||||||
|  |                  * removed and one will be left. | ||||||
|  |                  */ | ||||||
|  |                 void erase_duplicate_segments() { | ||||||
|  |                     while (true) { | ||||||
|  |                         auto it = std::adjacent_find(m_segments.begin(), m_segments.end()); | ||||||
|  |                         if (it == m_segments.end()) { | ||||||
|  |                             return; | ||||||
|  |                         } | ||||||
|  |                         if (m_debug) { | ||||||
|  |                             std::cerr << "  erase duplicate segment: " << *it << "\n"; | ||||||
|  |                         } | ||||||
|  |                         m_segments.erase(it, it+2); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Find intersection between segments. | ||||||
|  |                  * | ||||||
|  |                  * @param problem_reporter Any intersections found are reported to this object. | ||||||
|  |                  * @returns true if there are intersections. | ||||||
|  |                  */ | ||||||
|  |                 bool find_intersections(osmium::area::ProblemReporter* problem_reporter) const { | ||||||
|  |                     if (m_segments.empty()) { | ||||||
|  |                         return false; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     bool found_intersections = false; | ||||||
|  | 
 | ||||||
|  |                     for (auto it1 = m_segments.begin(); it1 != m_segments.end()-1; ++it1) { | ||||||
|  |                         const NodeRefSegment& s1 = *it1; | ||||||
|  |                         for (auto it2 = it1+1; it2 != m_segments.end(); ++it2) { | ||||||
|  |                             const NodeRefSegment& s2 = *it2; | ||||||
|  | 
 | ||||||
|  |                             assert(s1 != s2); // erase_duplicate_segments() should have made sure of that
 | ||||||
|  | 
 | ||||||
|  |                             if (outside_x_range(s2, s1)) { | ||||||
|  |                                 break; | ||||||
|  |                             } | ||||||
|  | 
 | ||||||
|  |                             if (y_range_overlap(s1, s2)) { | ||||||
|  |                                 osmium::Location intersection = calculate_intersection(s1, s2); | ||||||
|  |                                 if (intersection) { | ||||||
|  |                                     found_intersections = true; | ||||||
|  |                                     if (m_debug) { | ||||||
|  |                                         std::cerr << "  segments " << s1 << " and " << s2 << " intersecting at " << intersection << "\n"; | ||||||
|  |                                     } | ||||||
|  |                                     if (problem_reporter) { | ||||||
|  |                                         problem_reporter->report_intersection(s1.way()->id(), s1.first().location(), s1.second().location(), s2.way()->id(), s2.first().location(), s2.second().location(), intersection); | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     return found_intersections; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class SegmentList
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     } // namespace area
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_AREA_DETAIL_SEGMENT_LIST_HPP
 | ||||||
							
								
								
									
										211
									
								
								ThirdParty/osmium/area/multipolygon_collector.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								ThirdParty/osmium/area/multipolygon_collector.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +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 <jochen@topf.org> 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 <algorithm> | ||||||
|  | #include <cassert> | ||||||
|  | #include <cstddef> | ||||||
|  | #include <cstring> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/osm/item_type.hpp> | ||||||
|  | #include <osmium/osm/relation.hpp> | ||||||
|  | #include <osmium/osm/tag.hpp> | ||||||
|  | #include <osmium/osm/way.hpp> | ||||||
|  | #include <osmium/relations/collector.hpp> | ||||||
|  | #include <osmium/relations/detail/member_meta.hpp> | ||||||
|  | 
 | ||||||
|  | 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 TAssembler> | ||||||
|  |         class MultipolygonCollector : public osmium::relations::Collector<MultipolygonCollector<TAssembler>, false, true, false> { | ||||||
|  | 
 | ||||||
|  |             typedef typename osmium::relations::Collector<MultipolygonCollector<TAssembler>, 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<size_t> 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
 | ||||||
							
								
								
									
										149
									
								
								ThirdParty/osmium/area/problem_reporter.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								ThirdParty/osmium/area/problem_reporter.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +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 <jochen@topf.org> 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 <osmium/osm/item_type.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/types.hpp> | ||||||
|  | 
 | ||||||
|  | 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
 | ||||||
							
								
								
									
										96
									
								
								ThirdParty/osmium/area/problem_reporter_exception.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								ThirdParty/osmium/area/problem_reporter_exception.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,96 @@ | |||||||
|  | #ifndef OSMIUM_AREA_PROBLEM_REPORTER_EXCEPTION_HPP | ||||||
|  | #define OSMIUM_AREA_PROBLEM_REPORTER_EXCEPTION_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2014 Jochen Topf <jochen@topf.org> 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 <sstream> | ||||||
|  | #include <stdexcept> | ||||||
|  | 
 | ||||||
|  | #include <osmium/area/problem_reporter_stream.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/types.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace area { | ||||||
|  | 
 | ||||||
|  |         class ProblemReporterException : public ProblemReporterStream { | ||||||
|  | 
 | ||||||
|  |             std::stringstream m_sstream; | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             ProblemReporterException() : | ||||||
|  |                 ProblemReporterStream(m_sstream) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             virtual ~ProblemReporterException() = default; | ||||||
|  | 
 | ||||||
|  |             void report_duplicate_node(osmium::object_id_type node_id1, osmium::object_id_type node_id2, osmium::Location location) override { | ||||||
|  |                 m_sstream.str(); | ||||||
|  |                 ProblemReporterStream::report_duplicate_node(node_id1, node_id2, location); | ||||||
|  |                 throw std::runtime_error(m_sstream.str()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             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 { | ||||||
|  |                 m_sstream.str(); | ||||||
|  |                 ProblemReporterStream::report_intersection(way1_id, way1_seg_start, way1_seg_end, way2_id, way2_seg_start, way2_seg_end, intersection); | ||||||
|  |                 throw std::runtime_error(m_sstream.str()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void report_ring_not_closed(osmium::Location end1, osmium::Location end2) override { | ||||||
|  |                 m_sstream.str(); | ||||||
|  |                 ProblemReporterStream::report_ring_not_closed(end1, end2); | ||||||
|  |                 throw std::runtime_error(m_sstream.str()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void report_role_should_be_outer(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) override { | ||||||
|  |                 m_sstream.str(); | ||||||
|  |                 ProblemReporterStream::report_role_should_be_outer(way_id, seg_start, seg_end); | ||||||
|  |                 throw std::runtime_error(m_sstream.str()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void report_role_should_be_inner(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) override { | ||||||
|  |                 m_sstream.str(); | ||||||
|  |                 ProblemReporterStream::report_role_should_be_inner(way_id, seg_start, seg_end); | ||||||
|  |                 throw std::runtime_error(m_sstream.str()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class ProblemReporterException
 | ||||||
|  | 
 | ||||||
|  |     } // namespace area
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_AREA_PROBLEM_REPORTER_EXCEPTION_HPP
 | ||||||
							
								
								
									
										202
									
								
								ThirdParty/osmium/area/problem_reporter_ogr.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								ThirdParty/osmium/area/problem_reporter_ogr.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,202 @@ | |||||||
|  | #ifndef OSMIUM_AREA_PROBLEM_REPORTER_OGR_HPP | ||||||
|  | #define OSMIUM_AREA_PROBLEM_REPORTER_OGR_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2014 Jochen Topf <jochen@topf.org> 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. | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #define OSMIUM_COMPILE_WITH_CFLAGS_OGR `gdal-config --cflags` | ||||||
|  | #define OSMIUM_LINK_WITH_LIBS_OGR `gdal-config --libs` | ||||||
|  | 
 | ||||||
|  | #pragma GCC diagnostic push | ||||||
|  | #pragma GCC diagnostic ignored "-Wold-style-cast" | ||||||
|  | #pragma GCC diagnostic ignored "-Wredundant-decls" | ||||||
|  | #pragma GCC diagnostic ignored "-Wshadow" | ||||||
|  | #pragma GCC diagnostic ignored "-Wdocumentation-unknown-command" | ||||||
|  | # include <ogr_api.h> | ||||||
|  | # include <ogrsf_frmts.h> | ||||||
|  | #pragma GCC diagnostic pop | ||||||
|  | 
 | ||||||
|  | #include <memory> | ||||||
|  | #include <stdexcept> | ||||||
|  | 
 | ||||||
|  | #include <osmium/area/problem_reporter.hpp> | ||||||
|  | #include <osmium/geom/ogr.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/types.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace area { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Report problems when assembling areas by adding them to | ||||||
|  |          * layers in an OGR datasource. | ||||||
|  |          */ | ||||||
|  |         class ProblemReporterOGR : public ProblemReporter { | ||||||
|  | 
 | ||||||
|  |             osmium::geom::OGRFactory<> m_ogr_factory {}; | ||||||
|  | 
 | ||||||
|  |             OGRDataSource* m_data_source; | ||||||
|  | 
 | ||||||
|  |             OGRLayer* m_layer_perror; | ||||||
|  |             OGRLayer* m_layer_lerror; | ||||||
|  | 
 | ||||||
|  |             void write_point(const char* problem_type, osmium::object_id_type id1, osmium::object_id_type id2, osmium::Location location) { | ||||||
|  |                 OGRFeature* feature = OGRFeature::CreateFeature(m_layer_perror->GetLayerDefn()); | ||||||
|  |                 std::unique_ptr<OGRPoint> ogr_point = m_ogr_factory.create_point(location); | ||||||
|  |                 feature->SetGeometry(ogr_point.get()); | ||||||
|  |                 feature->SetField("id1", static_cast<double>(id1)); | ||||||
|  |                 feature->SetField("id2", static_cast<double>(id2)); | ||||||
|  |                 feature->SetField("problem_type", problem_type); | ||||||
|  | 
 | ||||||
|  |                 if (m_layer_perror->CreateFeature(feature) != OGRERR_NONE) { | ||||||
|  |                     std::runtime_error("Failed to create feature on layer 'perrors'"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 OGRFeature::DestroyFeature(feature); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void write_line(const char* problem_type, osmium::object_id_type id1, osmium::object_id_type id2, osmium::Location loc1, osmium::Location loc2) { | ||||||
|  |                 std::unique_ptr<OGRPoint> ogr_point1 = m_ogr_factory.create_point(loc1); | ||||||
|  |                 std::unique_ptr<OGRPoint> ogr_point2 = m_ogr_factory.create_point(loc2); | ||||||
|  |                 std::unique_ptr<OGRLineString> ogr_linestring = std::unique_ptr<OGRLineString>(new OGRLineString()); | ||||||
|  |                 ogr_linestring->addPoint(ogr_point1.get()); | ||||||
|  |                 ogr_linestring->addPoint(ogr_point2.get()); | ||||||
|  |                 OGRFeature* feature = OGRFeature::CreateFeature(m_layer_lerror->GetLayerDefn()); | ||||||
|  |                 feature->SetGeometry(ogr_linestring.get()); | ||||||
|  |                 feature->SetField("id1", static_cast<double>(id1)); | ||||||
|  |                 feature->SetField("id2", static_cast<double>(id2)); | ||||||
|  |                 feature->SetField("problem_type", problem_type); | ||||||
|  | 
 | ||||||
|  |                 if (m_layer_lerror->CreateFeature(feature) != OGRERR_NONE) { | ||||||
|  |                     std::runtime_error("Failed to create feature on layer 'lerrors'"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 OGRFeature::DestroyFeature(feature); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             explicit ProblemReporterOGR(OGRDataSource* data_source) : | ||||||
|  |                 m_data_source(data_source) { | ||||||
|  | 
 | ||||||
|  |                 OGRSpatialReference sparef; | ||||||
|  |                 sparef.SetWellKnownGeogCS("WGS84"); | ||||||
|  | 
 | ||||||
|  |                 m_layer_perror = m_data_source->CreateLayer("perrors", &sparef, wkbPoint, nullptr); | ||||||
|  |                 if (!m_layer_perror) { | ||||||
|  |                     std::runtime_error("Layer creation failed for layer 'perrors'"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 OGRFieldDefn layer_perror_field_id1("id1", OFTReal); | ||||||
|  |                 layer_perror_field_id1.SetWidth(10); | ||||||
|  | 
 | ||||||
|  |                 if (m_layer_perror->CreateField(&layer_perror_field_id1) != OGRERR_NONE) { | ||||||
|  |                     std::runtime_error("Creating field 'id1' failed for layer 'perrors'"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 OGRFieldDefn layer_perror_field_id2("id2", OFTReal); | ||||||
|  |                 layer_perror_field_id2.SetWidth(10); | ||||||
|  | 
 | ||||||
|  |                 if (m_layer_perror->CreateField(&layer_perror_field_id2) != OGRERR_NONE) { | ||||||
|  |                     std::runtime_error("Creating field 'id2' failed for layer 'perrors'"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 OGRFieldDefn layer_perror_field_problem_type("problem_type", OFTString); | ||||||
|  |                 layer_perror_field_problem_type.SetWidth(30); | ||||||
|  | 
 | ||||||
|  |                 if (m_layer_perror->CreateField(&layer_perror_field_problem_type) != OGRERR_NONE) { | ||||||
|  |                     std::runtime_error("Creating field 'problem_type' failed for layer 'perrors'"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**************/ | ||||||
|  | 
 | ||||||
|  |                 m_layer_lerror = m_data_source->CreateLayer("lerrors", &sparef, wkbLineString, nullptr); | ||||||
|  |                 if (!m_layer_lerror) { | ||||||
|  |                     std::runtime_error("Layer creation failed for layer 'lerrors'"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 OGRFieldDefn layer_lerror_field_id1("id1", OFTReal); | ||||||
|  |                 layer_lerror_field_id1.SetWidth(10); | ||||||
|  | 
 | ||||||
|  |                 if (m_layer_lerror->CreateField(&layer_lerror_field_id1) != OGRERR_NONE) { | ||||||
|  |                     std::runtime_error("Creating field 'id1' failed for layer 'lerrors'"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 OGRFieldDefn layer_lerror_field_id2("id2", OFTReal); | ||||||
|  |                 layer_lerror_field_id2.SetWidth(10); | ||||||
|  | 
 | ||||||
|  |                 if (m_layer_lerror->CreateField(&layer_lerror_field_id2) != OGRERR_NONE) { | ||||||
|  |                     std::runtime_error("Creating field 'id2' failed for layer 'lerrors'"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 OGRFieldDefn layer_lerror_field_problem_type("problem_type", OFTString); | ||||||
|  |                 layer_lerror_field_problem_type.SetWidth(30); | ||||||
|  | 
 | ||||||
|  |                 if (m_layer_lerror->CreateField(&layer_lerror_field_problem_type) != OGRERR_NONE) { | ||||||
|  |                     std::runtime_error("Creating field 'problem_type' failed for layer 'lerrors'"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             virtual ~ProblemReporterOGR() = default; | ||||||
|  | 
 | ||||||
|  |             void report_duplicate_node(osmium::object_id_type node_id1, osmium::object_id_type node_id2, osmium::Location location) override { | ||||||
|  |                 write_point("duplicate_node", node_id1, node_id2, location); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             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 { | ||||||
|  |                 write_point("intersection", m_object_id, 0, intersection); | ||||||
|  |                 write_line("intersection", m_object_id, way1_id, way1_seg_start, way1_seg_end); | ||||||
|  |                 write_line("intersection", m_object_id, way2_id, way2_seg_start, way2_seg_end); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void report_ring_not_closed(osmium::Location end1, osmium::Location end2) override { | ||||||
|  |                 write_point("ring_not_closed", m_object_id, 0, end1); | ||||||
|  |                 write_point("ring_not_closed", m_object_id, 0, end2); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void report_role_should_be_outer(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) override { | ||||||
|  |                 write_line("role_should_be_outer", m_object_id, way_id, seg_start, seg_end); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void report_role_should_be_inner(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) override { | ||||||
|  |                 write_line("role_should_be_inner", m_object_id, way_id, seg_start, seg_end); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class ProblemReporterOGR
 | ||||||
|  | 
 | ||||||
|  |     } // namespace area
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_AREA_PROBLEM_REPORTER_OGR_HPP
 | ||||||
							
								
								
									
										96
									
								
								ThirdParty/osmium/area/problem_reporter_stream.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								ThirdParty/osmium/area/problem_reporter_stream.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +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 <jochen@topf.org> 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 <ostream> | ||||||
|  | 
 | ||||||
|  | #include <osmium/area/problem_reporter.hpp> | ||||||
|  | #include <osmium/osm/item_type.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/types.hpp> | ||||||
|  | 
 | ||||||
|  | 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
 | ||||||
							
								
								
									
										179
									
								
								ThirdParty/osmium/builder/builder.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								ThirdParty/osmium/builder/builder.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,179 @@ | |||||||
|  | #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 <jochen@topf.org> 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 <cassert> | ||||||
|  | #include <cstddef> | ||||||
|  | #include <cstdint> | ||||||
|  | #include <cstring> | ||||||
|  | #include <new> | ||||||
|  | 
 | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/memory/item.hpp> | ||||||
|  | 
 | ||||||
|  | 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<osmium::memory::Item*>(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 <class T> | ||||||
|  |             T* reserve_space_for() { | ||||||
|  |                 assert(m_buffer.is_aligned()); | ||||||
|  |                 return reinterpret_cast<T*>(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 T> | ||||||
|  |         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<T&>(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
 | ||||||
							
								
								
									
										103
									
								
								ThirdParty/osmium/builder/builder_helper.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								ThirdParty/osmium/builder/builder_helper.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | |||||||
|  | #ifndef OSMIUM_BUILDER_BUILDER_HELPER_HPP | ||||||
|  | #define OSMIUM_BUILDER_BUILDER_HELPER_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cstddef> | ||||||
|  | #include <initializer_list> | ||||||
|  | #include <functional> | ||||||
|  | #include <map> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/builder/osm_object_builder.hpp> | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     class NodeRef; | ||||||
|  |     class TagList; | ||||||
|  |     class WayNodeList; | ||||||
|  | 
 | ||||||
|  |     namespace builder { | ||||||
|  | 
 | ||||||
|  |         inline const osmium::WayNodeList& build_way_node_list(osmium::memory::Buffer& buffer, std::initializer_list<osmium::NodeRef> nodes) { | ||||||
|  |             size_t pos = buffer.committed(); | ||||||
|  |             { | ||||||
|  |                 osmium::builder::WayNodeListBuilder wnl_builder(buffer); | ||||||
|  |                 for (const auto& node_ref : nodes) { | ||||||
|  |                     wnl_builder.add_node_ref(node_ref); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             buffer.commit(); | ||||||
|  |             return buffer.get<const osmium::WayNodeList>(pos); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         inline const osmium::TagList& build_tag_list(osmium::memory::Buffer& buffer, std::initializer_list<std::pair<const char*, const char*>> tags) { | ||||||
|  |             size_t pos = buffer.committed(); | ||||||
|  |             { | ||||||
|  |                 osmium::builder::TagListBuilder tl_builder(buffer); | ||||||
|  |                 for (const auto& p : tags) { | ||||||
|  |                     tl_builder.add_tag(p.first, p.second); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             buffer.commit(); | ||||||
|  |             return buffer.get<const osmium::TagList>(pos); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         inline const osmium::TagList& build_tag_list(osmium::memory::Buffer& buffer, const std::map<const char*, const char*>& tags) { | ||||||
|  |             size_t pos = buffer.committed(); | ||||||
|  |             { | ||||||
|  |                 osmium::builder::TagListBuilder tl_builder(buffer); | ||||||
|  |                 for (const auto& p : tags) { | ||||||
|  |                     tl_builder.add_tag(p.first, p.second); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             buffer.commit(); | ||||||
|  |             return buffer.get<const osmium::TagList>(pos); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         inline const osmium::TagList& build_tag_list(osmium::memory::Buffer& buffer, std::function<void(osmium::builder::TagListBuilder&)> func) { | ||||||
|  |             size_t pos = buffer.committed(); | ||||||
|  |             { | ||||||
|  |                 osmium::builder::TagListBuilder tl_builder(buffer); | ||||||
|  |                 func(tl_builder); | ||||||
|  |             } | ||||||
|  |             buffer.commit(); | ||||||
|  |             return buffer.get<const osmium::TagList>(pos); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } // namespace builder
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_BUILDER_BUILDER_HELPER_HPP
 | ||||||
							
								
								
									
										207
									
								
								ThirdParty/osmium/builder/osm_object_builder.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								ThirdParty/osmium/builder/osm_object_builder.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,207 @@ | |||||||
|  | #ifndef OSMIUM_BUILDER_OSM_OBJECT_BUILDER_HPP | ||||||
|  | #define OSMIUM_BUILDER_OSM_OBJECT_BUILDER_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cstring> | ||||||
|  | #include <initializer_list> | ||||||
|  | #include <new> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/builder/builder.hpp> | ||||||
|  | #include <osmium/osm.hpp> | ||||||
|  | #include <osmium/osm/item_type.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/node_ref.hpp> | ||||||
|  | #include <osmium/osm/object.hpp> | ||||||
|  | #include <osmium/osm/tag.hpp> | ||||||
|  | #include <osmium/osm/types.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace memory { | ||||||
|  |         class Buffer; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     namespace builder { | ||||||
|  | 
 | ||||||
|  |         class TagListBuilder : public ObjectBuilder<TagList> { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             explicit TagListBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) : | ||||||
|  |                 ObjectBuilder<TagList>(buffer, parent) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             ~TagListBuilder() { | ||||||
|  |                 add_padding(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void add_tag(const char* key, const char* value) { | ||||||
|  |                 add_size(append(key) + append(value)); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class TagListBuilder
 | ||||||
|  | 
 | ||||||
|  |         template <class T> | ||||||
|  |         class NodeRefListBuilder : public ObjectBuilder<T> { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             explicit NodeRefListBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) : | ||||||
|  |                 ObjectBuilder<T>(buffer, parent) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             ~NodeRefListBuilder() { | ||||||
|  |                 static_cast<Builder*>(this)->add_padding(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void add_node_ref(const NodeRef& node_ref) { | ||||||
|  |                 new (static_cast<Builder*>(this)->reserve_space_for<osmium::NodeRef>()) osmium::NodeRef(node_ref); | ||||||
|  |                 static_cast<Builder*>(this)->add_size(sizeof(osmium::NodeRef)); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void add_node_ref(const object_id_type ref, const osmium::Location location=Location()) { | ||||||
|  |                 add_node_ref(NodeRef(ref, location)); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class NodeRefListBuilder
 | ||||||
|  | 
 | ||||||
|  |         typedef NodeRefListBuilder<WayNodeList> WayNodeListBuilder; | ||||||
|  |         typedef NodeRefListBuilder<OuterRing> OuterRingBuilder; | ||||||
|  |         typedef NodeRefListBuilder<InnerRing> InnerRingBuilder; | ||||||
|  | 
 | ||||||
|  |         class RelationMemberListBuilder : public ObjectBuilder<RelationMemberList> { | ||||||
|  | 
 | ||||||
|  |             void add_role(osmium::RelationMember* member, const char* role) { | ||||||
|  |                 size_t length = std::strlen(role) + 1; | ||||||
|  |                 assert(length < std::numeric_limits<string_size_type>::max()); | ||||||
|  |                 member->set_role_size(static_cast<string_size_type>(length)); | ||||||
|  |                 add_size(append(role)); | ||||||
|  |                 add_padding(true); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             explicit RelationMemberListBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) : | ||||||
|  |                 ObjectBuilder<RelationMemberList>(buffer, parent) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             ~RelationMemberListBuilder() { | ||||||
|  |                 add_padding(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             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<osmium::RelationMember>(); | ||||||
|  |                 new (member) osmium::RelationMember(ref, type, full_member != nullptr); | ||||||
|  |                 add_size(sizeof(RelationMember)); | ||||||
|  |                 add_role(member, role); | ||||||
|  |                 if (full_member) { | ||||||
|  |                     add_item(full_member); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class RelationMemberListBuilder
 | ||||||
|  | 
 | ||||||
|  |         template <class T> | ||||||
|  |         class OSMObjectBuilder : public ObjectBuilder<T> { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             explicit OSMObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) : | ||||||
|  |                 ObjectBuilder<T>(buffer, parent) { | ||||||
|  |                 static_cast<Builder*>(this)->reserve_space_for<string_size_type>(); | ||||||
|  |                 static_cast<Builder*>(this)->add_size(sizeof(string_size_type)); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void add_tags(std::initializer_list<std::pair<const char*, const char*>> tags) { | ||||||
|  |                 osmium::builder::TagListBuilder tl_builder(static_cast<Builder*>(this)->buffer(), this); | ||||||
|  |                 for (const auto& p : tags) { | ||||||
|  |                     tl_builder.add_tag(p.first, p.second); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class OSMObjectBuilder
 | ||||||
|  | 
 | ||||||
|  |         typedef OSMObjectBuilder<osmium::Node> NodeBuilder; | ||||||
|  |         typedef OSMObjectBuilder<osmium::Relation> RelationBuilder; | ||||||
|  | 
 | ||||||
|  |         class WayBuilder : public OSMObjectBuilder<osmium::Way> { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             explicit WayBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) : | ||||||
|  |                 OSMObjectBuilder<osmium::Way>(buffer, parent) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void add_node_refs(std::initializer_list<osmium::NodeRef> nodes) { | ||||||
|  |                 osmium::builder::WayNodeListBuilder builder(buffer(), this); | ||||||
|  |                 for (const auto& node_ref : nodes) { | ||||||
|  |                     builder.add_node_ref(node_ref); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class WayBuilder
 | ||||||
|  | 
 | ||||||
|  |         class AreaBuilder : public OSMObjectBuilder<osmium::Area> { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             explicit AreaBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) : | ||||||
|  |                 OSMObjectBuilder<osmium::Area>(buffer, parent) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Initialize area attributes from the attributes of the given object. | ||||||
|  |              */ | ||||||
|  |             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()); | ||||||
|  | 
 | ||||||
|  |                 add_user(source.user()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class AreaBuilder
 | ||||||
|  | 
 | ||||||
|  |         typedef ObjectBuilder<osmium::Changeset> ChangesetBuilder; | ||||||
|  | 
 | ||||||
|  |     } // namespace builder
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_BUILDER_OSM_OBJECT_BUILDER_HPP
 | ||||||
							
								
								
									
										67
									
								
								ThirdParty/osmium/diff_handler.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								ThirdParty/osmium/diff_handler.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,67 @@ | |||||||
|  | #ifndef OSMIUM_DIFF_HANDLER_HPP | ||||||
|  | #define OSMIUM_DIFF_HANDLER_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <osmium/osm/diff_object.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Osmium diff handlers provide access to differences between OSM object versions | ||||||
|  |      */ | ||||||
|  |     namespace diff_handler { | ||||||
|  | 
 | ||||||
|  |         class DiffHandler { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             DiffHandler() { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void node(const osmium::DiffNode&) const { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void way(const osmium::DiffWay&) const { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void relation(const osmium::DiffRelation&) const { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class DiffHandler
 | ||||||
|  | 
 | ||||||
|  |     } // namespace diff_handler
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_DIFF_HANDLER_HPP
 | ||||||
							
								
								
									
										129
									
								
								ThirdParty/osmium/diff_iterator.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								ThirdParty/osmium/diff_iterator.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,129 @@ | |||||||
|  | #ifndef OSMIUM_DIFF_ITERATOR_HPP | ||||||
|  | #define OSMIUM_DIFF_ITERATOR_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cassert> | ||||||
|  | #include <iterator> | ||||||
|  | #include <type_traits> | ||||||
|  | 
 | ||||||
|  | #include <osmium/osm/diff_object.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     class OSMObject; | ||||||
|  | 
 | ||||||
|  |     template <class TBasicIterator> | ||||||
|  |     class DiffIterator : public std::iterator<std::input_iterator_tag, const osmium::DiffObject> { | ||||||
|  | 
 | ||||||
|  |         static_assert(std::is_base_of<osmium::OSMObject, typename TBasicIterator::value_type>::value, "TBasicIterator::value_type must derive from osmium::OSMObject"); | ||||||
|  | 
 | ||||||
|  |         TBasicIterator m_prev; | ||||||
|  |         TBasicIterator m_curr; | ||||||
|  |         TBasicIterator m_next; | ||||||
|  | 
 | ||||||
|  |         const TBasicIterator m_end; | ||||||
|  | 
 | ||||||
|  |         mutable osmium::DiffObject m_diff {}; | ||||||
|  | 
 | ||||||
|  |         void set_diff() const { | ||||||
|  |             assert(m_curr != m_end); | ||||||
|  | 
 | ||||||
|  |             TBasicIterator prev = m_prev; | ||||||
|  |             if (prev->type() != m_curr->type() || prev->id() != m_curr->id()) { | ||||||
|  |                 prev = m_curr; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             TBasicIterator next = m_next; | ||||||
|  |             if (next == m_end || next->type() != m_curr->type() || next->id() != m_curr->id()) { | ||||||
|  |                 next = m_curr; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             m_diff = osmium::DiffObject(*prev, *m_curr, *next); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     public: | ||||||
|  | 
 | ||||||
|  |         explicit DiffIterator(TBasicIterator begin, TBasicIterator end) : | ||||||
|  |             m_prev(begin), | ||||||
|  |             m_curr(begin), | ||||||
|  |             m_next(begin == end ? begin : ++begin), | ||||||
|  |             m_end(end) { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         DiffIterator(const DiffIterator& other) = default; | ||||||
|  |         DiffIterator& operator=(const DiffIterator& other) = default; | ||||||
|  | 
 | ||||||
|  |         DiffIterator(DiffIterator&& other) = default; | ||||||
|  |         DiffIterator& operator=(DiffIterator&& other) = default; | ||||||
|  | 
 | ||||||
|  |         DiffIterator& operator++() { | ||||||
|  |             m_prev = std::move(m_curr); | ||||||
|  |             m_curr = m_next; | ||||||
|  | 
 | ||||||
|  |             if (m_next != m_end) { | ||||||
|  |                 ++m_next; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         DiffIterator operator++(int) { | ||||||
|  |             DiffIterator tmp(*this); | ||||||
|  |             operator++(); | ||||||
|  |             return tmp; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         bool operator==(const DiffIterator& rhs) const { | ||||||
|  |             return m_curr == rhs.m_curr && m_end == rhs.m_end; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         bool operator!=(const DiffIterator& rhs) const { | ||||||
|  |             return !(*this == rhs); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         reference operator*() const { | ||||||
|  |             set_diff(); | ||||||
|  |             return m_diff; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         pointer operator->() const { | ||||||
|  |             set_diff(); | ||||||
|  |             return &m_diff; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     }; // class DiffIterator
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_DIFF_ITERATOR_HPP
 | ||||||
							
								
								
									
										104
									
								
								ThirdParty/osmium/diff_visitor.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								ThirdParty/osmium/diff_visitor.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,104 @@ | |||||||
|  | #ifndef OSMIUM_DIFF_VISITOR_HPP | ||||||
|  | #define OSMIUM_DIFF_VISITOR_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <osmium/diff_iterator.hpp> | ||||||
|  | #include <osmium/io/input_iterator.hpp> | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/osm/diff_object.hpp> | ||||||
|  | #include <osmium/osm/item_type.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace detail { | ||||||
|  | 
 | ||||||
|  |         template <class THandler> | ||||||
|  |         inline void apply_diff_iterator_recurse(const osmium::DiffObject& diff, THandler& handler) { | ||||||
|  |             switch (diff.type()) { | ||||||
|  |                 case osmium::item_type::node: | ||||||
|  |                     handler.node(static_cast<const osmium::DiffNode&>(diff)); | ||||||
|  |                     break; | ||||||
|  |                 case osmium::item_type::way: | ||||||
|  |                     handler.way(static_cast<const osmium::DiffWay&>(diff)); | ||||||
|  |                     break; | ||||||
|  |                 case osmium::item_type::relation: | ||||||
|  |                     handler.relation(static_cast<const osmium::DiffRelation&>(diff)); | ||||||
|  |                     break; | ||||||
|  |                 default: | ||||||
|  |                     throw osmium::unknown_type(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         template <class THandler, class ...TRest> | ||||||
|  |         inline void apply_diff_iterator_recurse(const osmium::DiffObject& diff, THandler& handler, TRest&... more) { | ||||||
|  |             apply_diff_iterator_recurse(diff, handler); | ||||||
|  |             apply_diff_iterator_recurse(diff, more...); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     template <class TIterator, class ...THandlers> | ||||||
|  |     inline void apply_diff(TIterator it, TIterator end, THandlers&... handlers) { | ||||||
|  |         typedef osmium::DiffIterator<TIterator> diff_iterator; | ||||||
|  | 
 | ||||||
|  |         diff_iterator dit(it, end); | ||||||
|  |         diff_iterator dend(end, end); | ||||||
|  | 
 | ||||||
|  |         for (; dit != dend; ++dit) { | ||||||
|  |             detail::apply_diff_iterator_recurse(*dit, handlers...); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     class OSMObject; | ||||||
|  | 
 | ||||||
|  |     template <class TSource, class ...THandlers> | ||||||
|  |     inline void apply_diff(TSource& source, THandlers&... handlers) { | ||||||
|  |         apply_diff(osmium::io::InputIterator<TSource, osmium::OSMObject> {source}, | ||||||
|  |                    osmium::io::InputIterator<TSource, osmium::OSMObject> {}, | ||||||
|  |                    handlers...); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     template <class ...THandlers> | ||||||
|  |     inline void apply_diff(osmium::memory::Buffer& buffer, THandlers&... handlers) { | ||||||
|  |         apply_diff(buffer.begin(), buffer.end(), handlers...); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     template <class ...THandlers> | ||||||
|  |     inline void apply_diff(const osmium::memory::Buffer& buffer, THandlers&... handlers) { | ||||||
|  |         apply_diff(buffer.cbegin(), buffer.cend(), handlers...); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_DIFF_VISITOR_HPP
 | ||||||
							
								
								
									
										195
									
								
								ThirdParty/osmium/dynamic_handler.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								ThirdParty/osmium/dynamic_handler.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +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 <jochen@topf.org> 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 <memory> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/handler.hpp> | ||||||
|  | 
 | ||||||
|  | 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 <class THandler> \ | ||||||
|  | auto _name_##_dispatch(THandler& handler, const osmium::_type_& object, int) -> decltype(handler._name_(object), void()) { \ | ||||||
|  |     handler._name_(object); \ | ||||||
|  | } \ | ||||||
|  | template <class THandler> \ | ||||||
|  | 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 <class THandler> | ||||||
|  |             auto flush_dispatch(THandler& handler, int) -> decltype(handler.flush(), void()) { | ||||||
|  |                 handler.flush(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <class THandler> | ||||||
|  |             void flush_dispatch(THandler&, long) {} | ||||||
|  | 
 | ||||||
|  |             template <class THandler> | ||||||
|  |             class HandlerWrapper : public HandlerWrapperBase { | ||||||
|  | 
 | ||||||
|  |                 THandler m_handler; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 template <class... TArgs> | ||||||
|  |                 HandlerWrapper(TArgs&&... args) : | ||||||
|  |                     m_handler(std::forward<TArgs>(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<osmium::handler::detail::HandlerWrapperBase> impl_ptr; | ||||||
|  |             impl_ptr m_impl; | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             DynamicHandler() : | ||||||
|  |                 m_impl(impl_ptr(new osmium::handler::detail::HandlerWrapperBase)) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <class THandler, class... TArgs> | ||||||
|  |             void set(TArgs&&... args) { | ||||||
|  |                 m_impl = impl_ptr(new osmium::handler::detail::HandlerWrapper<THandler>(std::forward<TArgs>(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
 | ||||||
							
								
								
									
										106
									
								
								ThirdParty/osmium/geom/coordinates.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								ThirdParty/osmium/geom/coordinates.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,106 @@ | |||||||
|  | #ifndef OSMIUM_GEOM_COORDINATES_HPP | ||||||
|  | #define OSMIUM_GEOM_COORDINATES_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cstddef> | ||||||
|  | #include <iosfwd> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | 
 | ||||||
|  | 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) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             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); | ||||||
|  |                 s += infix; | ||||||
|  |                 osmium::geom::detail::double2string(s, y); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void append_to_string(std::string& s, const char prefix, const char infix, const char suffix) const { | ||||||
|  |                 s += prefix; | ||||||
|  |                 append_to_string(s, infix); | ||||||
|  |                 s += suffix; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // struct coordinates
 | ||||||
|  | 
 | ||||||
|  |         inline bool operator==(const Coordinates& lhs, const Coordinates& rhs) { | ||||||
|  |             return lhs.x == rhs.x && lhs.y == rhs.y; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         inline bool operator!=(const Coordinates& lhs, const Coordinates& rhs) { | ||||||
|  |             return ! operator==(lhs, rhs); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         template <typename TChar, typename TTraits> | ||||||
|  |         inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const Coordinates& c) { | ||||||
|  |             return out << '(' << c.x << ',' << c.y << ')'; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } // namespace geom
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_GEOM_COORDINATES_HPP
 | ||||||
							
								
								
									
										284
									
								
								ThirdParty/osmium/geom/factory.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										284
									
								
								ThirdParty/osmium/geom/factory.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,284 @@ | |||||||
|  | #ifndef OSMIUM_GEOM_FACTORY_HPP | ||||||
|  | #define OSMIUM_GEOM_FACTORY_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <stdexcept> | ||||||
|  | #include <string> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/geom/coordinates.hpp> | ||||||
|  | #include <osmium/memory/collection.hpp> | ||||||
|  | #include <osmium/memory/item.hpp> | ||||||
|  | #include <osmium/osm/area.hpp> | ||||||
|  | #include <osmium/osm/item_type.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/node.hpp> | ||||||
|  | #include <osmium/osm/node_ref.hpp> | ||||||
|  | #include <osmium/osm/way.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     struct geometry_error : public std::runtime_error { | ||||||
|  | 
 | ||||||
|  |         geometry_error(const std::string& what) : | ||||||
|  |             std::runtime_error(what) { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         geometry_error(const char* what) : | ||||||
|  |             std::runtime_error(what) { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     }; // struct geometry_error
 | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Everything related to geometry handling. | ||||||
|  |      */ | ||||||
|  |     namespace geom { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Which nodes of a way to use for a linestring. | ||||||
|  |          */ | ||||||
|  |         enum class use_nodes : bool { | ||||||
|  |             unique = true, ///< Remove consecutive nodes with same location.
 | ||||||
|  |             all    = false ///< Use all nodes.
 | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Which direction the linestring created from a way | ||||||
|  |          * should have. | ||||||
|  |          */ | ||||||
|  |         enum class direction : bool { | ||||||
|  |             backward = true, ///< Linestring has reverse direction.
 | ||||||
|  |             forward  = false ///< Linestring has same direction as way.
 | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * This pseudo projection just returns its WGS84 input unchanged. | ||||||
|  |          * Used as a template parameter if a real projection is not needed. | ||||||
|  |          */ | ||||||
|  |         class IdentityProjection { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             Coordinates operator()(osmium::Location location) const { | ||||||
|  |                 return Coordinates{location.lon(), location.lat()}; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             int epsg() const { | ||||||
|  |                 return 4326; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             std::string proj_string() const { | ||||||
|  |                 return "+proj=longlat +datum=WGS84 +no_defs"; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class IdentityProjection
 | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Geometry factory. | ||||||
|  |          */ | ||||||
|  |         template <class TGeomImpl, class TProjection = IdentityProjection> | ||||||
|  |         class GeometryFactory { | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Add all points of an outer or inner ring to a multipolygon. | ||||||
|  |              */ | ||||||
|  |             void add_points(const osmium::OuterRing& nodes) { | ||||||
|  |                 osmium::Location last_location; | ||||||
|  |                 for (const osmium::NodeRef& node_ref : nodes) { | ||||||
|  |                     if (last_location != node_ref.location()) { | ||||||
|  |                         last_location = node_ref.location(); | ||||||
|  |                         m_impl.multipolygon_add_location(m_projection(last_location)); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             TProjection m_projection; | ||||||
|  |             TGeomImpl m_impl; | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             GeometryFactory<TGeomImpl, TProjection>() = default; | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Constructor for default initialized projection. | ||||||
|  |              */ | ||||||
|  |             template <class... TArgs> | ||||||
|  |             GeometryFactory<TGeomImpl, TProjection>(TArgs&&... args) : | ||||||
|  |                 m_projection(), | ||||||
|  |                 m_impl(std::forward<TArgs>(args)...) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Constructor for explicitly initialized projection. Note that the | ||||||
|  |              * projection is moved into the GeometryFactory. | ||||||
|  |              */ | ||||||
|  |             template <class... TArgs> | ||||||
|  |             GeometryFactory<TGeomImpl, TProjection>(TProjection&& projection, TArgs&&... args) : | ||||||
|  |                 m_projection(std::move(projection)), | ||||||
|  |                 m_impl(std::forward<TArgs>(args)...) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             typedef typename TGeomImpl::point_type        point_type; | ||||||
|  |             typedef typename TGeomImpl::linestring_type   linestring_type; | ||||||
|  |             typedef typename TGeomImpl::polygon_type      polygon_type; | ||||||
|  |             typedef typename TGeomImpl::multipolygon_type multipolygon_type; | ||||||
|  |             typedef typename TGeomImpl::ring_type         ring_type; | ||||||
|  | 
 | ||||||
|  |             int epsg() const { | ||||||
|  |                 return m_projection.epsg(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             std::string proj_string() const { | ||||||
|  |                 return m_projection.proj_string(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /* Point */ | ||||||
|  | 
 | ||||||
|  |             point_type create_point(const osmium::Location location) const { | ||||||
|  |                 return m_impl.make_point(m_projection(location)); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             point_type create_point(const osmium::Node& node) { | ||||||
|  |                 return create_point(node.location()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             point_type create_point(const osmium::NodeRef& node_ref) { | ||||||
|  |                 return create_point(node_ref.location()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /* LineString */ | ||||||
|  | 
 | ||||||
|  |             template <class TIter> | ||||||
|  |             size_t fill_linestring(TIter it, TIter end) { | ||||||
|  |                 size_t num_points = 0; | ||||||
|  |                 for (; it != end; ++it, ++num_points) { | ||||||
|  |                     m_impl.linestring_add_location(m_projection(it->location())); | ||||||
|  |                 } | ||||||
|  |                 return num_points; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <class TIter> | ||||||
|  |             size_t fill_linestring_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.linestring_add_location(m_projection(last_location)); | ||||||
|  |                         ++num_points; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 return num_points; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             linestring_type create_linestring(const osmium::WayNodeList& wnl, use_nodes un=use_nodes::unique, direction dir=direction::forward) { | ||||||
|  |                 m_impl.linestring_start(); | ||||||
|  |                 size_t num_points = 0; | ||||||
|  | 
 | ||||||
|  |                 if (un == use_nodes::unique) { | ||||||
|  |                     osmium::Location last_location; | ||||||
|  |                     switch (dir) { | ||||||
|  |                         case direction::forward: | ||||||
|  |                             num_points = fill_linestring_unique(wnl.cbegin(), wnl.cend()); | ||||||
|  |                             break; | ||||||
|  |                         case direction::backward: | ||||||
|  |                             num_points = fill_linestring_unique(wnl.crbegin(), wnl.crend()); | ||||||
|  |                             break; | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     switch (dir) { | ||||||
|  |                         case direction::forward: | ||||||
|  |                             num_points = fill_linestring(wnl.cbegin(), wnl.cend()); | ||||||
|  |                             break; | ||||||
|  |                         case direction::backward: | ||||||
|  |                             num_points = fill_linestring(wnl.crbegin(), wnl.crend()); | ||||||
|  |                             break; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if (num_points < 2) { | ||||||
|  |                     throw geometry_error("not enough points for linestring"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 return m_impl.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); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /* MultiPolygon */ | ||||||
|  | 
 | ||||||
|  |             multipolygon_type create_multipolygon(const osmium::Area& area) { | ||||||
|  |                 size_t num_polygons = 0; | ||||||
|  |                 size_t num_rings = 0; | ||||||
|  |                 m_impl.multipolygon_start(); | ||||||
|  | 
 | ||||||
|  |                 for (auto it = area.cbegin(); it != area.cend(); ++it) { | ||||||
|  |                     const osmium::OuterRing& ring = static_cast<const osmium::OuterRing&>(*it); | ||||||
|  |                     if (it->type() == osmium::item_type::outer_ring) { | ||||||
|  |                         if (num_polygons > 0) { | ||||||
|  |                             m_impl.multipolygon_polygon_finish(); | ||||||
|  |                         } | ||||||
|  |                         m_impl.multipolygon_polygon_start(); | ||||||
|  |                         m_impl.multipolygon_outer_ring_start(); | ||||||
|  |                         add_points(ring); | ||||||
|  |                         m_impl.multipolygon_outer_ring_finish(); | ||||||
|  |                         ++num_rings; | ||||||
|  |                         ++num_polygons; | ||||||
|  |                     } else if (it->type() == osmium::item_type::inner_ring) { | ||||||
|  |                         m_impl.multipolygon_inner_ring_start(); | ||||||
|  |                         add_points(ring); | ||||||
|  |                         m_impl.multipolygon_inner_ring_finish(); | ||||||
|  |                         ++num_rings; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 // if there are no rings, this area is invalid
 | ||||||
|  |                 if (num_rings == 0) { | ||||||
|  |                     throw geometry_error("invalid area"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 m_impl.multipolygon_polygon_finish(); | ||||||
|  |                 return m_impl.multipolygon_finish(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class GeometryFactory
 | ||||||
|  | 
 | ||||||
|  |     } // namespace geom
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_GEOM_FACTORY_HPP
 | ||||||
							
								
								
									
										149
									
								
								ThirdParty/osmium/geom/geojson.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								ThirdParty/osmium/geom/geojson.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,149 @@ | |||||||
|  | #ifndef OSMIUM_GEOM_GEOJSON_HPP | ||||||
|  | #define OSMIUM_GEOM_GEOJSON_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cassert> | ||||||
|  | #include <string> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/geom/coordinates.hpp> | ||||||
|  | #include <osmium/geom/factory.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace geom { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             class GeoJSONFactoryImpl { | ||||||
|  | 
 | ||||||
|  |                 std::string m_str {}; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 typedef std::string point_type; | ||||||
|  |                 typedef std::string linestring_type; | ||||||
|  |                 typedef std::string polygon_type; | ||||||
|  |                 typedef std::string multipolygon_type; | ||||||
|  |                 typedef std::string ring_type; | ||||||
|  | 
 | ||||||
|  |                 GeoJSONFactoryImpl() = default; | ||||||
|  | 
 | ||||||
|  |                 /* 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, '[', ',', ']'); | ||||||
|  |                     str += "}"; | ||||||
|  |                     return str; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /* LineString */ | ||||||
|  | 
 | ||||||
|  |                 // { "type": "LineString", "coordinates": [ [100.0, 0.0], [101.0, 1.0] ] }
 | ||||||
|  |                 void linestring_start() { | ||||||
|  |                     m_str = "{\"type\":\"LineString\",\"coordinates\":["; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void linestring_add_location(const osmium::geom::Coordinates& xy) { | ||||||
|  |                     xy.append_to_string(m_str, '[', ',', ']'); | ||||||
|  |                     m_str += ','; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 linestring_type linestring_finish(size_t /* num_points */) { | ||||||
|  |                     assert(!m_str.empty()); | ||||||
|  |                     std::string str; | ||||||
|  |                     std::swap(str, m_str); | ||||||
|  |                     str.back() = ']'; | ||||||
|  |                     str += "}"; | ||||||
|  |                     return str; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /* MultiPolygon */ | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_start() { | ||||||
|  |                     m_str = "{\"type\":\"MultiPolygon\",\"coordinates\":["; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_polygon_start() { | ||||||
|  |                     m_str += '['; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_polygon_finish() { | ||||||
|  |                     m_str += "],"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_outer_ring_start() { | ||||||
|  |                     m_str += '['; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_outer_ring_finish() { | ||||||
|  |                     assert(!m_str.empty()); | ||||||
|  |                     m_str.back() = ']'; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_inner_ring_start() { | ||||||
|  |                     m_str += ",["; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_inner_ring_finish() { | ||||||
|  |                     assert(!m_str.empty()); | ||||||
|  |                     m_str.back() = ']'; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_add_location(const osmium::geom::Coordinates& xy) { | ||||||
|  |                     xy.append_to_string(m_str, '[', ',', ']'); | ||||||
|  |                     m_str += ','; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 multipolygon_type multipolygon_finish() { | ||||||
|  |                     assert(!m_str.empty()); | ||||||
|  |                     m_str.back() = ']'; | ||||||
|  |                     m_str += "}"; | ||||||
|  |                     return std::move(m_str); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class GeoJSONFactoryImpl
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |         template <class TProjection = IdentityProjection> | ||||||
|  |         using GeoJSONFactory = GeometryFactory<osmium::geom::detail::GeoJSONFactoryImpl, TProjection>; | ||||||
|  | 
 | ||||||
|  |     } // namespace geom
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_GEOM_GEOJSON_HPP
 | ||||||
							
								
								
									
										215
									
								
								ThirdParty/osmium/geom/geos.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								ThirdParty/osmium/geom/geos.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,215 @@ | |||||||
|  | #ifndef OSMIUM_GEOM_GEOS_HPP | ||||||
|  | #define OSMIUM_GEOM_GEOS_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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. | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #define OSMIUM_COMPILE_WITH_CFLAGS_GEOS `geos-config --cflags` | ||||||
|  | #define OSMIUM_LINK_WITH_LIBS_GEOS `geos-config --libs` | ||||||
|  | 
 | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <geos/geom/Coordinate.h> | ||||||
|  | #include <geos/geom/CoordinateSequence.h> | ||||||
|  | #include <geos/geom/CoordinateSequenceFactory.h> | ||||||
|  | #include <geos/geom/GeometryFactory.h> | ||||||
|  | #include <geos/geom/LinearRing.h> | ||||||
|  | #include <geos/geom/MultiPolygon.h> | ||||||
|  | #include <geos/geom/Point.h> | ||||||
|  | #include <geos/geom/Polygon.h> | ||||||
|  | #include <geos/geom/PrecisionModel.h> | ||||||
|  | #include <geos/util/GEOSException.h> | ||||||
|  | 
 | ||||||
|  | #include <osmium/geom/factory.hpp> | ||||||
|  | #include <osmium/geom/coordinates.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     struct geos_geometry_error : public geometry_error { | ||||||
|  | 
 | ||||||
|  |         geos_geometry_error() : | ||||||
|  |             geometry_error("geometry creation failed in GEOS library, see nested exception for details") { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     }; // struct geos_geometry_error
 | ||||||
|  | 
 | ||||||
|  |     namespace geom { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             class GEOSFactoryImpl { | ||||||
|  | 
 | ||||||
|  |                 geos::geom::PrecisionModel m_precision_model; | ||||||
|  |                 geos::geom::GeometryFactory m_geos_factory; | ||||||
|  | 
 | ||||||
|  |                 std::unique_ptr<geos::geom::CoordinateSequence> m_coordinate_sequence; | ||||||
|  |                 std::vector<std::unique_ptr<geos::geom::LinearRing>> m_rings; | ||||||
|  |                 std::vector<std::unique_ptr<geos::geom::Polygon>> m_polygons; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 typedef std::unique_ptr<geos::geom::Point>        point_type; | ||||||
|  |                 typedef std::unique_ptr<geos::geom::LineString>   linestring_type; | ||||||
|  |                 typedef std::unique_ptr<geos::geom::Polygon>      polygon_type; | ||||||
|  |                 typedef std::unique_ptr<geos::geom::MultiPolygon> multipolygon_type; | ||||||
|  |                 typedef std::unique_ptr<geos::geom::LinearRing>   ring_type; | ||||||
|  | 
 | ||||||
|  |                 explicit GEOSFactoryImpl(int srid = -1) : | ||||||
|  |                     m_precision_model(), | ||||||
|  |                     m_geos_factory(&m_precision_model, srid) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /* Point */ | ||||||
|  | 
 | ||||||
|  |                 point_type make_point(const osmium::geom::Coordinates& xy) const { | ||||||
|  |                     try { | ||||||
|  |                         return point_type(m_geos_factory.createPoint(geos::geom::Coordinate(xy.x, xy.y))); | ||||||
|  |                     } catch (geos::util::GEOSException&) { | ||||||
|  |                         std::throw_with_nested(osmium::geos_geometry_error()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /* LineString */ | ||||||
|  | 
 | ||||||
|  |                 void linestring_start() { | ||||||
|  |                     try { | ||||||
|  |                         m_coordinate_sequence.reset(m_geos_factory.getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2)); | ||||||
|  |                     } catch (geos::util::GEOSException&) { | ||||||
|  |                         std::throw_with_nested(osmium::geos_geometry_error()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void linestring_add_location(const osmium::geom::Coordinates& xy) { | ||||||
|  |                     try { | ||||||
|  |                         m_coordinate_sequence->add(geos::geom::Coordinate(xy.x, xy.y)); | ||||||
|  |                     } catch (geos::util::GEOSException&) { | ||||||
|  |                         std::throw_with_nested(osmium::geos_geometry_error()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 linestring_type linestring_finish(size_t /* num_points */) { | ||||||
|  |                     try { | ||||||
|  |                         return linestring_type(m_geos_factory.createLineString(m_coordinate_sequence.release())); | ||||||
|  |                     } catch (geos::util::GEOSException&) { | ||||||
|  |                         std::throw_with_nested(osmium::geos_geometry_error()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /* MultiPolygon */ | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_start() { | ||||||
|  |                     m_polygons.clear(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_polygon_start() { | ||||||
|  |                     m_rings.clear(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_polygon_finish() { | ||||||
|  |                     try { | ||||||
|  |                         assert(!m_rings.empty()); | ||||||
|  |                         auto inner_rings = new std::vector<geos::geom::Geometry*>; | ||||||
|  |                         std::transform(std::next(m_rings.begin(), 1), m_rings.end(), std::back_inserter(*inner_rings), [](std::unique_ptr<geos::geom::LinearRing>& r) { | ||||||
|  |                             return r.release(); | ||||||
|  |                         }); | ||||||
|  |                         m_polygons.emplace_back(m_geos_factory.createPolygon(m_rings[0].release(), inner_rings)); | ||||||
|  |                         m_rings.clear(); | ||||||
|  |                     } catch (geos::util::GEOSException&) { | ||||||
|  |                         std::throw_with_nested(osmium::geos_geometry_error()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_outer_ring_start() { | ||||||
|  |                     try { | ||||||
|  |                         m_coordinate_sequence.reset(m_geos_factory.getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2)); | ||||||
|  |                     } catch (geos::util::GEOSException&) { | ||||||
|  |                         std::throw_with_nested(osmium::geos_geometry_error()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_outer_ring_finish() { | ||||||
|  |                     try { | ||||||
|  |                         m_rings.emplace_back(m_geos_factory.createLinearRing(m_coordinate_sequence.release())); | ||||||
|  |                     } catch (geos::util::GEOSException&) { | ||||||
|  |                         std::throw_with_nested(osmium::geos_geometry_error()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_inner_ring_start() { | ||||||
|  |                     try { | ||||||
|  |                         m_coordinate_sequence.reset(m_geos_factory.getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2)); | ||||||
|  |                     } catch (geos::util::GEOSException&) { | ||||||
|  |                         std::throw_with_nested(osmium::geos_geometry_error()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_inner_ring_finish() { | ||||||
|  |                     try { | ||||||
|  |                         m_rings.emplace_back(m_geos_factory.createLinearRing(m_coordinate_sequence.release())); | ||||||
|  |                     } catch (geos::util::GEOSException&) { | ||||||
|  |                         std::throw_with_nested(osmium::geos_geometry_error()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_add_location(const osmium::geom::Coordinates& xy) { | ||||||
|  |                     try { | ||||||
|  |                         m_coordinate_sequence->add(geos::geom::Coordinate(xy.x, xy.y)); | ||||||
|  |                     } catch (geos::util::GEOSException&) { | ||||||
|  |                         std::throw_with_nested(osmium::geos_geometry_error()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 multipolygon_type multipolygon_finish() { | ||||||
|  |                     try { | ||||||
|  |                         auto polygons = new std::vector<geos::geom::Geometry*>; | ||||||
|  |                         std::transform(m_polygons.begin(), m_polygons.end(), std::back_inserter(*polygons), [](std::unique_ptr<geos::geom::Polygon>& p) { | ||||||
|  |                             return p.release(); | ||||||
|  |                         }); | ||||||
|  |                         m_polygons.clear(); | ||||||
|  |                         return multipolygon_type(m_geos_factory.createMultiPolygon(polygons)); | ||||||
|  |                     } catch (geos::util::GEOSException&) { | ||||||
|  |                         std::throw_with_nested(osmium::geos_geometry_error()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class GEOSFactoryImpl
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |         template <class TProjection = IdentityProjection> | ||||||
|  |         using GEOSFactory = GeometryFactory<osmium::geom::detail::GEOSFactoryImpl, TProjection>; | ||||||
|  | 
 | ||||||
|  |     } // namespace geom
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_GEOM_GEOS_HPP
 | ||||||
							
								
								
									
										96
									
								
								ThirdParty/osmium/geom/haversine.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								ThirdParty/osmium/geom/haversine.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,96 @@ | |||||||
|  | #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 <jochen@topf.org> 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 <cmath> | ||||||
|  | #include <iterator> | ||||||
|  | 
 | ||||||
|  | #include <osmium/geom/coordinates.hpp> | ||||||
|  | #include <osmium/geom/util.hpp> | ||||||
|  | #include <osmium/memory/collection.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/node_ref.hpp> | ||||||
|  | #include <osmium/osm/way.hpp> | ||||||
|  | 
 | ||||||
|  | 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
 | ||||||
							
								
								
									
										109
									
								
								ThirdParty/osmium/geom/mercator_projection.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								ThirdParty/osmium/geom/mercator_projection.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | #ifndef OSMIUM_GEOM_MERCATOR_PROJECTION_HPP | ||||||
|  | #define OSMIUM_GEOM_MERCATOR_PROJECTION_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cmath> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | #include <osmium/geom/coordinates.hpp> | ||||||
|  | #include <osmium/geom/util.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace geom { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             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); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             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)); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             constexpr inline double x_to_lon(double x) { | ||||||
|  |                 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); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * The maximum latitude that can be projected with the Web Mercator | ||||||
|  |          * (EPSG:3857) projection. | ||||||
|  |          */ | ||||||
|  |         constexpr double MERCATOR_MAX_LAT = 85.0511288; | ||||||
|  | 
 | ||||||
|  |         inline Coordinates lonlat_to_mercator(const Coordinates& c) { | ||||||
|  |             return Coordinates(detail::lon_to_x(c.x), detail::lat_to_y(c.y)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         inline Coordinates mercator_to_lonlat(const Coordinates& c) { | ||||||
|  |             return Coordinates(detail::x_to_lon(c.x), detail::y_to_lat(c.y)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Functor that does projection from WGS84 (EPSG:4326) to "Web | ||||||
|  |          * Mercator" (EPSG:3857) | ||||||
|  |          */ | ||||||
|  |         class MercatorProjection { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             Coordinates operator()(osmium::Location location) const { | ||||||
|  |                 return Coordinates {detail::lon_to_x(location.lon()), detail::lat_to_y(location.lat())}; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             int epsg() const { | ||||||
|  |                 return 3857; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             std::string proj_string() const { | ||||||
|  |                 return "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class MercatorProjection
 | ||||||
|  | 
 | ||||||
|  |     } // namespace geom
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_GEOM_MERCATOR_PROJECTION_HPP
 | ||||||
							
								
								
									
										157
									
								
								ThirdParty/osmium/geom/ogr.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								ThirdParty/osmium/geom/ogr.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,157 @@ | |||||||
|  | #ifndef OSMIUM_GEOM_OGR_HPP | ||||||
|  | #define OSMIUM_GEOM_OGR_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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. | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #define OSMIUM_COMPILE_WITH_CFLAGS_OGR `gdal-config --cflags` | ||||||
|  | #define OSMIUM_LINK_WITH_LIBS_OGR `gdal-config --libs` | ||||||
|  | 
 | ||||||
|  | #include <cassert> | ||||||
|  | #include <memory> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #pragma GCC diagnostic push | ||||||
|  | #pragma GCC diagnostic ignored "-Wdocumentation-unknown-command" | ||||||
|  | # include <ogr_geometry.h> | ||||||
|  | #pragma GCC diagnostic pop | ||||||
|  | 
 | ||||||
|  | #include <osmium/geom/coordinates.hpp> | ||||||
|  | #include <osmium/geom/factory.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace geom { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             class OGRFactoryImpl { | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 typedef std::unique_ptr<OGRPoint>        point_type; | ||||||
|  |                 typedef std::unique_ptr<OGRLineString>   linestring_type; | ||||||
|  |                 typedef std::unique_ptr<OGRPolygon>      polygon_type; | ||||||
|  |                 typedef std::unique_ptr<OGRMultiPolygon> multipolygon_type; | ||||||
|  |                 typedef std::unique_ptr<OGRLinearRing>   ring_type; | ||||||
|  | 
 | ||||||
|  |             private: | ||||||
|  | 
 | ||||||
|  |                 linestring_type   m_linestring; | ||||||
|  |                 multipolygon_type m_multipolygon; | ||||||
|  |                 polygon_type      m_polygon; | ||||||
|  |                 ring_type         m_ring; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 OGRFactoryImpl() = default; | ||||||
|  | 
 | ||||||
|  |                 /* Point */ | ||||||
|  | 
 | ||||||
|  |                 point_type make_point(const osmium::geom::Coordinates& xy) const { | ||||||
|  |                     return point_type(new OGRPoint(xy.x, xy.y)); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /* LineString */ | ||||||
|  | 
 | ||||||
|  |                 void linestring_start() { | ||||||
|  |                     m_linestring = std::unique_ptr<OGRLineString>(new OGRLineString()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void linestring_add_location(const osmium::geom::Coordinates& xy) { | ||||||
|  |                     assert(!!m_linestring); | ||||||
|  |                     m_linestring->addPoint(xy.x, xy.y); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 linestring_type linestring_finish(size_t /* num_points */) { | ||||||
|  |                     return std::move(m_linestring); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /* MultiPolygon */ | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_start() { | ||||||
|  |                     m_multipolygon.reset(new OGRMultiPolygon()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_polygon_start() { | ||||||
|  |                     m_polygon.reset(new OGRPolygon()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_polygon_finish() { | ||||||
|  |                     assert(!!m_multipolygon); | ||||||
|  |                     assert(!!m_polygon); | ||||||
|  |                     m_multipolygon->addGeometryDirectly(m_polygon.release()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_outer_ring_start() { | ||||||
|  |                     m_ring.reset(new OGRLinearRing()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_outer_ring_finish() { | ||||||
|  |                     assert(!!m_polygon); | ||||||
|  |                     assert(!!m_ring); | ||||||
|  |                     m_polygon->addRingDirectly(m_ring.release()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_inner_ring_start() { | ||||||
|  |                     m_ring.reset(new OGRLinearRing()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_inner_ring_finish() { | ||||||
|  |                     assert(!!m_polygon); | ||||||
|  |                     assert(!!m_ring); | ||||||
|  |                     m_polygon->addRingDirectly(m_ring.release()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_add_location(const osmium::geom::Coordinates& xy) { | ||||||
|  |                     assert(!!m_polygon); | ||||||
|  |                     assert(!!m_ring); | ||||||
|  |                     m_ring->addPoint(xy.x, xy.y); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 multipolygon_type multipolygon_finish() { | ||||||
|  |                     assert(!!m_multipolygon); | ||||||
|  |                     return std::move(m_multipolygon); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class OGRFactoryImpl
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |         template <class TProjection = IdentityProjection> | ||||||
|  |         using OGRFactory = GeometryFactory<osmium::geom::detail::OGRFactoryImpl, TProjection>; | ||||||
|  | 
 | ||||||
|  |     } // namespace geom
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_GEOM_OGR_HPP
 | ||||||
							
								
								
									
										159
									
								
								ThirdParty/osmium/geom/projection.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								ThirdParty/osmium/geom/projection.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,159 @@ | |||||||
|  | #ifndef OSMIUM_GEOM_PROJECTION_HPP | ||||||
|  | #define OSMIUM_GEOM_PROJECTION_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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. | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #define OSMIUM_LINK_WITH_LIBS_PROJ -lproj | ||||||
|  | 
 | ||||||
|  | #include <memory> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | #include <proj_api.h> | ||||||
|  | 
 | ||||||
|  | #include <osmium/geom/coordinates.hpp> | ||||||
|  | #include <osmium/geom/util.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace geom { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * C++ wrapper for a Coordinate Reference System of the proj library. | ||||||
|  |          */ | ||||||
|  |         class CRS { | ||||||
|  | 
 | ||||||
|  |             struct ProjCRSDeleter { | ||||||
|  |                 void operator()(void* crs) { | ||||||
|  |                     pj_free(crs); | ||||||
|  |                 } | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             std::unique_ptr<void, ProjCRSDeleter> m_crs; | ||||||
|  | 
 | ||||||
|  |             projPJ get() const { | ||||||
|  |                 return m_crs.get(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             CRS(const std::string& crs) : | ||||||
|  |                 m_crs(pj_init_plus(crs.c_str()), ProjCRSDeleter()) { | ||||||
|  |                 if (!m_crs) { | ||||||
|  |                     throw osmium::projection_error(std::string("creation of CRS failed: ") + pj_strerrno(*pj_get_errno_ref())); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             CRS(int epsg) : | ||||||
|  |                 CRS(std::string("+init=epsg:") + std::to_string(epsg)) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool is_latlong() const { | ||||||
|  |                 return pj_is_latlong(m_crs.get()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool is_geocent() const { | ||||||
|  |                 return pj_is_geocent(m_crs.get()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Transform coordinates from one CRS into another. Wraps the same function | ||||||
|  |              * of the proj library. | ||||||
|  |              * | ||||||
|  |              * Coordinates have to be in radians and are produced in radians. | ||||||
|  |              * | ||||||
|  |              * @throws osmmium::projection_error if the projection fails | ||||||
|  |              */ | ||||||
|  |             friend Coordinates transform(const CRS& src, const CRS& dest, Coordinates c) { | ||||||
|  |                 int result = pj_transform(src.get(), dest.get(), 1, 1, &c.x, &c.y, nullptr); | ||||||
|  |                 if (result != 0) { | ||||||
|  |                     throw osmium::projection_error(std::string("projection failed: ") + pj_strerrno(result)); | ||||||
|  |                 } | ||||||
|  |                 return c; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class CRS
 | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Functor that does projection from WGS84 (EPSG:4326) in to the given | ||||||
|  |          * CRS. | ||||||
|  |          */ | ||||||
|  |         class Projection { | ||||||
|  | 
 | ||||||
|  |             int m_epsg; | ||||||
|  |             std::string m_proj_string; | ||||||
|  |             CRS m_crs_wgs84 {4326}; | ||||||
|  |             CRS m_crs_user; | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             Projection(const std::string& proj_string) : | ||||||
|  |                 m_epsg(-1), | ||||||
|  |                 m_proj_string(proj_string), | ||||||
|  |                 m_crs_user(proj_string) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             Projection(int epsg) : | ||||||
|  |                 m_epsg(epsg), | ||||||
|  |                 m_proj_string(std::string("+init=epsg:") + std::to_string(epsg)), | ||||||
|  |                 m_crs_user(epsg) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             Coordinates operator()(osmium::Location location) const { | ||||||
|  |                 if (m_epsg == 4326) { | ||||||
|  |                     return Coordinates(location.lon(), location.lat()); | ||||||
|  |                 } else { | ||||||
|  |                     Coordinates c = transform(m_crs_wgs84, m_crs_user, Coordinates(deg_to_rad(location.lon()), deg_to_rad(location.lat()))); | ||||||
|  |                     if (m_crs_user.is_latlong()) { | ||||||
|  |                         c.x = rad_to_deg(c.x); | ||||||
|  |                         c.y = rad_to_deg(c.y); | ||||||
|  |                     } | ||||||
|  |                     return c; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             int epsg() const { | ||||||
|  |                 return m_epsg; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             std::string proj_string() const { | ||||||
|  |                 return m_proj_string; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class Projection
 | ||||||
|  | 
 | ||||||
|  |     } // namespace geom
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_GEOM_PROJECTION_HPP
 | ||||||
							
								
								
									
										57
									
								
								ThirdParty/osmium/geom/relations.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								ThirdParty/osmium/geom/relations.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | |||||||
|  | #ifndef OSMIUM_GEOM_RELATIONS_HPP | ||||||
|  | #define OSMIUM_GEOM_RELATIONS_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <osmium/osm/box.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace geom { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Check whether one geometry contains another. | ||||||
|  |          */ | ||||||
|  |         inline bool contains(const osmium::Box& a, const osmium::Box& b) { | ||||||
|  |             return ((a.bottom_left().x() >= b.bottom_left().x()) && | ||||||
|  |                     (a.top_right().x()   <= b.top_right().x())   && | ||||||
|  |                     (a.bottom_left().y() >= b.bottom_left().y()) && | ||||||
|  |                     (a.top_right().y()   <= b.top_right().y())); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } // namespace geom
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_GEOM_RELATIONS_HPP
 | ||||||
							
								
								
									
										71
									
								
								ThirdParty/osmium/geom/util.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								ThirdParty/osmium/geom/util.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | |||||||
|  | #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 <jochen@topf.org> 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 <stdexcept> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | 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
 | ||||||
							
								
								
									
										264
									
								
								ThirdParty/osmium/geom/wkb.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										264
									
								
								ThirdParty/osmium/geom/wkb.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,264 @@ | |||||||
|  | #ifndef OSMIUM_GEOM_WKB_HPP | ||||||
|  | #define OSMIUM_GEOM_WKB_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cstddef> | ||||||
|  | #include <cstdint> | ||||||
|  | #include <cstring> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | #include <osmium/geom/coordinates.hpp> | ||||||
|  | #include <osmium/geom/factory.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace geom { | ||||||
|  | 
 | ||||||
|  |         enum class wkb_type : bool { | ||||||
|  |             wkb  = false, | ||||||
|  |             ewkb = true | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         enum class out_type : bool { | ||||||
|  |             binary = false, | ||||||
|  |             hex    = true | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             template <typename T> | ||||||
|  |             inline void str_push(std::string& str, T data) { | ||||||
|  |                 size_t size = str.size(); | ||||||
|  |                 str.resize(size + sizeof(T)); | ||||||
|  |                 std::memcpy(const_cast<char *>(&str[size]), reinterpret_cast<char*>(&data), sizeof(T)); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             inline std::string convert_to_hex(std::string& str) { | ||||||
|  |                 static const char* lookup_hex = "0123456789ABCDEF"; | ||||||
|  |                 std::string out; | ||||||
|  | 
 | ||||||
|  |                 for (char c : str) { | ||||||
|  |                     out += lookup_hex[(c >> 4) & 0xf]; | ||||||
|  |                     out += lookup_hex[c & 0xf]; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 return out; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             class WKBFactoryImpl { | ||||||
|  | 
 | ||||||
|  |                 /// OSM data always uses SRID 4326 (WGS84).
 | ||||||
|  |                 static constexpr uint32_t srid = 4326; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                 * Type of WKB geometry. | ||||||
|  |                 * These definitions are from | ||||||
|  |                 * 99-049_OpenGIS_Simple_Features_Specification_For_SQL_Rev_1.1.pdf (for WKB) | ||||||
|  |                 * and http://trac.osgeo.org/postgis/browser/trunk/doc/ZMSgeoms.txt (for EWKB).
 | ||||||
|  |                 * They are used to encode geometries into the WKB format. | ||||||
|  |                 */ | ||||||
|  |                 enum wkbGeometryType : uint32_t { | ||||||
|  |                     wkbPoint               = 1, | ||||||
|  |                     wkbLineString          = 2, | ||||||
|  |                     wkbPolygon             = 3, | ||||||
|  |                     wkbMultiPoint          = 4, | ||||||
|  |                     wkbMultiLineString     = 5, | ||||||
|  |                     wkbMultiPolygon        = 6, | ||||||
|  |                     wkbGeometryCollection  = 7, | ||||||
|  | 
 | ||||||
|  |                     // SRID-presence flag (EWKB)
 | ||||||
|  |                     wkbSRID                = 0x20000000 | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                 * Byte order marker in WKB geometry. | ||||||
|  |                 */ | ||||||
|  |                 enum class wkb_byte_order_type : uint8_t { | ||||||
|  |                     XDR = 0,         // Big Endian
 | ||||||
|  |                     NDR = 1          // Little Endian
 | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|  |                 std::string m_data {}; | ||||||
|  |                 uint32_t m_points {0}; | ||||||
|  |                 wkb_type m_wkb_type; | ||||||
|  |                 out_type m_out_type; | ||||||
|  | 
 | ||||||
|  |                 size_t m_linestring_size_offset = 0; | ||||||
|  |                 size_t m_polygons = 0; | ||||||
|  |                 size_t m_rings = 0; | ||||||
|  |                 size_t m_multipolygon_size_offset = 0; | ||||||
|  |                 size_t m_polygon_size_offset = 0; | ||||||
|  |                 size_t m_ring_size_offset = 0; | ||||||
|  | 
 | ||||||
|  |                 size_t header(std::string& str, wkbGeometryType type, bool add_length) const { | ||||||
|  |                     str_push(str, wkb_byte_order_type::NDR); | ||||||
|  |                     if (m_wkb_type == wkb_type::ewkb) { | ||||||
|  |                         str_push(str, type | wkbSRID); | ||||||
|  |                         str_push(str, srid); | ||||||
|  |                     } else { | ||||||
|  |                         str_push(str, type); | ||||||
|  |                     } | ||||||
|  |                     size_t offset = str.size(); | ||||||
|  |                     if (add_length) { | ||||||
|  |                         str_push(str, static_cast<uint32_t>(0)); | ||||||
|  |                     } | ||||||
|  |                     return offset; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void set_size(const size_t offset, const uint32_t size) { | ||||||
|  |                     memcpy(&m_data[offset], &size, sizeof(uint32_t)); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 typedef std::string point_type; | ||||||
|  |                 typedef std::string linestring_type; | ||||||
|  |                 typedef std::string polygon_type; | ||||||
|  |                 typedef std::string multipolygon_type; | ||||||
|  |                 typedef std::string ring_type; | ||||||
|  | 
 | ||||||
|  |                 explicit WKBFactoryImpl(wkb_type wtype=wkb_type::wkb, out_type otype=out_type::binary) : | ||||||
|  |                     m_wkb_type(wtype), | ||||||
|  |                     m_out_type(otype) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /* Point */ | ||||||
|  | 
 | ||||||
|  |                 point_type make_point(const osmium::geom::Coordinates& xy) const { | ||||||
|  |                     std::string data; | ||||||
|  |                     header(data, wkbPoint, false); | ||||||
|  |                     str_push(data, xy.x); | ||||||
|  |                     str_push(data, xy.y); | ||||||
|  | 
 | ||||||
|  |                     if (m_out_type == out_type::hex) { | ||||||
|  |                         return convert_to_hex(data); | ||||||
|  |                     } else { | ||||||
|  |                         return data; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /* LineString */ | ||||||
|  | 
 | ||||||
|  |                 void linestring_start() { | ||||||
|  |                     m_data.clear(); | ||||||
|  |                     m_linestring_size_offset = header(m_data, wkbLineString, true); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void linestring_add_location(const osmium::geom::Coordinates& xy) { | ||||||
|  |                     str_push(m_data, xy.x); | ||||||
|  |                     str_push(m_data, xy.y); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 linestring_type linestring_finish(size_t num_points) { | ||||||
|  |                     set_size(m_linestring_size_offset, num_points); | ||||||
|  |                     std::string data; | ||||||
|  |                     std::swap(data, m_data); | ||||||
|  | 
 | ||||||
|  |                     if (m_out_type == out_type::hex) { | ||||||
|  |                         return convert_to_hex(data); | ||||||
|  |                     } else { | ||||||
|  |                         return data; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /* MultiPolygon */ | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_start() { | ||||||
|  |                     m_data.clear(); | ||||||
|  |                     m_polygons = 0; | ||||||
|  |                     m_multipolygon_size_offset = header(m_data, wkbMultiPolygon, true); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_polygon_start() { | ||||||
|  |                     ++m_polygons; | ||||||
|  |                     m_rings = 0; | ||||||
|  |                     m_polygon_size_offset = header(m_data, wkbPolygon, true); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_polygon_finish() { | ||||||
|  |                     set_size(m_polygon_size_offset, m_rings); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_outer_ring_start() { | ||||||
|  |                     ++m_rings; | ||||||
|  |                     m_points = 0; | ||||||
|  |                     m_ring_size_offset = m_data.size(); | ||||||
|  |                     str_push(m_data, static_cast<uint32_t>(0)); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_outer_ring_finish() { | ||||||
|  |                     set_size(m_ring_size_offset, m_points); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_inner_ring_start() { | ||||||
|  |                     ++m_rings; | ||||||
|  |                     m_points = 0; | ||||||
|  |                     m_ring_size_offset = m_data.size(); | ||||||
|  |                     str_push(m_data, static_cast<uint32_t>(0)); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_inner_ring_finish() { | ||||||
|  |                     set_size(m_ring_size_offset, m_points); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_add_location(const osmium::geom::Coordinates& xy) { | ||||||
|  |                     str_push(m_data, xy.x); | ||||||
|  |                     str_push(m_data, xy.y); | ||||||
|  |                     ++m_points; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 multipolygon_type multipolygon_finish() { | ||||||
|  |                     set_size(m_multipolygon_size_offset, m_polygons); | ||||||
|  |                     std::string data; | ||||||
|  |                     std::swap(data, m_data); | ||||||
|  | 
 | ||||||
|  |                     if (m_out_type == out_type::hex) { | ||||||
|  |                         return convert_to_hex(data); | ||||||
|  |                     } else { | ||||||
|  |                         return data; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class WKBFactoryImpl
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |         template <class TProjection = IdentityProjection> | ||||||
|  |         using WKBFactory = GeometryFactory<osmium::geom::detail::WKBFactoryImpl, TProjection>; | ||||||
|  | 
 | ||||||
|  |     } // namespace geom
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_GEOM_WKB_HPP
 | ||||||
							
								
								
									
										142
									
								
								ThirdParty/osmium/geom/wkt.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								ThirdParty/osmium/geom/wkt.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,142 @@ | |||||||
|  | #ifndef OSMIUM_GEOM_WKT_HPP | ||||||
|  | #define OSMIUM_GEOM_WKT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cassert> | ||||||
|  | #include <string> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/geom/coordinates.hpp> | ||||||
|  | #include <osmium/geom/factory.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace geom { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             class WKTFactoryImpl { | ||||||
|  | 
 | ||||||
|  |                 std::string m_str {}; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 typedef std::string point_type; | ||||||
|  |                 typedef std::string linestring_type; | ||||||
|  |                 typedef std::string polygon_type; | ||||||
|  |                 typedef std::string multipolygon_type; | ||||||
|  |                 typedef std::string ring_type; | ||||||
|  | 
 | ||||||
|  |                 /* Point */ | ||||||
|  | 
 | ||||||
|  |                 point_type make_point(const osmium::geom::Coordinates& xy) const { | ||||||
|  |                     std::string str {"POINT"}; | ||||||
|  |                     xy.append_to_string(str, '(', ' ', ')'); | ||||||
|  |                     return str; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /* LineString */ | ||||||
|  | 
 | ||||||
|  |                 void linestring_start() { | ||||||
|  |                     m_str = "LINESTRING("; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void linestring_add_location(const osmium::geom::Coordinates& xy) { | ||||||
|  |                     xy.append_to_string(m_str, ' '); | ||||||
|  |                     m_str += ','; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 linestring_type linestring_finish(size_t /* num_points */) { | ||||||
|  |                     assert(!m_str.empty()); | ||||||
|  |                     std::string str; | ||||||
|  |                     std::swap(str, m_str); | ||||||
|  |                     str.back() = ')'; | ||||||
|  |                     return str; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /* MultiPolygon */ | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_start() { | ||||||
|  |                     m_str = "MULTIPOLYGON("; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_polygon_start() { | ||||||
|  |                     m_str += '('; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_polygon_finish() { | ||||||
|  |                     m_str += "),"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_outer_ring_start() { | ||||||
|  |                     m_str += '('; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_outer_ring_finish() { | ||||||
|  |                     assert(!m_str.empty()); | ||||||
|  |                     m_str.back() = ')'; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_inner_ring_start() { | ||||||
|  |                     m_str += ",("; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_inner_ring_finish() { | ||||||
|  |                     assert(!m_str.empty()); | ||||||
|  |                     m_str.back() = ')'; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void multipolygon_add_location(const osmium::geom::Coordinates& xy) { | ||||||
|  |                     xy.append_to_string(m_str, ' '); | ||||||
|  |                     m_str += ','; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 multipolygon_type multipolygon_finish() { | ||||||
|  |                     assert(!m_str.empty()); | ||||||
|  |                     m_str.back() = ')'; | ||||||
|  |                     return std::move(m_str); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class WKTFactoryImpl
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |         template <class TProjection = IdentityProjection> | ||||||
|  |         using WKTFactory = GeometryFactory<osmium::geom::detail::WKTFactoryImpl, TProjection>; | ||||||
|  | 
 | ||||||
|  |     } // namespace geom
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_GEOM_WKT_HPP
 | ||||||
							
								
								
									
										101
									
								
								ThirdParty/osmium/handler.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								ThirdParty/osmium/handler.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,101 @@ | |||||||
|  | #ifndef OSMIUM_HANDLER_HPP | ||||||
|  | #define OSMIUM_HANDLER_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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. | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     class OSMObject; | ||||||
|  |     class Node; | ||||||
|  |     class Way; | ||||||
|  |     class Relation; | ||||||
|  |     class Area; | ||||||
|  |     class Changeset; | ||||||
|  |     class TagList; | ||||||
|  |     class WayNodeList; | ||||||
|  |     class RelationMemberList; | ||||||
|  |     class OuterRing; | ||||||
|  |     class InnerRing; | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Osmium handlers provide callbacks for OSM objects | ||||||
|  |      */ | ||||||
|  |     namespace handler { | ||||||
|  | 
 | ||||||
|  |         class Handler { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             void osm_object(const osmium::OSMObject&) const { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void node(const osmium::Node&) const { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void way(const osmium::Way&) const { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void relation(const osmium::Relation&) const { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void area(const osmium::Area&) const { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void changeset(const osmium::Changeset&) const { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void tag_list(const osmium::TagList&) const { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void way_node_list(const osmium::WayNodeList&) const { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void relation_member_list(const osmium::RelationMemberList&) const { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void outer_ring(const osmium::OuterRing&) const { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void inner_ring(const osmium::InnerRing&) const { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void flush() const { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class Handler
 | ||||||
|  | 
 | ||||||
|  |     } // namspace handler
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_HANDLER_HPP
 | ||||||
							
								
								
									
										128
									
								
								ThirdParty/osmium/handler/chain.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								ThirdParty/osmium/handler/chain.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +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 <jochen@topf.org> 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 <tuple> | ||||||
|  | 
 | ||||||
|  | #include <osmium/handler.hpp> | ||||||
|  | 
 | ||||||
|  | #define OSMIUM_CHAIN_HANDLER_CALL(_func_, _type_) \ | ||||||
|  |     template <int N, int SIZE, class THandlers> \ | ||||||
|  |     struct call_ ## _func_ { \ | ||||||
|  |         void operator()(THandlers& handlers, osmium::_type_& object) { \ | ||||||
|  |             std::get<N>(handlers)._func_(object); \ | ||||||
|  |             call_ ## _func_<N+1, SIZE, THandlers>()(handlers, object); \ | ||||||
|  |         } \ | ||||||
|  |     }; \ | ||||||
|  |     template <int SIZE, class THandlers> \ | ||||||
|  |     struct call_ ## _func_<SIZE, SIZE, THandlers> { \ | ||||||
|  |         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 ...THandler> | ||||||
|  |         class ChainHandler : public osmium::handler::Handler { | ||||||
|  | 
 | ||||||
|  |             typedef std::tuple<THandler&...> handlers_type; | ||||||
|  |             handlers_type m_handlers; | ||||||
|  | 
 | ||||||
|  |             template <int N, int SIZE, class THandlers> | ||||||
|  |             struct call_flush { | ||||||
|  |                 void operator()(THandlers& handlers) { | ||||||
|  |                     std::get<N>(handlers).flush(); | ||||||
|  |                     call_flush<N+1, SIZE, THandlers>()(handlers); | ||||||
|  |                 } | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             template <int SIZE, class THandlers> | ||||||
|  |             struct call_flush<SIZE, SIZE, THandlers> { | ||||||
|  |                 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
 | ||||||
							
								
								
									
										111
									
								
								ThirdParty/osmium/handler/disk_store.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								ThirdParty/osmium/handler/disk_store.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,111 @@ | |||||||
|  | #ifndef OSMIUM_HANDLER_DISK_STORE_HPP | ||||||
|  | #define OSMIUM_HANDLER_DISK_STORE_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cstddef> | ||||||
|  | 
 | ||||||
|  | #include <osmium/handler.hpp> | ||||||
|  | #include <osmium/index/map.hpp> | ||||||
|  | #include <osmium/io/detail/read_write.hpp> | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/memory/item_iterator.hpp> | ||||||
|  | #include <osmium/osm/node.hpp> | ||||||
|  | #include <osmium/osm/relation.hpp> | ||||||
|  | #include <osmium/osm/types.hpp> | ||||||
|  | #include <osmium/osm/way.hpp> | ||||||
|  | #include <osmium/visitor.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace handler { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * | ||||||
|  |          * Note: This handler will only work if either all object IDs are | ||||||
|  |          *       positive or all object IDs are negative. | ||||||
|  |          */ | ||||||
|  |         class DiskStore : public osmium::handler::Handler { | ||||||
|  | 
 | ||||||
|  |             typedef osmium::index::map::Map<unsigned_object_id_type, size_t> offset_index_type; | ||||||
|  | 
 | ||||||
|  |             size_t m_offset = 0; | ||||||
|  |             int m_data_fd; | ||||||
|  | 
 | ||||||
|  |             offset_index_type& m_node_index; | ||||||
|  |             offset_index_type& m_way_index; | ||||||
|  |             offset_index_type& m_relation_index; | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             explicit DiskStore(int data_fd, offset_index_type& node_index, offset_index_type& way_index, offset_index_type& relation_index) : | ||||||
|  |                 m_data_fd(data_fd), | ||||||
|  |                 m_node_index(node_index), | ||||||
|  |                 m_way_index(way_index), | ||||||
|  |                 m_relation_index(relation_index) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             DiskStore(const DiskStore&) = delete; | ||||||
|  |             DiskStore& operator=(const DiskStore&) = delete; | ||||||
|  | 
 | ||||||
|  |             ~DiskStore() noexcept = default; | ||||||
|  | 
 | ||||||
|  |             void node(const osmium::Node& node) { | ||||||
|  |                 m_node_index.set(node.positive_id(), m_offset); | ||||||
|  |                 m_offset += node.byte_size(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void way(const osmium::Way& way) { | ||||||
|  |                 m_way_index.set(way.positive_id(), m_offset); | ||||||
|  |                 m_offset += way.byte_size(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void relation(const osmium::Relation& relation) { | ||||||
|  |                 m_relation_index.set(relation.positive_id(), m_offset); | ||||||
|  |                 m_offset += relation.byte_size(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // XXX
 | ||||||
|  |             void operator()(const osmium::memory::Buffer& buffer) { | ||||||
|  |                 osmium::io::detail::reliable_write(m_data_fd, buffer.data(), buffer.committed()); | ||||||
|  | 
 | ||||||
|  |                 osmium::apply(buffer.begin(), buffer.end(), *this); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class DiskStore
 | ||||||
|  | 
 | ||||||
|  |     } // namespace handler
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_HANDLER_DISK_STORE_HPP
 | ||||||
							
								
								
									
										294
									
								
								ThirdParty/osmium/handler/dump.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										294
									
								
								ThirdParty/osmium/handler/dump.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +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 <jochen@topf.org> 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 <iomanip> | ||||||
|  | #include <iostream> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | #include <osmium/handler.hpp> | ||||||
|  | #include <osmium/memory/collection.hpp> | ||||||
|  | #include <osmium/memory/item.hpp> | ||||||
|  | #include <osmium/osm/area.hpp> | ||||||
|  | #include <osmium/osm/box.hpp> | ||||||
|  | #include <osmium/osm/changeset.hpp> | ||||||
|  | #include <osmium/osm/item_type.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/node.hpp> | ||||||
|  | #include <osmium/osm/node_ref.hpp> | ||||||
|  | #include <osmium/osm/object.hpp> | ||||||
|  | #include <osmium/osm/relation.hpp> | ||||||
|  | #include <osmium/osm/tag.hpp> | ||||||
|  | #include <osmium/osm/timestamp.hpp> | ||||||
|  | #include <osmium/osm/way.hpp> | ||||||
|  | #include <osmium/visitor.hpp> | ||||||
|  | 
 | ||||||
|  | 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
 | ||||||
							
								
								
									
										148
									
								
								ThirdParty/osmium/handler/node_locations_for_ways.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								ThirdParty/osmium/handler/node_locations_for_ways.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,148 @@ | |||||||
|  | #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 <jochen@topf.org> 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 <osmium/handler.hpp> | ||||||
|  | #include <osmium/index/index.hpp> | ||||||
|  | #include <osmium/index/map/dummy.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/node.hpp> | ||||||
|  | #include <osmium/osm/node_ref.hpp> | ||||||
|  | #include <osmium/osm/types.hpp> | ||||||
|  | #include <osmium/osm/way.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace handler { | ||||||
|  | 
 | ||||||
|  |         typedef osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location> 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 TStoragePosIDs, class TStorageNegIDs = dummy_type> | ||||||
|  |         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
 | ||||||
							
								
								
									
										106
									
								
								ThirdParty/osmium/handler/object_relations.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								ThirdParty/osmium/handler/object_relations.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,106 @@ | |||||||
|  | #ifndef OSMIUM_HANDLER_OBJECT_RELATIONS_HPP | ||||||
|  | #define OSMIUM_HANDLER_OBJECT_RELATIONS_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <osmium/handler.hpp> | ||||||
|  | #include <osmium/index/multimap.hpp> | ||||||
|  | #include <osmium/osm/node_ref.hpp> | ||||||
|  | #include <osmium/osm/item_type.hpp> | ||||||
|  | #include <osmium/osm/relation.hpp> | ||||||
|  | #include <osmium/osm/types.hpp> | ||||||
|  | #include <osmium/osm/way.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace handler { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * | ||||||
|  |          * Note: This handler will only work if either all object IDs are | ||||||
|  |          *       positive or all object IDs are negative. | ||||||
|  |          */ | ||||||
|  |         class ObjectRelations : public osmium::handler::Handler { | ||||||
|  | 
 | ||||||
|  |             typedef osmium::index::multimap::Multimap<unsigned_object_id_type, unsigned_object_id_type> index_type; | ||||||
|  | 
 | ||||||
|  |             index_type& m_index_n2w; | ||||||
|  |             index_type& m_index_n2r; | ||||||
|  |             index_type& m_index_w2r; | ||||||
|  |             index_type& m_index_r2r; | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             explicit ObjectRelations(index_type& n2w, index_type& n2r, index_type& w2r, index_type& r2r) : | ||||||
|  |                 m_index_n2w(n2w), | ||||||
|  |                 m_index_n2r(n2r), | ||||||
|  |                 m_index_w2r(w2r), | ||||||
|  |                 m_index_r2r(r2r) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             ObjectRelations(const ObjectRelations&) = delete; | ||||||
|  |             ObjectRelations& operator=(const ObjectRelations&) = delete; | ||||||
|  | 
 | ||||||
|  |             ~ObjectRelations() noexcept = default; | ||||||
|  | 
 | ||||||
|  |             void way(const osmium::Way& way) { | ||||||
|  |                 for (const auto& node_ref : way.nodes()) { | ||||||
|  |                     m_index_n2w.set(node_ref.positive_ref(), way.positive_id()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void relation(const osmium::Relation& relation) { | ||||||
|  |                 for (const auto& member : relation.members()) { | ||||||
|  |                     switch (member.type()) { | ||||||
|  |                         case osmium::item_type::node: | ||||||
|  |                             m_index_n2r.set(member.positive_ref(), relation.positive_id()); | ||||||
|  |                             break; | ||||||
|  |                         case osmium::item_type::way: | ||||||
|  |                             m_index_w2r.set(member.positive_ref(), relation.positive_id()); | ||||||
|  |                             break; | ||||||
|  |                         case osmium::item_type::relation: | ||||||
|  |                             m_index_r2r.set(member.positive_ref(), relation.positive_id()); | ||||||
|  |                             break; | ||||||
|  |                         default: | ||||||
|  |                             break; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class ObjectRelations
 | ||||||
|  | 
 | ||||||
|  |     } // namespace handler
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_HANDLER_OBJECT_RELATIONS_HPP
 | ||||||
							
								
								
									
										78
									
								
								ThirdParty/osmium/index/detail/mmap_vector_anon.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								ThirdParty/osmium/index/detail/mmap_vector_anon.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,78 @@ | |||||||
|  | #ifndef OSMIUM_DETAIL_MMAP_VECTOR_ANON_HPP | ||||||
|  | #define OSMIUM_DETAIL_MMAP_VECTOR_ANON_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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. | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #ifdef __linux__ | ||||||
|  | 
 | ||||||
|  | #include <cstddef> | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/detail/typed_mmap.hpp> | ||||||
|  | #include <osmium/index/detail/mmap_vector_base.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace detail { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |         * This class looks and behaves like STL vector, but uses mmap internally. | ||||||
|  |         */ | ||||||
|  |         template <typename T> | ||||||
|  |         class mmap_vector_anon : public mmap_vector_base<T, mmap_vector_anon> { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             mmap_vector_anon() : | ||||||
|  |                 mmap_vector_base<T, osmium::detail::mmap_vector_anon>( | ||||||
|  |                     -1, | ||||||
|  |                     osmium::detail::mmap_vector_size_increment, | ||||||
|  |                     0, | ||||||
|  |                     osmium::detail::typed_mmap<T>::map(osmium::detail::mmap_vector_size_increment)) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void reserve(size_t new_capacity) { | ||||||
|  |                 if (new_capacity > this->capacity()) { | ||||||
|  |                     this->data(osmium::detail::typed_mmap<T>::remap(this->data(), this->capacity(), new_capacity)); | ||||||
|  |                     this->m_capacity = new_capacity; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class mmap_vector_anon
 | ||||||
|  | 
 | ||||||
|  |     } // namespace detail
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // __linux__
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_DETAIL_MMAP_VECTOR_ANON_HPP
 | ||||||
							
								
								
									
										183
									
								
								ThirdParty/osmium/index/detail/mmap_vector_base.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								ThirdParty/osmium/index/detail/mmap_vector_base.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +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 <jochen@topf.org> 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 <cstddef> | ||||||
|  | #include <new> | ||||||
|  | #include <stdexcept> | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/detail/typed_mmap.hpp> | ||||||
|  | 
 | ||||||
|  | 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 <typename T, template <typename> 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<T>::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<T>::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<TDerived<T>*>(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
 | ||||||
							
								
								
									
										83
									
								
								ThirdParty/osmium/index/detail/mmap_vector_file.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								ThirdParty/osmium/index/detail/mmap_vector_file.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,83 @@ | |||||||
|  | #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 <jochen@topf.org> 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 <cstddef> | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/detail/typed_mmap.hpp> | ||||||
|  | #include <osmium/index/detail/mmap_vector_base.hpp> | ||||||
|  | #include <osmium/index/detail/tmpfile.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace detail { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |         * This class looks and behaves like STL vector, but mmap's a file internally. | ||||||
|  |         */ | ||||||
|  |         template <typename T> | ||||||
|  |         class mmap_vector_file : public mmap_vector_base<T, mmap_vector_file> { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             explicit mmap_vector_file() : | ||||||
|  |                 mmap_vector_base<T, osmium::detail::mmap_vector_file>( | ||||||
|  |                     osmium::detail::create_tmp_file(), | ||||||
|  |                     osmium::detail::mmap_vector_size_increment, | ||||||
|  |                     0) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             explicit mmap_vector_file(int fd) : | ||||||
|  |                 mmap_vector_base<T, osmium::detail::mmap_vector_file>( | ||||||
|  |                     fd, | ||||||
|  |                     osmium::detail::typed_mmap<T>::file_size(fd) == 0 ? osmium::detail::mmap_vector_size_increment : osmium::detail::typed_mmap<T>::file_size(fd), | ||||||
|  |                     osmium::detail::typed_mmap<T>::file_size(fd)) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void reserve(size_t new_capacity) { | ||||||
|  |                 if (new_capacity > this->capacity()) { | ||||||
|  |                     osmium::detail::typed_mmap<T>::unmap(this->data(), this->capacity()); | ||||||
|  |                     osmium::detail::typed_mmap<T>::grow_file(new_capacity, this->m_fd); | ||||||
|  |                     osmium::detail::typed_mmap<T>::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
 | ||||||
							
								
								
									
										62
									
								
								ThirdParty/osmium/index/detail/tmpfile.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								ThirdParty/osmium/index/detail/tmpfile.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,62 @@ | |||||||
|  | #ifndef OSMIUM_DETAIL_TMPFILE_HPP | ||||||
|  | #define OSMIUM_DETAIL_TMPFILE_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cerrno> | ||||||
|  | #include <cstdio> | ||||||
|  | #include <system_error> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace detail { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * 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. | ||||||
|  |          */ | ||||||
|  |         inline int create_tmp_file() { | ||||||
|  |             FILE* file = ::tmpfile(); | ||||||
|  |             if (!file) { | ||||||
|  |                 throw std::system_error(errno, std::system_category(), "tempfile failed"); | ||||||
|  |             } | ||||||
|  |             return fileno(file); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } // namespace detail
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_DETAIL_TMPFILE
 | ||||||
							
								
								
									
										217
									
								
								ThirdParty/osmium/index/detail/typed_mmap.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								ThirdParty/osmium/index/detail/typed_mmap.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,217 @@ | |||||||
|  | #ifndef OSMIUM_DETAIL_TYPED_MMAP_HPP | ||||||
|  | #define OSMIUM_DETAIL_TYPED_MMAP_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cerrno> | ||||||
|  | #include <cstddef> | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <system_error> | ||||||
|  | 
 | ||||||
|  | #include <sys/mman.h> | ||||||
|  | #include <sys/stat.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | 
 | ||||||
|  | // for bsd systems
 | ||||||
|  | #ifndef MAP_ANONYMOUS | ||||||
|  | # define MAP_ANONYMOUS MAP_ANON | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Namespace for Osmium internal use | ||||||
|  |      */ | ||||||
|  |     namespace detail { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * This is a helper class for working with memory mapped files and | ||||||
|  |          * anonymous shared memory. It wraps the necessary system calls | ||||||
|  |          * adding: | ||||||
|  |          * - error checking: all functions throw exceptions where needed | ||||||
|  |          * - internal casts and size calculations allow use with user defined | ||||||
|  |          *   type T instead of void* | ||||||
|  |          * | ||||||
|  |          * This class only contains static functions. It should never be | ||||||
|  |          * instantiated. | ||||||
|  |          * | ||||||
|  |          * @tparam T Type of objects we want to store. | ||||||
|  |          */ | ||||||
|  |         template <typename T> | ||||||
|  |         class typed_mmap { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Create anonymous private memory mapping with enough space for size | ||||||
|  |              * objects of type T. | ||||||
|  |              * | ||||||
|  |              * 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 | ||||||
|  |              */ | ||||||
|  |             static T* map(size_t size) { | ||||||
|  |                 void* addr = ::mmap(nullptr, sizeof(T) * size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | ||||||
|  | #pragma GCC diagnostic push | ||||||
|  | #pragma GCC diagnostic ignored "-Wold-style-cast" | ||||||
|  |                 if (addr == MAP_FAILED) { | ||||||
|  |                     throw std::system_error(errno, std::system_category(), "mmap failed"); | ||||||
|  |                 } | ||||||
|  | #pragma GCC diagnostic pop | ||||||
|  |                 return reinterpret_cast<T*>(addr); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Create shared memory mapping of a file with enough space for size | ||||||
|  |              * objects of type T. The file must already have at least the | ||||||
|  |              * required size. | ||||||
|  |              * | ||||||
|  |              * 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 | ||||||
|  |              * @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 | ||||||
|  |              */ | ||||||
|  |             static T* map(size_t size, int fd, bool write = false) { | ||||||
|  |                 int prot = PROT_READ; | ||||||
|  |                 if (write) { | ||||||
|  |                     prot |= PROT_WRITE; | ||||||
|  |                 } | ||||||
|  |                 void* addr = ::mmap(nullptr, sizeof(T) * size, prot, MAP_SHARED, fd, 0); | ||||||
|  | #pragma GCC diagnostic push | ||||||
|  | #pragma GCC diagnostic ignored "-Wold-style-cast" | ||||||
|  |                 if (addr == MAP_FAILED) { | ||||||
|  |                     throw std::system_error(errno, std::system_category(), "mmap failed"); | ||||||
|  |                 } | ||||||
|  | #pragma GCC diagnostic pop | ||||||
|  |                 return reinterpret_cast<T*>(addr); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  | // mremap(2) is only available on linux systems
 | ||||||
|  | #ifdef __linux__ | ||||||
|  |             /**
 | ||||||
|  |              * Grow memory mapping created with map(). | ||||||
|  |              * | ||||||
|  |              * Note that no constructor is called for any of the objects in this memory! | ||||||
|  |              * | ||||||
|  |              * @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 | ||||||
|  |              */ | ||||||
|  |             static T* remap(T* data, size_t old_size, size_t new_size) { | ||||||
|  |                 void* addr = ::mremap(reinterpret_cast<void*>(data), sizeof(T) * old_size, sizeof(T) * new_size, MREMAP_MAYMOVE); | ||||||
|  | #pragma GCC diagnostic push | ||||||
|  | #pragma GCC diagnostic ignored "-Wold-style-cast" | ||||||
|  |                 if (addr == MAP_FAILED) { | ||||||
|  |                     throw std::system_error(errno, std::system_category(), "mremap failed"); | ||||||
|  |                 } | ||||||
|  | #pragma GCC diagnostic pop | ||||||
|  |                 return reinterpret_cast<T*>(addr); | ||||||
|  |             } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Release memory from map() call. | ||||||
|  |              * | ||||||
|  |              * Note that no destructor is called for the objects in this memory! | ||||||
|  |              * | ||||||
|  |              * @param data Pointer to the data | ||||||
|  |              * @param size Number of objects of type T stored | ||||||
|  |              * @exception std::system_error If munmap(2) call failed | ||||||
|  |              */ | ||||||
|  |             static void unmap(T* data, size_t size) { | ||||||
|  |                 if (::munmap(reinterpret_cast<void*>(data), sizeof(T) * size) != 0) { | ||||||
|  |                     throw std::system_error(errno, std::system_category(), "munmap failed"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * 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) | ||||||
|  |              */ | ||||||
|  |             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) { | ||||||
|  |                     throw std::length_error("file size has to be multiple of object size"); | ||||||
|  |                 } | ||||||
|  |                 return s.st_size / sizeof(T); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Grow file so there is enough space for at least new_size objects | ||||||
|  |              * of type T. If the file is large enough already, nothing is done. | ||||||
|  |              * The file is never shrunk. | ||||||
|  |              * | ||||||
|  |              * @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 | ||||||
|  |              */ | ||||||
|  |             static void grow_file(size_t new_size, int fd) { | ||||||
|  |                 if (file_size(fd) < new_size) { | ||||||
|  |                     if (::ftruncate(fd, sizeof(T) * new_size) < 0) { | ||||||
|  |                         throw std::system_error(errno, std::system_category(), "ftruncate failed"); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Grow file to given size (if it is smaller) and mmap it. | ||||||
|  |              * | ||||||
|  |              * @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() | ||||||
|  |              */ | ||||||
|  |             static T* grow_and_map(size_t size, int fd) { | ||||||
|  |                 grow_file(size, fd); | ||||||
|  |                 return map(size, fd, true); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class typed_mmap
 | ||||||
|  | 
 | ||||||
|  |     } // namespace detail
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_DETAIL_TYPED_MMAP_HPP
 | ||||||
							
								
								
									
										98
									
								
								ThirdParty/osmium/index/index.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								ThirdParty/osmium/index/index.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,98 @@ | |||||||
|  | #ifndef OSMIUM_INDEX_INDEX_HPP | ||||||
|  | #define OSMIUM_INDEX_INDEX_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cstddef> | ||||||
|  | #include <limits> | ||||||
|  | #include <sstream> | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Exception signaling that an element could not be | ||||||
|  |      * found in an index. | ||||||
|  |      */ | ||||||
|  |     struct not_found : public std::runtime_error { | ||||||
|  | 
 | ||||||
|  |         not_found(const std::string& what) : | ||||||
|  |             std::runtime_error(what) { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         not_found(const char* what) : | ||||||
|  |             std::runtime_error(what) { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     }; // struct not_found
 | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Indexing of OSM data, Locations, etc. | ||||||
|  |      */ | ||||||
|  |     namespace index { | ||||||
|  | 
 | ||||||
|  |         template <typename TKey> | ||||||
|  |         [[noreturn]] void not_found_error(TKey key) { | ||||||
|  |             std::stringstream s; | ||||||
|  |             s << "id " << key << " no found"; | ||||||
|  |             throw not_found(s.str()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Some of the index classes need an "empty" value that can | ||||||
|  |          * never appear in real data. This function must return this | ||||||
|  |          * empty value for any class used as a value in an index. | ||||||
|  |          * The default implementation returns a default constructed | ||||||
|  |          * object, but it can be specialized. | ||||||
|  |          */ | ||||||
|  |         template <typename T> | ||||||
|  |         inline constexpr T empty_value() { | ||||||
|  |             return T{}; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * The size_t value in indexes is usually used for offsets | ||||||
|  |          * into a buffer or file. It is unlikely that we ever need | ||||||
|  |          * the full range, so the max value is a good "empty" value. | ||||||
|  |          */ | ||||||
|  |         template <> | ||||||
|  |         inline constexpr size_t empty_value<size_t>() { | ||||||
|  |             return std::numeric_limits<size_t>::max(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } // namespace index
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_INDEX_INDEX_HPP
 | ||||||
							
								
								
									
										156
									
								
								ThirdParty/osmium/index/map.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								ThirdParty/osmium/index/map.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,156 @@ | |||||||
|  | #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 <jochen@topf.org> 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 <cstddef> | ||||||
|  | #include <type_traits> | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/index.hpp> // 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 <typename TId, typename TValue> | ||||||
|  |             class Map { | ||||||
|  | 
 | ||||||
|  |                 static_assert(std::is_integral<TId>::value && std::is_unsigned<TId>::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
 | ||||||
							
								
								
									
										87
									
								
								ThirdParty/osmium/index/map/dummy.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								ThirdParty/osmium/index/map/dummy.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | |||||||
|  | #ifndef OSMIUM_INDEX_MAP_DUMMY_HPP | ||||||
|  | #define OSMIUM_INDEX_MAP_DUMMY_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cstddef> | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/map.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace index { | ||||||
|  | 
 | ||||||
|  |         namespace map { | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Pseudo map. | ||||||
|  |              * Use this class if you don't need a map, but you | ||||||
|  |              * need an object that behaves like one. | ||||||
|  |              */ | ||||||
|  |             template <typename TId, typename TValue> | ||||||
|  |             class Dummy : public osmium::index::map::Map<TId, TValue> { | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 Dummy() = default; | ||||||
|  | 
 | ||||||
|  |                 ~Dummy() override final = default; | ||||||
|  | 
 | ||||||
|  |                 void set(const TId, const TValue) override final { | ||||||
|  |                     // intentionally left blank
 | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 const TValue get(const TId id) const override final { | ||||||
|  |                     not_found_error(id); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 size_t size() const override final { | ||||||
|  |                     return 0; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 size_t used_memory() const override final { | ||||||
|  |                     return 0; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void clear() override final { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class Dummy
 | ||||||
|  | 
 | ||||||
|  |         } // namespace map
 | ||||||
|  | 
 | ||||||
|  |     } // namespace index
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_INDEX_MAP_DUMMY_HPP
 | ||||||
							
								
								
									
										61
									
								
								ThirdParty/osmium/index/map/mmap_vector_anon.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								ThirdParty/osmium/index/map/mmap_vector_anon.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | |||||||
|  | #ifndef OSMIUM_INDEX_MAP_MMAP_VECTOR_ANON_HPP | ||||||
|  | #define OSMIUM_INDEX_MAP_MMAP_VECTOR_ANON_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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. | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #ifdef __linux__ | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/map/vector.hpp> | ||||||
|  | #include <osmium/index/detail/mmap_vector_anon.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace index { | ||||||
|  | 
 | ||||||
|  |         namespace map { | ||||||
|  | 
 | ||||||
|  |             template <typename TId, typename TValue> | ||||||
|  |             using DenseMapMmap = VectorBasedDenseMap<osmium::detail::mmap_vector_anon<TValue>, TId, TValue>; | ||||||
|  | 
 | ||||||
|  |             template <typename TId, typename TValue> | ||||||
|  |             using SparseMapMmap = VectorBasedSparseMap<TId, TValue, osmium::detail::mmap_vector_anon>; | ||||||
|  | 
 | ||||||
|  |         } // namespace map
 | ||||||
|  | 
 | ||||||
|  |     } // namespace index
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // __linux__
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_INDEX_MAP_MMAP_VECTOR_ANON_HPP
 | ||||||
							
								
								
									
										57
									
								
								ThirdParty/osmium/index/map/mmap_vector_file.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								ThirdParty/osmium/index/map/mmap_vector_file.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | |||||||
|  | #ifndef OSMIUM_INDEX_MAP_MMAP_VECTOR_FILE_HPP | ||||||
|  | #define OSMIUM_INDEX_MAP_MMAP_VECTOR_FILE_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <osmium/index/map/vector.hpp> | ||||||
|  | #include <osmium/index/detail/mmap_vector_file.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace index { | ||||||
|  | 
 | ||||||
|  |         namespace map { | ||||||
|  | 
 | ||||||
|  |             template <typename TId, typename TValue> | ||||||
|  |             using DenseMapFile = VectorBasedDenseMap<osmium::detail::mmap_vector_file<TValue>, TId, TValue>; | ||||||
|  | 
 | ||||||
|  |             template <typename TId, typename TValue> | ||||||
|  |             using SparseMapFile = VectorBasedSparseMap<TId, TValue, osmium::detail::mmap_vector_file>; | ||||||
|  | 
 | ||||||
|  |         } // namespace map
 | ||||||
|  | 
 | ||||||
|  |     } // namespace index
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_INDEX_MAP_MMAP_VECTOR_FILE_HPP
 | ||||||
							
								
								
									
										140
									
								
								ThirdParty/osmium/index/map/sparse_table.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								ThirdParty/osmium/index/map/sparse_table.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +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 <jochen@topf.org> 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 <cstddef> | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <utility> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <google/sparsetable> | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/map.hpp> | ||||||
|  | #include <osmium/io/detail/read_write.hpp> | ||||||
|  | 
 | ||||||
|  | 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 <typename TId, typename TValue> | ||||||
|  |             class SparseTable : public osmium::index::map::Map<TId, TValue> { | ||||||
|  | 
 | ||||||
|  |                 TId m_grow_size; | ||||||
|  | 
 | ||||||
|  |                 google::sparsetable<TValue> m_elements; | ||||||
|  | 
 | ||||||
|  |                 static_assert(sizeof(typename google::sparsetable<TValue>::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<TValue>()) { | ||||||
|  |                         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<std::pair<TId, TValue>> v; | ||||||
|  |                     int n=0; | ||||||
|  |                     for (const TValue value : m_elements) { | ||||||
|  |                         if (value != osmium::index::empty_value<TValue>()) { | ||||||
|  |                             v.emplace_back(n, value); | ||||||
|  |                         } | ||||||
|  |                         ++n; | ||||||
|  |                     } | ||||||
|  |                     osmium::io::detail::reliable_write(fd, reinterpret_cast<const char*>(v.data()), sizeof(std::pair<TId, TValue>) * v.size()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class SparseTable
 | ||||||
|  | 
 | ||||||
|  |         } // namespace map
 | ||||||
|  | 
 | ||||||
|  |     } // namespace index
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_INDEX_BYID_SPARSE_TABLE_HPP
 | ||||||
							
								
								
									
										112
									
								
								ThirdParty/osmium/index/map/stl_map.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								ThirdParty/osmium/index/map/stl_map.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +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 <jochen@topf.org> 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 <algorithm> | ||||||
|  | #include <cstddef> | ||||||
|  | #include <iterator> | ||||||
|  | #include <map> | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/map.hpp> | ||||||
|  | #include <osmium/io/detail/read_write.hpp> | ||||||
|  | 
 | ||||||
|  | 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 <typename TId, typename TValue> | ||||||
|  |             class StlMap : public osmium::index::map::Map<TId, TValue> { | ||||||
|  | 
 | ||||||
|  |                 // 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<TId, TValue> 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<TId, TValue>::value_type t; | ||||||
|  |                     std::vector<t> v; | ||||||
|  |                     std::copy(m_elements.begin(), m_elements.end(), std::back_inserter(v)); | ||||||
|  |                     osmium::io::detail::reliable_write(fd, reinterpret_cast<const char*>(v.data()), sizeof(t) * v.size()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class StlMap
 | ||||||
|  | 
 | ||||||
|  |         } // namespace map
 | ||||||
|  | 
 | ||||||
|  |     } // namespace index
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_INDEX_MAP_STL_MAP_HPP
 | ||||||
							
								
								
									
										58
									
								
								ThirdParty/osmium/index/map/stl_vector.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								ThirdParty/osmium/index/map/stl_vector.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | |||||||
|  | #ifndef OSMIUM_INDEX_MAP_STL_VECTOR_HPP | ||||||
|  | #define OSMIUM_INDEX_MAP_STL_VECTOR_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <vector> | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/map/vector.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace index { | ||||||
|  | 
 | ||||||
|  |         namespace map { | ||||||
|  | 
 | ||||||
|  |             template <typename TId, typename TValue> | ||||||
|  |             using DenseMapMem = VectorBasedDenseMap<std::vector<TValue>, TId, TValue>; | ||||||
|  | 
 | ||||||
|  |             template <typename TId, typename TValue> | ||||||
|  |             using SparseMapMem = VectorBasedSparseMap<TId, TValue, std::vector>; | ||||||
|  | 
 | ||||||
|  |         } // namespace map
 | ||||||
|  | 
 | ||||||
|  |     } // namespace index
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_INDEX_MAP_STL_VECTOR_HPP
 | ||||||
							
								
								
									
										208
									
								
								ThirdParty/osmium/index/map/vector.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								ThirdParty/osmium/index/map/vector.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +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 <jochen@topf.org> 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 <algorithm> | ||||||
|  | #include <cstddef> | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/map.hpp> | ||||||
|  | #include <osmium/io/detail/read_write.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace index { | ||||||
|  | 
 | ||||||
|  |         namespace map { | ||||||
|  | 
 | ||||||
|  |             template <class TVector, typename TId, typename TValue> | ||||||
|  |             class VectorBasedDenseMap : public Map<TId, TValue> { | ||||||
|  | 
 | ||||||
|  |                 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<TValue>()) { | ||||||
|  |                             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 <typename TId, typename TValue, template<typename...> class TVector> | ||||||
|  |             class VectorBasedSparseMap : public Map<TId, TValue> { | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 typedef typename std::pair<TId, TValue> element_type; | ||||||
|  |                 typedef TVector<element_type> 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<TValue>() | ||||||
|  |                     }; | ||||||
|  |                     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<const char*>(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
 | ||||||
							
								
								
									
										125
									
								
								ThirdParty/osmium/index/multimap.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								ThirdParty/osmium/index/multimap.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,125 @@ | |||||||
|  | #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 <jochen@topf.org> 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 <cstddef> | ||||||
|  | #include <type_traits> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/index.hpp> // IWYU pragma: export
 | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace index { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * @brief Key-value containers with multiple values for an integer key | ||||||
|  |          */ | ||||||
|  |         namespace multimap { | ||||||
|  | 
 | ||||||
|  |             template <typename TId, typename TValue> | ||||||
|  |             class Multimap { | ||||||
|  | 
 | ||||||
|  |                 static_assert(std::is_integral<TId>::value && std::is_unsigned<TId>::value, | ||||||
|  |                               "TId template parameter for class Multimap must be unsigned integral type"); | ||||||
|  | 
 | ||||||
|  |                 typedef typename std::pair<TId, TValue> 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<iterator, iterator> 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
 | ||||||
							
								
								
									
										199
									
								
								ThirdParty/osmium/index/multimap/hybrid.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								ThirdParty/osmium/index/multimap/hybrid.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +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 <jochen@topf.org> 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 <cstddef> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/multimap.hpp> | ||||||
|  | #include <osmium/index/multimap/stl_vector.hpp> | ||||||
|  | #include <osmium/index/multimap/stl_multimap.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace index { | ||||||
|  | 
 | ||||||
|  |         namespace multimap { | ||||||
|  | 
 | ||||||
|  |             template <typename TId, typename TValue> | ||||||
|  |             class HybridIterator { | ||||||
|  | 
 | ||||||
|  |                 typedef SparseMultimapMem<TId, TValue> main_map_type; | ||||||
|  |                 typedef StlMultimap<TId, TValue> extra_map_type; | ||||||
|  | 
 | ||||||
|  |                 typedef typename std::pair<TId, TValue> 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<TValue>()) { // ignore removed elements
 | ||||||
|  |                             ++m_begin_main; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     return *this; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 HybridIterator<TId, TValue> 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 <typename TId, typename TValue> | ||||||
|  |             class Hybrid : public Multimap<TId, TValue> { | ||||||
|  | 
 | ||||||
|  |                 typedef SparseMultimapMem<TId, TValue> main_map_type; | ||||||
|  |                 typedef StlMultimap<TId, TValue> extra_map_type; | ||||||
|  | 
 | ||||||
|  |                 main_map_type m_main; | ||||||
|  |                 extra_map_type m_extra; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 typedef HybridIterator<TId, TValue> iterator; | ||||||
|  |                 typedef const HybridIterator<TId, TValue> 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<iterator, iterator> 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
 | ||||||
							
								
								
									
										58
									
								
								ThirdParty/osmium/index/multimap/mmap_vector_anon.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								ThirdParty/osmium/index/multimap/mmap_vector_anon.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | |||||||
|  | #ifndef OSMIUM_INDEX_MULTIMAP_MMAP_VECTOR_ANON_HPP | ||||||
|  | #define OSMIUM_INDEX_MULTIMAP_MMAP_VECTOR_ANON_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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. | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #ifdef __linux__ | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/multimap/vector.hpp> | ||||||
|  | #include <osmium/index/detail/mmap_vector_anon.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace index { | ||||||
|  | 
 | ||||||
|  |         namespace multimap { | ||||||
|  | 
 | ||||||
|  |             template <typename TId, typename TValue> | ||||||
|  |             using SparseMultimapMmap = VectorBasedSparseMultimap<TId, TValue, osmium::detail::mmap_vector_anon>; | ||||||
|  | 
 | ||||||
|  |         } // namespace multimap
 | ||||||
|  | 
 | ||||||
|  |     } // namespace index
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // __linux__
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_INDEX_MULTIMAP_MMAP_VECTOR_ANON_HPP
 | ||||||
							
								
								
									
										54
									
								
								ThirdParty/osmium/index/multimap/mmap_vector_file.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								ThirdParty/osmium/index/multimap/mmap_vector_file.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | |||||||
|  | #ifndef OSMIUM_INDEX_MULTIMAP_MMAP_VECTOR_FILE_HPP | ||||||
|  | #define OSMIUM_INDEX_MULTIMAP_MMAP_VECTOR_FILE_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <osmium/index/multimap/vector.hpp> | ||||||
|  | #include <osmium/index/detail/mmap_vector_file.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace index { | ||||||
|  | 
 | ||||||
|  |         namespace multimap { | ||||||
|  | 
 | ||||||
|  |             template <typename TId, typename TValue> | ||||||
|  |             using SparseMultimapFile = VectorBasedSparseMultimap<TId, TValue, osmium::detail::mmap_vector_file>; | ||||||
|  | 
 | ||||||
|  |         } // namespace multimap
 | ||||||
|  | 
 | ||||||
|  |     } // namespace index
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_INDEX_MULTIMAP_MMAP_VECTOR_FILE_HPP
 | ||||||
							
								
								
									
										151
									
								
								ThirdParty/osmium/index/multimap/stl_multimap.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								ThirdParty/osmium/index/multimap/stl_multimap.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +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 <jochen@topf.org> 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 <algorithm> | ||||||
|  | #include <cstddef> | ||||||
|  | #include <map> | ||||||
|  | #include <utility> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/multimap.hpp> | ||||||
|  | #include <osmium/io/detail/read_write.hpp> | ||||||
|  | 
 | ||||||
|  | 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 <typename TId, typename TValue> | ||||||
|  |             class StlMultimap : public osmium::index::multimap::Multimap<TId, TValue> { | ||||||
|  | 
 | ||||||
|  |                 // 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<const TId, TValue> 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<TId, TValue> 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<iterator, iterator> get_all(const TId id) { | ||||||
|  |                     return m_elements.equal_range(id); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 std::pair<const_iterator, const_iterator> get_all(const TId id) const { | ||||||
|  |                     return m_elements.equal_range(id); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void remove(const TId id, const TValue value) { | ||||||
|  |                     std::pair<iterator, iterator> 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<element_type> 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<const char*>(v.data()), sizeof(element_type) * v.size()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class StlMultimap
 | ||||||
|  | 
 | ||||||
|  |         } // namespace multimap
 | ||||||
|  | 
 | ||||||
|  |     } // namespace index
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_INDEX_MULTIMAP_STL_MULTIMAP_HPP
 | ||||||
							
								
								
									
										55
									
								
								ThirdParty/osmium/index/multimap/stl_vector.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								ThirdParty/osmium/index/multimap/stl_vector.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | |||||||
|  | #ifndef OSMIUM_INDEX_MULTIMAP_STL_VECTOR_HPP | ||||||
|  | #define OSMIUM_INDEX_MULTIMAP_STL_VECTOR_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <vector> | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/multimap/vector.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace index { | ||||||
|  | 
 | ||||||
|  |         namespace multimap { | ||||||
|  | 
 | ||||||
|  |             template <typename TId, typename TValue> | ||||||
|  |             using SparseMultimapMem = VectorBasedSparseMultimap<TId, TValue, std::vector>; | ||||||
|  | 
 | ||||||
|  |         } // namespace multimap
 | ||||||
|  | 
 | ||||||
|  |     } // namespace index
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_INDEX_MULTIMAP_STL_VECTOR_HPP
 | ||||||
							
								
								
									
										141
									
								
								ThirdParty/osmium/index/multimap/vector.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								ThirdParty/osmium/index/multimap/vector.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,141 @@ | |||||||
|  | #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 <jochen@topf.org> 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 <algorithm> | ||||||
|  | #include <cstddef> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/index/multimap.hpp> | ||||||
|  | #include <osmium/io/detail/read_write.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace index { | ||||||
|  | 
 | ||||||
|  |         namespace multimap { | ||||||
|  | 
 | ||||||
|  |             template <typename TId, typename TValue, template<typename...> class TVector> | ||||||
|  |             class VectorBasedSparseMultimap : public Multimap<TId, TValue> { | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 typedef typename std::pair<TId, TValue> element_type; | ||||||
|  |                 typedef TVector<element_type> 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<TValue>(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             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<iterator, iterator> get_all(const TId id) { | ||||||
|  |                     const element_type element { | ||||||
|  |                         id, | ||||||
|  |                         osmium::index::empty_value<TValue>() | ||||||
|  |                     }; | ||||||
|  |                     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<const char*>(m_vector.data()), byte_size()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class VectorBasedSparseMultimap
 | ||||||
|  | 
 | ||||||
|  |         } // namespace multimap
 | ||||||
|  | 
 | ||||||
|  |     } // namespace index
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_INDEX_MULTIMAP_VECTOR_HPP
 | ||||||
							
								
								
									
										39
									
								
								ThirdParty/osmium/io/any_compression.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								ThirdParty/osmium/io/any_compression.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | #ifndef OSMIUM_IO_ANY_COMPRESSION_HPP | ||||||
|  | #define OSMIUM_IO_ANY_COMPRESSION_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <osmium/io/bzip2_compression.hpp> // IWYU pragma: export
 | ||||||
|  | #include <osmium/io/gzip_compression.hpp> // IWYU pragma: export
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_ANY_COMPRESSION_HPP
 | ||||||
							
								
								
									
										41
									
								
								ThirdParty/osmium/io/any_input.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								ThirdParty/osmium/io/any_input.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | #ifndef OSMIUM_IO_ANY_INPUT_HPP | ||||||
|  | #define OSMIUM_IO_ANY_INPUT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <osmium/io/any_compression.hpp> // IWYU pragma: export
 | ||||||
|  | 
 | ||||||
|  | #include <osmium/io/pbf_input.hpp> // IWYU pragma: export
 | ||||||
|  | #include <osmium/io/xml_input.hpp> // IWYU pragma: export
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_ANY_INPUT_HPP
 | ||||||
							
								
								
									
										42
									
								
								ThirdParty/osmium/io/any_output.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								ThirdParty/osmium/io/any_output.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | |||||||
|  | #ifndef OSMIUM_IO_ANY_OUTPUT_HPP | ||||||
|  | #define OSMIUM_IO_ANY_OUTPUT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <osmium/io/any_compression.hpp> // IWYU pragma: export
 | ||||||
|  | 
 | ||||||
|  | #include <osmium/io/opl_output.hpp> // IWYU pragma: export
 | ||||||
|  | #include <osmium/io/pbf_output.hpp> // IWYU pragma: export
 | ||||||
|  | #include <osmium/io/xml_output.hpp> // IWYU pragma: export
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_ANY_OUTPUT_HPP
 | ||||||
							
								
								
									
										193
									
								
								ThirdParty/osmium/io/bzip2_compression.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								ThirdParty/osmium/io/bzip2_compression.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,193 @@ | |||||||
|  | #ifndef OSMIUM_IO_BZIP2_COMPRESSION_HPP | ||||||
|  | #define OSMIUM_IO_BZIP2_COMPRESSION_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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. | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #define OSMIUM_LINK_WITH_LIBS_BZ2LIB -lbz2 | ||||||
|  | 
 | ||||||
|  | #include <cstdio> | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | #include <bzlib.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | 
 | ||||||
|  | #include <osmium/io/compression.hpp> | ||||||
|  | #include <osmium/io/file_compression.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             [[noreturn]] inline void throw_bzip2_error(const std::string& msg, int error) { | ||||||
|  |                 throw std::runtime_error("bzip2 error: " + msg + ": " + std::to_string(error)); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |         class Bzip2Compressor : public Compressor { | ||||||
|  | 
 | ||||||
|  |             FILE* m_file; | ||||||
|  |             int m_bzerror; | ||||||
|  |             BZFILE* m_bzfile; | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             explicit Bzip2Compressor(int fd) : | ||||||
|  |                 Compressor(), | ||||||
|  |                 m_file(fdopen(dup(fd), "wb")), | ||||||
|  |                 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); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             ~Bzip2Compressor() override final { | ||||||
|  |                 this->close(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void write(const std::string& data) override final { | ||||||
|  |                 int error; | ||||||
|  |                 ::BZ2_bzWrite(&error, m_bzfile, const_cast<char*>(data.data()), data.size()); | ||||||
|  |                 if (error != BZ_OK && error != BZ_STREAM_END) { | ||||||
|  |                     detail::throw_bzip2_error("write failed", error); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void close() override final { | ||||||
|  |                 if (m_bzfile) { | ||||||
|  |                     int error; | ||||||
|  |                     ::BZ2_bzWriteClose(&error, m_bzfile, 0, nullptr, nullptr); | ||||||
|  |                     m_bzfile = nullptr; | ||||||
|  |                     if (m_file) { | ||||||
|  |                         fclose(m_file); | ||||||
|  |                     } | ||||||
|  |                     if (error != BZ_OK) { | ||||||
|  |                         detail::throw_bzip2_error("write close failed", error); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class Bzip2Compressor
 | ||||||
|  | 
 | ||||||
|  |         class Bzip2Decompressor : public Decompressor { | ||||||
|  | 
 | ||||||
|  |             FILE* m_file; | ||||||
|  |             int m_bzerror; | ||||||
|  |             BZFILE* m_bzfile; | ||||||
|  |             bool m_stream_end {false}; | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             Bzip2Decompressor(int fd) : | ||||||
|  |                 Decompressor(), | ||||||
|  |                 m_file(fdopen(dup(fd), "rb")), | ||||||
|  |                 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); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             ~Bzip2Decompressor() override final { | ||||||
|  |                 this->close(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             std::string read() override final { | ||||||
|  |                 if (m_stream_end) { | ||||||
|  |                     return std::string(); | ||||||
|  |                 } | ||||||
|  |                 std::string buffer(osmium::io::Decompressor::input_buffer_size, '\0'); | ||||||
|  |                 int error; | ||||||
|  |                 int nread = ::BZ2_bzRead(&error, m_bzfile, const_cast<char*>(buffer.data()), buffer.size()); | ||||||
|  |                 if (error != BZ_OK && error != BZ_STREAM_END) { | ||||||
|  |                     detail::throw_bzip2_error("read failed", error); | ||||||
|  |                 } | ||||||
|  |                 if (error == BZ_STREAM_END) { | ||||||
|  |                     void* unused; | ||||||
|  |                     int nunused; | ||||||
|  |                     if (! feof(m_file)) { | ||||||
|  |                         ::BZ2_bzReadGetUnused(&error, m_bzfile, &unused, &nunused); | ||||||
|  |                         if (error != BZ_OK) { | ||||||
|  |                             detail::throw_bzip2_error("get unused failed", error); | ||||||
|  |                         } | ||||||
|  |                         std::string unused_data(static_cast<const char*>(unused), static_cast<std::string::size_type>(nunused)); | ||||||
|  |                         ::BZ2_bzReadClose(&error, m_bzfile); | ||||||
|  |                         if (error != BZ_OK) { | ||||||
|  |                             detail::throw_bzip2_error("read close failed", error); | ||||||
|  |                         } | ||||||
|  |                         m_bzfile = ::BZ2_bzReadOpen(&error, m_file, 0, 0, const_cast<void*>(static_cast<const void*>(unused_data.data())), unused_data.size()); | ||||||
|  |                         if (error != BZ_OK) { | ||||||
|  |                             detail::throw_bzip2_error("read open failed", error); | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|  |                         m_stream_end = true; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 buffer.resize(static_cast<std::string::size_type>(nread)); | ||||||
|  |                 return buffer; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void close() override final { | ||||||
|  |                 if (m_bzfile) { | ||||||
|  |                     int error; | ||||||
|  |                     ::BZ2_bzReadClose(&error, m_bzfile); | ||||||
|  |                     m_bzfile = nullptr; | ||||||
|  |                     if (m_file) { | ||||||
|  |                         fclose(m_file); | ||||||
|  |                     } | ||||||
|  |                     if (error != BZ_OK) { | ||||||
|  |                         detail::throw_bzip2_error("read close failed", error); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class Bzip2Decompressor
 | ||||||
|  | 
 | ||||||
|  |         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); } | ||||||
|  |             ); | ||||||
|  | 
 | ||||||
|  |         } // anonymous namespace
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_BZIP2_COMPRESSION_HPP
 | ||||||
							
								
								
									
										235
									
								
								ThirdParty/osmium/io/compression.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										235
									
								
								ThirdParty/osmium/io/compression.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,235 @@ | |||||||
|  | #ifndef OSMIUM_IO_COMPRESSION_HPP | ||||||
|  | #define OSMIUM_IO_COMPRESSION_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cerrno> | ||||||
|  | #include <functional> | ||||||
|  | #include <map> | ||||||
|  | #include <memory> | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <string> | ||||||
|  | #include <system_error> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/io/detail/read_write.hpp> | ||||||
|  | #include <osmium/io/file_compression.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         class Compressor { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             Compressor() = default; | ||||||
|  | 
 | ||||||
|  |             virtual ~Compressor() { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             virtual void write(const std::string& data) = 0; | ||||||
|  | 
 | ||||||
|  |             virtual void close() = 0; | ||||||
|  | 
 | ||||||
|  |         }; // class Compressor
 | ||||||
|  | 
 | ||||||
|  |         class Decompressor { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             static constexpr size_t input_buffer_size = 256 * 1024; | ||||||
|  | 
 | ||||||
|  |             Decompressor() = default; | ||||||
|  | 
 | ||||||
|  |             Decompressor(const Decompressor&) = delete; | ||||||
|  |             Decompressor& operator=(const Decompressor&) = delete; | ||||||
|  | 
 | ||||||
|  |             Decompressor(Decompressor&&) = delete; | ||||||
|  |             Decompressor& operator=(Decompressor&&) = delete; | ||||||
|  | 
 | ||||||
|  |             virtual ~Decompressor() { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             virtual std::string read() = 0; | ||||||
|  | 
 | ||||||
|  |             virtual void close() = 0; | ||||||
|  | 
 | ||||||
|  |         }; // class Decompressor
 | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * This singleton factory class is used to register compression | ||||||
|  |          * algorithms used for reading and writing OSM files. | ||||||
|  |          * | ||||||
|  |          * For each algorithm we store two functions that construct | ||||||
|  |          * a compressor and decompressor object, respectively. | ||||||
|  |          */ | ||||||
|  |         class CompressionFactory { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             typedef std::function<osmium::io::Compressor*(int)> create_compressor_type; | ||||||
|  |             typedef std::function<osmium::io::Decompressor*(int)> create_decompressor_type; | ||||||
|  | 
 | ||||||
|  |         private: | ||||||
|  | 
 | ||||||
|  |             typedef std::map<const osmium::io::file_compression, std::pair<create_compressor_type, create_decompressor_type>> compression_map_type; | ||||||
|  | 
 | ||||||
|  |             compression_map_type m_callbacks {}; | ||||||
|  | 
 | ||||||
|  |             CompressionFactory() = default; | ||||||
|  | 
 | ||||||
|  |             CompressionFactory(const CompressionFactory&) = delete; | ||||||
|  |             CompressionFactory& operator=(const CompressionFactory&) = delete; | ||||||
|  | 
 | ||||||
|  |             CompressionFactory(CompressionFactory&&) = delete; | ||||||
|  |             CompressionFactory& operator=(CompressionFactory&&) = delete; | ||||||
|  | 
 | ||||||
|  |             [[noreturn]] void error(osmium::io::file_compression compression) { | ||||||
|  |                 std::string error_message {"Support for compression '"}; | ||||||
|  |                 error_message += as_string(compression); | ||||||
|  |                 error_message += "' not compiled into this binary."; | ||||||
|  |                 throw std::runtime_error(error_message); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             static CompressionFactory& instance() { | ||||||
|  |                 static CompressionFactory factory; | ||||||
|  |                 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)); | ||||||
|  |                 return m_callbacks.insert(cc).second; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             std::unique_ptr<osmium::io::Compressor> create_compressor(osmium::io::file_compression compression, int fd) { | ||||||
|  |                 auto it = m_callbacks.find(compression); | ||||||
|  | 
 | ||||||
|  |                 if (it != m_callbacks.end()) { | ||||||
|  |                     return std::unique_ptr<osmium::io::Compressor>((it->second.first)(fd)); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 error(compression); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             std::unique_ptr<osmium::io::Decompressor> create_decompressor(osmium::io::file_compression compression, int fd) { | ||||||
|  |                 auto it = m_callbacks.find(compression); | ||||||
|  | 
 | ||||||
|  |                 if (it != m_callbacks.end()) { | ||||||
|  |                     return std::unique_ptr<osmium::io::Decompressor>((it->second.second)(fd)); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 error(compression); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class CompressionFactory
 | ||||||
|  | 
 | ||||||
|  |         class NoCompressor : public Compressor { | ||||||
|  | 
 | ||||||
|  |             int m_fd; | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             NoCompressor(int fd) : | ||||||
|  |                 Compressor(), | ||||||
|  |                 m_fd(fd) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             ~NoCompressor() override final { | ||||||
|  |                 this->close(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void write(const std::string& data) override final { | ||||||
|  |                 osmium::io::detail::reliable_write(m_fd, data.data(), data.size()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void close() override final { | ||||||
|  |                 if (m_fd >= 0) { | ||||||
|  |                     ::close(m_fd); | ||||||
|  |                     m_fd = -1; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class NoCompressor
 | ||||||
|  | 
 | ||||||
|  |         class NoDecompressor : public Decompressor { | ||||||
|  | 
 | ||||||
|  |             int m_fd; | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             NoDecompressor(int fd) : | ||||||
|  |                 Decompressor(), | ||||||
|  |                 m_fd(fd) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             ~NoDecompressor() override final { | ||||||
|  |                 this->close(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             std::string read() override final { | ||||||
|  |                 std::string buffer(osmium::io::Decompressor::input_buffer_size, '\0'); | ||||||
|  |                 ssize_t nread = ::read(m_fd, const_cast<char*>(buffer.data()), buffer.size()); | ||||||
|  |                 if (nread < 0) { | ||||||
|  |                     throw std::system_error(errno, std::system_category(), "Read failed"); | ||||||
|  |                 } | ||||||
|  |                 buffer.resize(static_cast<size_t>(nread)); | ||||||
|  |                 return buffer; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void close() override final { | ||||||
|  |                 if (m_fd >= 0) { | ||||||
|  |                     ::close(m_fd); | ||||||
|  |                     m_fd = -1; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class NoDecompressor
 | ||||||
|  | 
 | ||||||
|  |         namespace { | ||||||
|  | 
 | ||||||
|  |             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); } | ||||||
|  |             ); | ||||||
|  | 
 | ||||||
|  |         } // anonymous namespace
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_COMPRESSION_HPP
 | ||||||
							
								
								
									
										160
									
								
								ThirdParty/osmium/io/detail/input_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								ThirdParty/osmium/io/detail/input_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,160 @@ | |||||||
|  | #ifndef OSMIUM_IO_DETAIL_INPUT_FORMAT_HPP | ||||||
|  | #define OSMIUM_IO_DETAIL_INPUT_FORMAT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <functional> | ||||||
|  | #include <map> | ||||||
|  | #include <memory> | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <string> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/io/file.hpp> | ||||||
|  | #include <osmium/io/file_format.hpp> | ||||||
|  | #include <osmium/io/header.hpp> | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/osm/entity_bits.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace thread { | ||||||
|  |         template <typename T> class Queue; | ||||||
|  |     } // namespace thread
 | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Virtual base class for all classes reading OSM files in different | ||||||
|  |              * formats. | ||||||
|  |              * | ||||||
|  |              * Do not use this class or derived classes directly. Use the | ||||||
|  |              * osmium::io::Reader class instead. | ||||||
|  |              */ | ||||||
|  |             class InputFormat { | ||||||
|  | 
 | ||||||
|  |             protected: | ||||||
|  | 
 | ||||||
|  |                 osmium::io::File m_file; | ||||||
|  |                 osmium::osm_entity_bits::type m_read_which_entities; | ||||||
|  |                 osmium::thread::Queue<std::string>& m_input_queue; | ||||||
|  |                 osmium::io::Header m_header {}; | ||||||
|  | 
 | ||||||
|  |                 explicit InputFormat(const osmium::io::File& file, osmium::osm_entity_bits::type read_which_entities, osmium::thread::Queue<std::string>& input_queue) : | ||||||
|  |                     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()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 InputFormat(const InputFormat&) = delete; | ||||||
|  |                 InputFormat(InputFormat&&) = delete; | ||||||
|  | 
 | ||||||
|  |                 InputFormat& operator=(const InputFormat&) = delete; | ||||||
|  |                 InputFormat& operator=(InputFormat&&) = delete; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 virtual ~InputFormat() { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 virtual osmium::memory::Buffer read() = 0; | ||||||
|  | 
 | ||||||
|  |                 virtual void close() { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 virtual osmium::io::Header header() { | ||||||
|  |                     return m_header; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class InputFormat
 | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * This factory class is used to create objects that read OSM data | ||||||
|  |              * written in a specified format. | ||||||
|  |              * | ||||||
|  |              * Do not use this class directly. Instead use the osmium::io::Reader | ||||||
|  |              * class. | ||||||
|  |              */ | ||||||
|  |             class InputFormatFactory { | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 typedef std::function<osmium::io::detail::InputFormat*(const osmium::io::File&, osmium::osm_entity_bits::type read_which_entities, osmium::thread::Queue<std::string>&)> create_input_type; | ||||||
|  | 
 | ||||||
|  |             private: | ||||||
|  | 
 | ||||||
|  |                 typedef std::map<osmium::io::file_format, create_input_type> map_type; | ||||||
|  | 
 | ||||||
|  |                 map_type m_callbacks; | ||||||
|  | 
 | ||||||
|  |                 InputFormatFactory() : | ||||||
|  |                     m_callbacks() { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 static InputFormatFactory& instance() { | ||||||
|  |                     static InputFormatFactory factory; | ||||||
|  |                     return factory; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 bool register_input_format(osmium::io::file_format format, create_input_type create_function) { | ||||||
|  |                     if (! m_callbacks.insert(map_type::value_type(format, create_function)).second) { | ||||||
|  |                         return false; | ||||||
|  |                     } | ||||||
|  |                     return true; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 std::unique_ptr<osmium::io::detail::InputFormat> create_input(const osmium::io::File& file, osmium::osm_entity_bits::type read_which_entities, osmium::thread::Queue<std::string>& input_queue) { | ||||||
|  |                     file.check(); | ||||||
|  | 
 | ||||||
|  |                     auto it = m_callbacks.find(file.format()); | ||||||
|  |                     if (it != m_callbacks.end()) { | ||||||
|  |                         return std::unique_ptr<osmium::io::detail::InputFormat>((it->second)(file, read_which_entities, input_queue)); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     throw std::runtime_error(std::string("Support for input format '") + as_string(file.format()) + "' not compiled into this binary."); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class InputFormatFactory
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_DETAIL_INPUT_FORMAT_HPP
 | ||||||
							
								
								
									
										301
									
								
								ThirdParty/osmium/io/detail/opl_output_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										301
									
								
								ThirdParty/osmium/io/detail/opl_output_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,301 @@ | |||||||
|  | #ifndef OSMIUM_IO_DETAIL_OPL_OUTPUT_FORMAT_HPP | ||||||
|  | #define OSMIUM_IO_DETAIL_OPL_OUTPUT_FORMAT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <chrono> | ||||||
|  | #include <cinttypes> | ||||||
|  | #include <cstddef> | ||||||
|  | #include <cstdint> | ||||||
|  | #include <cstdio> | ||||||
|  | #include <future> | ||||||
|  | #include <iterator> | ||||||
|  | #include <memory> | ||||||
|  | #include <ratio> | ||||||
|  | #include <string> | ||||||
|  | #include <thread> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <boost/version.hpp> | ||||||
|  | 
 | ||||||
|  | #if BOOST_VERSION >= 104800 | ||||||
|  | # include <boost/regex/pending/unicode_iterator.hpp> | ||||||
|  | #else | ||||||
|  | # include <boost_unicode_iterator.hpp> | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include <osmium/handler.hpp> | ||||||
|  | #include <osmium/io/detail/output_format.hpp> | ||||||
|  | #include <osmium/io/file_format.hpp> | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/memory/collection.hpp> | ||||||
|  | #include <osmium/osm/box.hpp> | ||||||
|  | #include <osmium/osm/changeset.hpp> | ||||||
|  | #include <osmium/osm/item_type.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/node.hpp> | ||||||
|  | #include <osmium/osm/object.hpp> | ||||||
|  | #include <osmium/osm/relation.hpp> | ||||||
|  | #include <osmium/osm/tag.hpp> | ||||||
|  | #include <osmium/osm/timestamp.hpp> | ||||||
|  | #include <osmium/osm/way.hpp> | ||||||
|  | #include <osmium/thread/pool.hpp> | ||||||
|  | #include <osmium/visitor.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         class File; | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Writes out one buffer with OSM data in OPL format. | ||||||
|  |              */ | ||||||
|  |             class OPLOutputBlock : public osmium::handler::Handler { | ||||||
|  | 
 | ||||||
|  |                 static constexpr size_t tmp_buffer_size = 100; | ||||||
|  | 
 | ||||||
|  |                 osmium::memory::Buffer m_input_buffer; | ||||||
|  | 
 | ||||||
|  |                 std::string m_out; | ||||||
|  | 
 | ||||||
|  |                 char m_tmp_buffer[tmp_buffer_size+1]; | ||||||
|  | 
 | ||||||
|  |                 void append_encoded_string(const std::string& data) { | ||||||
|  |                     boost::u8_to_u32_iterator<std::string::const_iterator> it(data.cbegin(), data.cbegin(), data.cend()); | ||||||
|  |                     boost::u8_to_u32_iterator<std::string::const_iterator> end(data.cend(), data.cend(), data.cend()); | ||||||
|  |                     boost::utf8_output_iterator<std::back_insert_iterator<std::string>> oit(std::back_inserter(m_out)); | ||||||
|  | 
 | ||||||
|  |                     for (; it != end; ++it) { | ||||||
|  |                         uint32_t c = *it; | ||||||
|  | 
 | ||||||
|  |                         // This is a list of Unicode code points that we let
 | ||||||
|  |                         // through instead of escaping them. It is incomplete
 | ||||||
|  |                         // and can be extended later.
 | ||||||
|  |                         // Generally we don't want to let through any character
 | ||||||
|  |                         // that has special meaning in the OPL format such as
 | ||||||
|  |                         // space, comma, @, etc. and any non-printing characters.
 | ||||||
|  |                         if ((0x0021 <= c && c <= 0x0024) || | ||||||
|  |                             (0x0026 <= c && c <= 0x002b) || | ||||||
|  |                             (0x002d <= c && c <= 0x003c) || | ||||||
|  |                             (0x003e <= c && c <= 0x003f) || | ||||||
|  |                             (0x0041 <= c && c <= 0x007e) || | ||||||
|  |                             (0x00a1 <= c && c <= 0x00ac) || | ||||||
|  |                             (0x00ae <= c && c <= 0x05ff)) { | ||||||
|  |                             *oit = c; | ||||||
|  |                         } else { | ||||||
|  |                             m_out += '%'; | ||||||
|  |                             snprintf(m_tmp_buffer, tmp_buffer_size, "%04x", c); | ||||||
|  |                             m_out += m_tmp_buffer; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void write_meta(const osmium::OSMObject& object) { | ||||||
|  |                     snprintf(m_tmp_buffer, tmp_buffer_size, "%" PRId64 " v%d d", object.id(), object.version()); | ||||||
|  |                     m_out += m_tmp_buffer; | ||||||
|  |                     m_out += (object.visible() ? 'V' : 'D'); | ||||||
|  |                     snprintf(m_tmp_buffer, tmp_buffer_size, " c%d t", object.changeset()); | ||||||
|  |                     m_out += m_tmp_buffer; | ||||||
|  |                     m_out += object.timestamp().to_iso(); | ||||||
|  |                     snprintf(m_tmp_buffer, tmp_buffer_size, " i%d u", object.uid()); | ||||||
|  |                     m_out += m_tmp_buffer; | ||||||
|  |                     append_encoded_string(object.user()); | ||||||
|  |                     m_out += " T"; | ||||||
|  |                     bool first = true; | ||||||
|  |                     for (const auto& tag : object.tags()) { | ||||||
|  |                         if (first) { | ||||||
|  |                             first = false; | ||||||
|  |                         } else { | ||||||
|  |                             m_out += ','; | ||||||
|  |                         } | ||||||
|  |                         append_encoded_string(tag.key()); | ||||||
|  |                         m_out += '='; | ||||||
|  |                         append_encoded_string(tag.value()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void write_location(const osmium::Location location, const char x, const char y) { | ||||||
|  |                     if (location) { | ||||||
|  |                         snprintf(m_tmp_buffer, tmp_buffer_size, " %c%.7f %c%.7f", x, location.lon_without_check(), y, location.lat_without_check()); | ||||||
|  |                         m_out += m_tmp_buffer; | ||||||
|  |                     } else { | ||||||
|  |                         m_out += ' '; | ||||||
|  |                         m_out += x; | ||||||
|  |                         m_out += ' '; | ||||||
|  |                         m_out += y; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 explicit OPLOutputBlock(osmium::memory::Buffer&& buffer) : | ||||||
|  |                     m_input_buffer(std::move(buffer)), | ||||||
|  |                     m_out(), | ||||||
|  |                     m_tmp_buffer() { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 OPLOutputBlock(const OPLOutputBlock&) = delete; | ||||||
|  |                 OPLOutputBlock& operator=(const OPLOutputBlock&) = delete; | ||||||
|  | 
 | ||||||
|  |                 OPLOutputBlock(OPLOutputBlock&& other) = default; | ||||||
|  |                 OPLOutputBlock& operator=(OPLOutputBlock&& other) = default; | ||||||
|  | 
 | ||||||
|  |                 std::string operator()() { | ||||||
|  |                     osmium::apply(m_input_buffer.cbegin(), m_input_buffer.cend(), *this); | ||||||
|  | 
 | ||||||
|  |                     std::string out; | ||||||
|  |                     std::swap(out, m_out); | ||||||
|  |                     return out; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void node(const osmium::Node& node) { | ||||||
|  |                     m_out += 'n'; | ||||||
|  |                     write_meta(node); | ||||||
|  |                     write_location(node.location(), 'x', 'y'); | ||||||
|  |                     m_out += '\n'; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void way(const osmium::Way& way) { | ||||||
|  |                     m_out += 'w'; | ||||||
|  |                     write_meta(way); | ||||||
|  | 
 | ||||||
|  |                     m_out += " N"; | ||||||
|  |                     bool first = true; | ||||||
|  |                     for (const auto& node_ref : way.nodes()) { | ||||||
|  |                         if (first) { | ||||||
|  |                             first = false; | ||||||
|  |                         } else { | ||||||
|  |                             m_out += ','; | ||||||
|  |                         } | ||||||
|  |                         snprintf(m_tmp_buffer, tmp_buffer_size, "n%" PRId64, node_ref.ref()); | ||||||
|  |                         m_out += m_tmp_buffer; | ||||||
|  |                     } | ||||||
|  |                     m_out += '\n'; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void relation(const osmium::Relation& relation) { | ||||||
|  |                     m_out += 'r'; | ||||||
|  |                     write_meta(relation); | ||||||
|  | 
 | ||||||
|  |                     m_out += " M"; | ||||||
|  |                     bool first = true; | ||||||
|  |                     for (const auto& member : relation.members()) { | ||||||
|  |                         if (first) { | ||||||
|  |                             first = false; | ||||||
|  |                         } else { | ||||||
|  |                             m_out += ','; | ||||||
|  |                         } | ||||||
|  |                         m_out += item_type_to_char(member.type()); | ||||||
|  |                         snprintf(m_tmp_buffer, tmp_buffer_size, "%" PRId64 "@", member.ref()); | ||||||
|  |                         m_out += m_tmp_buffer; | ||||||
|  |                         m_out += member.role(); | ||||||
|  |                     } | ||||||
|  |                     m_out += '\n'; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void changeset(const osmium::Changeset& changeset) { | ||||||
|  |                     snprintf(m_tmp_buffer, tmp_buffer_size, "c%d k%d s", changeset.id(), changeset.num_changes()); | ||||||
|  |                     m_out += m_tmp_buffer; | ||||||
|  |                     m_out += changeset.created_at().to_iso(); | ||||||
|  |                     m_out += " e"; | ||||||
|  |                     m_out += changeset.closed_at().to_iso(); | ||||||
|  |                     snprintf(m_tmp_buffer, tmp_buffer_size, " i%d u", changeset.uid()); | ||||||
|  |                     m_out += m_tmp_buffer; | ||||||
|  |                     append_encoded_string(changeset.user()); | ||||||
|  |                     write_location(changeset.bounds().bottom_left(), 'x', 'y'); | ||||||
|  |                     write_location(changeset.bounds().top_right(), 'X', 'Y'); | ||||||
|  |                     m_out += " T"; | ||||||
|  |                     bool first = true; | ||||||
|  |                     for (const auto& tag : changeset.tags()) { | ||||||
|  |                         if (first) { | ||||||
|  |                             first = false; | ||||||
|  |                         } else { | ||||||
|  |                             m_out += ','; | ||||||
|  |                         } | ||||||
|  |                         append_encoded_string(tag.key()); | ||||||
|  |                         m_out += '='; | ||||||
|  |                         append_encoded_string(tag.value()); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     m_out += '\n'; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // OPLOutputBlock
 | ||||||
|  | 
 | ||||||
|  |             class OPLOutputFormat : public osmium::io::detail::OutputFormat { | ||||||
|  | 
 | ||||||
|  |                 OPLOutputFormat(const OPLOutputFormat&) = delete; | ||||||
|  |                 OPLOutputFormat& operator=(const OPLOutputFormat&) = delete; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 OPLOutputFormat(const osmium::io::File& file, data_queue_type& output_queue) : | ||||||
|  |                     OutputFormat(file, output_queue) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void write_buffer(osmium::memory::Buffer&& buffer) override final { | ||||||
|  |                     OPLOutputBlock 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
 | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void close() override final { | ||||||
|  |                     std::string out; | ||||||
|  |                     std::promise<std::string> promise; | ||||||
|  |                     m_output_queue.push(promise.get_future()); | ||||||
|  |                     promise.set_value(out); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class OPLOutputFormat
 | ||||||
|  | 
 | ||||||
|  |             namespace { | ||||||
|  | 
 | ||||||
|  |                 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); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |             } // anonymous namespace
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_DETAIL_OPL_OUTPUT_FORMAT_HPP
 | ||||||
							
								
								
									
										156
									
								
								ThirdParty/osmium/io/detail/output_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								ThirdParty/osmium/io/detail/output_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,156 @@ | |||||||
|  | #ifndef OSMIUM_IO_DETAIL_OUTPUT_FORMAT_HPP | ||||||
|  | #define OSMIUM_IO_DETAIL_OUTPUT_FORMAT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <functional> | ||||||
|  | #include <future> | ||||||
|  | #include <map> | ||||||
|  | #include <memory> | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <string> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/io/file.hpp> | ||||||
|  | #include <osmium/io/file_format.hpp> | ||||||
|  | #include <osmium/io/header.hpp> | ||||||
|  | #include <osmium/thread/queue.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace memory { | ||||||
|  |         class Buffer; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             typedef osmium::thread::Queue<std::future<std::string>> data_queue_type; | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Virtual base class for all classes writing OSM files in different | ||||||
|  |              * formats. | ||||||
|  |              * | ||||||
|  |              * Do not use this class or derived classes directly. Use the | ||||||
|  |              * osmium::io::Writer class instead. | ||||||
|  |              */ | ||||||
|  |             class OutputFormat { | ||||||
|  | 
 | ||||||
|  |             protected: | ||||||
|  | 
 | ||||||
|  |                 osmium::io::File m_file; | ||||||
|  |                 data_queue_type& m_output_queue; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 explicit OutputFormat(const osmium::io::File& file, data_queue_type& output_queue) : | ||||||
|  |                     m_file(file), | ||||||
|  |                     m_output_queue(output_queue) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 OutputFormat(const OutputFormat&) = delete; | ||||||
|  |                 OutputFormat(OutputFormat&&) = delete; | ||||||
|  | 
 | ||||||
|  |                 OutputFormat& operator=(const OutputFormat&) = delete; | ||||||
|  |                 OutputFormat& operator=(OutputFormat&&) = delete; | ||||||
|  | 
 | ||||||
|  |                 virtual ~OutputFormat() { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 virtual void write_header(const osmium::io::Header&) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 virtual void write_buffer(osmium::memory::Buffer&&) = 0; | ||||||
|  | 
 | ||||||
|  |                 virtual void close() = 0; | ||||||
|  | 
 | ||||||
|  |             }; // class OutputFormat
 | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * This factory class is used to create objects that write OSM data | ||||||
|  |              * into a specified output format. | ||||||
|  |              * | ||||||
|  |              * Do not use this class directly. Instead use the osmium::io::Writer | ||||||
|  |              * class. | ||||||
|  |              */ | ||||||
|  |             class OutputFormatFactory { | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 typedef std::function<osmium::io::detail::OutputFormat*(const osmium::io::File&, data_queue_type&)> create_output_type; | ||||||
|  | 
 | ||||||
|  |             private: | ||||||
|  | 
 | ||||||
|  |                 typedef std::map<osmium::io::file_format, create_output_type> map_type; | ||||||
|  | 
 | ||||||
|  |                 map_type m_callbacks; | ||||||
|  | 
 | ||||||
|  |                 OutputFormatFactory() : | ||||||
|  |                     m_callbacks() { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 static OutputFormatFactory& instance() { | ||||||
|  |                     static OutputFormatFactory factory; | ||||||
|  |                     return factory; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 bool register_output_format(osmium::io::file_format format, create_output_type create_function) { | ||||||
|  |                     if (! m_callbacks.insert(map_type::value_type(format, create_function)).second) { | ||||||
|  |                         return false; | ||||||
|  |                     } | ||||||
|  |                     return true; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 std::unique_ptr<osmium::io::detail::OutputFormat> create_output(const osmium::io::File& file, data_queue_type& output_queue) { | ||||||
|  |                     file.check(); | ||||||
|  | 
 | ||||||
|  |                     auto it = m_callbacks.find(file.format()); | ||||||
|  |                     if (it != m_callbacks.end()) { | ||||||
|  |                         return std::unique_ptr<osmium::io::detail::OutputFormat>((it->second)(file, output_queue)); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     throw std::runtime_error(std::string("Support for output format '") + as_string(file.format()) + "' not compiled into this binary."); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class OutputFormatFactory
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_DETAIL_OUTPUT_FORMAT_HPP
 | ||||||
							
								
								
									
										79
									
								
								ThirdParty/osmium/io/detail/pbf.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								ThirdParty/osmium/io/detail/pbf.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,79 @@ | |||||||
|  | #ifndef OSMIUM_IO_DETAIL_PBF_HPP | ||||||
|  | #define OSMIUM_IO_DETAIL_PBF_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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. | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #define OSMIUM_LINK_WITH_LIBS_PBF -pthread -lz -lprotobuf-lite -losmpbf | ||||||
|  | 
 | ||||||
|  | #include <stdexcept> | ||||||
|  | 
 | ||||||
|  | #include <osmpbf/osmpbf.h> | ||||||
|  | 
 | ||||||
|  | // needed for htonl and ntohl
 | ||||||
|  | #ifndef WIN32 | ||||||
|  | # include <netinet/in.h> | ||||||
|  | #else | ||||||
|  | # include <winsock2.h> | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include <osmium/osm/item_type.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     inline item_type osmpbf_membertype_to_item_type(const OSMPBF::Relation::MemberType mt) { | ||||||
|  |         switch (mt) { | ||||||
|  |             case OSMPBF::Relation::NODE: | ||||||
|  |                 return item_type::node; | ||||||
|  |             case OSMPBF::Relation::WAY: | ||||||
|  |                 return item_type::way; | ||||||
|  |             case OSMPBF::Relation::RELATION: | ||||||
|  |                 return item_type::relation; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     inline OSMPBF::Relation::MemberType item_type_to_osmpbf_membertype(const item_type type) { | ||||||
|  |         switch (type) { | ||||||
|  |             case item_type::node: | ||||||
|  |                 return OSMPBF::Relation::NODE; | ||||||
|  |             case item_type::way: | ||||||
|  |                 return OSMPBF::Relation::WAY; | ||||||
|  |             case item_type::relation: | ||||||
|  |                 return OSMPBF::Relation::RELATION; | ||||||
|  |             default: | ||||||
|  |                 throw std::runtime_error("Unknown relation member type"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_DETAIL_PBF_HPP
 | ||||||
							
								
								
									
										681
									
								
								ThirdParty/osmium/io/detail/pbf_input_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										681
									
								
								ThirdParty/osmium/io/detail/pbf_input_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,681 @@ | |||||||
|  | #ifndef OSMIUM_IO_DETAIL_PBF_INPUT_FORMAT_HPP | ||||||
|  | #define OSMIUM_IO_DETAIL_PBF_INPUT_FORMAT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <algorithm> | ||||||
|  | #include <atomic> | ||||||
|  | #include <cassert> | ||||||
|  | #include <chrono> | ||||||
|  | #include <cstddef> | ||||||
|  | #include <cstdint> | ||||||
|  | #include <cstring> | ||||||
|  | #include <future> | ||||||
|  | #include <memory> | ||||||
|  | #include <ratio> | ||||||
|  | #include <sstream> | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <string> | ||||||
|  | #include <thread> | ||||||
|  | 
 | ||||||
|  | #include <osmium/builder/osm_object_builder.hpp> | ||||||
|  | #include <osmium/io/detail/input_format.hpp> | ||||||
|  | #include <osmium/io/detail/pbf.hpp> // IWYU pragma: export
 | ||||||
|  | #include <osmium/io/detail/zlib.hpp> | ||||||
|  | #include <osmium/io/file_format.hpp> | ||||||
|  | #include <osmium/io/header.hpp> | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/osm.hpp> | ||||||
|  | #include <osmium/osm/box.hpp> | ||||||
|  | #include <osmium/osm/entity_bits.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/object.hpp> | ||||||
|  | #include <osmium/osm/timestamp.hpp> | ||||||
|  | #include <osmium/thread/name.hpp> | ||||||
|  | #include <osmium/thread/pool.hpp> | ||||||
|  | #include <osmium/thread/queue.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         class File; | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             class PBFPrimitiveBlockParser { | ||||||
|  | 
 | ||||||
|  |                 static constexpr size_t initial_buffer_size = 10 * 1024; | ||||||
|  | 
 | ||||||
|  |                 const void* m_data; | ||||||
|  |                 const size_t m_size; | ||||||
|  | 
 | ||||||
|  |                 const OSMPBF::StringTable* m_stringtable; | ||||||
|  |                 int64_t m_lon_offset; | ||||||
|  |                 int64_t m_lat_offset; | ||||||
|  |                 int64_t m_date_factor; | ||||||
|  |                 int32_t m_granularity; | ||||||
|  | 
 | ||||||
|  |                 osmium::osm_entity_bits::type m_read_types; | ||||||
|  | 
 | ||||||
|  |                 osmium::memory::Buffer m_buffer; | ||||||
|  | 
 | ||||||
|  |                 PBFPrimitiveBlockParser(const PBFPrimitiveBlockParser&) = delete; | ||||||
|  |                 PBFPrimitiveBlockParser(PBFPrimitiveBlockParser&&) = delete; | ||||||
|  | 
 | ||||||
|  |                 PBFPrimitiveBlockParser& operator=(const PBFPrimitiveBlockParser&) = delete; | ||||||
|  |                 PBFPrimitiveBlockParser& operator=(PBFPrimitiveBlockParser&&) = delete; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 explicit PBFPrimitiveBlockParser(const void* data, const size_t size, osmium::osm_entity_bits::type read_types) : | ||||||
|  |                     m_data(data), | ||||||
|  |                     m_size(size), | ||||||
|  |                     m_stringtable(nullptr), | ||||||
|  |                     m_lon_offset(0), | ||||||
|  |                     m_lat_offset(0), | ||||||
|  |                     m_date_factor(1000), | ||||||
|  |                     m_granularity(100), | ||||||
|  |                     m_read_types(read_types), | ||||||
|  |                     m_buffer(initial_buffer_size) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 ~PBFPrimitiveBlockParser() = default; | ||||||
|  | 
 | ||||||
|  |                 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."); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     m_stringtable = &pbf_primitive_block.stringtable(); | ||||||
|  |                     m_lon_offset  = pbf_primitive_block.lon_offset(); | ||||||
|  |                     m_lat_offset  = pbf_primitive_block.lat_offset(); | ||||||
|  |                     m_date_factor = pbf_primitive_block.date_granularity() / 1000; | ||||||
|  |                     m_granularity = pbf_primitive_block.granularity(); | ||||||
|  | 
 | ||||||
|  |                     for (int i=0; i < pbf_primitive_block.primitivegroup_size(); ++i) { | ||||||
|  |                         const OSMPBF::PrimitiveGroup& group = pbf_primitive_block.primitivegroup(i); | ||||||
|  | 
 | ||||||
|  |                         if (group.has_dense())  { | ||||||
|  |                             if (m_read_types & osmium::osm_entity_bits::node) parse_dense_node_group(group); | ||||||
|  |                         } else if (group.ways_size() != 0) { | ||||||
|  |                             if (m_read_types & osmium::osm_entity_bits::way) parse_way_group(group); | ||||||
|  |                         } else if (group.relations_size() != 0) { | ||||||
|  |                             if (m_read_types & osmium::osm_entity_bits::relation) parse_relation_group(group); | ||||||
|  |                         } 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."); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     return std::move(m_buffer); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             private: | ||||||
|  | 
 | ||||||
|  |                 template <class TBuilder, class TPBFObject> | ||||||
|  |                 void parse_attributes(TBuilder& builder, const TPBFObject& pbf_object) { | ||||||
|  |                     auto& object = builder.object(); | ||||||
|  | 
 | ||||||
|  |                     object.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()); | ||||||
|  |                         if (pbf_object.info().has_visible()) { | ||||||
|  |                             object.visible(pbf_object.info().visible()); | ||||||
|  |                         } | ||||||
|  |                         builder.add_user(m_stringtable->s(pbf_object.info().user_sid()).data()); | ||||||
|  |                     } else { | ||||||
|  |                         builder.add_user(""); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void parse_node_group(const OSMPBF::PrimitiveGroup& group) { | ||||||
|  |                     for (int i=0; i < group.nodes_size(); ++i) { | ||||||
|  |                         osmium::builder::NodeBuilder builder(m_buffer); | ||||||
|  |                         const OSMPBF::Node& pbf_node = group.nodes(i); | ||||||
|  |                         parse_attributes(builder, pbf_node); | ||||||
|  | 
 | ||||||
|  |                         if (builder.object().visible()) { | ||||||
|  |                             builder.object().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))); | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         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<int>(pbf_node.keys(tag))).data(), | ||||||
|  |                                                    m_stringtable->s(static_cast<int>(pbf_node.vals(tag))).data()); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         m_buffer.commit(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void parse_way_group(const OSMPBF::PrimitiveGroup& group) { | ||||||
|  |                     for (int i=0; i < group.ways_size(); ++i) { | ||||||
|  |                         osmium::builder::WayBuilder builder(m_buffer); | ||||||
|  |                         const OSMPBF::Way& pbf_way = group.ways(i); | ||||||
|  |                         parse_attributes(builder, pbf_way); | ||||||
|  | 
 | ||||||
|  |                         if (pbf_way.refs_size() > 0) { | ||||||
|  |                             osmium::builder::WayNodeListBuilder wnl_builder(m_buffer, &builder); | ||||||
|  |                             int64_t ref = 0; | ||||||
|  |                             for (int n=0; n < pbf_way.refs_size(); ++n) { | ||||||
|  |                                 ref += pbf_way.refs(n); | ||||||
|  |                                 wnl_builder.add_node_ref(ref); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         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<int>(pbf_way.keys(tag))).data(), | ||||||
|  |                                                    m_stringtable->s(static_cast<int>(pbf_way.vals(tag))).data()); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         m_buffer.commit(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void parse_relation_group(const OSMPBF::PrimitiveGroup& group) { | ||||||
|  |                     for (int i=0; i < group.relations_size(); ++i) { | ||||||
|  |                         osmium::builder::RelationBuilder builder(m_buffer); | ||||||
|  |                         const OSMPBF::Relation& pbf_relation = group.relations(i); | ||||||
|  |                         parse_attributes(builder, pbf_relation); | ||||||
|  | 
 | ||||||
|  |                         if (pbf_relation.types_size() > 0) { | ||||||
|  |                             osmium::builder::RelationMemberListBuilder rml_builder(m_buffer, &builder); | ||||||
|  |                             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()); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         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<int>(pbf_relation.keys(tag))).data(), | ||||||
|  |                                                    m_stringtable->s(static_cast<int>(pbf_relation.vals(tag))).data()); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         m_buffer.commit(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 int add_tags(const OSMPBF::DenseNodes& dense, int n, osmium::builder::NodeBuilder* builder) { | ||||||
|  |                     if (n >= dense.keys_vals_size()) { | ||||||
|  |                         return n; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (dense.keys_vals(n) == 0) { | ||||||
|  |                         return n+1; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     osmium::builder::TagListBuilder tl_builder(m_buffer, builder); | ||||||
|  | 
 | ||||||
|  |                     while (n < dense.keys_vals_size()) { | ||||||
|  |                         int tag_key_pos = dense.keys_vals(n++); | ||||||
|  | 
 | ||||||
|  |                         if (tag_key_pos == 0) { | ||||||
|  |                             break; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         tl_builder.add_tag(m_stringtable->s(tag_key_pos).data(), | ||||||
|  |                                            m_stringtable->s(dense.keys_vals(n)).data()); | ||||||
|  | 
 | ||||||
|  |                         ++n; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     return n; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void parse_dense_node_group(const OSMPBF::PrimitiveGroup& group) { | ||||||
|  |                     int64_t last_dense_id        = 0; | ||||||
|  |                     int64_t last_dense_latitude  = 0; | ||||||
|  |                     int64_t last_dense_longitude = 0; | ||||||
|  |                     int64_t last_dense_uid       = 0; | ||||||
|  |                     int64_t last_dense_user_sid  = 0; | ||||||
|  |                     int64_t last_dense_changeset = 0; | ||||||
|  |                     int64_t last_dense_timestamp = 0; | ||||||
|  |                     int     last_dense_tag       = 0; | ||||||
|  | 
 | ||||||
|  |                     const OSMPBF::DenseNodes& dense = group.dense(); | ||||||
|  | 
 | ||||||
|  |                     for (int i=0; i < dense.id_size(); ++i) { | ||||||
|  |                         bool visible = true; | ||||||
|  | 
 | ||||||
|  |                         last_dense_id        += dense.id(i); | ||||||
|  |                         last_dense_latitude  += dense.lat(i); | ||||||
|  |                         last_dense_longitude += dense.lon(i); | ||||||
|  | 
 | ||||||
|  |                         if (dense.has_denseinfo()) { | ||||||
|  |                             last_dense_changeset += dense.denseinfo().changeset(i); | ||||||
|  |                             last_dense_timestamp += dense.denseinfo().timestamp(i); | ||||||
|  |                             last_dense_uid       += dense.denseinfo().uid(i); | ||||||
|  |                             last_dense_user_sid  += dense.denseinfo().user_sid(i); | ||||||
|  |                             if (dense.denseinfo().visible_size() > 0) { | ||||||
|  |                                 visible = dense.denseinfo().visible(i); | ||||||
|  |                             } | ||||||
|  |                             assert(last_dense_changeset >= 0); | ||||||
|  |                             assert(last_dense_timestamp >= 0); | ||||||
|  |                             assert(last_dense_uid >= -1); | ||||||
|  |                             assert(last_dense_user_sid >= 0); | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         osmium::builder::NodeBuilder builder(m_buffer); | ||||||
|  |                         osmium::Node& node = builder.object(); | ||||||
|  | 
 | ||||||
|  |                         node.id(last_dense_id); | ||||||
|  | 
 | ||||||
|  |                         if (dense.has_denseinfo()) { | ||||||
|  |                             auto v = dense.denseinfo().version(i); | ||||||
|  |                             assert(v > 0); | ||||||
|  |                             node.version(static_cast<osmium::object_version_type>(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()); | ||||||
|  |                         } else { | ||||||
|  |                             builder.add_user(""); | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         if (visible) { | ||||||
|  |                             builder.object().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))); | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         last_dense_tag = add_tags(dense, last_dense_tag, &builder); | ||||||
|  |                         m_buffer.commit(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class PBFPrimitiveBlockParser
 | ||||||
|  | 
 | ||||||
|  |             typedef osmium::thread::Queue<std::future<osmium::memory::Buffer>> queue_type; | ||||||
|  | 
 | ||||||
|  |             class InputQueueReader { | ||||||
|  | 
 | ||||||
|  |                 osmium::thread::Queue<std::string>& m_queue; | ||||||
|  |                 std::string m_buffer {}; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 InputQueueReader(osmium::thread::Queue<std::string>& queue) : | ||||||
|  |                     m_queue(queue) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 bool operator()(unsigned char* data, size_t size) { | ||||||
|  |                     while (m_buffer.size() < size) { | ||||||
|  |                         std::string new_data; | ||||||
|  |                         m_queue.wait_and_pop(new_data); | ||||||
|  |                         if (new_data.empty()) { | ||||||
|  |                             return false; | ||||||
|  |                         } | ||||||
|  |                         m_buffer += new_data; | ||||||
|  |                     } | ||||||
|  |                     memcpy(data, m_buffer.data(), size); | ||||||
|  |                     m_buffer.erase(0, size); | ||||||
|  |                     return true; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             template <class TDerived> | ||||||
|  |             class BlobParser { | ||||||
|  | 
 | ||||||
|  |             protected: | ||||||
|  | 
 | ||||||
|  |                 std::shared_ptr<unsigned char> m_input_buffer; | ||||||
|  |                 const int m_size; | ||||||
|  |                 const int m_blob_num; | ||||||
|  |                 InputQueueReader& m_input_queue_reader; | ||||||
|  | 
 | ||||||
|  |                 BlobParser(const int size, const int blob_num, InputQueueReader& input_queue_reader) : | ||||||
|  |                     m_input_buffer(new unsigned char[size], [](unsigned char* ptr) { delete[] ptr; }), | ||||||
|  |                     m_size(size), | ||||||
|  |                     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()); | ||||||
|  |                     } | ||||||
|  |                     if (! input_queue_reader(m_input_buffer.get(), size)) { | ||||||
|  |                         // EOF
 | ||||||
|  |                         throw std::runtime_error("read error (EOF)"); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 void doit() { | ||||||
|  |                     OSMPBF::Blob pbf_blob; | ||||||
|  |                     if (!pbf_blob.ParseFromArray(m_input_buffer.get(), m_size)) { | ||||||
|  |                         throw std::runtime_error("failed to parse blob"); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (pbf_blob.has_raw()) { | ||||||
|  |                         static_cast<TDerived*>(this)->handle_blob(pbf_blob.raw()); | ||||||
|  |                         return; | ||||||
|  |                     } else if (pbf_blob.has_zlib_data()) { | ||||||
|  |                         auto raw_size = pbf_blob.raw_size(); | ||||||
|  |                         assert(raw_size >= 0); | ||||||
|  |                         assert(raw_size <= OSMPBF::max_uncompressed_blob_size); | ||||||
|  | 
 | ||||||
|  |                         std::string unpack_buffer { osmium::io::detail::zlib_uncompress(pbf_blob.zlib_data(), static_cast<unsigned long>(raw_size)) }; | ||||||
|  |                         static_cast<TDerived*>(this)->handle_blob(unpack_buffer); | ||||||
|  |                         return; | ||||||
|  |                     } else if (pbf_blob.has_lzma_data()) { | ||||||
|  |                         throw std::runtime_error("lzma blobs not implemented"); | ||||||
|  |                     } else { | ||||||
|  |                         throw std::runtime_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"); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (pbf_blob.has_raw()) { | ||||||
|  |                         return static_cast<TDerived*>(this)->handle_blob(pbf_blob.raw()); | ||||||
|  |                     } else if (pbf_blob.has_zlib_data()) { | ||||||
|  |                         auto raw_size = pbf_blob.raw_size(); | ||||||
|  |                         assert(raw_size >= 0); | ||||||
|  |                         assert(raw_size <= OSMPBF::max_uncompressed_blob_size); | ||||||
|  | 
 | ||||||
|  |                         std::string unpack_buffer { osmium::io::detail::zlib_uncompress(pbf_blob.zlib_data(), static_cast<unsigned long>(raw_size)) }; | ||||||
|  |                         return static_cast<TDerived*>(this)->handle_blob(unpack_buffer); | ||||||
|  |                     } else if (pbf_blob.has_lzma_data()) { | ||||||
|  |                         throw std::runtime_error("lzma blobs not implemented"); | ||||||
|  |                     } else { | ||||||
|  |                         throw std::runtime_error("Blob contains no data"); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class BlobParser;
 | ||||||
|  | 
 | ||||||
|  |             class HeaderBlobParser : public BlobParser<HeaderBlobParser> { | ||||||
|  | 
 | ||||||
|  |                 osmium::io::Header& m_header; | ||||||
|  | 
 | ||||||
|  |                 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."); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     for (int i=0; i < pbf_header_block.required_features_size(); ++i) { | ||||||
|  |                         const std::string& feature = pbf_header_block.required_features(i); | ||||||
|  | 
 | ||||||
|  |                         if (feature == "OsmSchema-V0.6") continue; | ||||||
|  |                         if (feature == "DenseNodes") { | ||||||
|  |                             m_header.set("pbf_dense_nodes", true); | ||||||
|  |                             continue; | ||||||
|  |                         } | ||||||
|  |                         if (feature == "HistoricalInformation") { | ||||||
|  |                             m_header.has_multiple_object_versions(true); | ||||||
|  |                             continue; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         std::ostringstream errmsg; | ||||||
|  |                         errmsg << "Required feature not supported: " << feature; | ||||||
|  |                         throw std::runtime_error(errmsg.str()); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (pbf_header_block.has_writingprogram()) { | ||||||
|  |                         m_header.set("generator", pbf_header_block.writingprogram()); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (pbf_header_block.has_bbox()) { | ||||||
|  |                         const OSMPBF::HeaderBBox& pbf_bbox = pbf_header_block.bbox(); | ||||||
|  |                         const int64_t resolution_convert = OSMPBF::lonlat_resolution / osmium::Location::coordinate_precision; | ||||||
|  |                         osmium::Box box; | ||||||
|  |                         box.extend(osmium::Location(pbf_bbox.left()  / resolution_convert, pbf_bbox.bottom() / resolution_convert)); | ||||||
|  |                         box.extend(osmium::Location(pbf_bbox.right() / resolution_convert, pbf_bbox.top()    / resolution_convert)); | ||||||
|  |                         m_header.add_box(box); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (pbf_header_block.has_osmosis_replication_timestamp()) { | ||||||
|  |                         m_header.set("osmosis_replication_timestamp", osmium::Timestamp(pbf_header_block.osmosis_replication_timestamp()).to_iso()); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (pbf_header_block.has_osmosis_replication_sequence_number()) { | ||||||
|  |                         m_header.set("osmosis_replication_sequence_number", std::to_string(pbf_header_block.osmosis_replication_sequence_number())); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (pbf_header_block.has_osmosis_replication_base_url()) { | ||||||
|  |                         m_header.set("osmosis_replication_base_url", pbf_header_block.osmosis_replication_base_url()); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 friend class BlobParser; | ||||||
|  | 
 | ||||||
|  |                 HeaderBlobParser(const int size, InputQueueReader& input_queue_reader, osmium::io::Header& header) : | ||||||
|  |                     BlobParser(size, 0, input_queue_reader), | ||||||
|  |                     m_header(header) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class HeaderBlobParser
 | ||||||
|  | 
 | ||||||
|  |             class DataBlobParser : public BlobParser<DataBlobParser> { | ||||||
|  | 
 | ||||||
|  |                 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); | ||||||
|  |                     return std::move(parser()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 friend class BlobParser; | ||||||
|  | 
 | ||||||
|  |                 DataBlobParser(const int size, const int blob_num, InputQueueReader& input_queue_reader, osmium::osm_entity_bits::type read_types) : | ||||||
|  |                     BlobParser(size, blob_num, input_queue_reader), | ||||||
|  |                     m_read_types(read_types) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class DataBlobParser
 | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Class for parsing PBF files. | ||||||
|  |              */ | ||||||
|  |             class PBFInputFormat : public osmium::io::detail::InputFormat { | ||||||
|  | 
 | ||||||
|  |                 bool m_use_thread_pool; | ||||||
|  |                 queue_type m_queue; | ||||||
|  |                 const size_t m_max_work_queue_size; | ||||||
|  |                 const size_t m_max_buffer_queue_size; | ||||||
|  |                 std::atomic<bool> m_done; | ||||||
|  |                 std::thread m_reader; | ||||||
|  |                 OSMPBF::BlobHeader m_blob_header; | ||||||
|  |                 InputQueueReader m_input_queue_reader; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Read BlobHeader by first reading the size and then the BlobHeader. | ||||||
|  |                  * The BlobHeader contains a type field (which is checked against | ||||||
|  |                  * 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). | ||||||
|  |                  */ | ||||||
|  |                 size_t read_blob_header(const char* expected_type) { | ||||||
|  |                     uint32_t size_in_network_byte_order; | ||||||
|  | 
 | ||||||
|  |                     if (! m_input_queue_reader(reinterpret_cast<unsigned char*>(&size_in_network_byte_order), sizeof(size_in_network_byte_order))) { | ||||||
|  |                         return 0; // EOF
 | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     uint32_t size = ntohl(size_in_network_byte_order); | ||||||
|  |                     if (size > static_cast<uint32_t>(OSMPBF::max_blob_header_size)) { | ||||||
|  |                         throw std::runtime_error("Invalid BlobHeader 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."); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (!m_blob_header.ParseFromArray(blob_header_buffer, static_cast<int>(size))) { | ||||||
|  |                         throw std::runtime_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)."); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     return static_cast<size_t>(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")) { | ||||||
|  |                         DataBlobParser data_blob_parser(size, n, m_input_queue_reader, read_types); | ||||||
|  | 
 | ||||||
|  |                         if (m_use_thread_pool) { | ||||||
|  |                             m_queue.push(osmium::thread::Pool::instance().submit(data_blob_parser)); | ||||||
|  | 
 | ||||||
|  |                             // if the work queue is getting too large, wait for a while
 | ||||||
|  |                             while (!m_done && osmium::thread::Pool::instance().queue_size() >= m_max_work_queue_size) { | ||||||
|  |                                 std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||||||
|  |                             } | ||||||
|  |                         } else { | ||||||
|  |                             std::promise<osmium::memory::Buffer> promise; | ||||||
|  |                             m_queue.push(promise.get_future()); | ||||||
|  |                             promise.set_value(data_blob_parser()); | ||||||
|  |                         } | ||||||
|  |                         ++n; | ||||||
|  | 
 | ||||||
|  |                         // wait if the backlog of buffers with parsed data is too large
 | ||||||
|  |                         while (!m_done && m_queue.size() > m_max_buffer_queue_size) { | ||||||
|  |                             std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         if (m_done) { | ||||||
|  |                             return; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     m_done = true; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Instantiate PBF Parser | ||||||
|  |                  * | ||||||
|  |                  * @param file osmium::io::File instance describing file to be read from. | ||||||
|  |                  * @param read_which_entities Which types of OSM entities (nodes, ways, relations, changesets) should be parsed? | ||||||
|  |                  * @param input_queue String queue where data is read from. | ||||||
|  |                  */ | ||||||
|  |                 PBFInputFormat(const osmium::io::File& file, osmium::osm_entity_bits::type read_which_entities, osmium::thread::Queue<std::string>& input_queue) : | ||||||
|  |                     osmium::io::detail::InputFormat(file, read_which_entities, input_queue), | ||||||
|  |                     m_use_thread_pool(true), | ||||||
|  |                     m_queue(), | ||||||
|  |                     m_max_work_queue_size(10), // XXX tune these settings
 | ||||||
|  |                     m_max_buffer_queue_size(20), // XXX tune these settings
 | ||||||
|  |                     m_done(false), | ||||||
|  |                     m_input_queue_reader(input_queue) { | ||||||
|  |                     GOOGLE_PROTOBUF_VERIFY_VERSION; | ||||||
|  | 
 | ||||||
|  |                     // handle OSMHeader
 | ||||||
|  |                     size_t size = read_blob_header("OSMHeader"); | ||||||
|  | 
 | ||||||
|  |                     { | ||||||
|  |                         HeaderBlobParser header_blob_parser(size, m_input_queue_reader, m_header); | ||||||
|  |                         header_blob_parser.doit(); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (m_read_which_entities != osmium::osm_entity_bits::nothing) { | ||||||
|  |                         m_reader = std::thread(&PBFInputFormat::parse_osm_data, this, m_read_which_entities); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 ~PBFInputFormat() { | ||||||
|  |                     m_done = true; | ||||||
|  |                     if (m_reader.joinable()) { | ||||||
|  |                         m_reader.join(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Returns the next buffer with OSM data read from the PBF file. | ||||||
|  |                  * Blocks if data is not available yet. | ||||||
|  |                  * Returns an empty buffer at end of input. | ||||||
|  |                  */ | ||||||
|  |                 osmium::memory::Buffer read() override { | ||||||
|  |                     if (!m_done || !m_queue.empty()) { | ||||||
|  |                         std::future<osmium::memory::Buffer> buffer_future; | ||||||
|  |                         m_queue.wait_and_pop(buffer_future); | ||||||
|  |                         return std::move(buffer_future.get()); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     return osmium::memory::Buffer(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class PBFInputFormat
 | ||||||
|  | 
 | ||||||
|  |             namespace { | ||||||
|  | 
 | ||||||
|  |                 const bool registered_pbf_input = osmium::io::detail::InputFormatFactory::instance().register_input_format(osmium::io::file_format::pbf, | ||||||
|  |                     [](const osmium::io::File& file, osmium::osm_entity_bits::type read_which_entities, osmium::thread::Queue<std::string>& input_queue) { | ||||||
|  |                         return new osmium::io::detail::PBFInputFormat(file, read_which_entities, input_queue); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |             } // anonymous namespace
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_DETAIL_PBF_INPUT_FORMAT_HPP
 | ||||||
							
								
								
									
										950
									
								
								ThirdParty/osmium/io/detail/pbf_output_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										950
									
								
								ThirdParty/osmium/io/detail/pbf_output_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,950 @@ | |||||||
|  | #ifndef OSMIUM_IO_DETAIL_PBF_OUTPUT_FORMAT_HPP | ||||||
|  | #define OSMIUM_IO_DETAIL_PBF_OUTPUT_FORMAT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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. | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | About the .osm.pbf file format | ||||||
|  | This is an excerpt of <http://wiki.openstreetmap.org/wiki/PBF_Format>
 | ||||||
|  | 
 | ||||||
|  | The .osm.pbf format and it's derived formats (.osh.pbf and .osc.pbf) are encoded | ||||||
|  | using googles protobuf library for the low-level storage. They are constructed | ||||||
|  | by nesting data on two levels: | ||||||
|  | 
 | ||||||
|  | On the lower level the file is constructed using BlobHeaders and Blobs. A .osm.pbf | ||||||
|  | file contains multiple sequences of | ||||||
|  |  1. a 4-byte header size, stored in network-byte-order | ||||||
|  |  2. a BlobHeader of exactly this size | ||||||
|  |  3. a Blob | ||||||
|  | 
 | ||||||
|  | The BlobHeader tells the reader about the type and size of the following Blob. The | ||||||
|  | Blob can contain data in raw or zlib-compressed form. After uncompressing the blob | ||||||
|  | it is treated differently depending on the type specified in the BlobHeader. | ||||||
|  | 
 | ||||||
|  | The contents of the Blob belongs to the higher level. It contains either an HeaderBlock | ||||||
|  | (type="OSMHeader") or an PrimitiveBlock (type="OSMData"). The file needs to have | ||||||
|  | at least one HeaderBlock before the first PrimitiveBlock. | ||||||
|  | 
 | ||||||
|  | The HeaderBlock contains meta-information like the writing program or a bbox. It may | ||||||
|  | also contain multiple "required features" that describe what kinds of input a | ||||||
|  | reading program needs to handle in order to fully understand the files' contents. | ||||||
|  | 
 | ||||||
|  | The PrimitiveBlock can store multiple types of objects (i.e. 5 nodes, 2 ways and | ||||||
|  | 1 relation). It contains one or more PrimitiveGroup which in turn contain multiple | ||||||
|  | nodes, ways or relations. A PrimitiveGroup should only contain one kind of object. | ||||||
|  | 
 | ||||||
|  | There's a special kind of "object type" called dense-nodes. It is used to store nodes | ||||||
|  | in a very dense format, avoiding message overheads and using delta-encoding for nearly | ||||||
|  | all ids. | ||||||
|  | 
 | ||||||
|  | All Strings are stored as indexes to rows in a StringTable. The StringTable contains | ||||||
|  | one row for each used string, so strings that are used multiple times need to be | ||||||
|  | stored only once. The StringTable is sorted by usage-count, so the most often used | ||||||
|  | string is stored at index 1. | ||||||
|  | 
 | ||||||
|  | A simple outline of a .osm.pbf file could look like this: | ||||||
|  | 
 | ||||||
|  |   4-bytes header size | ||||||
|  |   BlobHeader | ||||||
|  |   Blob | ||||||
|  |     HeaderBlock | ||||||
|  |   4-bytes header size | ||||||
|  |   BlobHeader | ||||||
|  |   Blob | ||||||
|  |     PrimitiveBlock | ||||||
|  |       StringTable | ||||||
|  |       PrimitiveGroup | ||||||
|  |         5 nodes | ||||||
|  |       PrimitiveGroup | ||||||
|  |         2 ways | ||||||
|  |       PrimitiveGroup | ||||||
|  |         1 relation | ||||||
|  | 
 | ||||||
|  | More complete outlines of real .osm.pbf files can be created using the osmpbf-outline tool: | ||||||
|  |  <https://github.com/MaZderMind/OSM-binary/tree/osmpbf-outline>
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include <algorithm> | ||||||
|  | #include <chrono> | ||||||
|  | #include <cmath> | ||||||
|  | #include <cstdint> | ||||||
|  | #include <cstdlib> | ||||||
|  | #include <future> | ||||||
|  | #include <iostream> | ||||||
|  | #include <memory> | ||||||
|  | #include <ratio> | ||||||
|  | #include <string> | ||||||
|  | #include <thread> | ||||||
|  | #include <time.h> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/handler.hpp> | ||||||
|  | #include <osmium/io/detail/output_format.hpp> | ||||||
|  | #include <osmium/io/detail/pbf.hpp> // IWYU pragma: export
 | ||||||
|  | #include <osmium/io/detail/pbf_stringtable.hpp> | ||||||
|  | #include <osmium/io/detail/zlib.hpp> | ||||||
|  | #include <osmium/io/file.hpp> | ||||||
|  | #include <osmium/io/file_format.hpp> | ||||||
|  | #include <osmium/io/header.hpp> | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/memory/collection.hpp> | ||||||
|  | #include <osmium/osm/box.hpp> | ||||||
|  | #include <osmium/osm/item_type.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/node.hpp> | ||||||
|  | #include <osmium/osm/object.hpp> | ||||||
|  | #include <osmium/osm/relation.hpp> | ||||||
|  | #include <osmium/osm/tag.hpp> | ||||||
|  | #include <osmium/osm/timestamp.hpp> | ||||||
|  | #include <osmium/osm/way.hpp> | ||||||
|  | #include <osmium/visitor.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             namespace { | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Serialize a protobuf message into a Blob, optionally apply compression | ||||||
|  |                  * and return it together with a BlobHeader ready to be written to a file. | ||||||
|  |                  * | ||||||
|  |                  * @param type Type-string used in the BlobHeader. | ||||||
|  |                  * @param msg Protobuf-message. | ||||||
|  |                  * @param use_compression Should the output be compressed using zlib? | ||||||
|  |                  */ | ||||||
|  |                 std::string serialize_blob(const std::string& type, const google::protobuf::MessageLite& msg, bool use_compression) { | ||||||
|  |                     OSMPBF::Blob pbf_blob; | ||||||
|  | 
 | ||||||
|  |                     { | ||||||
|  |                         std::string content; | ||||||
|  |                         msg.SerializeToString(&content); | ||||||
|  | 
 | ||||||
|  |                         pbf_blob.set_raw_size(content.size()); | ||||||
|  | 
 | ||||||
|  |                         if (use_compression) { | ||||||
|  |                             pbf_blob.set_zlib_data(osmium::io::detail::zlib_compress(content)); | ||||||
|  |                         } else { | ||||||
|  |                             pbf_blob.set_raw(content); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     std::string blob_data; | ||||||
|  |                     pbf_blob.SerializeToString(&blob_data); | ||||||
|  | 
 | ||||||
|  |                     OSMPBF::BlobHeader pbf_blob_header; | ||||||
|  |                     pbf_blob_header.set_type(type); | ||||||
|  |                     pbf_blob_header.set_datasize(blob_data.size()); | ||||||
|  | 
 | ||||||
|  |                     std::string blob_header_data; | ||||||
|  |                     pbf_blob_header.SerializeToString(&blob_header_data); | ||||||
|  | 
 | ||||||
|  |                     uint32_t sz = htonl(blob_header_data.size()); | ||||||
|  | 
 | ||||||
|  |                     // write to output: the 4-byte BlobHeader-Size followed by the BlobHeader followed by the Blob
 | ||||||
|  |                     std::string output; | ||||||
|  |                     output.reserve(sizeof(sz) + blob_header_data.size() + blob_data.size()); | ||||||
|  |                     output.append(reinterpret_cast<const char*>(&sz), sizeof(sz)); | ||||||
|  |                     output.append(blob_header_data); | ||||||
|  |                     output.append(blob_data); | ||||||
|  | 
 | ||||||
|  |                     return output; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             } // anonymous namespace
 | ||||||
|  | 
 | ||||||
|  |             class PBFOutputFormat : public osmium::io::detail::OutputFormat, public osmium::handler::Handler { | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * This class models a variable that keeps track of the value | ||||||
|  |                  * it was last set to and returns the delta between old and | ||||||
|  |                  * new value from the update() call. | ||||||
|  |                  */ | ||||||
|  |                 template <typename T> | ||||||
|  |                 class Delta { | ||||||
|  | 
 | ||||||
|  |                     T m_value; | ||||||
|  | 
 | ||||||
|  |                 public: | ||||||
|  | 
 | ||||||
|  |                     Delta() : | ||||||
|  |                         m_value(0) { | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     void clear() { | ||||||
|  |                         m_value = 0; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     T update(T new_value) { | ||||||
|  |                         using std::swap; | ||||||
|  |                         swap(m_value, new_value); | ||||||
|  |                         return m_value - new_value; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                 }; // class Delta
 | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Maximum number of items in a primitive block. | ||||||
|  |                  * | ||||||
|  |                  * The uncompressed length of a Blob *should* be less | ||||||
|  |                  * than 16 megabytes and *must* be less than 32 megabytes. | ||||||
|  |                  * | ||||||
|  |                  * A block may contain any number of entities, as long as | ||||||
|  |                  * the size limits for the surrounding blob are obeyed. | ||||||
|  |                  * However, for simplicity, the current Osmosis (0.38) | ||||||
|  |                  * as well as Osmium implementation always | ||||||
|  |                  * uses at most 8k entities in a block. | ||||||
|  |                  */ | ||||||
|  |                 static constexpr uint32_t max_block_contents = 8000; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * The output buffer (block) will be filled to about | ||||||
|  |                  * 95% and then written to disk. This leaves more than | ||||||
|  |                  * 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; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * protobuf-struct of a HeaderBlock | ||||||
|  |                  */ | ||||||
|  |                 OSMPBF::HeaderBlock pbf_header_block; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * protobuf-struct of a PrimitiveBlock | ||||||
|  |                  */ | ||||||
|  |                 OSMPBF::PrimitiveBlock pbf_primitive_block; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * pointer to PrimitiveGroups inside the current PrimitiveBlock, | ||||||
|  |                  * used for writing nodes, ways or relations | ||||||
|  |                  */ | ||||||
|  |                 OSMPBF::PrimitiveGroup* pbf_nodes; | ||||||
|  |                 OSMPBF::PrimitiveGroup* pbf_ways; | ||||||
|  |                 OSMPBF::PrimitiveGroup* pbf_relations; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * To flexibly handle multiple resolutions, the granularity, or | ||||||
|  |                  * resolution used for representing locations is adjustable in | ||||||
|  |                  * multiples of 1 nanodegree. The default scaling factor is 100 | ||||||
|  |                  * nanodegrees, corresponding to about ~1cm at the equator. | ||||||
|  |                  * This is the current resolution of the OSM database. | ||||||
|  |                  */ | ||||||
|  |                 int m_location_granularity; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * The granularity used for representing timestamps is also adjustable in | ||||||
|  |                  * multiples of 1 millisecond. The default scaling factor is 1000 | ||||||
|  |                  * milliseconds, which is the current resolution of the OSM database. | ||||||
|  |                  */ | ||||||
|  |                 int m_date_granularity; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * should nodes be serialized into the dense format? | ||||||
|  |                  * | ||||||
|  |                  * nodes can be encoded one of two ways, as a Node | ||||||
|  |                  * (m_use_dense_nodes = false) and a special dense format. | ||||||
|  |                  * In the dense format, all information is stored 'column wise', | ||||||
|  |                  * as an array of ID's, array of latitudes, and array of | ||||||
|  |                  * longitudes. Each column is delta-encoded. This reduces | ||||||
|  |                  * header overheads and allows delta-coding to work very effectively. | ||||||
|  |                  */ | ||||||
|  |                 bool m_use_dense_nodes {true}; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * should the PBF blobs contain zlib compressed data? | ||||||
|  |                  * | ||||||
|  |                  * the zlib compression is optional, it's possible to store the | ||||||
|  |                  * blobs in raw format. Disabling the compression can improve the | ||||||
|  |                  * writing speed a little but the output will be 2x to 3x bigger. | ||||||
|  |                  */ | ||||||
|  |                 bool m_use_compression {true}; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * While the .osm.pbf-format is able to carry all meta information, it is | ||||||
|  |                  * also able to omit this information to reduce size. | ||||||
|  |                  */ | ||||||
|  |                 bool m_should_add_metadata {true}; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Should the visible flag be added on objects? | ||||||
|  |                  */ | ||||||
|  |                 bool m_add_visible; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * counter used to quickly check the number of objects stored inside | ||||||
|  |                  * the current PrimitiveBlock. When the counter reaches max_block_contents | ||||||
|  |                  * the PrimitiveBlock is serialized into a Blob and flushed to the file. | ||||||
|  |                  * | ||||||
|  |                  * this check is performed in check_block_contents_counter() which is | ||||||
|  |                  * called once for each object. | ||||||
|  |                  */ | ||||||
|  |                 uint16_t primitive_block_contents; | ||||||
|  |                 uint32_t primitive_block_size; | ||||||
|  | 
 | ||||||
|  |                 // StringTable management
 | ||||||
|  |                 StringTable string_table; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * These variables are used to calculate the | ||||||
|  |                  * delta-encoding while storing dense-nodes. It holds the last seen values | ||||||
|  |                  * from which the difference is stored into the protobuf. | ||||||
|  |                  */ | ||||||
|  |                 Delta<int64_t> m_delta_id; | ||||||
|  |                 Delta<int64_t> m_delta_lat; | ||||||
|  |                 Delta<int64_t> m_delta_lon; | ||||||
|  |                 Delta<int64_t> m_delta_timestamp; | ||||||
|  |                 Delta<int64_t> m_delta_changeset; | ||||||
|  |                 Delta<int64_t> m_delta_uid; | ||||||
|  |                 Delta<uint32_t> m_delta_user_sid; | ||||||
|  | 
 | ||||||
|  |                 bool debug; | ||||||
|  | 
 | ||||||
|  |                 bool has_debug_level(int) { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 ///// Blob writing /////
 | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Before a PrimitiveBlock gets serialized, all interim StringTable-ids needs to be | ||||||
|  |                  * mapped to the associated real StringTable ids. This is done in this function. | ||||||
|  |                  * | ||||||
|  |                  * This function needs to know about the concrete structure of all item types to find | ||||||
|  |                  * all occurrences of string-ids. | ||||||
|  |                  */ | ||||||
|  |                 void map_string_ids() { | ||||||
|  |                     // test, if the node-block has been allocated
 | ||||||
|  |                     if (pbf_nodes) { | ||||||
|  |                         // iterate over all nodes, passing them to the map_common_string_ids function
 | ||||||
|  |                         for (int i=0, l=pbf_nodes->nodes_size(); i<l; ++i) { | ||||||
|  |                             map_common_string_ids(pbf_nodes->mutable_nodes(i)); | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         // test, if the node-block has a densenodes structure
 | ||||||
|  |                         if (pbf_nodes->has_dense()) { | ||||||
|  |                             // get a pointer to the densenodes structure
 | ||||||
|  |                             OSMPBF::DenseNodes* dense = pbf_nodes->mutable_dense(); | ||||||
|  | 
 | ||||||
|  |                             // in the densenodes structure keys and vals are encoded in an intermixed
 | ||||||
|  |                             // array, individual nodes are seperated by a value of 0 (0 in the StringTable
 | ||||||
|  |                             // is always unused). String-ids of 0 are thus kept alone.
 | ||||||
|  |                             for (int i=0, l=dense->keys_vals_size(); i<l; ++i) { | ||||||
|  |                                 // map interim string-ids > 0 to real string ids
 | ||||||
|  |                                 auto sid = dense->keys_vals(i); | ||||||
|  |                                 assert(sid >= 0); | ||||||
|  |                                 assert(sid < std::numeric_limits<osmium::io::detail::StringTable::string_id_type>::max()); | ||||||
|  |                                 if (sid > 0) { | ||||||
|  |                                     dense->set_keys_vals(i, string_table.map_string_id(static_cast<osmium::io::detail::StringTable::string_id_type>(sid))); | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  | 
 | ||||||
|  |                             // test if the densenodes block has meta infos
 | ||||||
|  |                             if (dense->has_denseinfo()) { | ||||||
|  |                                 // get a pointer to the denseinfo structure
 | ||||||
|  |                                 OSMPBF::DenseInfo* denseinfo = dense->mutable_denseinfo(); | ||||||
|  | 
 | ||||||
|  |                                 // iterate over all username string-ids
 | ||||||
|  |                                 for (int i=0, l=denseinfo->user_sid_size(); i<l; ++i) { | ||||||
|  |                                     // map interim string-ids > 0 to real string ids
 | ||||||
|  |                                     auto usid = denseinfo->user_sid(i); | ||||||
|  |                                     assert(usid < std::numeric_limits<osmium::io::detail::StringTable::string_id_type>::max()); | ||||||
|  |                                     auto user_sid = string_table.map_string_id(static_cast<osmium::io::detail::StringTable::string_id_type>(usid)); | ||||||
|  | 
 | ||||||
|  |                                     // delta encode the string-id
 | ||||||
|  |                                     denseinfo->set_user_sid(i, m_delta_user_sid.update(user_sid)); | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     // test, if the ways-block has been allocated
 | ||||||
|  |                     if (pbf_ways) { | ||||||
|  |                         // iterate over all ways, passing them to the map_common_string_ids function
 | ||||||
|  |                         for (int i=0, l=pbf_ways->ways_size(); i<l; ++i) { | ||||||
|  |                             map_common_string_ids(pbf_ways->mutable_ways(i)); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     // test, if the relations-block has been allocated
 | ||||||
|  |                     if (pbf_relations) { | ||||||
|  |                         // iterate over all relations
 | ||||||
|  |                         for (int i=0, l=pbf_relations->relations_size(); i<l; ++i) { | ||||||
|  |                             // get a pointer to the relation
 | ||||||
|  |                             OSMPBF::Relation* relation = pbf_relations->mutable_relations(i); | ||||||
|  | 
 | ||||||
|  |                             // pass them to the map_common_string_ids function
 | ||||||
|  |                             map_common_string_ids(relation); | ||||||
|  | 
 | ||||||
|  |                             // 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(); mi<ml; ++mi) { | ||||||
|  |                                 relation->set_roles_sid(mi, string_table.map_string_id(relation->roles_sid(mi))); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                 * a helper function used in map_string_ids to map common interim string-ids of the | ||||||
|  |                 * user name and all tags to real string ids. | ||||||
|  |                 * | ||||||
|  |                 * TPBFObject is either OSMPBF::Node, OSMPBF::Way or OSMPBF::Relation. | ||||||
|  |                 */ | ||||||
|  |                 template <class TPBFObject> | ||||||
|  |                 void map_common_string_ids(TPBFObject* in) { | ||||||
|  |                     // if the object has meta-info attached
 | ||||||
|  |                     if (in->has_info()) { | ||||||
|  |                         // map the interim-id of the user name to a real id
 | ||||||
|  |                         OSMPBF::Info* info = in->mutable_info(); | ||||||
|  |                         info->set_user_sid(string_table.map_string_id(info->user_sid())); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     // iterate over all tags and map the interim-ids of the key and the value to real ids
 | ||||||
|  |                     for (int i=0, l=in->keys_size(); i<l; ++i) { | ||||||
|  |                         in->set_keys(i, string_table.map_string_id(in->keys(i))); | ||||||
|  |                         in->set_vals(i, string_table.map_string_id(in->vals(i))); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                 ///// MetaData helper /////
 | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * 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()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * convert a timestamp to an int, respecting the current blocks granularity | ||||||
|  |                  */ | ||||||
|  |                 int64_t timestamp2int(time_t timestamp) { | ||||||
|  |                     return round(timestamp * (static_cast<double>(1000) / date_granularity())); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * helper function used in the write()-calls to apply common information from an osmium-object | ||||||
|  |                  * onto a pbf-object. | ||||||
|  |                  * | ||||||
|  |                  * TPBFObject is either OSMPBF::Node, OSMPBF::Way or OSMPBF::Relation. | ||||||
|  |                  */ | ||||||
|  |                 template <class TPBFObject> | ||||||
|  |                 void apply_common_info(const osmium::OSMObject& in, TPBFObject* out) { | ||||||
|  |                     // set the object-id
 | ||||||
|  |                     out->set_id(in.id()); | ||||||
|  | 
 | ||||||
|  |                     // iterate over all tags and set the keys and vals, recording the strings in the
 | ||||||
|  |                     // interim StringTable and storing the interim ids
 | ||||||
|  |                     for (const auto& tag : in.tags()) { | ||||||
|  |                         out->add_keys(string_table.record_string(tag.key())); | ||||||
|  |                         out->add_vals(string_table.record_string(tag.value())); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (m_should_add_metadata) { | ||||||
|  |                         // add an info-section to the pbf object and set the meta-info on it
 | ||||||
|  |                         OSMPBF::Info* out_info = out->mutable_info(); | ||||||
|  |                         if (m_add_visible) { | ||||||
|  |                             out_info->set_visible(in.visible()); | ||||||
|  |                         } | ||||||
|  |                         out_info->set_version(static_cast<::google::protobuf::int32>(in.version())); | ||||||
|  |                         out_info->set_timestamp(timestamp2int(in.timestamp())); | ||||||
|  |                         out_info->set_changeset(in.changeset()); | ||||||
|  |                         out_info->set_uid(static_cast<::google::protobuf::int32>(in.uid())); | ||||||
|  |                         out_info->set_user_sid(string_table.record_string(in.user())); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                 ///// High-Level Block writing /////
 | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * store the current pbf_header_block into a Blob and clear this struct afterwards. | ||||||
|  |                  */ | ||||||
|  |                 void store_header_block() { | ||||||
|  |                     if (debug && has_debug_level(1)) { | ||||||
|  |                         std::cerr << "storing header block" << std::endl; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     std::promise<std::string> promise; | ||||||
|  |                     m_output_queue.push(promise.get_future()); | ||||||
|  |                     promise.set_value(serialize_blob("OSMHeader", pbf_header_block, m_use_compression)); | ||||||
|  | 
 | ||||||
|  |                     pbf_header_block.Clear(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * store the interim StringTable to the current pbf_primitive_block, map all interim string ids | ||||||
|  |                  * to real StringTable ids and then store the current pbf_primitive_block into a Blob and clear | ||||||
|  |                  * this struct and all related pointers and maps afterwards. | ||||||
|  |                  */ | ||||||
|  |                 void store_primitive_block() { | ||||||
|  |                     if (debug && has_debug_level(1)) { | ||||||
|  |                         std::cerr << "storing primitive block with " << primitive_block_contents << " items" << std::endl; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     // set the granularity
 | ||||||
|  |                     pbf_primitive_block.set_granularity(location_granularity()); | ||||||
|  |                     pbf_primitive_block.set_date_granularity(date_granularity()); | ||||||
|  | 
 | ||||||
|  |                     // store the interim StringTable into the protobuf object
 | ||||||
|  |                     string_table.store_stringtable(pbf_primitive_block.mutable_stringtable()); | ||||||
|  | 
 | ||||||
|  |                     // map all interim string ids to real ids
 | ||||||
|  |                     map_string_ids(); | ||||||
|  | 
 | ||||||
|  |                     std::promise<std::string> promise; | ||||||
|  |                     m_output_queue.push(promise.get_future()); | ||||||
|  |                     promise.set_value(serialize_blob("OSMData", pbf_primitive_block, m_use_compression)); | ||||||
|  |                     while (m_output_queue.size() > 10) { | ||||||
|  |                         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // XXX
 | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     // clear the PrimitiveBlock struct
 | ||||||
|  |                     pbf_primitive_block.Clear(); | ||||||
|  | 
 | ||||||
|  |                     // clear the interim StringTable and its id map
 | ||||||
|  |                     string_table.clear(); | ||||||
|  | 
 | ||||||
|  |                     // reset the delta variables
 | ||||||
|  |                     m_delta_id.clear(); | ||||||
|  |                     m_delta_lat.clear(); | ||||||
|  |                     m_delta_lon.clear(); | ||||||
|  |                     m_delta_timestamp.clear(); | ||||||
|  |                     m_delta_changeset.clear(); | ||||||
|  |                     m_delta_uid.clear(); | ||||||
|  |                     m_delta_user_sid.clear(); | ||||||
|  | 
 | ||||||
|  |                     // reset the contents-counter to zero
 | ||||||
|  |                     primitive_block_contents = 0; | ||||||
|  |                     primitive_block_size = 0; | ||||||
|  | 
 | ||||||
|  |                     // reset the node/way/relation pointers to nullptr
 | ||||||
|  |                     pbf_nodes = nullptr; | ||||||
|  |                     pbf_ways = nullptr; | ||||||
|  |                     pbf_relations = nullptr; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * this little function checks primitive_block_contents counter against its maximum and calls | ||||||
|  |                  * store_primitive_block to flush the block to the disk when it's reached. It's also responsible | ||||||
|  |                  * for increasing this counter. | ||||||
|  |                  * | ||||||
|  |                  * this function also checks the estimated size of the current block and calls store_primitive_block | ||||||
|  |                  * when the estimated size reaches buffer_fill_percent of the maximum uncompressed blob size. | ||||||
|  |                  */ | ||||||
|  |                 void check_block_contents_counter() { | ||||||
|  |                     if (primitive_block_contents >= max_block_contents) { | ||||||
|  |                         store_primitive_block(); | ||||||
|  |                     } else if (primitive_block_size > (static_cast<uint32_t>(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<float>(primitive_block_size) / static_cast<float>(OSMPBF::max_uncompressed_blob_size) * 100.0) << "% of the maximum blob-size" << std::endl; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         store_primitive_block(); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     ++primitive_block_contents; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                 ///// Block content writing /////
 | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Add a node to the block. | ||||||
|  |                  * | ||||||
|  |                  * @param node The node to add. | ||||||
|  |                  */ | ||||||
|  |                 void write_node(const osmium::Node& node) { | ||||||
|  |                     // add a way to the group
 | ||||||
|  |                     OSMPBF::Node* pbf_node = pbf_nodes->add_nodes(); | ||||||
|  | 
 | ||||||
|  |                     // copy the common meta-info from the osmium-object to the pbf-object
 | ||||||
|  |                     apply_common_info(node, pbf_node); | ||||||
|  | 
 | ||||||
|  |                     // modify lat & lon to integers, respecting the block's granularity and copy
 | ||||||
|  |                     // the ints to the pbf-object
 | ||||||
|  |                     pbf_node->set_lon(lonlat2int(node.location().lon_without_check())); | ||||||
|  |                     pbf_node->set_lat(lonlat2int(node.location().lat_without_check())); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Add a node to the block using DenseNodes. | ||||||
|  |                  * | ||||||
|  |                  * @param node The node to add. | ||||||
|  |                  */ | ||||||
|  |                 void write_dense_node(const osmium::Node& node) { | ||||||
|  |                     // add a DenseNodes-Section to the PrimitiveGroup
 | ||||||
|  |                     OSMPBF::DenseNodes* dense = pbf_nodes->mutable_dense(); | ||||||
|  | 
 | ||||||
|  |                     // copy the id, delta encoded
 | ||||||
|  |                     dense->add_id(m_delta_id.update(node.id())); | ||||||
|  | 
 | ||||||
|  |                     // copy the longitude, delta encoded
 | ||||||
|  |                     dense->add_lon(m_delta_lon.update(lonlat2int(node.location().lon_without_check()))); | ||||||
|  | 
 | ||||||
|  |                     // copy the latitude, delta encoded
 | ||||||
|  |                     dense->add_lat(m_delta_lat.update(lonlat2int(node.location().lat_without_check()))); | ||||||
|  | 
 | ||||||
|  |                     // in the densenodes structure keys and vals are encoded in an intermixed
 | ||||||
|  |                     // array, individual nodes are seperated by a value of 0 (0 in the StringTable
 | ||||||
|  |                     // is always unused)
 | ||||||
|  |                     // so for three nodes the keys_vals array may look like this: 3 5 2 1 0 0 8 5
 | ||||||
|  |                     // the first node has two tags (3=>5 and 2=>1), the second node does not
 | ||||||
|  |                     // have any tags and the third node has a single tag (8=>5)
 | ||||||
|  |                     for (const auto& tag : node.tags()) { | ||||||
|  |                         dense->add_keys_vals(string_table.record_string(tag.key())); | ||||||
|  |                         dense->add_keys_vals(string_table.record_string(tag.value())); | ||||||
|  |                     } | ||||||
|  |                     dense->add_keys_vals(0); | ||||||
|  | 
 | ||||||
|  |                     if (m_should_add_metadata) { | ||||||
|  |                         // add a DenseInfo-Section to the PrimitiveGroup
 | ||||||
|  |                         OSMPBF::DenseInfo* denseinfo = dense->mutable_denseinfo(); | ||||||
|  | 
 | ||||||
|  |                         denseinfo->add_version(static_cast<::google::protobuf::int32>(node.version())); | ||||||
|  | 
 | ||||||
|  |                         if (m_add_visible) { | ||||||
|  |                             denseinfo->add_visible(node.visible()); | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         // copy the timestamp, delta encoded
 | ||||||
|  |                         denseinfo->add_timestamp(m_delta_timestamp.update(timestamp2int(node.timestamp()))); | ||||||
|  | 
 | ||||||
|  |                         // copy the changeset, delta encoded
 | ||||||
|  |                         denseinfo->add_changeset(m_delta_changeset.update(node.changeset())); | ||||||
|  | 
 | ||||||
|  |                         // copy the user id, delta encoded
 | ||||||
|  |                         denseinfo->add_uid(m_delta_uid.update(node.uid())); | ||||||
|  | 
 | ||||||
|  |                         // record the user-name to the interim stringtable and copy the
 | ||||||
|  |                         // interim string-id to the pbf-object
 | ||||||
|  |                         denseinfo->add_user_sid(string_table.record_string(node.user())); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Add a way to the block. | ||||||
|  |                  * | ||||||
|  |                  * @param way The way to add. | ||||||
|  |                  */ | ||||||
|  |                 void write_way(const osmium::Way& way) { | ||||||
|  |                     // add a way to the group
 | ||||||
|  |                     OSMPBF::Way* pbf_way = pbf_ways->add_ways(); | ||||||
|  | 
 | ||||||
|  |                     // copy the common meta-info from the osmium-object to the pbf-object
 | ||||||
|  |                     apply_common_info(way, pbf_way); | ||||||
|  | 
 | ||||||
|  |                     // last way-node-id used for delta-encoding
 | ||||||
|  |                     Delta<int64_t> delta_id; | ||||||
|  | 
 | ||||||
|  |                     for (const auto& node_ref : way.nodes()) { | ||||||
|  |                         // copy the way-node-id, delta encoded
 | ||||||
|  |                         pbf_way->add_refs(delta_id.update(node_ref.ref())); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     // count up blob size by the size of the Way
 | ||||||
|  |                     primitive_block_size += pbf_way->ByteSize(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Add a relation to the block. | ||||||
|  |                  * | ||||||
|  |                  * @param relation The relation to add. | ||||||
|  |                  */ | ||||||
|  |                 void write_relation(const osmium::Relation& relation) { | ||||||
|  |                     // add a relation to the group
 | ||||||
|  |                     OSMPBF::Relation* pbf_relation = pbf_relations->add_relations(); | ||||||
|  | 
 | ||||||
|  |                     // copy the common meta-info from the osmium-object to the pbf-object
 | ||||||
|  |                     apply_common_info(relation, pbf_relation); | ||||||
|  | 
 | ||||||
|  |                     Delta<int64_t> delta_id; | ||||||
|  | 
 | ||||||
|  |                     for (const auto& member : relation.members()) { | ||||||
|  |                         // record the relation-member role to the interim stringtable and copy the
 | ||||||
|  |                         // interim string-id to the pbf-object
 | ||||||
|  |                         pbf_relation->add_roles_sid(string_table.record_string(member.role())); | ||||||
|  | 
 | ||||||
|  |                         // copy the relation-member-id, delta encoded
 | ||||||
|  |                         pbf_relation->add_memids(delta_id.update(member.ref())); | ||||||
|  | 
 | ||||||
|  |                         // copy the relation-member-type, mapped to the OSMPBF enum
 | ||||||
|  |                         pbf_relation->add_types(item_type_to_osmpbf_membertype(member.type())); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     // count up blob size by the size of the Relation
 | ||||||
|  |                     primitive_block_size += pbf_relation->ByteSize(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 // objects of this class can't be copied
 | ||||||
|  |                 PBFOutputFormat(const PBFOutputFormat&) = delete; | ||||||
|  |                 PBFOutputFormat& operator=(const PBFOutputFormat&) = delete; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Create PBFOutputFormat object from File. | ||||||
|  |                  */ | ||||||
|  |                 explicit PBFOutputFormat(const osmium::io::File& file, data_queue_type& output_queue) : | ||||||
|  |                     OutputFormat(file, output_queue), | ||||||
|  |                     pbf_header_block(), | ||||||
|  |                     pbf_primitive_block(), | ||||||
|  |                     pbf_nodes(nullptr), | ||||||
|  |                     pbf_ways(nullptr), | ||||||
|  |                     pbf_relations(nullptr), | ||||||
|  |                     m_location_granularity(pbf_primitive_block.granularity()), | ||||||
|  |                     m_date_granularity(pbf_primitive_block.date_granularity()), | ||||||
|  |                     m_add_visible(file.has_multiple_object_versions()), | ||||||
|  |                     primitive_block_contents(0), | ||||||
|  |                     primitive_block_size(0), | ||||||
|  |                     string_table(), | ||||||
|  |                     m_delta_id(), | ||||||
|  |                     m_delta_lat(), | ||||||
|  |                     m_delta_lon(), | ||||||
|  |                     m_delta_timestamp(), | ||||||
|  |                     m_delta_changeset(), | ||||||
|  |                     m_delta_uid(), | ||||||
|  |                     m_delta_user_sid(), | ||||||
|  |                     debug(true) { | ||||||
|  |                     GOOGLE_PROTOBUF_VERIFY_VERSION; | ||||||
|  |                     if (file.get("pbf_dense_nodes") == "false") { | ||||||
|  |                         m_use_dense_nodes = false; | ||||||
|  |                     } | ||||||
|  |                     if (file.get("pbf_compression") == "none" || file.get("pbf_compression") == "false") { | ||||||
|  |                         m_use_compression = false; | ||||||
|  |                     } | ||||||
|  |                     if (file.get("pbf_add_metadata") == "false") { | ||||||
|  |                         m_should_add_metadata = false; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void write_buffer(osmium::memory::Buffer&& buffer) override final { | ||||||
|  |                     osmium::apply(buffer.cbegin(), buffer.cend(), *this); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * getter to access the granularity | ||||||
|  |                  */ | ||||||
|  |                 int location_granularity() const { | ||||||
|  |                     return m_location_granularity; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * setter to set the granularity | ||||||
|  |                  */ | ||||||
|  |                 PBFOutputFormat& location_granularity(int g) { | ||||||
|  |                     m_location_granularity = g; | ||||||
|  |                     return *this; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * getter to access the date_granularity | ||||||
|  |                  */ | ||||||
|  |                 int date_granularity() const { | ||||||
|  |                     return m_date_granularity; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Set date granularity. | ||||||
|  |                  */ | ||||||
|  |                 PBFOutputFormat& date_granularity(int g) { | ||||||
|  |                     m_date_granularity = g; | ||||||
|  |                     return *this; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Initialize the writing process. | ||||||
|  |                  * | ||||||
|  |                  * This initializes the header-block, sets the required-features and | ||||||
|  |                  * the writing-program and adds the obligatory StringTable-Index 0. | ||||||
|  |                  */ | ||||||
|  |                 void write_header(const osmium::io::Header& header) override final { | ||||||
|  |                     // add the schema version as required feature to the HeaderBlock
 | ||||||
|  |                     pbf_header_block.add_required_features("OsmSchema-V0.6"); | ||||||
|  | 
 | ||||||
|  |                     // when the densenodes-feature is used, add DenseNodes as required feature
 | ||||||
|  |                     if (m_use_dense_nodes) { | ||||||
|  |                         pbf_header_block.add_required_features("DenseNodes"); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     // when the resulting file will carry history information, add
 | ||||||
|  |                     // HistoricalInformation as required feature
 | ||||||
|  |                     if (this->m_file.has_multiple_object_versions()) { | ||||||
|  |                         pbf_header_block.add_required_features("HistoricalInformation"); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     // set the writing program
 | ||||||
|  |                     pbf_header_block.set_writingprogram(header.get("generator")); | ||||||
|  | 
 | ||||||
|  |                     if (!header.boxes().empty()) { | ||||||
|  |                         OSMPBF::HeaderBBox* pbf_bbox = pbf_header_block.mutable_bbox(); | ||||||
|  |                         osmium::Box box = header.joined_boxes(); | ||||||
|  |                         pbf_bbox->set_left(static_cast<::google::protobuf::int64>(box.bottom_left().lon() * OSMPBF::lonlat_resolution)); | ||||||
|  |                         pbf_bbox->set_bottom(static_cast<::google::protobuf::int64>(box.bottom_left().lat() * OSMPBF::lonlat_resolution)); | ||||||
|  |                         pbf_bbox->set_right(static_cast<::google::protobuf::int64>(box.top_right().lon() * OSMPBF::lonlat_resolution)); | ||||||
|  |                         pbf_bbox->set_top(static_cast<::google::protobuf::int64>(box.top_right().lat() * OSMPBF::lonlat_resolution)); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     std::string osmosis_replication_timestamp = header.get("osmosis_replication_timestamp"); | ||||||
|  |                     if (!osmosis_replication_timestamp.empty()) { | ||||||
|  |                         osmium::Timestamp ts(osmosis_replication_timestamp.c_str()); | ||||||
|  |                         pbf_header_block.set_osmosis_replication_timestamp(ts); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     std::string osmosis_replication_sequence_number = header.get("osmosis_replication_sequence_number"); | ||||||
|  |                     if (!osmosis_replication_sequence_number.empty()) { | ||||||
|  |                         pbf_header_block.set_osmosis_replication_sequence_number(std::atoll(osmosis_replication_sequence_number.c_str())); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     std::string osmosis_replication_base_url = header.get("osmosis_replication_base_url"); | ||||||
|  |                     if (!osmosis_replication_base_url.empty()) { | ||||||
|  |                         pbf_header_block.set_osmosis_replication_base_url(osmosis_replication_base_url); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     store_header_block(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Add a node to the pbf. | ||||||
|  |                  * | ||||||
|  |                  * A call to this method won't write the node to the file directly but | ||||||
|  |                  * cache it for later bulk-writing. Calling final() ensures that everything | ||||||
|  |                  * gets written and every file pointer is closed. | ||||||
|  |                  */ | ||||||
|  |                 void node(const osmium::Node& node) { | ||||||
|  |                     // first of we check the contents-counter which may flush the cached nodes to
 | ||||||
|  |                     // disk if the limit is reached. This call also increases the contents-counter
 | ||||||
|  |                     check_block_contents_counter(); | ||||||
|  | 
 | ||||||
|  |                     if (debug && has_debug_level(2)) { | ||||||
|  |                         std::cerr << "node " << node.id() << " v" << node.version() << std::endl; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     // if no PrimitiveGroup for nodes has been added, add one and save the pointer
 | ||||||
|  |                     if (!pbf_nodes) { | ||||||
|  |                         pbf_nodes = pbf_primitive_block.add_primitivegroup(); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (m_use_dense_nodes) { | ||||||
|  |                         write_dense_node(node); | ||||||
|  |                     } else { | ||||||
|  |                         write_node(node); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Add a way to the pbf. | ||||||
|  |                  * | ||||||
|  |                  * A call to this method won't write the way to the file directly but | ||||||
|  |                  * cache it for later bulk-writing. Calling final() ensures that everything | ||||||
|  |                  * gets written and every file pointer is closed. | ||||||
|  |                  */ | ||||||
|  |                 void way(const osmium::Way& way) { | ||||||
|  |                     // first of we check the contents-counter which may flush the cached ways to
 | ||||||
|  |                     // disk if the limit is reached. This call also increases the contents-counter
 | ||||||
|  |                     check_block_contents_counter(); | ||||||
|  | 
 | ||||||
|  |                     // if no PrimitiveGroup for nodes has been added, add one and save the pointer
 | ||||||
|  |                     if (!pbf_ways) { | ||||||
|  |                         pbf_ways = pbf_primitive_block.add_primitivegroup(); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     write_way(way); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Add a relation to the pbf. | ||||||
|  |                  * | ||||||
|  |                  * A call to this method won't write the way to the file directly but | ||||||
|  |                  * cache it for later bulk-writing. Calling final() ensures that everything | ||||||
|  |                  * gets written and every file pointer is closed. | ||||||
|  |                  */ | ||||||
|  |                 void relation(const osmium::Relation& relation) { | ||||||
|  |                     // first of we check the contents-counter which may flush the cached relations to
 | ||||||
|  |                     // disk if the limit is reached. This call also increases the contents-counter
 | ||||||
|  |                     check_block_contents_counter(); | ||||||
|  | 
 | ||||||
|  |                     // if no PrimitiveGroup for relations has been added, add one and save the pointer
 | ||||||
|  |                     if (!pbf_relations) { | ||||||
|  |                         pbf_relations = pbf_primitive_block.add_primitivegroup(); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     write_relation(relation); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Finalize the writing process, flush any open primitive blocks to the file and | ||||||
|  |                  * close the file. | ||||||
|  |                  */ | ||||||
|  |                 void close() override final { | ||||||
|  |                     if (debug && has_debug_level(1)) { | ||||||
|  |                         std::cerr << "finishing" << std::endl; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     // if the current block contains any elements, flush it to the protobuf
 | ||||||
|  |                     if (primitive_block_contents > 0) { | ||||||
|  |                         store_primitive_block(); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     std::promise<std::string> promise; | ||||||
|  |                     m_output_queue.push(promise.get_future()); | ||||||
|  |                     promise.set_value(std::string()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class PBFOutputFormat
 | ||||||
|  | 
 | ||||||
|  |             namespace { | ||||||
|  | 
 | ||||||
|  |                 const bool registered_pbf_output = osmium::io::detail::OutputFormatFactory::instance().register_output_format(osmium::io::file_format::pbf, | ||||||
|  |                     [](const osmium::io::File& file, data_queue_type& output_queue) { | ||||||
|  |                         return new osmium::io::detail::PBFOutputFormat(file, output_queue); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |             } // anonymous namespace
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_DETAIL_PBF_OUTPUT_FORMAT_HPP
 | ||||||
							
								
								
									
										196
									
								
								ThirdParty/osmium/io/detail/pbf_stringtable.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								ThirdParty/osmium/io/detail/pbf_stringtable.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,196 @@ | |||||||
|  | #ifndef OSMIUM_IO_DETAIL_PBF_STRINGTABLE_HPP | ||||||
|  | #define OSMIUM_IO_DETAIL_PBF_STRINGTABLE_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <algorithm> | ||||||
|  | #include <iterator> | ||||||
|  | #include <map> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <string> | ||||||
|  | #include <utility> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <osmpbf/osmpbf.h> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * StringTable management for PBF writer | ||||||
|  |              * | ||||||
|  |              * All strings are stored as indexes to rows in a StringTable. The StringTable contains | ||||||
|  |              * one row for each used string, so strings that are used multiple times need to be | ||||||
|  |              * stored only once. The StringTable is sorted by usage-count, so the most often used | ||||||
|  |              * string is stored at index 1. | ||||||
|  |              */ | ||||||
|  |             class StringTable { | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 /// type for string IDs (interim and final)
 | ||||||
|  |                 typedef uint16_t string_id_type; | ||||||
|  | 
 | ||||||
|  |             private: | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * this is the struct used to build the StringTable. It is stored as | ||||||
|  |                  * the value-part in the strings-map. | ||||||
|  |                  * | ||||||
|  |                  * when a new string is added to the map, its count is set to 0 and | ||||||
|  |                  * the interim_id is set to the current size of the map. This interim_id | ||||||
|  |                  * is then stored into the pbf-objects. | ||||||
|  |                  * | ||||||
|  |                  * before the PrimitiveBlock is serialized, the map is sorted by count | ||||||
|  |                  * and stored into the pbf-StringTable. Afterwards the interim-ids are | ||||||
|  |                  * mapped to the "real" id in the StringTable. | ||||||
|  |                  * | ||||||
|  |                  * this way often used strings get lower ids in the StringTable. As the | ||||||
|  |                  * protobuf-serializer stores numbers in variable bit-lengths, lower | ||||||
|  |                  * 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; | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Interim StringTable, storing all strings that should be written to | ||||||
|  |                  * the StringTable once the block is written to disk. | ||||||
|  |                  */ | ||||||
|  |                 typedef std::map<std::string, string_info> string2string_info_type; | ||||||
|  |                 string2string_info_type m_strings {}; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * This vector is used to map the interim IDs to real StringTable IDs after | ||||||
|  |                  * writing all strings to the StringTable. | ||||||
|  |                  */ | ||||||
|  |                 typedef std::vector<string_id_type> interim_id2id_type; | ||||||
|  |                 interim_id2id_type m_id2id_map {}; | ||||||
|  | 
 | ||||||
|  |                 size_t m_size = 0; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 StringTable() { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 friend bool operator<(const string_info& lhs, const string_info& rhs) { | ||||||
|  |                     return lhs.count > rhs.count; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * record a string in the interim StringTable if it's missing, otherwise just increase its counter, | ||||||
|  |                  * return the interim-id assigned to the string. | ||||||
|  |                  */ | ||||||
|  |                 string_id_type record_string(const std::string& string) { | ||||||
|  |                     string_info& info = m_strings[string]; | ||||||
|  |                     if (info.interim_id == 0) { | ||||||
|  |                         ++m_size; | ||||||
|  |                         assert(m_size < std::numeric_limits<string_id_type>::max()); | ||||||
|  |                         info.interim_id = static_cast<string_id_type>(m_size); | ||||||
|  |                     } else { | ||||||
|  |                         info.count++; | ||||||
|  |                     } | ||||||
|  |                     return info.interim_id; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Sort the interim StringTable and store it to the real protobuf StringTable. | ||||||
|  |                  * while storing to the real table, this function fills the id2id_map with | ||||||
|  |                  * pairs, mapping the interim-ids to final and real StringTable ids. | ||||||
|  |                  * | ||||||
|  |                  * Note that the m_strings table is a std::map and as such is sorted lexicographically. | ||||||
|  |                  * When the transformation into the sortedby multimap is done, it gets sorted by | ||||||
|  |                  * the count. The end result (at least with the glibc standard container/algorithm | ||||||
|  |                  * implementation) is that the string table is sorted first by reverse count (ie descending) | ||||||
|  |                  * and then by reverse lexicographic order. | ||||||
|  |                  */ | ||||||
|  |                 void store_stringtable(OSMPBF::StringTable* st) { | ||||||
|  |                     // add empty StringTable entry at index 0
 | ||||||
|  |                     // StringTable index 0 is reserved as delimiter in the densenodes key/value list
 | ||||||
|  |                     // this line also ensures that there's always a valid StringTable
 | ||||||
|  |                     st->add_s(""); | ||||||
|  | 
 | ||||||
|  |                     std::multimap<string_info, std::string> sortedbycount; | ||||||
|  | 
 | ||||||
|  |                     m_id2id_map.resize(m_size+1); | ||||||
|  | 
 | ||||||
|  |                     std::transform(m_strings.begin(), m_strings.end(), | ||||||
|  |                                 std::inserter(sortedbycount, sortedbycount.begin()), | ||||||
|  |                                 [](const std::pair<std::string, string_info>& p) { | ||||||
|  |                                         return std::pair<string_info, std::string>(p.second, p.first); | ||||||
|  |                                 }); | ||||||
|  | 
 | ||||||
|  |                     string_id_type n=0; | ||||||
|  | 
 | ||||||
|  |                     for (const auto& mapping : sortedbycount) { | ||||||
|  |                         // add the string of the current item to the pbf StringTable
 | ||||||
|  |                         st->add_s(mapping.second); | ||||||
|  | 
 | ||||||
|  |                         // store the mapping from the interim-id to the real id
 | ||||||
|  |                         m_id2id_map[mapping.first.interim_id] = ++n; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Map from an interim ID to a real string ID. | ||||||
|  |                  */ | ||||||
|  |                 string_id_type map_string_id(const string_id_type interim_id) const { | ||||||
|  |                     return m_id2id_map[interim_id]; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Clear the stringtable, preparing for the next block. | ||||||
|  |                  */ | ||||||
|  |                 void clear() { | ||||||
|  |                     m_strings.clear(); | ||||||
|  |                     m_id2id_map.clear(); | ||||||
|  |                     m_size = 0; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class StringTable
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_DETAIL_PBF_STRINGTABLE_HPP
 | ||||||
							
								
								
									
										104
									
								
								ThirdParty/osmium/io/detail/read_thread.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								ThirdParty/osmium/io/detail/read_thread.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,104 @@ | |||||||
|  | #ifndef OSMIUM_IO_DETAIL_READ_THREAD_HPP | ||||||
|  | #define OSMIUM_IO_DETAIL_READ_THREAD_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <atomic> | ||||||
|  | #include <chrono> | ||||||
|  | #include <ratio> | ||||||
|  | #include <string> | ||||||
|  | #include <thread> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/io/compression.hpp> | ||||||
|  | #include <osmium/thread/name.hpp> | ||||||
|  | #include <osmium/thread/queue.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             class ReadThread { | ||||||
|  | 
 | ||||||
|  |                 osmium::thread::Queue<std::string>& m_queue; | ||||||
|  |                 osmium::io::Decompressor* m_decompressor; | ||||||
|  | 
 | ||||||
|  |                 // If this is set in the main thread, we have to wrap up at the
 | ||||||
|  |                 // next possible moment.
 | ||||||
|  |                 std::atomic<bool>& m_done; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 explicit ReadThread(osmium::thread::Queue<std::string>& queue, osmium::io::Decompressor* decompressor, std::atomic<bool>& done) : | ||||||
|  |                     m_queue(queue), | ||||||
|  |                     m_decompressor(decompressor), | ||||||
|  |                     m_done(done) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void operator()() { | ||||||
|  |                     osmium::thread::set_thread_name("_osmium_input"); | ||||||
|  | 
 | ||||||
|  |                     try { | ||||||
|  |                         while (!m_done) { | ||||||
|  |                             std::string data {m_decompressor->read()}; | ||||||
|  |                             if (data.empty()) { | ||||||
|  |                                 m_done = true; | ||||||
|  |                             } | ||||||
|  |                             m_queue.push(std::move(data)); | ||||||
|  |                             while (m_queue.size() > 10) { | ||||||
|  |                                 std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         m_decompressor->close(); | ||||||
|  |                     } catch (...) { | ||||||
|  |                         // If there is an exception in this thread, we make sure
 | ||||||
|  |                         // to push an empty string onto the queue to signal the
 | ||||||
|  |                         // end-of-data to the reading thread so that it will not
 | ||||||
|  |                         // hang. Then we re-throw the exception.
 | ||||||
|  |                         m_queue.push(std::string()); | ||||||
|  |                         throw; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class ReadThread
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_DETAIL_READ_THREAD_HPP
 | ||||||
							
								
								
									
										165
									
								
								ThirdParty/osmium/io/detail/read_write.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								ThirdParty/osmium/io/detail/read_write.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,165 @@ | |||||||
|  | #ifndef OSMIUM_IO_DETAIL_READ_WRITE_HPP | ||||||
|  | #define OSMIUM_IO_DETAIL_READ_WRITE_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cerrno> | ||||||
|  | #include <cstddef> | ||||||
|  | #include <fcntl.h> | ||||||
|  | #include <string> | ||||||
|  | //#include <sys/stat.h>
 | ||||||
|  | //#include <sys/types.h>
 | ||||||
|  | #include <system_error> | ||||||
|  | #include <unistd.h> | ||||||
|  | 
 | ||||||
|  | #include <osmium/io/overwrite.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * @brief Namespace for Osmium internal use | ||||||
|  |          */ | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * 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. | ||||||
|  |              * | ||||||
|  |              * @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. | ||||||
|  |              * @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) { | ||||||
|  |                 if (filename == "" || filename == "-") { | ||||||
|  |                     return 1; // stdout
 | ||||||
|  |                 } else { | ||||||
|  |                     int flags = O_WRONLY | O_CREAT; | ||||||
|  |                     if (allow_overwrite == osmium::io::overwrite::allow) { | ||||||
|  |                         flags |= O_TRUNC; | ||||||
|  |                     } else { | ||||||
|  |                         flags |= O_EXCL; | ||||||
|  |                     } | ||||||
|  | #ifdef WIN32 | ||||||
|  |                     flags |= O_BINARY; | ||||||
|  | #endif | ||||||
|  |                     int fd = ::open(filename.c_str(), flags, 0666); | ||||||
|  |                     if (fd < 0) { | ||||||
|  |                         throw std::system_error(errno, std::system_category(), std::string("Open failed for '") + filename + "'"); | ||||||
|  |                     } | ||||||
|  |                     return fd; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Open file for reading. If the file name is empty or "-", no file | ||||||
|  |              * is open and the stdin file descriptor (0) is returned. | ||||||
|  |              * | ||||||
|  |              * @return File descriptor of open file. | ||||||
|  |              * @throws system_error if the file can't be opened. | ||||||
|  |              */ | ||||||
|  |             inline int open_for_reading(const std::string& filename) { | ||||||
|  |                 if (filename == "" || filename == "-") { | ||||||
|  |                     return 0; // stdin
 | ||||||
|  |                 } else { | ||||||
|  |                     int flags = O_RDONLY; | ||||||
|  | #ifdef WIN32 | ||||||
|  |                     flags |= O_BINARY; | ||||||
|  | #endif | ||||||
|  |                     int fd = ::open(filename.c_str(), flags); | ||||||
|  |                     if (fd < 0) { | ||||||
|  |                         throw std::system_error(errno, std::system_category(), std::string("Open failed for '") + filename + "'"); | ||||||
|  |                     } | ||||||
|  |                     return fd; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * 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<size_t>(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). | ||||||
|  |              * | ||||||
|  |              * @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. | ||||||
|  |              */ | ||||||
|  |             inline void reliable_write(const int fd, const unsigned char* output_buffer, const size_t size) { | ||||||
|  |                 size_t offset = 0; | ||||||
|  |                 do { | ||||||
|  |                     ssize_t length = ::write(fd, output_buffer + offset, size - offset); | ||||||
|  |                     if (length < 0) { | ||||||
|  |                         throw std::system_error(errno, std::system_category(), "Write failed"); | ||||||
|  |                     } | ||||||
|  |                     offset += static_cast<size_t>(length); | ||||||
|  |                 } while (offset < size); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             inline void reliable_write(const int fd, const char* output_buffer, const size_t size) { | ||||||
|  |                 reliable_write(fd, reinterpret_cast<const unsigned char*>(output_buffer), size); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_DETAIL_READ_WRITE_HPP
 | ||||||
							
								
								
									
										85
									
								
								ThirdParty/osmium/io/detail/write_thread.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								ThirdParty/osmium/io/detail/write_thread.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,85 @@ | |||||||
|  | #ifndef OSMIUM_IO_DETAIL_WRITE_THREAD_HPP | ||||||
|  | #define OSMIUM_IO_DETAIL_WRITE_THREAD_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <future> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | #include <osmium/io/compression.hpp> | ||||||
|  | #include <osmium/io/detail/output_format.hpp> | ||||||
|  | #include <osmium/thread/name.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             class WriteThread { | ||||||
|  | 
 | ||||||
|  |                 typedef osmium::io::detail::data_queue_type data_queue_type; | ||||||
|  | 
 | ||||||
|  |                 data_queue_type& m_input_queue; | ||||||
|  |                 osmium::io::Compressor* m_compressor; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 explicit WriteThread(data_queue_type& input_queue, osmium::io::Compressor* compressor) : | ||||||
|  |                     m_input_queue(input_queue), | ||||||
|  |                     m_compressor(compressor) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void operator()() { | ||||||
|  |                     osmium::thread::set_thread_name("_osmium_output"); | ||||||
|  | 
 | ||||||
|  |                     std::future<std::string> data_future; | ||||||
|  |                     std::string data; | ||||||
|  |                     do { | ||||||
|  |                         m_input_queue.wait_and_pop(data_future); | ||||||
|  |                         data = data_future.get(); | ||||||
|  |                         m_compressor->write(data); | ||||||
|  |                     } while (!data.empty()); | ||||||
|  | 
 | ||||||
|  |                     m_compressor->close(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class WriteThread
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_DETAIL_WRITE_THREAD_HPP
 | ||||||
							
								
								
									
										640
									
								
								ThirdParty/osmium/io/detail/xml_input_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										640
									
								
								ThirdParty/osmium/io/detail/xml_input_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,640 @@ | |||||||
|  | #ifndef OSMIUM_IO_DETAIL_XML_INPUT_FORMAT_HPP | ||||||
|  | #define OSMIUM_IO_DETAIL_XML_INPUT_FORMAT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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. | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #define OSMIUM_LINK_WITH_LIBS_EXPAT -lexpat | ||||||
|  | 
 | ||||||
|  | #include <atomic> | ||||||
|  | #include <cassert> | ||||||
|  | #include <chrono> | ||||||
|  | #include <cstddef> | ||||||
|  | #include <cstdlib> | ||||||
|  | #include <cstring> | ||||||
|  | #include <exception> | ||||||
|  | #include <future> | ||||||
|  | #include <iostream> | ||||||
|  | #include <memory> | ||||||
|  | #include <ratio> | ||||||
|  | #include <sstream> | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <string> | ||||||
|  | #include <thread> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <expat.h> | ||||||
|  | 
 | ||||||
|  | #include <osmium/builder/builder.hpp> | ||||||
|  | #include <osmium/builder/osm_object_builder.hpp> | ||||||
|  | #include <osmium/io/detail/input_format.hpp> | ||||||
|  | #include <osmium/io/file_format.hpp> | ||||||
|  | #include <osmium/io/header.hpp> | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/osm.hpp> | ||||||
|  | #include <osmium/osm/box.hpp> | ||||||
|  | #include <osmium/osm/entity_bits.hpp> | ||||||
|  | #include <osmium/osm/item_type.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/object.hpp> | ||||||
|  | #include <osmium/osm/types.hpp> | ||||||
|  | #include <osmium/thread/queue.hpp> | ||||||
|  | #include <osmium/thread/checked_task.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     struct xml_error : public io_error { | ||||||
|  | 
 | ||||||
|  |         unsigned long line; | ||||||
|  |         unsigned long column; | ||||||
|  |         XML_Error error_code; | ||||||
|  |         std::string error_string; | ||||||
|  | 
 | ||||||
|  |         xml_error(XML_Parser parser) : | ||||||
|  |             io_error(std::string("XML parsing error at line ") | ||||||
|  |                     + std::to_string(XML_GetCurrentLineNumber(parser)) | ||||||
|  |                     + ", column " | ||||||
|  |                     + std::to_string(XML_GetCurrentColumnNumber(parser)) | ||||||
|  |                     + ": " | ||||||
|  |                     + XML_ErrorString(XML_GetErrorCode(parser))), | ||||||
|  |             line(XML_GetCurrentLineNumber(parser)), | ||||||
|  |             column(XML_GetCurrentColumnNumber(parser)), | ||||||
|  |             error_code(XML_GetErrorCode(parser)), | ||||||
|  |             error_string(XML_ErrorString(error_code)) { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     }; // struct xml_error
 | ||||||
|  | 
 | ||||||
|  |     struct format_version_error : public io_error { | ||||||
|  | 
 | ||||||
|  |         std::string version; | ||||||
|  | 
 | ||||||
|  |         explicit format_version_error() : | ||||||
|  |             io_error("Can not read file without version (missing version attribute on osm element)."), | ||||||
|  |             version() { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         explicit format_version_error(const char* v) : | ||||||
|  |             io_error(std::string("Can not read file with version ") + v), | ||||||
|  |             version(v) { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     }; // struct format_version_error
 | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         class File; | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * 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. | ||||||
|  |              */ | ||||||
|  |             class ParserIsDone : std::exception { | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             class XMLParser { | ||||||
|  | 
 | ||||||
|  |                 static constexpr int buffer_size = 10 * 1000 * 1000; | ||||||
|  | 
 | ||||||
|  |                 enum class context { | ||||||
|  |                     root, | ||||||
|  |                     top, | ||||||
|  |                     node, | ||||||
|  |                     way, | ||||||
|  |                     relation, | ||||||
|  |                     changeset, | ||||||
|  |                     ignored_node, | ||||||
|  |                     ignored_way, | ||||||
|  |                     ignored_relation, | ||||||
|  |                     ignored_changeset, | ||||||
|  |                     in_object | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|  |                 context m_context; | ||||||
|  |                 context m_last_context; | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * This is used only for change files which contain create, modify, | ||||||
|  |                  * and delete sections. | ||||||
|  |                  */ | ||||||
|  |                 bool m_in_delete_section; | ||||||
|  | 
 | ||||||
|  |                 osmium::io::Header m_header; | ||||||
|  | 
 | ||||||
|  |                 osmium::memory::Buffer m_buffer; | ||||||
|  | 
 | ||||||
|  |                 std::unique_ptr<osmium::builder::NodeBuilder>               m_node_builder; | ||||||
|  |                 std::unique_ptr<osmium::builder::WayBuilder>                m_way_builder; | ||||||
|  |                 std::unique_ptr<osmium::builder::RelationBuilder>           m_relation_builder; | ||||||
|  |                 std::unique_ptr<osmium::builder::ChangesetBuilder>          m_changeset_builder; | ||||||
|  | 
 | ||||||
|  |                 std::unique_ptr<osmium::builder::TagListBuilder>            m_tl_builder; | ||||||
|  |                 std::unique_ptr<osmium::builder::WayNodeListBuilder>        m_wnl_builder; | ||||||
|  |                 std::unique_ptr<osmium::builder::RelationMemberListBuilder> m_rml_builder; | ||||||
|  | 
 | ||||||
|  |                 osmium::thread::Queue<std::string>& m_input_queue; | ||||||
|  |                 osmium::thread::Queue<osmium::memory::Buffer>& m_queue; | ||||||
|  |                 std::promise<osmium::io::Header>& m_header_promise; | ||||||
|  | 
 | ||||||
|  |                 bool m_promise_fulfilled; | ||||||
|  | 
 | ||||||
|  |                 osmium::osm_entity_bits::type m_read_types; | ||||||
|  | 
 | ||||||
|  |                 size_t m_max_queue_size; | ||||||
|  | 
 | ||||||
|  |                 std::atomic<bool>& m_done; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 explicit XMLParser(osmium::thread::Queue<std::string>& input_queue, osmium::thread::Queue<osmium::memory::Buffer>& queue, std::promise<osmium::io::Header>& header_promise, osmium::osm_entity_bits::type read_types, std::atomic<bool>& done) : | ||||||
|  |                     m_context(context::root), | ||||||
|  |                     m_last_context(context::root), | ||||||
|  |                     m_in_delete_section(false), | ||||||
|  |                     m_header(), | ||||||
|  |                     m_buffer(buffer_size), | ||||||
|  |                     m_node_builder(), | ||||||
|  |                     m_way_builder(), | ||||||
|  |                     m_relation_builder(), | ||||||
|  |                     m_changeset_builder(), | ||||||
|  |                     m_tl_builder(), | ||||||
|  |                     m_wnl_builder(), | ||||||
|  |                     m_rml_builder(), | ||||||
|  |                     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) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void 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)); | ||||||
|  |                         } | ||||||
|  |                         m_queue.push(osmium::memory::Buffer()); // empty buffer to signify eof
 | ||||||
|  |                     } catch (ParserIsDone&) { | ||||||
|  |                         // intentionally left blank
 | ||||||
|  |                     } | ||||||
|  |                     XML_ParserFree(parser); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             private: | ||||||
|  | 
 | ||||||
|  |                 static void XMLCALL start_element_wrapper(void* data, const XML_Char* element, const XML_Char** attrs) { | ||||||
|  |                     static_cast<XMLParser*>(data)->start_element(element, attrs); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 static void XMLCALL end_element_wrapper(void* data, const XML_Char* element) { | ||||||
|  |                     static_cast<XMLParser*>(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); | ||||||
|  |                     } | ||||||
|  |                     for (int count = 0; attrs[count]; count += 2) { | ||||||
|  |                         if (!strcmp(attrs[count], "lon")) { | ||||||
|  |                             static_cast<osmium::Node&>(object).location().lon(std::atof(attrs[count+1])); // XXX doesn't detect garbage after the number
 | ||||||
|  |                         } else if (!strcmp(attrs[count], "lat")) { | ||||||
|  |                             static_cast<osmium::Node&>(object).location().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 { | ||||||
|  |                             object.set_attribute(attrs[count], attrs[count+1]); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     return user; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void init_changeset(osmium::builder::ChangesetBuilder* builder, const XML_Char** attrs) { | ||||||
|  |                     static const char* empty = ""; | ||||||
|  |                     const char* user = empty; | ||||||
|  |                     osmium::Changeset& new_changeset = builder->object(); | ||||||
|  | 
 | ||||||
|  |                     osmium::Location min {}; | ||||||
|  |                     osmium::Location max {}; | ||||||
|  |                     for (int count = 0; attrs[count]; count += 2) { | ||||||
|  |                         if (!strcmp(attrs[count], "min_lon")) { | ||||||
|  |                             min.lon(atof(attrs[count+1])); | ||||||
|  |                         } else if (!strcmp(attrs[count], "min_lat")) { | ||||||
|  |                             min.lat(atof(attrs[count+1])); | ||||||
|  |                         } else if (!strcmp(attrs[count], "max_lon")) { | ||||||
|  |                             max.lon(atof(attrs[count+1])); | ||||||
|  |                         } else if (!strcmp(attrs[count], "max_lat")) { | ||||||
|  |                             max.lat(atof(attrs[count+1])); | ||||||
|  |                         } else if (!strcmp(attrs[count], "user")) { | ||||||
|  |                             user = attrs[count+1]; | ||||||
|  |                         } else { | ||||||
|  |                             new_changeset.set_attribute(attrs[count], attrs[count+1]); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     new_changeset.bounds().extend(min); | ||||||
|  |                     new_changeset.bounds().extend(max); | ||||||
|  | 
 | ||||||
|  |                     builder->add_user(user); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void check_tag(osmium::builder::Builder* builder, const XML_Char* element, const XML_Char** attrs) { | ||||||
|  |                     if (!strcmp(element, "tag")) { | ||||||
|  |                         m_wnl_builder.reset(); | ||||||
|  |                         m_rml_builder.reset(); | ||||||
|  | 
 | ||||||
|  |                         const char* key = ""; | ||||||
|  |                         const char* value = ""; | ||||||
|  |                         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) { | ||||||
|  |                                 value = attrs[count+1]; | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         if (!m_tl_builder) { | ||||||
|  |                             m_tl_builder = std::unique_ptr<osmium::builder::TagListBuilder>(new osmium::builder::TagListBuilder(m_buffer, builder)); | ||||||
|  |                         } | ||||||
|  |                         m_tl_builder->add_tag(key, value); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 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(); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void start_element(const XML_Char* element, const XML_Char** attrs) { | ||||||
|  |                     switch (m_context) { | ||||||
|  |                         case context::root: | ||||||
|  |                             if (!strcmp(element, "osm") || !strcmp(element, "osmChange")) { | ||||||
|  |                                 if (!strcmp(element, "osmChange")) { | ||||||
|  |                                     m_header.has_multiple_object_versions(true); | ||||||
|  |                                 } | ||||||
|  |                                 for (int count = 0; attrs[count]; count += 2) { | ||||||
|  |                                     if (!strcmp(attrs[count], "version")) { | ||||||
|  |                                         m_header.set("version", attrs[count+1]); | ||||||
|  |                                         if (strcmp(attrs[count+1], "0.6")) { | ||||||
|  |                                             throw osmium::format_version_error(attrs[count+1]); | ||||||
|  |                                         } | ||||||
|  |                                     } else if (!strcmp(attrs[count], "generator")) { | ||||||
|  |                                         m_header.set("generator", attrs[count+1]); | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                                 if (m_header.get("version") == "") { | ||||||
|  |                                     throw osmium::format_version_error(); | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                             m_context = context::top; | ||||||
|  |                             break; | ||||||
|  |                         case context::top: | ||||||
|  |                             assert(!m_tl_builder); | ||||||
|  |                             if (!strcmp(element, "node")) { | ||||||
|  |                                 header_is_done(); | ||||||
|  |                                 if (m_read_types & osmium::osm_entity_bits::node) { | ||||||
|  |                                     m_node_builder = std::unique_ptr<osmium::builder::NodeBuilder>(new osmium::builder::NodeBuilder(m_buffer)); | ||||||
|  |                                     m_node_builder->add_user(init_object(m_node_builder->object(), attrs)); | ||||||
|  |                                     m_context = context::node; | ||||||
|  |                                 } else { | ||||||
|  |                                     m_context = context::ignored_node; | ||||||
|  |                                 } | ||||||
|  |                             } else if (!strcmp(element, "way")) { | ||||||
|  |                                 header_is_done(); | ||||||
|  |                                 if (m_read_types & osmium::osm_entity_bits::way) { | ||||||
|  |                                     m_way_builder = std::unique_ptr<osmium::builder::WayBuilder>(new osmium::builder::WayBuilder(m_buffer)); | ||||||
|  |                                     m_way_builder->add_user(init_object(m_way_builder->object(), attrs)); | ||||||
|  |                                     m_context = context::way; | ||||||
|  |                                 } else { | ||||||
|  |                                     m_context = context::ignored_way; | ||||||
|  |                                 } | ||||||
|  |                             } else if (!strcmp(element, "relation")) { | ||||||
|  |                                 header_is_done(); | ||||||
|  |                                 if (m_read_types & osmium::osm_entity_bits::relation) { | ||||||
|  |                                     m_relation_builder = std::unique_ptr<osmium::builder::RelationBuilder>(new osmium::builder::RelationBuilder(m_buffer)); | ||||||
|  |                                     m_relation_builder->add_user(init_object(m_relation_builder->object(), attrs)); | ||||||
|  |                                     m_context = context::relation; | ||||||
|  |                                 } else { | ||||||
|  |                                     m_context = context::ignored_relation; | ||||||
|  |                                 } | ||||||
|  |                             } else if (!strcmp(element, "changeset")) { | ||||||
|  |                                 header_is_done(); | ||||||
|  |                                 if (m_read_types & osmium::osm_entity_bits::changeset) { | ||||||
|  |                                     m_changeset_builder = std::unique_ptr<osmium::builder::ChangesetBuilder>(new osmium::builder::ChangesetBuilder(m_buffer)); | ||||||
|  |                                     init_changeset(m_changeset_builder.get(), attrs); | ||||||
|  |                                     m_context = context::changeset; | ||||||
|  |                                 } else { | ||||||
|  |                                     m_context = context::ignored_changeset; | ||||||
|  |                                 } | ||||||
|  |                             } else if (!strcmp(element, "bounds")) { | ||||||
|  |                                 osmium::Location min; | ||||||
|  |                                 osmium::Location max; | ||||||
|  |                                 for (int count = 0; attrs[count]; count += 2) { | ||||||
|  |                                     if (!strcmp(attrs[count], "minlon")) { | ||||||
|  |                                         min.lon(atof(attrs[count+1])); | ||||||
|  |                                     } else if (!strcmp(attrs[count], "minlat")) { | ||||||
|  |                                         min.lat(atof(attrs[count+1])); | ||||||
|  |                                     } else if (!strcmp(attrs[count], "maxlon")) { | ||||||
|  |                                         max.lon(atof(attrs[count+1])); | ||||||
|  |                                     } else if (!strcmp(attrs[count], "maxlat")) { | ||||||
|  |                                         max.lat(atof(attrs[count+1])); | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                                 osmium::Box box; | ||||||
|  |                                 box.extend(min).extend(max); | ||||||
|  |                                 m_header.add_box(box); | ||||||
|  |                             } else if (!strcmp(element, "delete")) { | ||||||
|  |                                 m_in_delete_section = true; | ||||||
|  |                             } | ||||||
|  |                             break; | ||||||
|  |                         case context::node: | ||||||
|  |                             m_last_context = context::node; | ||||||
|  |                             m_context = context::in_object; | ||||||
|  |                             check_tag(m_node_builder.get(), element, attrs); | ||||||
|  |                             break; | ||||||
|  |                         case context::way: | ||||||
|  |                             m_last_context = context::way; | ||||||
|  |                             m_context = context::in_object; | ||||||
|  |                             if (!strcmp(element, "nd")) { | ||||||
|  |                                 m_tl_builder.reset(); | ||||||
|  | 
 | ||||||
|  |                                 if (!m_wnl_builder) { | ||||||
|  |                                     m_wnl_builder = std::unique_ptr<osmium::builder::WayNodeListBuilder>(new osmium::builder::WayNodeListBuilder(m_buffer, m_way_builder.get())); | ||||||
|  |                                 } | ||||||
|  | 
 | ||||||
|  |                                 for (int count = 0; attrs[count]; count += 2) { | ||||||
|  |                                     if (!strcmp(attrs[count], "ref")) { | ||||||
|  |                                         m_wnl_builder->add_node_ref(osmium::string_to_object_id(attrs[count+1])); | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } else { | ||||||
|  |                                 check_tag(m_way_builder.get(), element, attrs); | ||||||
|  |                             } | ||||||
|  |                             break; | ||||||
|  |                         case context::relation: | ||||||
|  |                             m_last_context = context::relation; | ||||||
|  |                             m_context = context::in_object; | ||||||
|  |                             if (!strcmp(element, "member")) { | ||||||
|  |                                 m_tl_builder.reset(); | ||||||
|  | 
 | ||||||
|  |                                 if (!m_rml_builder) { | ||||||
|  |                                     m_rml_builder = std::unique_ptr<osmium::builder::RelationMemberListBuilder>(new osmium::builder::RelationMemberListBuilder(m_buffer, m_relation_builder.get())); | ||||||
|  |                                 } | ||||||
|  | 
 | ||||||
|  |                                 char type = 'x'; | ||||||
|  |                                 object_id_type ref  = 0; | ||||||
|  |                                 const char* role = ""; | ||||||
|  |                                 for (int count = 0; attrs[count]; count += 2) { | ||||||
|  |                                     if (!strcmp(attrs[count], "type")) { | ||||||
|  |                                         type = static_cast<char>(attrs[count+1][0]); | ||||||
|  |                                     } else if (!strcmp(attrs[count], "ref")) { | ||||||
|  |                                         ref = osmium::string_to_object_id(attrs[count+1]); | ||||||
|  |                                     } else if (!strcmp(attrs[count], "role")) { | ||||||
|  |                                         role = static_cast<const char*>(attrs[count+1]); | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                                 // XXX assert type, ref, role are set
 | ||||||
|  |                                 m_rml_builder->add_member(char_to_item_type(type), ref, role); | ||||||
|  |                             } else { | ||||||
|  |                                 check_tag(m_relation_builder.get(), element, attrs); | ||||||
|  |                             } | ||||||
|  |                             break; | ||||||
|  |                         case context::changeset: | ||||||
|  |                             m_last_context = context::changeset; | ||||||
|  |                             m_context = context::in_object; | ||||||
|  |                             check_tag(m_changeset_builder.get(), element, attrs); | ||||||
|  |                             break; | ||||||
|  |                         case context::ignored_node: | ||||||
|  |                             break; | ||||||
|  |                         case context::ignored_way: | ||||||
|  |                             break; | ||||||
|  |                         case context::ignored_relation: | ||||||
|  |                             break; | ||||||
|  |                         case context::ignored_changeset: | ||||||
|  |                             break; | ||||||
|  |                         case context::in_object: | ||||||
|  |                             assert(false); // should never be here
 | ||||||
|  |                             break; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void end_element(const XML_Char* element) { | ||||||
|  |                     switch (m_context) { | ||||||
|  |                         case context::root: | ||||||
|  |                             assert(false); // should never be here
 | ||||||
|  |                             break; | ||||||
|  |                         case context::top: | ||||||
|  |                             if (!strcmp(element, "osm") || !strcmp(element, "osmChange")) { | ||||||
|  |                                 header_is_done(); | ||||||
|  |                                 m_context = context::root; | ||||||
|  |                             } else if (!strcmp(element, "delete")) { | ||||||
|  |                                 m_in_delete_section = false; | ||||||
|  |                             } | ||||||
|  |                             break; | ||||||
|  |                         case context::node: | ||||||
|  |                             assert(!strcmp(element, "node")); | ||||||
|  |                             m_tl_builder.reset(); | ||||||
|  |                             m_node_builder.reset(); | ||||||
|  |                             m_buffer.commit(); | ||||||
|  |                             m_context = context::top; | ||||||
|  |                             flush_buffer(); | ||||||
|  |                             break; | ||||||
|  |                         case context::way: | ||||||
|  |                             assert(!strcmp(element, "way")); | ||||||
|  |                             m_tl_builder.reset(); | ||||||
|  |                             m_wnl_builder.reset(); | ||||||
|  |                             m_way_builder.reset(); | ||||||
|  |                             m_buffer.commit(); | ||||||
|  |                             m_context = context::top; | ||||||
|  |                             flush_buffer(); | ||||||
|  |                             break; | ||||||
|  |                         case context::relation: | ||||||
|  |                             assert(!strcmp(element, "relation")); | ||||||
|  |                             m_tl_builder.reset(); | ||||||
|  |                             m_rml_builder.reset(); | ||||||
|  |                             m_relation_builder.reset(); | ||||||
|  |                             m_buffer.commit(); | ||||||
|  |                             m_context = context::top; | ||||||
|  |                             flush_buffer(); | ||||||
|  |                             break; | ||||||
|  |                         case context::changeset: | ||||||
|  |                             assert(!strcmp(element, "changeset")); | ||||||
|  |                             m_tl_builder.reset(); | ||||||
|  |                             m_changeset_builder.reset(); | ||||||
|  |                             m_buffer.commit(); | ||||||
|  |                             m_context = context::top; | ||||||
|  |                             flush_buffer(); | ||||||
|  |                             break; | ||||||
|  |                         case context::in_object: | ||||||
|  |                             m_context = m_last_context; | ||||||
|  |                             break; | ||||||
|  |                         case context::ignored_node: | ||||||
|  |                             if (!strcmp(element, "node")) { | ||||||
|  |                                 m_context = context::top; | ||||||
|  |                             } | ||||||
|  |                             break; | ||||||
|  |                         case context::ignored_way: | ||||||
|  |                             if (!strcmp(element, "way")) { | ||||||
|  |                                 m_context = context::top; | ||||||
|  |                             } | ||||||
|  |                             break; | ||||||
|  |                         case context::ignored_relation: | ||||||
|  |                             if (!strcmp(element, "relation")) { | ||||||
|  |                                 m_context = context::top; | ||||||
|  |                             } | ||||||
|  |                             break; | ||||||
|  |                         case context::ignored_changeset: | ||||||
|  |                             if (!strcmp(element, "changeset")) { | ||||||
|  |                                 m_context = context::top; | ||||||
|  |                             } | ||||||
|  |                             break; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void flush_buffer() { | ||||||
|  |                     if (m_buffer.capacity() - m_buffer.committed() < 1000 * 1000) { | ||||||
|  |                         m_queue.push(std::move(m_buffer)); | ||||||
|  |                         osmium::memory::Buffer buffer(buffer_size); | ||||||
|  |                         std::swap(m_buffer, buffer); | ||||||
|  | 
 | ||||||
|  |                         while (m_queue.size() > m_max_queue_size) { | ||||||
|  |                             std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // XMLParser
 | ||||||
|  | 
 | ||||||
|  |             class XMLInputFormat : public osmium::io::detail::InputFormat { | ||||||
|  | 
 | ||||||
|  |                 static constexpr size_t m_max_queue_size = 100; | ||||||
|  | 
 | ||||||
|  |                 osmium::thread::Queue<osmium::memory::Buffer> m_queue; | ||||||
|  |                 std::atomic<bool> m_done; | ||||||
|  |                 std::promise<osmium::io::Header> m_header_promise; | ||||||
|  |                 osmium::thread::CheckedTask<XMLParser> m_parser_task; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 /**
 | ||||||
|  |                  * Instantiate XML Parser | ||||||
|  |                  * | ||||||
|  |                  * @param file osmium::io::File instance describing file to be read from. | ||||||
|  |                  * @param read_which_entities Which types of OSM entities (nodes, ways, relations, changesets) should be parsed? | ||||||
|  |                  * @param input_queue String queue where data is read from. | ||||||
|  |                  */ | ||||||
|  |                 explicit XMLInputFormat(const osmium::io::File& file, osmium::osm_entity_bits::type read_which_entities, osmium::thread::Queue<std::string>& input_queue) : | ||||||
|  |                     osmium::io::detail::InputFormat(file, read_which_entities, input_queue), | ||||||
|  |                     m_queue(), | ||||||
|  |                     m_done(false), | ||||||
|  |                     m_header_promise(), | ||||||
|  |                     m_parser_task(input_queue, m_queue, m_header_promise, read_which_entities, m_done) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 ~XMLInputFormat() { | ||||||
|  |                     m_done = true; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 virtual osmium::io::Header header() override final { | ||||||
|  |                     m_parser_task.check_for_exception(); | ||||||
|  |                     return m_header_promise.get_future().get(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 osmium::memory::Buffer read() override { | ||||||
|  |                     osmium::memory::Buffer buffer; | ||||||
|  |                     if (!m_done || !m_queue.empty()) { | ||||||
|  |                         m_queue.wait_and_pop(buffer); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     m_parser_task.check_for_exception(); | ||||||
|  |                     return buffer; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class XMLInputFormat
 | ||||||
|  | 
 | ||||||
|  |             namespace { | ||||||
|  | 
 | ||||||
|  |                 const bool registered_xml_input = osmium::io::detail::InputFormatFactory::instance().register_input_format(osmium::io::file_format::xml, | ||||||
|  |                     [](const osmium::io::File& file, osmium::osm_entity_bits::type read_which_entities, osmium::thread::Queue<std::string>& input_queue) { | ||||||
|  |                         return new osmium::io::detail::XMLInputFormat(file, read_which_entities, input_queue); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |             } // anonymous namespace
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_DETAIL_XML_INPUT_FORMAT_HPP
 | ||||||
							
								
								
									
										475
									
								
								ThirdParty/osmium/io/detail/xml_output_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										475
									
								
								ThirdParty/osmium/io/detail/xml_output_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,475 @@ | |||||||
|  | #ifndef OSMIUM_IO_DETAIL_XML_OUTPUT_FORMAT_HPP | ||||||
|  | #define OSMIUM_IO_DETAIL_XML_OUTPUT_FORMAT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <chrono> | ||||||
|  | #include <cinttypes> | ||||||
|  | #include <cstddef> | ||||||
|  | #include <cstdio> | ||||||
|  | #include <future> | ||||||
|  | #include <iterator> | ||||||
|  | #include <memory> | ||||||
|  | #include <ratio> | ||||||
|  | #include <string> | ||||||
|  | #include <thread> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/handler.hpp> | ||||||
|  | #include <osmium/io/detail/output_format.hpp> | ||||||
|  | #include <osmium/io/file.hpp> | ||||||
|  | #include <osmium/io/file_format.hpp> | ||||||
|  | #include <osmium/io/header.hpp> | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/memory/collection.hpp> | ||||||
|  | #include <osmium/osm/box.hpp> | ||||||
|  | #include <osmium/osm/changeset.hpp> | ||||||
|  | #include <osmium/osm/item_type.hpp> | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | #include <osmium/osm/node.hpp> | ||||||
|  | #include <osmium/osm/object.hpp> | ||||||
|  | #include <osmium/osm/relation.hpp> | ||||||
|  | #include <osmium/osm/tag.hpp> | ||||||
|  | #include <osmium/osm/timestamp.hpp> | ||||||
|  | #include <osmium/osm/types.hpp> | ||||||
|  | #include <osmium/osm/way.hpp> | ||||||
|  | #include <osmium/thread/pool.hpp> | ||||||
|  | #include <osmium/visitor.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             struct XMLWriteError {}; | ||||||
|  | 
 | ||||||
|  |             namespace { | ||||||
|  | 
 | ||||||
|  |                 void xml_string(std::string& out, const char* in) { | ||||||
|  |                     for (; *in != '\0'; ++in) { | ||||||
|  |                         switch(*in) { | ||||||
|  |                             case '&':  out += "&";  break; | ||||||
|  |                             case '\"': out += """; break; | ||||||
|  |                             case '\'': out += "'"; break; | ||||||
|  |                             case '<':  out += "<";   break; | ||||||
|  |                             case '>':  out += ">";   break; | ||||||
|  |                             default:   out += *in;      break; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 const size_t tmp_buffer_size = 100; | ||||||
|  | 
 | ||||||
|  |                 template <typename T> | ||||||
|  |                 void oprintf(std::string& out, const char* format, T value) { | ||||||
|  |                     char buffer[tmp_buffer_size+1]; | ||||||
|  |                     snprintf(buffer, sizeof(buffer)/sizeof(char), format, value); | ||||||
|  |                     out += buffer; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             } // anonymous namespace
 | ||||||
|  | 
 | ||||||
|  |             class XMLOutputBlock : public osmium::handler::Handler { | ||||||
|  | 
 | ||||||
|  |                 // operation (create, modify, delete) for osc files
 | ||||||
|  |                 enum class operation { | ||||||
|  |                     op_none   = 0, | ||||||
|  |                     op_create = 1, | ||||||
|  |                     op_modify = 2, | ||||||
|  |                     op_delete = 3 | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|  |                 osmium::memory::Buffer m_input_buffer; | ||||||
|  | 
 | ||||||
|  |                 std::string m_out {}; | ||||||
|  | 
 | ||||||
|  |                 operation m_last_op {operation::op_none}; | ||||||
|  | 
 | ||||||
|  |                 const bool m_write_visible_flag; | ||||||
|  |                 const bool m_write_change_ops; | ||||||
|  | 
 | ||||||
|  |                 void write_spaces(int num) { | ||||||
|  |                     for (; num!=0; --num) { | ||||||
|  |                         m_out += ' '; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void write_prefix() { | ||||||
|  |                     if (m_write_change_ops) { | ||||||
|  |                         write_spaces(4); | ||||||
|  |                     } else { | ||||||
|  |                         write_spaces(2); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void write_meta(const osmium::OSMObject& object) { | ||||||
|  |                     oprintf(m_out, " id=\"%" PRId64 "\"", object.id()); | ||||||
|  | 
 | ||||||
|  |                     if (object.version()) { | ||||||
|  |                         oprintf(m_out, " version=\"%d\"", object.version()); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (object.timestamp()) { | ||||||
|  |                         m_out += " timestamp=\""; | ||||||
|  |                         m_out += object.timestamp().to_iso(); | ||||||
|  |                         m_out += "\""; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (!object.user_is_anonymous()) { | ||||||
|  |                         oprintf(m_out, " uid=\"%d\" user=\"", object.uid()); | ||||||
|  |                         xml_string(m_out, object.user()); | ||||||
|  |                         m_out += "\""; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (object.changeset()) { | ||||||
|  |                         oprintf(m_out, " changeset=\"%d\"", object.changeset()); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (m_write_visible_flag) { | ||||||
|  |                         if (object.visible()) { | ||||||
|  |                             m_out += " visible=\"true\""; | ||||||
|  |                         } else { | ||||||
|  |                             m_out += " visible=\"false\""; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void write_tags(const osmium::TagList& tags) { | ||||||
|  |                     for (const auto& tag : tags) { | ||||||
|  |                         write_prefix(); | ||||||
|  |                         m_out += "  <tag k=\""; | ||||||
|  |                         xml_string(m_out, tag.key()); | ||||||
|  |                         m_out += "\" v=\""; | ||||||
|  |                         xml_string(m_out, tag.value()); | ||||||
|  |                         m_out += "\"/>\n"; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void open_close_op_tag(const operation op = operation::op_none) { | ||||||
|  |                     if (op == m_last_op) { | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     switch (m_last_op) { | ||||||
|  |                         case operation::op_none: | ||||||
|  |                             break; | ||||||
|  |                         case operation::op_create: | ||||||
|  |                             m_out += "  </create>\n"; | ||||||
|  |                             break; | ||||||
|  |                         case operation::op_modify: | ||||||
|  |                             m_out += "  </modify>\n"; | ||||||
|  |                             break; | ||||||
|  |                         case operation::op_delete: | ||||||
|  |                             m_out += "  </delete>\n"; | ||||||
|  |                             break; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     switch (op) { | ||||||
|  |                         case operation::op_none: | ||||||
|  |                             break; | ||||||
|  |                         case operation::op_create: | ||||||
|  |                             m_out += "  <create>\n"; | ||||||
|  |                             break; | ||||||
|  |                         case operation::op_modify: | ||||||
|  |                             m_out += "  <modify>\n"; | ||||||
|  |                             break; | ||||||
|  |                         case operation::op_delete: | ||||||
|  |                             m_out += "  <delete>\n"; | ||||||
|  |                             break; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     m_last_op = op; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 explicit XMLOutputBlock(osmium::memory::Buffer&& buffer, bool write_visible_flag, bool write_change_ops) : | ||||||
|  |                     m_input_buffer(std::move(buffer)), | ||||||
|  |                     m_write_visible_flag(write_visible_flag && !write_change_ops), | ||||||
|  |                     m_write_change_ops(write_change_ops) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 XMLOutputBlock(const XMLOutputBlock&) = delete; | ||||||
|  |                 XMLOutputBlock& operator=(const XMLOutputBlock&) = delete; | ||||||
|  | 
 | ||||||
|  |                 XMLOutputBlock(XMLOutputBlock&& other) = default; | ||||||
|  |                 XMLOutputBlock& operator=(XMLOutputBlock&& other) = default; | ||||||
|  | 
 | ||||||
|  |                 std::string operator()() { | ||||||
|  |                     osmium::apply(m_input_buffer.cbegin(), m_input_buffer.cend(), *this); | ||||||
|  | 
 | ||||||
|  |                     if (m_write_change_ops) { | ||||||
|  |                         open_close_op_tag(); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     std::string out; | ||||||
|  |                     std::swap(out, m_out); | ||||||
|  |                     return out; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void node(const osmium::Node& node) { | ||||||
|  |                     if (m_write_change_ops) { | ||||||
|  |                         open_close_op_tag(node.visible() ? (node.version() == 1 ? operation::op_create : operation::op_modify) : operation::op_delete); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     write_prefix(); | ||||||
|  |                     m_out += "<node"; | ||||||
|  | 
 | ||||||
|  |                     write_meta(node); | ||||||
|  | 
 | ||||||
|  |                     if (node.location()) { | ||||||
|  |                         m_out += " lat=\""; | ||||||
|  |                         osmium::Location::coordinate2string(std::back_inserter(m_out), node.location().lat_without_check()); | ||||||
|  |                         m_out += "\" lon=\""; | ||||||
|  |                         osmium::Location::coordinate2string(std::back_inserter(m_out), node.location().lon_without_check()); | ||||||
|  |                         m_out += "\""; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (node.tags().empty()) { | ||||||
|  |                         m_out += "/>\n"; | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     m_out += ">\n"; | ||||||
|  | 
 | ||||||
|  |                     write_tags(node.tags()); | ||||||
|  | 
 | ||||||
|  |                     write_prefix(); | ||||||
|  |                     m_out += "</node>\n"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void way(const osmium::Way& way) { | ||||||
|  |                     if (m_write_change_ops) { | ||||||
|  |                         open_close_op_tag(way.visible() ? (way.version() == 1 ? operation::op_create : operation::op_modify) : operation::op_delete); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     write_prefix(); | ||||||
|  |                     m_out += "<way"; | ||||||
|  |                     write_meta(way); | ||||||
|  | 
 | ||||||
|  |                     if (way.tags().empty() && way.nodes().empty()) { | ||||||
|  |                         m_out += "/>\n"; | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     m_out += ">\n"; | ||||||
|  | 
 | ||||||
|  |                     for (const auto& node_ref : way.nodes()) { | ||||||
|  |                         write_prefix(); | ||||||
|  |                         oprintf(m_out, "  <nd ref=\"%" PRId64 "\"/>\n", node_ref.ref()); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     write_tags(way.tags()); | ||||||
|  | 
 | ||||||
|  |                     write_prefix(); | ||||||
|  |                     m_out += "</way>\n"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void relation(const osmium::Relation& relation) { | ||||||
|  |                     if (m_write_change_ops) { | ||||||
|  |                         open_close_op_tag(relation.visible() ? (relation.version() == 1 ? operation::op_create : operation::op_modify) : operation::op_delete); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     write_prefix(); | ||||||
|  |                     m_out += "<relation"; | ||||||
|  |                     write_meta(relation); | ||||||
|  | 
 | ||||||
|  |                     if (relation.tags().empty() && relation.members().empty()) { | ||||||
|  |                         m_out += "/>\n"; | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     m_out += ">\n"; | ||||||
|  | 
 | ||||||
|  |                     for (const auto& member : relation.members()) { | ||||||
|  |                         write_prefix(); | ||||||
|  |                         m_out += "  <member type=\""; | ||||||
|  |                         m_out += item_type_to_name(member.type()); | ||||||
|  |                         oprintf(m_out, "\" ref=\"%" PRId64 "\" role=\"", member.ref()); | ||||||
|  |                         xml_string(m_out, member.role()); | ||||||
|  |                         m_out += "\"/>\n"; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     write_tags(relation.tags()); | ||||||
|  | 
 | ||||||
|  |                     write_prefix(); | ||||||
|  |                     m_out += "</relation>\n"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void changeset(const osmium::Changeset& changeset) { | ||||||
|  |                     write_prefix(); | ||||||
|  |                     m_out += "<changeset"; | ||||||
|  | 
 | ||||||
|  |                     oprintf(m_out, " id=\"%" PRId32 "\"", changeset.id()); | ||||||
|  | 
 | ||||||
|  |                     if (changeset.created_at()) { | ||||||
|  |                         m_out += " created_at=\""; | ||||||
|  |                         m_out += changeset.created_at().to_iso(); | ||||||
|  |                         m_out += "\""; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     oprintf(m_out, " num_changes=\"%" PRId32 "\"", changeset.num_changes()); | ||||||
|  | 
 | ||||||
|  |                     if (changeset.closed_at()) { | ||||||
|  |                         m_out += " closed_at=\""; | ||||||
|  |                         m_out += changeset.closed_at().to_iso(); | ||||||
|  |                         m_out += "\" open=\"false\""; | ||||||
|  |                     } else { | ||||||
|  |                         m_out += " open=\"true\""; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (changeset.bounds()) { | ||||||
|  |                         oprintf(m_out, " min_lon=\"%.7f\"", changeset.bounds().bottom_left().lon_without_check()); | ||||||
|  |                         oprintf(m_out, " min_lat=\"%.7f\"", changeset.bounds().bottom_left().lat_without_check()); | ||||||
|  |                         oprintf(m_out, " max_lon=\"%.7f\"", changeset.bounds().top_right().lon_without_check()); | ||||||
|  |                         oprintf(m_out, " max_lat=\"%.7f\"", changeset.bounds().top_right().lat_without_check()); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (!changeset.user_is_anonymous()) { | ||||||
|  |                         m_out += " user=\""; | ||||||
|  |                         xml_string(m_out, changeset.user()); | ||||||
|  |                         oprintf(m_out, "\" uid=\"%d\"", changeset.uid()); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (changeset.tags().empty()) { | ||||||
|  |                         m_out += "/>\n"; | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     m_out += ">\n"; | ||||||
|  | 
 | ||||||
|  |                     write_tags(changeset.tags()); | ||||||
|  | 
 | ||||||
|  |                     write_prefix(); | ||||||
|  |                     m_out += "</changeset>\n"; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class XMLOutputBlock
 | ||||||
|  | 
 | ||||||
|  |             class XMLOutputFormat : public osmium::io::detail::OutputFormat, public osmium::handler::Handler { | ||||||
|  | 
 | ||||||
|  |                 bool m_write_visible_flag; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 XMLOutputFormat(const osmium::io::File& file, data_queue_type& output_queue) : | ||||||
|  |                     OutputFormat(file, output_queue), | ||||||
|  |                     m_write_visible_flag(file.has_multiple_object_versions() || m_file.is_true("force_visible_flag")) { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 XMLOutputFormat(const XMLOutputFormat&) = delete; | ||||||
|  |                 XMLOutputFormat& operator=(const XMLOutputFormat&) = delete; | ||||||
|  | 
 | ||||||
|  |                 ~XMLOutputFormat() override final { | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 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")); | ||||||
|  |                     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
 | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void write_header(const osmium::io::Header& header) override final { | ||||||
|  |                     std::string out = "<?xml version='1.0' encoding='UTF-8'?>\n"; | ||||||
|  | 
 | ||||||
|  |                     if (m_file.is_true("xml_change_format")) { | ||||||
|  |                         out += "<osmChange version=\"0.6\" generator=\""; | ||||||
|  |                         xml_string(out, header.get("generator").c_str()); | ||||||
|  |                         out += "\">\n"; | ||||||
|  |                     } else { | ||||||
|  |                         out += "<osm version=\"0.6\""; | ||||||
|  | 
 | ||||||
|  |                         std::string xml_josm_upload = header.get("xml_josm_upload"); | ||||||
|  |                         if (xml_josm_upload == "true" || xml_josm_upload == "false") { | ||||||
|  |                             out += " upload=\""; | ||||||
|  |                             out += xml_josm_upload; | ||||||
|  |                             out += "\""; | ||||||
|  |                         } | ||||||
|  |                         out += " generator=\""; | ||||||
|  |                         xml_string(out, header.get("generator").c_str()); | ||||||
|  |                         out += "\">\n"; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     for (const auto& box : header.boxes()) { | ||||||
|  |                         out += "  <bounds"; | ||||||
|  |                         oprintf(out, " minlon=\"%.7f\"", box.bottom_left().lon()); | ||||||
|  |                         oprintf(out, " minlat=\"%.7f\"", box.bottom_left().lat()); | ||||||
|  |                         oprintf(out, " maxlon=\"%.7f\"", box.top_right().lon()); | ||||||
|  |                         oprintf(out, " maxlat=\"%.7f\"/>\n", box.top_right().lat()); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     std::promise<std::string> promise; | ||||||
|  |                     m_output_queue.push(promise.get_future()); | ||||||
|  |                     promise.set_value(std::move(out)); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 void close() override final { | ||||||
|  |                     { | ||||||
|  |                         std::string out; | ||||||
|  |                         if (m_file.is_true("xml_change_format")) { | ||||||
|  |                             out += "</osmChange>\n"; | ||||||
|  |                         } else { | ||||||
|  |                             out += "</osm>\n"; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         std::promise<std::string> promise; | ||||||
|  |                         m_output_queue.push(promise.get_future()); | ||||||
|  |                         promise.set_value(std::move(out)); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     std::promise<std::string> promise; | ||||||
|  |                     m_output_queue.push(promise.get_future()); | ||||||
|  |                     promise.set_value(std::string()); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; // class XMLOutputFormat
 | ||||||
|  | 
 | ||||||
|  |             namespace { | ||||||
|  | 
 | ||||||
|  |                 const bool registered_xml_output = osmium::io::detail::OutputFormatFactory::instance().register_output_format(osmium::io::file_format::xml, | ||||||
|  |                     [](const osmium::io::File& file, data_queue_type& output_queue) { | ||||||
|  |                         return new osmium::io::detail::XMLOutputFormat(file, output_queue); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |             } // anonymous namespace
 | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     } // namespace output
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_DETAIL_XML_OUTPUT_FORMAT_HPP
 | ||||||
							
								
								
									
										98
									
								
								ThirdParty/osmium/io/detail/zlib.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								ThirdParty/osmium/io/detail/zlib.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,98 @@ | |||||||
|  | #ifndef OSMIUM_IO_DETAIL_ZLIB_HPP | ||||||
|  | #define OSMIUM_IO_DETAIL_ZLIB_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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. | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #define OSMIUM_LINK_WITH_LIBS_ZLIB -lz | ||||||
|  | 
 | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | #include <zlib.h> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Compress data using zlib. | ||||||
|  |              * | ||||||
|  |              * @param input Data to compress. | ||||||
|  |              * @return Compressed data. | ||||||
|  |              */ | ||||||
|  |             inline std::string zlib_compress(const std::string& input) { | ||||||
|  |                 unsigned long output_size = ::compressBound(input.size()); | ||||||
|  | 
 | ||||||
|  |                 std::string output(output_size, '\0'); | ||||||
|  | 
 | ||||||
|  |                 if (::compress(reinterpret_cast<unsigned char*>(const_cast<char *>(output.data())), | ||||||
|  |                                &output_size, | ||||||
|  |                                reinterpret_cast<const unsigned char*>(input.data()), | ||||||
|  |                                input.size()) != Z_OK) { | ||||||
|  |                     throw std::runtime_error("failed to compress data"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 output.resize(output_size); | ||||||
|  | 
 | ||||||
|  |                 return output; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Uncompress data using zlib. | ||||||
|  |              * | ||||||
|  |              * @param input Compressed input data. | ||||||
|  |              * @param raw_size Size of uncompressed data. | ||||||
|  |              * @return Uncompressed data. | ||||||
|  |              */ | ||||||
|  |             inline std::string zlib_uncompress(const std::string& input, unsigned long raw_size) { | ||||||
|  |                 std::string output(raw_size, '\0'); | ||||||
|  | 
 | ||||||
|  |                 if (::uncompress(reinterpret_cast<unsigned char*>(const_cast<char *>(output.data())), | ||||||
|  |                                  &raw_size, | ||||||
|  |                                  reinterpret_cast<const unsigned char*>(input.data()), | ||||||
|  |                                  input.size()) != Z_OK) { | ||||||
|  |                     throw std::runtime_error("failed to uncompress data"); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 return output; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_DETAIL_ZLIB_HPP
 | ||||||
							
								
								
									
										319
									
								
								ThirdParty/osmium/io/file.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										319
									
								
								ThirdParty/osmium/io/file.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,319 @@ | |||||||
|  | #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 <jochen@topf.org> 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 <cstddef> | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <sstream> | ||||||
|  | #include <string> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <osmium/io/file_format.hpp> | ||||||
|  | #include <osmium/io/file_compression.hpp> | ||||||
|  | #include <osmium/util/options.hpp> | ||||||
|  | 
 | ||||||
|  | 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<std::string> split(const std::string& in, const char delim) { | ||||||
|  |                 std::vector<std::string> 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<std::string> 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<std::string> 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
 | ||||||
							
								
								
									
										68
									
								
								ThirdParty/osmium/io/file_compression.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								ThirdParty/osmium/io/file_compression.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | |||||||
|  | #ifndef OSMIUM_IO_FILE_COMPRESSION_HPP | ||||||
|  | #define OSMIUM_IO_FILE_COMPRESSION_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <iosfwd> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         enum class file_compression { | ||||||
|  |             none  = 0, | ||||||
|  |             gzip  = 1, | ||||||
|  |             bzip2 = 2 | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         inline const char* as_string(file_compression compression) { | ||||||
|  |             switch (compression) { | ||||||
|  |                 case file_compression::none: | ||||||
|  |                     return "none"; | ||||||
|  |                 case file_compression::gzip: | ||||||
|  |                     return "gzip"; | ||||||
|  |                 case file_compression::bzip2: | ||||||
|  |                     return "bzip2"; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         template <typename TChar, typename TTraits> | ||||||
|  |         inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const file_compression compression) { | ||||||
|  |             return out << as_string(compression); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_FILE_COMPRESSION_HPP
 | ||||||
							
								
								
									
										74
									
								
								ThirdParty/osmium/io/file_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								ThirdParty/osmium/io/file_format.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,74 @@ | |||||||
|  | #ifndef OSMIUM_IO_FILE_FORMAT_HPP | ||||||
|  | #define OSMIUM_IO_FILE_FORMAT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <iosfwd> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         enum class file_format { | ||||||
|  |             unknown = 0, | ||||||
|  |             xml     = 1, | ||||||
|  |             pbf     = 2, | ||||||
|  |             opl     = 3, | ||||||
|  |             json    = 4 | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         inline const char* as_string(file_format format) { | ||||||
|  |             switch (format) { | ||||||
|  |                 case file_format::unknown: | ||||||
|  |                     return "unknown"; | ||||||
|  |                 case file_format::xml: | ||||||
|  |                     return "XML"; | ||||||
|  |                 case file_format::pbf: | ||||||
|  |                     return "PBF"; | ||||||
|  |                 case file_format::opl: | ||||||
|  |                     return "OPL"; | ||||||
|  |                 case file_format::json: | ||||||
|  |                     return "JSON"; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         template <typename TChar, typename TTraits> | ||||||
|  |         inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const file_format format) { | ||||||
|  |             return out << as_string(format); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_FILE_FORMAT_HPP
 | ||||||
							
								
								
									
										132
									
								
								ThirdParty/osmium/io/gzip_compression.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								ThirdParty/osmium/io/gzip_compression.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,132 @@ | |||||||
|  | #ifndef OSMIUM_IO_GZIP_COMPRESSION_HPP | ||||||
|  | #define OSMIUM_IO_GZIP_COMPRESSION_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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. | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #define OSMIUM_LINK_WITH_LIBS_ZLIB -lz | ||||||
|  | 
 | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | #include <zlib.h> | ||||||
|  | 
 | ||||||
|  | #include <osmium/io/compression.hpp> | ||||||
|  | #include <osmium/io/file_compression.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         class GzipCompressor : public Compressor { | ||||||
|  | 
 | ||||||
|  |             gzFile m_gzfile; | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             explicit GzipCompressor(int fd) : | ||||||
|  |                 Compressor(), | ||||||
|  |                 m_gzfile(::gzdopen(fd, "w")) { | ||||||
|  |                 if (!m_gzfile) { | ||||||
|  |                     throw std::runtime_error("initialization of gzip compression failed"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             ~GzipCompressor() override final { | ||||||
|  |                 this->close(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void write(const std::string& data) override final { | ||||||
|  |                 ::gzwrite(m_gzfile, data.data(), data.size()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void close() override final { | ||||||
|  |                 if (m_gzfile) { | ||||||
|  |                     ::gzclose(m_gzfile); | ||||||
|  |                     m_gzfile = nullptr; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class GzipCompressor
 | ||||||
|  | 
 | ||||||
|  |         class GzipDecompressor : public Decompressor { | ||||||
|  | 
 | ||||||
|  |             gzFile m_gzfile; | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             explicit GzipDecompressor(int fd) : | ||||||
|  |                 Decompressor(), | ||||||
|  |                 m_gzfile(::gzdopen(fd, "r")) { | ||||||
|  |                 if (!m_gzfile) { | ||||||
|  |                     throw std::runtime_error("initialization of gzip compression failed"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             ~GzipDecompressor() override final { | ||||||
|  |                 this->close(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             std::string read() override final { | ||||||
|  |                 std::string buffer(osmium::io::Decompressor::input_buffer_size, '\0'); | ||||||
|  |                 int nread = ::gzread(m_gzfile, const_cast<char*>(buffer.data()), 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");
 | ||||||
|  |                 } | ||||||
|  |                 buffer.resize(static_cast<std::string::size_type>(nread)); | ||||||
|  |                 return buffer; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void close() override final { | ||||||
|  |                 if (m_gzfile) { | ||||||
|  |                     ::gzclose(m_gzfile); | ||||||
|  |                     m_gzfile = nullptr; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class GzipDecompressor
 | ||||||
|  | 
 | ||||||
|  |         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); } | ||||||
|  |             ); | ||||||
|  | 
 | ||||||
|  |         } // anonymous namespace
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_GZIP_COMPRESSION_HPP
 | ||||||
							
								
								
									
										122
									
								
								ThirdParty/osmium/io/header.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								ThirdParty/osmium/io/header.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,122 @@ | |||||||
|  | #ifndef OSMIUM_IO_HEADER_HPP | ||||||
|  | #define OSMIUM_IO_HEADER_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <initializer_list> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <osmium/osm/box.hpp> | ||||||
|  | #include <osmium/util/options.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |         * Meta information from the header of an OSM file. | ||||||
|  |         */ | ||||||
|  |         class Header : public osmium::util::Options { | ||||||
|  | 
 | ||||||
|  |             /// Bounding boxes
 | ||||||
|  |             std::vector<osmium::Box> m_boxes; | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |             * Are there possibly multiple versions of the same object in this stream of objects? | ||||||
|  |             * This is true for history files and for change files, but not for normal OSM files. | ||||||
|  |             */ | ||||||
|  |             bool m_has_multiple_object_versions = false; | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             Header() = default; | ||||||
|  | 
 | ||||||
|  |             explicit Header(std::initializer_list<osmium::util::Options::value_type> values) : | ||||||
|  |                 Options(values) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             Header(const Header&) = default; | ||||||
|  |             Header& operator=(const Header&) = default; | ||||||
|  | 
 | ||||||
|  |             Header(Header&&) = default; | ||||||
|  |             Header& operator=(Header&&) = default; | ||||||
|  | 
 | ||||||
|  |             ~Header() = default; | ||||||
|  | 
 | ||||||
|  |             std::vector<osmium::Box>& boxes() { | ||||||
|  |                 return m_boxes; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             const std::vector<osmium::Box>& boxes() const { | ||||||
|  |                 return m_boxes; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             Header& boxes(const std::vector<osmium::Box>& boxes) { | ||||||
|  |                 m_boxes = boxes; | ||||||
|  |                 return *this; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             osmium::Box box() const { | ||||||
|  |                 return m_boxes.empty() ? osmium::Box() : m_boxes.front(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             osmium::Box joined_boxes() const { | ||||||
|  |                 osmium::Box box; | ||||||
|  |                 for (const auto& b : m_boxes) { | ||||||
|  |                     box.extend(b.bottom_left()); | ||||||
|  |                     box.extend(b.top_right()); | ||||||
|  |                 } | ||||||
|  |                 return box; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             Header& add_box(const osmium::Box& box) { | ||||||
|  |                 m_boxes.push_back(box); | ||||||
|  |                 return *this; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool has_multiple_object_versions() const { | ||||||
|  |                 return m_has_multiple_object_versions; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             Header& has_multiple_object_versions(bool h) { | ||||||
|  |                 m_has_multiple_object_versions = h; | ||||||
|  |                 return *this; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class Header
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_HEADER_HPP
 | ||||||
							
								
								
									
										139
									
								
								ThirdParty/osmium/io/input_iterator.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								ThirdParty/osmium/io/input_iterator.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,139 @@ | |||||||
|  | #ifndef OSMIUM_IO_INPUT_ITERATOR_HPP | ||||||
|  | #define OSMIUM_IO_INPUT_ITERATOR_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cassert> | ||||||
|  | #include <cstddef> | ||||||
|  | #include <iterator> | ||||||
|  | #include <memory> | ||||||
|  | #include <type_traits> | ||||||
|  | 
 | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/memory/item.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * This iterator class allows you to iterate over all items from a | ||||||
|  |          * source. It hides all the buffer handling and makes the contents of a | ||||||
|  |          * source accessible as a normal STL input iterator. | ||||||
|  |          */ | ||||||
|  |         template <class TSource, class TItem = osmium::memory::Item> | ||||||
|  |         class InputIterator { | ||||||
|  | 
 | ||||||
|  |             static_assert(std::is_base_of<osmium::memory::Item, TItem>::value, "TItem must derive from osmium::buffer::Item"); | ||||||
|  | 
 | ||||||
|  |             typedef typename osmium::memory::Buffer::t_iterator<TItem> item_iterator; | ||||||
|  | 
 | ||||||
|  |             TSource* m_source; | ||||||
|  |             std::shared_ptr<osmium::memory::Buffer> m_buffer {}; | ||||||
|  |             item_iterator m_iter {}; | ||||||
|  | 
 | ||||||
|  |             void update_buffer() { | ||||||
|  |                 do { | ||||||
|  |                     m_buffer = std::make_shared<osmium::memory::Buffer>(std::move(m_source->read())); | ||||||
|  |                     if (!m_buffer || !*m_buffer) { // end of input
 | ||||||
|  |                         m_source = nullptr; | ||||||
|  |                         m_buffer.reset(); | ||||||
|  |                         m_iter = item_iterator(); | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  |                     m_iter = m_buffer->begin<TItem>(); | ||||||
|  |                 } while (m_iter == m_buffer->end<TItem>()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             typedef std::input_iterator_tag iterator_category; | ||||||
|  |             typedef TItem                   value_type; | ||||||
|  |             typedef ptrdiff_t               difference_type; | ||||||
|  |             typedef TItem*                  pointer; | ||||||
|  |             typedef TItem&                  reference; | ||||||
|  | 
 | ||||||
|  |             explicit InputIterator(TSource& source) : | ||||||
|  |                 m_source(&source) { | ||||||
|  |                 update_buffer(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // end iterator
 | ||||||
|  |             InputIterator() : | ||||||
|  |                 m_source(nullptr) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             InputIterator& operator++() { | ||||||
|  |                 assert(m_source); | ||||||
|  |                 assert(m_buffer); | ||||||
|  |                 assert(m_iter); | ||||||
|  |                 ++m_iter; | ||||||
|  |                 if (m_iter == m_buffer->end<TItem>()) { | ||||||
|  |                     update_buffer(); | ||||||
|  |                 } | ||||||
|  |                 return *this; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             InputIterator operator++(int) { | ||||||
|  |                 InputIterator tmp(*this); | ||||||
|  |                 operator++(); | ||||||
|  |                 return tmp; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool operator==(const InputIterator& rhs) const { | ||||||
|  |                 return m_source == rhs.m_source && | ||||||
|  |                        m_buffer == rhs.m_buffer && | ||||||
|  |                        m_iter == rhs.m_iter; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool operator!=(const InputIterator& rhs) const { | ||||||
|  |                 return !(*this == rhs); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             reference operator*() const { | ||||||
|  |                 assert(m_iter); | ||||||
|  |                 return static_cast<reference>(*m_iter); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             pointer operator->() const { | ||||||
|  |                 assert(m_iter); | ||||||
|  |                 return &static_cast<reference>(*m_iter); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class InputIterator
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_INPUT_ITERATOR_HPP
 | ||||||
							
								
								
									
										39
									
								
								ThirdParty/osmium/io/opl_output.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								ThirdParty/osmium/io/opl_output.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | #ifndef OSMIUM_IO_OPL_OUTPUT_HPP | ||||||
|  | #define OSMIUM_IO_OPL_OUTPUT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <osmium/io/writer.hpp> // IWYU pragma: export
 | ||||||
|  | #include <osmium/io/detail/opl_output_format.hpp> // IWYU pragma: export
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_OPL_OUTPUT_HPP
 | ||||||
							
								
								
									
										114
									
								
								ThirdParty/osmium/io/output_iterator.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								ThirdParty/osmium/io/output_iterator.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,114 @@ | |||||||
|  | #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 <jochen@topf.org> 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 <cstddef> | ||||||
|  | #include <iterator> | ||||||
|  | #include <memory> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/osm/diff_object.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace memory { | ||||||
|  |         class Item; | ||||||
|  |     } // namespace memory
 | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         template <class TDest> | ||||||
|  |         class OutputIterator : public std::iterator<std::output_iterator_tag, osmium::memory::Item> { | ||||||
|  | 
 | ||||||
|  |             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<buffer_wrapper> 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_wrapper>(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
 | ||||||
							
								
								
									
										52
									
								
								ThirdParty/osmium/io/overwrite.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								ThirdParty/osmium/io/overwrite.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | |||||||
|  | #ifndef OSMIUM_IO_OVERWRITE_HPP | ||||||
|  | #define OSMIUM_IO_OVERWRITE_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2014 Jochen Topf <jochen@topf.org> 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. | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Allow overwriting of existing file. | ||||||
|  |          */ | ||||||
|  |         enum class overwrite : bool { | ||||||
|  |             no    = false, | ||||||
|  |             allow = true | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_OVERWRITE_HPP
 | ||||||
							
								
								
									
										39
									
								
								ThirdParty/osmium/io/pbf_input.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								ThirdParty/osmium/io/pbf_input.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | #ifndef OSMIUM_IO_PBF_INPUT_HPP | ||||||
|  | #define OSMIUM_IO_PBF_INPUT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <osmium/io/reader.hpp> // IWYU pragma: export
 | ||||||
|  | #include <osmium/io/detail/pbf_input_format.hpp> // IWYU pragma: export
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_PBF_INPUT_HPP
 | ||||||
							
								
								
									
										39
									
								
								ThirdParty/osmium/io/pbf_output.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								ThirdParty/osmium/io/pbf_output.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | #ifndef OSMIUM_IO_PBF_OUTPUT_HPP | ||||||
|  | #define OSMIUM_IO_PBF_OUTPUT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <osmium/io/writer.hpp> // IWYU pragma: export
 | ||||||
|  | #include <osmium/io/detail/pbf_output_format.hpp> // IWYU pragma: export
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_PBF_OUTPUT_HPP
 | ||||||
							
								
								
									
										268
									
								
								ThirdParty/osmium/io/reader.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										268
									
								
								ThirdParty/osmium/io/reader.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,268 @@ | |||||||
|  | #ifndef OSMIUM_IO_READER_HPP | ||||||
|  | #define OSMIUM_IO_READER_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <atomic> | ||||||
|  | #include <cerrno> | ||||||
|  | #include <cstdlib> | ||||||
|  | #include <fcntl.h> | ||||||
|  | #include <memory> | ||||||
|  | #include <string> | ||||||
|  | #include <sys/wait.h> | ||||||
|  | #include <system_error> | ||||||
|  | #include <thread> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/io/compression.hpp> | ||||||
|  | #include <osmium/io/detail/input_format.hpp> | ||||||
|  | #include <osmium/io/detail/read_thread.hpp> | ||||||
|  | #include <osmium/io/detail/read_write.hpp> | ||||||
|  | #include <osmium/io/file.hpp> | ||||||
|  | #include <osmium/io/header.hpp> | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/osm/entity_bits.hpp> | ||||||
|  | #include <osmium/thread/checked_task.hpp> | ||||||
|  | #include <osmium/thread/name.hpp> | ||||||
|  | #include <osmium/thread/queue.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * This is the user-facing interface for reading OSM files. Instantiate | ||||||
|  |          * an object of this class with a file name or osmium::io::File object | ||||||
|  |          * and then call read() on it in a loop until it returns an invalid | ||||||
|  |          * Buffer. | ||||||
|  |          */ | ||||||
|  |         class Reader { | ||||||
|  | 
 | ||||||
|  |             osmium::io::File m_file; | ||||||
|  |             osmium::osm_entity_bits::type m_read_which_entities; | ||||||
|  |             std::atomic<bool> m_input_done; | ||||||
|  |             int m_childpid; | ||||||
|  | 
 | ||||||
|  |             osmium::thread::Queue<std::string> m_input_queue; | ||||||
|  | 
 | ||||||
|  |             std::unique_ptr<osmium::io::Decompressor> m_decompressor; | ||||||
|  |             osmium::thread::CheckedTask<detail::ReadThread> m_read_task; | ||||||
|  | 
 | ||||||
|  |             std::unique_ptr<osmium::io::detail::InputFormat> m_input; | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Fork and execute the given command in the child. | ||||||
|  |              * A pipe is created between the child and the parent. | ||||||
|  |              * The child writes to the pipe, the parent reads from it. | ||||||
|  |              * This function never returns in the child. | ||||||
|  |              * | ||||||
|  |              * @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. | ||||||
|  |              * @throws std::system_error if a system call fails. | ||||||
|  |              */ | ||||||
|  |             static int execute(const std::string& command, const std::string& filename, int* childpid) { | ||||||
|  |                 int pipefd[2]; | ||||||
|  |                 if (pipe(pipefd) < 0) { | ||||||
|  |                     throw std::system_error(errno, std::system_category(), "opening pipe failed"); | ||||||
|  |                 } | ||||||
|  |                 pid_t pid = fork(); | ||||||
|  |                 if (pid < 0) { | ||||||
|  |                     throw std::system_error(errno, std::system_category(), "fork failed"); | ||||||
|  |                 } | ||||||
|  |                 if (pid == 0) { // child
 | ||||||
|  |                     // close all file descriptors except one end of the pipe
 | ||||||
|  |                     for (int i=0; i < 32; ++i) { | ||||||
|  |                         if (i != pipefd[1]) { | ||||||
|  |                             ::close(i); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     if (dup2(pipefd[1], 1) < 0) { // put end of pipe as stdout/stdin
 | ||||||
|  |                         exit(1); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     ::open("/dev/null", O_RDONLY); // stdin
 | ||||||
|  |                     ::open("/dev/null", O_WRONLY); // stderr
 | ||||||
|  |                     // hack: -g switches off globbing in curl which allows [] to be used in file names
 | ||||||
|  |                     // this is important for XAPI URLs
 | ||||||
|  |                     // in theory this execute() function could be used for other commands, but it is
 | ||||||
|  |                     // only used for curl at the moment, so this is okay.
 | ||||||
|  |                     if (::execlp(command.c_str(), command.c_str(), "-g", filename.c_str(), nullptr) < 0) { | ||||||
|  |                         exit(1); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 // parent
 | ||||||
|  |                 *childpid = pid; | ||||||
|  |                 ::close(pipefd[1]); | ||||||
|  |                 return pipefd[0]; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Open File for reading. Handles URLs or normal files. URLs | ||||||
|  |              * are opened by executing the "curl" program (which must be installed) | ||||||
|  |              * and reading from its output. | ||||||
|  |              * | ||||||
|  |              * @return 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) { | ||||||
|  |                 std::string protocol = filename.substr(0, filename.find_first_of(':')); | ||||||
|  |                 if (protocol == "http" || protocol == "https" || protocol == "ftp" || protocol == "file") { | ||||||
|  |                     return execute("curl", filename, childpid); | ||||||
|  |                 } else { | ||||||
|  |                     return osmium::io::detail::open_for_reading(filename); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Create new Reader object. | ||||||
|  |              * | ||||||
|  |              * @param file The file we want to open. | ||||||
|  |              * @param read_which_entities Which OSM entities (nodes, ways, relations, and/or changesets) | ||||||
|  |              *                            should be read from the input file. It can speed the read up | ||||||
|  |              *                            significantly if objects that are not needed anyway are not | ||||||
|  |              *                            parsed. | ||||||
|  |              */ | ||||||
|  |             explicit Reader(const osmium::io::File& file, osmium::osm_entity_bits::type read_which_entities = osmium::osm_entity_bits::all) : | ||||||
|  |                 m_file(file), | ||||||
|  |                 m_read_which_entities(read_which_entities), | ||||||
|  |                 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_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)) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             explicit Reader(const std::string& filename, osmium::osm_entity_bits::type read_types = osmium::osm_entity_bits::all) : | ||||||
|  |                 Reader(osmium::io::File(filename), read_types) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             explicit Reader(const char* filename, osmium::osm_entity_bits::type read_types = osmium::osm_entity_bits::all) : | ||||||
|  |                 Reader(osmium::io::File(filename), read_types) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             Reader(const Reader&) = delete; | ||||||
|  |             Reader& operator=(const Reader&) = delete; | ||||||
|  | 
 | ||||||
|  |             ~Reader() { | ||||||
|  |                 close(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Close down the Reader. A call to this is optional, because the | ||||||
|  |              * destructor of Reader will also call this. But if you don't call | ||||||
|  |              * this function first, the destructor might throw an exception | ||||||
|  |              * which is not good. | ||||||
|  |              * | ||||||
|  |              * @throws Some form of std::runtime_error when there is a problem. | ||||||
|  |              */ | ||||||
|  |             void close() { | ||||||
|  |                 // Signal to input child process that it should wrap up.
 | ||||||
|  |                 m_input_done = true; | ||||||
|  | 
 | ||||||
|  |                 m_input->close(); | ||||||
|  | 
 | ||||||
|  |                 if (m_childpid) { | ||||||
|  |                     int status; | ||||||
|  |                     pid_t pid = ::waitpid(m_childpid, &status, 0); | ||||||
|  | #pragma GCC diagnostic push | ||||||
|  | #pragma GCC diagnostic ignored "-Wold-style-cast" | ||||||
|  |                     if (pid < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) { | ||||||
|  |                         throw std::system_error(errno, std::system_category(), "subprocess returned error"); | ||||||
|  |                     } | ||||||
|  | #pragma GCC diagnostic pop | ||||||
|  |                     m_childpid = 0; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 m_read_task.close(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Get the header data from the file. | ||||||
|  |              */ | ||||||
|  |             osmium::io::Header header() const { | ||||||
|  |                 return m_input->header(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Reads the next buffer from the input. An invalid buffer signals | ||||||
|  |              * end-of-file. Do not call read() after the end-of-file. | ||||||
|  |              * | ||||||
|  |              * @returns Buffer. | ||||||
|  |              * @throws Some form of std::runtime_error if there is an error. | ||||||
|  |              */ | ||||||
|  |             osmium::memory::Buffer read() { | ||||||
|  |                 // If an exception happened in the input thread, re-throw
 | ||||||
|  |                 // it in this (the main) thread.
 | ||||||
|  |                 m_read_task.check_for_exception(); | ||||||
|  | 
 | ||||||
|  |                 if (m_read_which_entities == osmium::osm_entity_bits::nothing) { | ||||||
|  |                     // 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(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class Reader
 | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Read contents of the given file into a buffer in one go. Takes | ||||||
|  |          * the same arguments as any of the Reader constructors. | ||||||
|  |          * | ||||||
|  |          * The buffer can take up quite a lot of memory, so don't do this | ||||||
|  |          * unless you are working with small OSM files and/or have lots of | ||||||
|  |          * RAM. | ||||||
|  |          */ | ||||||
|  |         template <class... TArgs> | ||||||
|  |         osmium::memory::Buffer read_file(TArgs&&... args) { | ||||||
|  |             osmium::memory::Buffer buffer(1024*1024, osmium::memory::Buffer::auto_grow::yes); | ||||||
|  | 
 | ||||||
|  |             Reader reader(std::forward<TArgs>(args)...); | ||||||
|  |             while (osmium::memory::Buffer read_buffer = reader.read()) { | ||||||
|  |                 buffer.add_buffer(read_buffer); | ||||||
|  |                 buffer.commit(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return buffer; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_READER_HPP
 | ||||||
							
								
								
									
										51
									
								
								ThirdParty/osmium/io/reader_iterator.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								ThirdParty/osmium/io/reader_iterator.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | |||||||
|  | #ifndef OSMIUM_IO_READER_ITERATOR_HPP | ||||||
|  | #define OSMIUM_IO_READER_ITERATOR_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2014 Jochen Topf <jochen@topf.org> 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 <osmium/io/reader.hpp> | ||||||
|  | #include <osmium/io/input_iterator.hpp> | ||||||
|  | 
 | ||||||
|  | namespace std { | ||||||
|  | 
 | ||||||
|  |     inline osmium::io::InputIterator<osmium::io::Reader> begin(osmium::io::Reader& reader) { | ||||||
|  |         return osmium::io::InputIterator<osmium::io::Reader>(reader); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     inline osmium::io::InputIterator<osmium::io::Reader> end(osmium::io::Reader&) { | ||||||
|  |         return osmium::io::InputIterator<osmium::io::Reader>(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } // namespace std
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_READER_ITERATOR_HPP
 | ||||||
							
								
								
									
										142
									
								
								ThirdParty/osmium/io/writer.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								ThirdParty/osmium/io/writer.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,142 @@ | |||||||
|  | #ifndef OSMIUM_IO_WRITER_HPP | ||||||
|  | #define OSMIUM_IO_WRITER_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <memory> | ||||||
|  | #include <string> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/io/compression.hpp> | ||||||
|  | #include <osmium/io/detail/output_format.hpp> | ||||||
|  | #include <osmium/io/detail/read_write.hpp> | ||||||
|  | #include <osmium/io/detail/write_thread.hpp> | ||||||
|  | #include <osmium/io/file.hpp> | ||||||
|  | #include <osmium/io/header.hpp> | ||||||
|  | #include <osmium/io/overwrite.hpp> | ||||||
|  | #include <osmium/memory/buffer.hpp> | ||||||
|  | #include <osmium/thread/checked_task.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace io { | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * This is the user-facing interface for writing OSM files. Instantiate | ||||||
|  |          * an object of this class with a file name or osmium::io::File object | ||||||
|  |          * and optionally the data for the header and then call operator() on it | ||||||
|  |          * to write Buffers. Call close() to finish up. | ||||||
|  |          */ | ||||||
|  |         class Writer { | ||||||
|  | 
 | ||||||
|  |             osmium::io::File m_file; | ||||||
|  | 
 | ||||||
|  |             std::unique_ptr<osmium::io::detail::OutputFormat> m_output; | ||||||
|  |             osmium::io::detail::data_queue_type m_output_queue {}; | ||||||
|  | 
 | ||||||
|  |             std::unique_ptr<osmium::io::Compressor> m_compressor; | ||||||
|  | 
 | ||||||
|  |             osmium::thread::CheckedTask<detail::WriteThread> m_write_task; | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * The constructor of the Writer object opens a file and writes the | ||||||
|  |              * header to it. | ||||||
|  |              * | ||||||
|  |              * @param file File (contains name and format info) to open. | ||||||
|  |              * @param header Optional header data. If this is not given sensible | ||||||
|  |              *               defaults will be used. See the default constructor | ||||||
|  |              *               of osmium::io::Header for details. | ||||||
|  |              * @param allow_overwrite Allow overwriting of existing file? Can be | ||||||
|  |              *               osmium::io::overwrite::allow or osmium::io::overwrite::no+ | ||||||
|  |              *               (default). | ||||||
|  |              * | ||||||
|  |              * @throws std::runtime_error If the file could not be opened. | ||||||
|  |              * @throws std::system_error If the file could not be opened. | ||||||
|  |              */ | ||||||
|  |             explicit Writer(const osmium::io::File& file, const osmium::io::Header& header = osmium::io::Header(), overwrite allow_overwrite = overwrite::no) : | ||||||
|  |                 m_file(file), | ||||||
|  |                 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()) { | ||||||
|  |                 m_output->write_header(header); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             explicit Writer(const std::string& filename, const osmium::io::Header& header = osmium::io::Header(), overwrite allow_overwrite = overwrite::no) : | ||||||
|  |                 Writer(osmium::io::File(filename), header, allow_overwrite) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             explicit Writer(const char* filename, const osmium::io::Header& header = osmium::io::Header(), overwrite allow_overwrite = overwrite::no) : | ||||||
|  |                 Writer(osmium::io::File(filename), header, allow_overwrite) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             Writer(const Writer&) = delete; | ||||||
|  |             Writer& operator=(const Writer&) = delete; | ||||||
|  | 
 | ||||||
|  |             ~Writer() { | ||||||
|  |                 close(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Write contents of a buffer to the output file. | ||||||
|  |              * | ||||||
|  |              * @throws Some form of std::runtime_error when there is a problem. | ||||||
|  |              */ | ||||||
|  |             void operator()(osmium::memory::Buffer&& buffer) { | ||||||
|  |                 m_write_task.check_for_exception(); | ||||||
|  |                 if (buffer.committed() > 0) { | ||||||
|  |                     m_output->write_buffer(std::move(buffer)); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Flush writes to output file and close 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. | ||||||
|  |              * | ||||||
|  |              * @throws Some form of std::runtime_error when there is a problem. | ||||||
|  |              */ | ||||||
|  |             void close() { | ||||||
|  |                 m_output->close(); | ||||||
|  |                 m_write_task.close(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class Writer
 | ||||||
|  | 
 | ||||||
|  |     } // namespace io
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_WRITER_HPP
 | ||||||
							
								
								
									
										39
									
								
								ThirdParty/osmium/io/xml_input.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								ThirdParty/osmium/io/xml_input.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | #ifndef OSMIUM_IO_XML_INPUT_HPP | ||||||
|  | #define OSMIUM_IO_XML_INPUT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <osmium/io/reader.hpp> // IWYU pragma: export
 | ||||||
|  | #include <osmium/io/detail/xml_input_format.hpp> // IWYU pragma: export
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_XML_INPUT_HPP
 | ||||||
							
								
								
									
										39
									
								
								ThirdParty/osmium/io/xml_output.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								ThirdParty/osmium/io/xml_output.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | #ifndef OSMIUM_IO_XML_OUTPUT_HPP | ||||||
|  | #define OSMIUM_IO_XML_OUTPUT_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <osmium/io/writer.hpp> // IWYU pragma: export
 | ||||||
|  | #include <osmium/io/detail/xml_output_format.hpp> // IWYU pragma: export
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_IO_XML_OUTPUT_HPP
 | ||||||
							
								
								
									
										523
									
								
								ThirdParty/osmium/memory/buffer.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										523
									
								
								ThirdParty/osmium/memory/buffer.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,523 @@ | |||||||
|  | #ifndef OSMIUM_MEMORY_BUFFER_HPP | ||||||
|  | #define OSMIUM_MEMORY_BUFFER_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cassert> | ||||||
|  | #include <cstddef> | ||||||
|  | #include <cstring> | ||||||
|  | #include <exception> | ||||||
|  | #include <functional> | ||||||
|  | #include <iterator> | ||||||
|  | #include <stdexcept> | ||||||
|  | #include <utility> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <osmium/memory/item.hpp> | ||||||
|  | #include <osmium/memory/item_iterator.hpp> | ||||||
|  | #include <osmium/osm/entity.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @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. | ||||||
|  |          * | ||||||
|  |          * Data can be added to a buffer piece by piece using reserve_space() and | ||||||
|  |          * add_item(). After all data that together forms an item is added, it must | ||||||
|  |          * be committed using the commit() call. Usually this is done through the | ||||||
|  |          * Builder class and its derived classes. | ||||||
|  |          * | ||||||
|  |          * You can iterate over all items in a buffer using the iterators returned | ||||||
|  |          * by begin(), end(), cbegin(), and cend(). | ||||||
|  |          * | ||||||
|  |          * Buffers exist in two flavours, those with external memory management and | ||||||
|  |          * those with internal memory management. If you already have some memory | ||||||
|  |          * with data in it (for instance read from disk), you create a Buffer with | ||||||
|  |          * external memory managment. It is your job then to free the memory once | ||||||
|  |          * the buffer isn't used any more. If you don't have memory already, you can | ||||||
|  |          * 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. | ||||||
|  |          * You can use the set_full_callback() method to set a callback functor | ||||||
|  |          * which will be called instead of throwing an exception. | ||||||
|  |          */ | ||||||
|  |         class Buffer { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             enum class auto_grow : bool { | ||||||
|  |                 yes = true, | ||||||
|  |                 no  = false | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |         private: | ||||||
|  | 
 | ||||||
|  |             std::vector<unsigned char> m_memory; | ||||||
|  |             unsigned char* m_data; | ||||||
|  |             size_t m_capacity; | ||||||
|  |             size_t m_written; | ||||||
|  |             size_t m_committed; | ||||||
|  |             auto_grow m_auto_grow {auto_grow::no}; | ||||||
|  |             std::function<void(Buffer&)> m_full {}; | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             typedef Item value_type; | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * The constructor without any parameters creates a non-initialized | ||||||
|  |              * 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() : | ||||||
|  |                 m_memory(), | ||||||
|  |                 m_data(nullptr), | ||||||
|  |                 m_capacity(0), | ||||||
|  |                 m_written(0), | ||||||
|  |                 m_committed(0) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Constructs an externally memory-managed buffer using the given | ||||||
|  |              * memory and size. | ||||||
|  |              * | ||||||
|  |              * @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. | ||||||
|  |              */ | ||||||
|  |             explicit Buffer(unsigned char* data, size_t size) : | ||||||
|  |                 m_memory(), | ||||||
|  |                 m_data(data), | ||||||
|  |                 m_capacity(size), | ||||||
|  |                 m_written(size), | ||||||
|  |                 m_committed(size) { | ||||||
|  |                 if (size % align_bytes != 0) { | ||||||
|  |                     throw std::invalid_argument("buffer size needs to be multiple of alignment"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Constructs an externally memory-managed buffer with the given | ||||||
|  |              * capacity that already contains 'committed' bytes of data. | ||||||
|  |              * | ||||||
|  |              * @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. | ||||||
|  |              */ | ||||||
|  |             explicit Buffer(unsigned char* data, size_t capacity, size_t committed) : | ||||||
|  |                 m_memory(), | ||||||
|  |                 m_data(data), | ||||||
|  |                 m_capacity(capacity), | ||||||
|  |                 m_written(committed), | ||||||
|  |                 m_committed(committed) { | ||||||
|  |                 if (capacity % align_bytes != 0) { | ||||||
|  |                     throw std::invalid_argument("buffer capacity needs to be multiple of alignment"); | ||||||
|  |                 } | ||||||
|  |                 if (committed % align_bytes != 0) { | ||||||
|  |                     throw std::invalid_argument("buffer parameter 'committed' needs to be multiple of alignment"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Create an internally memory-managed buffer with the given capacity. | ||||||
|  |              * different in that it internally gets dynamic memory of the | ||||||
|  |              * required size. The dynamic memory will be automatically | ||||||
|  |              * freed when the Buffer is destroyed. | ||||||
|  |              */ | ||||||
|  |             explicit Buffer(size_t capacity, auto_grow auto_grow = auto_grow::yes) : | ||||||
|  |                 m_memory(capacity), | ||||||
|  |                 m_data(m_memory.data()), | ||||||
|  |                 m_capacity(capacity), | ||||||
|  |                 m_written(0), | ||||||
|  |                 m_committed(0), | ||||||
|  |                 m_auto_grow(auto_grow) { | ||||||
|  |                 if (capacity % align_bytes != 0) { | ||||||
|  |                     throw std::invalid_argument("buffer capacity needs to be multiple of alignment"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // buffers can not be copied
 | ||||||
|  |             Buffer(const Buffer&) = delete; | ||||||
|  |             Buffer& operator=(const Buffer&) = delete; | ||||||
|  | 
 | ||||||
|  |             // buffers can be moved
 | ||||||
|  |             Buffer(Buffer&&) = default; | ||||||
|  |             Buffer& operator=(Buffer&&) = default; | ||||||
|  | 
 | ||||||
|  |             ~Buffer() = default; | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Return a pointer to data inside the buffer. | ||||||
|  |              */ | ||||||
|  |             unsigned char* data() const { | ||||||
|  |                 return m_data; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Returns the capacity of the buffer, ie how many bytes it can contain. | ||||||
|  |              */ | ||||||
|  |             size_t capacity() const { | ||||||
|  |                 return m_capacity; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Returns the number of bytes already filled in this buffer. | ||||||
|  |              */ | ||||||
|  |             size_t committed() const { | ||||||
|  |                 return m_committed; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Returns the number of bytes currently filled in this buffer that | ||||||
|  |              * are not yet committed. | ||||||
|  |              */ | ||||||
|  |             size_t written() const { | ||||||
|  |                 return m_written; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * This tests if the current state of the buffer is aligned | ||||||
|  |              * properly. Can be used for asserts. | ||||||
|  |              */ | ||||||
|  |             bool is_aligned() const { | ||||||
|  |                 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. | ||||||
|  |              */ | ||||||
|  |             void set_full_callback(std::function<void(Buffer&)> full) { | ||||||
|  |                 m_full = full; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Grow capacity of this buffer to the given size. | ||||||
|  |              * This works only with internally memory-managed buffers. | ||||||
|  |              * If the given size is not larger than the current capacity, nothing is done. | ||||||
|  |              * Already written but not committed data is discarded. | ||||||
|  |              * | ||||||
|  |              * @param size New capacity. | ||||||
|  |              */ | ||||||
|  |             void grow(size_t size) { | ||||||
|  |                 if (m_memory.empty()) { | ||||||
|  |                     throw std::logic_error("Can't grow Buffer if it doesn't use internal memory management."); | ||||||
|  |                 } | ||||||
|  |                 if (m_capacity < size) { | ||||||
|  |                     if (size % align_bytes != 0) { | ||||||
|  |                         throw std::invalid_argument("buffer capacity needs to be multiple of alignment"); | ||||||
|  |                     } | ||||||
|  |                     m_memory.resize(size); | ||||||
|  |                     m_data = m_memory.data(); | ||||||
|  |                     m_capacity = size; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Mark currently written bytes in the buffer as committed. | ||||||
|  |              * | ||||||
|  |              * @return Last number of committed bytes before this commit. | ||||||
|  |              */ | ||||||
|  |             size_t commit() { | ||||||
|  |                 assert(is_aligned()); | ||||||
|  | 
 | ||||||
|  |                 const size_t offset = m_committed; | ||||||
|  |                 m_committed = m_written; | ||||||
|  |                 return offset; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Roll back changes in buffer to last committed state. | ||||||
|  |              */ | ||||||
|  |             void rollback() { | ||||||
|  |                 m_written = m_committed; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Clear the buffer. | ||||||
|  |              * | ||||||
|  |              * @return Number of bytes in the buffer before it was cleared. | ||||||
|  |              */ | ||||||
|  |             size_t clear() { | ||||||
|  |                 const size_t committed = m_committed; | ||||||
|  |                 m_written = 0; | ||||||
|  |                 m_committed = 0; | ||||||
|  |                 return committed; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * 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. | ||||||
|  |              */ | ||||||
|  |             template <class T> | ||||||
|  |             T& get(const size_t offset) const { | ||||||
|  |                 return *reinterpret_cast<T*>(&m_data[offset]); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Reserve space of given size in buffer and return pointer to it. | ||||||
|  |              * This is the only way of adding data to the buffer. You reserve | ||||||
|  |              * the space and then fill it. | ||||||
|  |              * | ||||||
|  |              * Note that you have to eventually call commit() to actually | ||||||
|  |              * commit this data. | ||||||
|  |              * | ||||||
|  |              * If there isn't enough space in the buffer, one of three things | ||||||
|  |              * can happen: | ||||||
|  |              * | ||||||
|  |              * * If you have set a callback with set_full_callback(), it is | ||||||
|  |              *   called. After the call returns, you must have either grown | ||||||
|  |              *   the buffer or cleared it by calling buffer.clear(). | ||||||
|  |              * * 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. | ||||||
|  |              * | ||||||
|  |              * @param size Number of bytes to reserve. | ||||||
|  |              * @return 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. | ||||||
|  |              */ | ||||||
|  |             unsigned char* reserve_space(const size_t size) { | ||||||
|  |                 if (m_written + size > m_capacity) { | ||||||
|  |                     if (m_full) { | ||||||
|  |                         m_full(*this); | ||||||
|  |                     } else if (!m_memory.empty() && (m_auto_grow == auto_grow::yes)) { | ||||||
|  |                         // double buffer size until there is enough space
 | ||||||
|  |                         size_t new_capacity = m_capacity * 2; | ||||||
|  |                         while (m_written + size > new_capacity) { | ||||||
|  |                             new_capacity *= 2; | ||||||
|  |                         } | ||||||
|  |                         grow(new_capacity); | ||||||
|  |                     } else { | ||||||
|  |                         throw BufferIsFull(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 unsigned char* data = &m_data[m_written]; | ||||||
|  |                 m_written += size; | ||||||
|  |                 return data; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Add an item to the buffer. The size of the item is stored inside | ||||||
|  |              * the item, so we know how much memory to copy. | ||||||
|  |              * | ||||||
|  |              * Note that you have to eventually call commit() to actually | ||||||
|  |              * commit this data. | ||||||
|  |              * | ||||||
|  |              * @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. | ||||||
|  |              */ | ||||||
|  |             template <class T> | ||||||
|  |             T& add_item(const T& item) { | ||||||
|  |                 unsigned char* ptr = reserve_space(item.padded_size()); | ||||||
|  |                 std::memcpy(ptr, &item, item.padded_size()); | ||||||
|  |                 return *reinterpret_cast<T*>(ptr); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Add committed contents of the given buffer to this buffer. | ||||||
|  |              * | ||||||
|  |              * Note that you have to eventually call commit() to actually | ||||||
|  |              * commit this data. | ||||||
|  |              */ | ||||||
|  |             void add_buffer(const Buffer& buffer) { | ||||||
|  |                 unsigned char* ptr = reserve_space(buffer.committed()); | ||||||
|  |                 std::memcpy(ptr, buffer.data(), buffer.committed()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Add an item to the buffer. This function is provided so that | ||||||
|  |              * you can use std::back_inserter. | ||||||
|  |              */ | ||||||
|  |             void push_back(const osmium::memory::Item& item) { | ||||||
|  |                 add_item(item); | ||||||
|  |                 commit(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * These iterators can be used to iterate over all items in | ||||||
|  |              * a buffer. | ||||||
|  |              */ | ||||||
|  |             template <class T> | ||||||
|  |             using t_iterator = osmium::memory::ItemIterator<T>; | ||||||
|  | 
 | ||||||
|  |             template <class T> | ||||||
|  |             using t_const_iterator = osmium::memory::ItemIterator<const T>; | ||||||
|  | 
 | ||||||
|  |             typedef t_iterator<osmium::OSMEntity> iterator; | ||||||
|  |             typedef t_const_iterator<osmium::OSMEntity> const_iterator; | ||||||
|  | 
 | ||||||
|  |             template <class T> | ||||||
|  |             t_iterator<T> begin() { | ||||||
|  |                 return t_iterator<T>(m_data, m_data + m_committed); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             iterator begin() { | ||||||
|  |                 return iterator(m_data, m_data + m_committed); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <class T> | ||||||
|  |             t_iterator<T> end() { | ||||||
|  |                 return t_iterator<T>(m_data + m_committed, m_data + m_committed); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             iterator end() { | ||||||
|  |                 return iterator(m_data + m_committed, m_data + m_committed); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <class T> | ||||||
|  |             t_const_iterator<T> cbegin() const { | ||||||
|  |                 return t_const_iterator<T>(m_data, m_data + m_committed); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             const_iterator cbegin() const { | ||||||
|  |                 return const_iterator(m_data, m_data + m_committed); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <class T> | ||||||
|  |             t_const_iterator<T> cend() const { | ||||||
|  |                 return t_const_iterator<T>(m_data + m_committed, m_data + m_committed); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             const_iterator cend() const { | ||||||
|  |                 return const_iterator(m_data + m_committed, m_data + m_committed); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <class T> | ||||||
|  |             t_const_iterator<T> begin() const { | ||||||
|  |                 return cbegin<T>(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             const_iterator begin() const { | ||||||
|  |                 return cbegin(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <class T> | ||||||
|  |             t_const_iterator<T> end() const { | ||||||
|  |                 return cend<T>(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             const_iterator end() const { | ||||||
|  |                 return cend(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * In a bool context any initialized buffer is true. | ||||||
|  |              */ | ||||||
|  |             explicit operator bool() const { | ||||||
|  |                 return m_data != nullptr; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             friend void swap(Buffer& lhs, Buffer& rhs) { | ||||||
|  |                 using std::swap; | ||||||
|  | 
 | ||||||
|  |                 swap(lhs.m_memory, rhs.m_memory); | ||||||
|  |                 swap(lhs.m_data, rhs.m_data); | ||||||
|  |                 swap(lhs.m_capacity, rhs.m_capacity); | ||||||
|  |                 swap(lhs.m_written, rhs.m_written); | ||||||
|  |                 swap(lhs.m_committed, rhs.m_committed); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Purge removed items from the buffer. This is done by moving all | ||||||
|  |              * non-removed items forward in the buffer overwriting removed | ||||||
|  |              * items and then correcting the m_written and m_committed numbers. | ||||||
|  |              * | ||||||
|  |              * Note that calling this function invalidates all iterators on this | ||||||
|  |              * buffer and all offsets in this buffer. | ||||||
|  |              * | ||||||
|  |              * For every non-removed item that moves its position, the function | ||||||
|  |              * 'moving_in_buffer' is called on the given callback object with | ||||||
|  |              * the old and new offsets in the buffer where the object used to | ||||||
|  |              * be and is now, respectively. This call can be used to update any | ||||||
|  |              * indexes. | ||||||
|  |              */ | ||||||
|  |             template <class TCallbackClass> | ||||||
|  |             void purge_removed(TCallbackClass* callback) { | ||||||
|  |                 iterator it_write = begin(); | ||||||
|  | 
 | ||||||
|  |                 iterator next; | ||||||
|  |                 for (iterator it_read = begin(); it_read != end(); it_read = next) { | ||||||
|  |                     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<size_t>(it_read->data() - data()); | ||||||
|  |                             size_t new_offset = static_cast<size_t>(it_write->data() - data()); | ||||||
|  |                             callback->moving_in_buffer(old_offset, new_offset); | ||||||
|  |                             std::memmove(it_write->data(), it_read->data(), it_read->padded_size()); | ||||||
|  |                         } | ||||||
|  |                         ++it_write; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 assert(it_write->data() >= data()); | ||||||
|  |                 m_written = static_cast<size_t>(it_write->data() - data()); | ||||||
|  |                 m_committed = m_written; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class Buffer
 | ||||||
|  | 
 | ||||||
|  |         inline bool operator==(const Buffer& lhs, const Buffer& rhs) { | ||||||
|  |             return lhs.data() == rhs.data() && lhs.capacity() == rhs.capacity() && lhs.committed() == rhs.committed(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         inline bool operator!=(const Buffer& lhs, const Buffer& rhs) { | ||||||
|  |             return ! (lhs == rhs); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } // namespace memory
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_MEMORY_BUFFER_HPP
 | ||||||
							
								
								
									
										153
									
								
								ThirdParty/osmium/memory/collection.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								ThirdParty/osmium/memory/collection.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +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 <jochen@topf.org> 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 <iterator> | ||||||
|  | #include <iosfwd> | ||||||
|  | #include <type_traits> | ||||||
|  | 
 | ||||||
|  | #include <osmium/memory/item.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace memory { | ||||||
|  | 
 | ||||||
|  |         template <class TMember> | ||||||
|  |         class CollectionIterator : public std::iterator<std::forward_iterator_tag, TMember> { | ||||||
|  | 
 | ||||||
|  |             // 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<std::is_const<TMember>::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<TMember>& operator++() { | ||||||
|  |                 m_data = reinterpret_cast<TMember*>(m_data)->next(); | ||||||
|  |                 return *static_cast<CollectionIterator<TMember>*>(this); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             CollectionIterator<TMember> operator++(int) { | ||||||
|  |                 CollectionIterator<TMember> tmp(*this); | ||||||
|  |                 operator++(); | ||||||
|  |                 return tmp; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool operator==(const CollectionIterator<TMember>& rhs) const { | ||||||
|  |                 return m_data == rhs.m_data; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool operator!=(const CollectionIterator<TMember>& rhs) const { | ||||||
|  |                 return m_data != rhs.m_data; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             unsigned char* data() const { | ||||||
|  |                 return m_data; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             TMember& operator*() const { | ||||||
|  |                 return *reinterpret_cast<TMember*>(m_data); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             TMember* operator->() const { | ||||||
|  |                 return reinterpret_cast<TMember*>(m_data); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <typename TChar, typename TTraits> | ||||||
|  |             friend std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const CollectionIterator<TMember>& iter) { | ||||||
|  |                 return out << static_cast<void*>(iter.m_data); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class CollectionIterator
 | ||||||
|  | 
 | ||||||
|  |         template <class TMember, osmium::item_type TCollectionItemType> | ||||||
|  |         class Collection : public Item { | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             typedef CollectionIterator<TMember> iterator; | ||||||
|  |             typedef CollectionIterator<const TMember> const_iterator; | ||||||
|  |             typedef TMember value_type; | ||||||
|  | 
 | ||||||
|  |             static constexpr osmium::item_type itemtype = TCollectionItemType; | ||||||
|  | 
 | ||||||
|  |             Collection() : | ||||||
|  |                 Item(sizeof(Collection<TMember, TCollectionItemType>), TCollectionItemType) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool empty() const { | ||||||
|  |                 return sizeof(Collection<TMember, TCollectionItemType>) == byte_size(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             iterator begin() { | ||||||
|  |                 return iterator(data() + sizeof(Collection<TMember, TCollectionItemType>)); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             iterator end() { | ||||||
|  |                 return iterator(data() + byte_size()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             const_iterator cbegin() const { | ||||||
|  |                 return const_iterator(data() + sizeof(Collection<TMember, TCollectionItemType>)); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             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
 | ||||||
							
								
								
									
										178
									
								
								ThirdParty/osmium/memory/item.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								ThirdParty/osmium/memory/item.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,178 @@ | |||||||
|  | #ifndef OSMIUM_MEMORY_ITEM_HPP | ||||||
|  | #define OSMIUM_MEMORY_ITEM_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cstddef> | ||||||
|  | #include <cstdint> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     // forward declaration, see osmium/osm/item_type.hpp for declaration
 | ||||||
|  |     enum class item_type : uint16_t; | ||||||
|  | 
 | ||||||
|  |     namespace builder { | ||||||
|  |         class Builder; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     namespace memory { | ||||||
|  | 
 | ||||||
|  |         typedef uint32_t item_size_type; | ||||||
|  | 
 | ||||||
|  |         // align datastructures to this many bytes
 | ||||||
|  |         constexpr item_size_type align_bytes = 8; | ||||||
|  | 
 | ||||||
|  |         inline size_t padded_length(size_t length) { | ||||||
|  |             return (length + align_bytes - 1) & ~(align_bytes - 1); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         inline item_size_type padded_length(item_size_type length) { | ||||||
|  |             return (length + align_bytes - 1) & ~(align_bytes - 1); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * @brief Namespace for Osmium internal use | ||||||
|  |          */ | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |             * This class contains only a helper method used in several | ||||||
|  |             * other classes. | ||||||
|  |             */ | ||||||
|  |             class ItemHelper { | ||||||
|  | 
 | ||||||
|  |             protected: | ||||||
|  | 
 | ||||||
|  |                 ItemHelper() = default; | ||||||
|  | 
 | ||||||
|  |                 ~ItemHelper() = default; | ||||||
|  | 
 | ||||||
|  |                 ItemHelper(const ItemHelper&) = default; | ||||||
|  |                 ItemHelper(ItemHelper&&) = default; | ||||||
|  | 
 | ||||||
|  |                 ItemHelper& operator=(const ItemHelper&) = default; | ||||||
|  |                 ItemHelper& operator=(ItemHelper&&) = default; | ||||||
|  | 
 | ||||||
|  |             public: | ||||||
|  | 
 | ||||||
|  |                 unsigned char* data() { | ||||||
|  |                     return reinterpret_cast<unsigned char*>(this); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 const unsigned char* data() const { | ||||||
|  |                     return reinterpret_cast<const unsigned char*>(this); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |         } // namespace detail
 | ||||||
|  | 
 | ||||||
|  |         class Item : public osmium::memory::detail::ItemHelper { | ||||||
|  | 
 | ||||||
|  |             item_size_type m_size; | ||||||
|  |             item_type m_type; | ||||||
|  |             bool m_removed : 1; | ||||||
|  |             int m_padding : 15; | ||||||
|  | 
 | ||||||
|  |             template <class TMember> | ||||||
|  |             friend class CollectionIterator; | ||||||
|  | 
 | ||||||
|  |             template <class TMember> | ||||||
|  |             friend class ItemIterator; | ||||||
|  | 
 | ||||||
|  |             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) { | ||||||
|  |                 m_size += size; | ||||||
|  |                 return *this; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         protected: | ||||||
|  | 
 | ||||||
|  |             explicit Item(item_size_type size=0, item_type type=item_type()) : | ||||||
|  |                 m_size(size), | ||||||
|  |                 m_type(type), | ||||||
|  |                 m_removed(false) { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             Item(const Item&) = delete; | ||||||
|  |             Item(Item&&) = delete; | ||||||
|  | 
 | ||||||
|  |             Item& operator=(const Item&) = delete; | ||||||
|  |             Item& operator=(Item&&) = delete; | ||||||
|  | 
 | ||||||
|  |             Item& type(const item_type item_type) { | ||||||
|  |                 m_type = item_type; | ||||||
|  |                 return *this; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         public: | ||||||
|  | 
 | ||||||
|  |             item_size_type byte_size() const { | ||||||
|  |                 return m_size; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             item_size_type padded_size() const { | ||||||
|  |                 return padded_length(m_size); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             item_type type() const { | ||||||
|  |                 return m_type; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool removed() const { | ||||||
|  |                 return m_removed; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             void removed(bool removed) { | ||||||
|  |                 m_removed = removed; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class Item
 | ||||||
|  | 
 | ||||||
|  |         static_assert(sizeof(Item) == 8, "Class osmium::Item has wrong size!"); | ||||||
|  |         static_assert(sizeof(Item) % align_bytes == 0, "Class osmium::Item has wrong size to be aligned properly!"); | ||||||
|  | 
 | ||||||
|  |     } // namespace memory
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_MEMORY_ITEM_HPP
 | ||||||
							
								
								
									
										181
									
								
								ThirdParty/osmium/memory/item_iterator.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								ThirdParty/osmium/memory/item_iterator.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,181 @@ | |||||||
|  | #ifndef OSMIUM_ITEM_ITERATOR_HPP | ||||||
|  | #define OSMIUM_ITEM_ITERATOR_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2014 Jochen Topf <jochen@topf.org> 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 <cassert> | ||||||
|  | #include <iterator> | ||||||
|  | #include <iosfwd> | ||||||
|  | #include <type_traits> | ||||||
|  | 
 | ||||||
|  | #include <osmium/memory/item.hpp> | ||||||
|  | #include <osmium/osm.hpp> | ||||||
|  | #include <osmium/osm/item_type.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace memory { | ||||||
|  | 
 | ||||||
|  |         namespace detail { | ||||||
|  | 
 | ||||||
|  |             template <class T> | ||||||
|  |             inline bool type_is_compatible(osmium::item_type) { | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <> | ||||||
|  |             inline bool type_is_compatible<osmium::Node>(osmium::item_type t) { | ||||||
|  |                 return t == osmium::item_type::node; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <> | ||||||
|  |             inline bool type_is_compatible<osmium::Way>(osmium::item_type t) { | ||||||
|  |                 return t == osmium::item_type::way; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <> | ||||||
|  |             inline bool type_is_compatible<osmium::Relation>(osmium::item_type t) { | ||||||
|  |                 return t == osmium::item_type::relation; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <> | ||||||
|  |             inline bool type_is_compatible<osmium::Area>(osmium::item_type t) { | ||||||
|  |                 return t == osmium::item_type::area; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <> | ||||||
|  |             inline bool type_is_compatible<osmium::Changeset>(osmium::item_type t) { | ||||||
|  |                 return t == osmium::item_type::changeset; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <> | ||||||
|  |             inline bool type_is_compatible<osmium::OSMObject>(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::OSMEntity>(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 TMember> | ||||||
|  |         class ItemIterator : public std::iterator<std::forward_iterator_tag, TMember> { | ||||||
|  | 
 | ||||||
|  |             static_assert(std::is_base_of<osmium::memory::Item, TMember>::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<std::is_const<TMember>::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<typename std::remove_const<TMember>::type>(reinterpret_cast<const osmium::memory::Item*>(m_data)->type())) { | ||||||
|  |                     m_data = reinterpret_cast<TMember*>(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<TMember>& operator++() { | ||||||
|  |                 assert(m_data); | ||||||
|  |                 assert(m_data != m_end); | ||||||
|  |                 m_data = reinterpret_cast<TMember*>(m_data)->next(); | ||||||
|  |                 advance_to_next_item_of_right_type(); | ||||||
|  |                 return *static_cast<ItemIterator<TMember>*>(this); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             ItemIterator<TMember> operator++(int) { | ||||||
|  |                 ItemIterator<TMember> tmp(*this); | ||||||
|  |                 operator++(); | ||||||
|  |                 return tmp; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool operator==(const ItemIterator<TMember>& rhs) const { | ||||||
|  |                 return m_data == rhs.m_data && m_end == rhs.m_end; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool operator!=(const ItemIterator<TMember>& 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<TMember*>(m_data); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             TMember* operator->() const { | ||||||
|  |                 assert(m_data); | ||||||
|  |                 assert(m_data != m_end); | ||||||
|  |                 return reinterpret_cast<TMember*>(m_data); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             explicit operator bool() const { | ||||||
|  |                 return m_data != nullptr; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             template <typename TChar, typename TTraits> | ||||||
|  |             friend std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const ItemIterator<TMember>& iter) { | ||||||
|  |                 return out << static_cast<void*>(iter.m_data); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         }; // class ItemIterator
 | ||||||
|  | 
 | ||||||
|  |     } // namespace memory
 | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_ITEM_ITERATOR_HPP
 | ||||||
							
								
								
									
										112
									
								
								ThirdParty/osmium/object_pointer_collection.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								ThirdParty/osmium/object_pointer_collection.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +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 <jochen@topf.org> 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 <algorithm> | ||||||
|  | #include <utility> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | #include <boost/iterator/indirect_iterator.hpp> | ||||||
|  | 
 | ||||||
|  | #include <osmium/handler.hpp> | ||||||
|  | #include <osmium/memory/item.hpp> | ||||||
|  | #include <osmium/osm/object.hpp> | ||||||
|  | 
 | ||||||
|  | // 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<osmium::OSMObject*> m_objects; | ||||||
|  | 
 | ||||||
|  |     public: | ||||||
|  | 
 | ||||||
|  |         typedef boost::indirect_iterator<std::vector<osmium::OSMObject*>::iterator, osmium::OSMObject> iterator; | ||||||
|  |         typedef boost::indirect_iterator<std::vector<osmium::OSMObject*>::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 <class TCompare> | ||||||
|  |         void sort(TCompare&& compare) { | ||||||
|  |             std::sort(m_objects.begin(), m_objects.end(), std::forward<TCompare>(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
 | ||||||
							
								
								
									
										48
									
								
								ThirdParty/osmium/osm.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								ThirdParty/osmium/osm.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | #ifndef OSMIUM_OSM_HPP | ||||||
|  | #define OSMIUM_OSM_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <osmium/osm/node.hpp> // IWYU pragma: export
 | ||||||
|  | #include <osmium/osm/way.hpp> // IWYU pragma: export
 | ||||||
|  | #include <osmium/osm/relation.hpp> // IWYU pragma: export
 | ||||||
|  | #include <osmium/osm/area.hpp> // IWYU pragma: export
 | ||||||
|  | #include <osmium/osm/changeset.hpp> // IWYU pragma: export
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Namespace for everything in the Osmium library. | ||||||
|  |  */ | ||||||
|  | namespace osmium { | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_OSM_HPP
 | ||||||
							
								
								
									
										172
									
								
								ThirdParty/osmium/osm/area.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								ThirdParty/osmium/osm/area.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,172 @@ | |||||||
|  | #ifndef OSMIUM_OSM_AREA_HPP | ||||||
|  | #define OSMIUM_OSM_AREA_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cstdlib> | ||||||
|  | #include <utility> | ||||||
|  | 
 | ||||||
|  | #include <osmium/memory/collection.hpp> | ||||||
|  | #include <osmium/memory/item.hpp> | ||||||
|  | #include <osmium/osm/item_type.hpp> | ||||||
|  | #include <osmium/osm/object.hpp> | ||||||
|  | #include <osmium/osm/types.hpp> | ||||||
|  | #include <osmium/osm/node_ref_list.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace builder { | ||||||
|  |         template <class T> class ObjectBuilder; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * An outer ring of an Area. | ||||||
|  |      */ | ||||||
|  |     class OuterRing : public NodeRefList<osmium::item_type::outer_ring> { | ||||||
|  | 
 | ||||||
|  |     public: | ||||||
|  | 
 | ||||||
|  |         OuterRing(): | ||||||
|  |             NodeRefList<osmium::item_type::outer_ring>() { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     }; // class OuterRing
 | ||||||
|  | 
 | ||||||
|  |     static_assert(sizeof(OuterRing) % osmium::memory::align_bytes == 0, "Class osmium::OuterRing has wrong size to be aligned properly!"); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * An inner ring of an Area. | ||||||
|  |      */ | ||||||
|  |     class InnerRing : public NodeRefList<osmium::item_type::inner_ring> { | ||||||
|  | 
 | ||||||
|  |     public: | ||||||
|  | 
 | ||||||
|  |         InnerRing(): | ||||||
|  |             NodeRefList<osmium::item_type::inner_ring>() { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     }; // class InnerRing
 | ||||||
|  | 
 | ||||||
|  |     static_assert(sizeof(InnerRing) % osmium::memory::align_bytes == 0, "Class osmium::InnerRing has wrong size to be aligned properly!"); | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Convert way or (multipolygon) relation id into unique area id. | ||||||
|  |      * | ||||||
|  |      * @param id Id of a way or relation | ||||||
|  |      * @param type Type of object (way or relation) | ||||||
|  |      * @returns Area id | ||||||
|  |      */ | ||||||
|  |     inline osmium::object_id_type object_id_to_area_id(osmium::object_id_type id, osmium::item_type type) { | ||||||
|  |         osmium::object_id_type area_id = std::abs(id) * 2; | ||||||
|  |         if (type == osmium::item_type::relation) { | ||||||
|  |             ++area_id; | ||||||
|  |         } | ||||||
|  |         return id < 0 ? -area_id : area_id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Convert area id into id of the way or relation it was created from. | ||||||
|  |      * | ||||||
|  |      * @param id Area id | ||||||
|  |      * @returns Way or Relation id. | ||||||
|  |      */ | ||||||
|  |     inline osmium::object_id_type area_id_to_object_id(osmium::object_id_type id) { | ||||||
|  |         return id / 2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * An OSM area created out of a closed way or a multipolygon relation. | ||||||
|  |      */ | ||||||
|  |     class Area : public OSMObject { | ||||||
|  | 
 | ||||||
|  |         friend class osmium::builder::ObjectBuilder<osmium::Area>; | ||||||
|  | 
 | ||||||
|  |         Area() : | ||||||
|  |             OSMObject(sizeof(Area), osmium::item_type::area) { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     public: | ||||||
|  | 
 | ||||||
|  |         static constexpr osmium::item_type itemtype = osmium::item_type::area; | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Was this area created from a way? (In contrast to areas | ||||||
|  |          * created from a relation and their members.) | ||||||
|  |          */ | ||||||
|  |         bool from_way() const { | ||||||
|  |             return (positive_id() & 0x1) == 0; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Return the Id of the way or relation this area was created from. | ||||||
|  |          */ | ||||||
|  |         osmium::object_id_type orig_id() const { | ||||||
|  |             return osmium::area_id_to_object_id(id()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Count the number of outer and inner rings of this area. | ||||||
|  |          */ | ||||||
|  |         std::pair<int, int> num_rings() const { | ||||||
|  |             std::pair<int, int> counter; | ||||||
|  | 
 | ||||||
|  |             for (auto it = cbegin(); it != cend(); ++it) { | ||||||
|  |                 switch (it->type()) { | ||||||
|  |                     case osmium::item_type::outer_ring: | ||||||
|  |                         ++counter.first; | ||||||
|  |                         break; | ||||||
|  |                     case osmium::item_type::inner_ring: | ||||||
|  |                         ++counter.second; | ||||||
|  |                         break; | ||||||
|  |                     default: | ||||||
|  |                         break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return counter; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Is this area a multipolygon, ie. has it more than one outer ring? | ||||||
|  |          */ | ||||||
|  |         bool is_multipolygon() const { | ||||||
|  |             return num_rings().first > 1; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     }; // class Area
 | ||||||
|  | 
 | ||||||
|  |     static_assert(sizeof(Area) % osmium::memory::align_bytes == 0, "Class osmium::Area has wrong size to be aligned properly!"); | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_OSM_AREA_HPP
 | ||||||
							
								
								
									
										206
									
								
								ThirdParty/osmium/osm/box.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								ThirdParty/osmium/osm/box.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,206 @@ | |||||||
|  | #ifndef OSMIUM_OSM_BOX_HPP | ||||||
|  | #define OSMIUM_OSM_BOX_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <iosfwd> | ||||||
|  | 
 | ||||||
|  | #include <osmium/osm/location.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Bounding box. | ||||||
|  |      */ | ||||||
|  |     class Box { | ||||||
|  | 
 | ||||||
|  |         osmium::Location m_bottom_left; | ||||||
|  |         osmium::Location m_top_right; | ||||||
|  | 
 | ||||||
|  |     public: | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Create undefined Box. Use the extend() function | ||||||
|  |          * to add actual bounds. | ||||||
|  |          */ | ||||||
|  |         constexpr Box() : | ||||||
|  |             m_bottom_left(), | ||||||
|  |             m_top_right() { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Box(double minx, double miny, double maxx, double maxy) : | ||||||
|  |             m_bottom_left(minx, miny), | ||||||
|  |             m_top_right(maxx, maxy) { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Box(const osmium::Location& bottom_left, const osmium::Location& top_right) : | ||||||
|  |             m_bottom_left(bottom_left), | ||||||
|  |             m_top_right(top_right) { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Box(const Box&) = default; | ||||||
|  |         Box(Box&&) = default; | ||||||
|  |         Box& operator=(const Box&) = default; | ||||||
|  |         Box& operator=(Box&&) = default; | ||||||
|  |         ~Box() = default; | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Extend this bounding box by the given location. If the | ||||||
|  |          * location is undefined, the bounding box is unchanged. | ||||||
|  |          */ | ||||||
|  |         Box& extend(const Location& location) noexcept { | ||||||
|  |             if (location) { | ||||||
|  |                 if (m_bottom_left) { | ||||||
|  |                     if (location.x() < m_bottom_left.x()) { | ||||||
|  |                         m_bottom_left.x(location.x()); | ||||||
|  |                     } | ||||||
|  |                     if (location.x() > m_top_right.x()) { | ||||||
|  |                         m_top_right.x(location.x()); | ||||||
|  |                     } | ||||||
|  |                     if (location.y() < m_bottom_left.y()) { | ||||||
|  |                         m_bottom_left.y(location.y()); | ||||||
|  |                     } | ||||||
|  |                     if (location.y() > m_top_right.y()) { | ||||||
|  |                         m_top_right.y(location.y()); | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     m_bottom_left = location; | ||||||
|  |                     m_top_right = location; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Extend this bounding box by the given box. If the | ||||||
|  |          * box is undefined, the bounding box is unchanged. | ||||||
|  |          */ | ||||||
|  |         Box& extend(const Box& box) noexcept { | ||||||
|  |             extend(box.bottom_left()); | ||||||
|  |             extend(box.top_right()); | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Box are defined, ie. contains defined coordinates. | ||||||
|  |          */ | ||||||
|  |         explicit constexpr operator bool() const noexcept { | ||||||
|  |             return static_cast<bool>(m_bottom_left); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Box are valid, ie. defined and inside usual bounds | ||||||
|  |          * (-180<=lon<=180, -90<=lat<=90). | ||||||
|  |          */ | ||||||
|  |         constexpr bool valid() const noexcept { | ||||||
|  |             return bottom_left().valid() && top_right().valid(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Bottom-left location. | ||||||
|  |          */ | ||||||
|  |         constexpr Location bottom_left() const noexcept { | ||||||
|  |             return m_bottom_left; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Bottom-left location. | ||||||
|  |          */ | ||||||
|  |         Location& bottom_left() noexcept { | ||||||
|  |             return m_bottom_left; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Top-right location. | ||||||
|  |          */ | ||||||
|  |         constexpr Location top_right() const noexcept { | ||||||
|  |             return m_top_right; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Top-right location. | ||||||
|  |          */ | ||||||
|  |         Location& top_right() noexcept { | ||||||
|  |             return m_top_right; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Is the location inside the box? | ||||||
|  |          */ | ||||||
|  |         bool contains(const osmium::Location& location) const { | ||||||
|  |             return location.x() >= bottom_left().x() && location.y() >= bottom_left().y() && | ||||||
|  |                    location.x() <= top_right().x() && location.y() <= top_right().y(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Calculate size of the box in square degrees. | ||||||
|  |          * | ||||||
|  |          * @throws osmium::invalid_location unless all coordinates are valid | ||||||
|  |          */ | ||||||
|  |         double size() const { | ||||||
|  |             return (m_top_right.lon() - m_bottom_left.lon()) * | ||||||
|  |                    (m_top_right.lat() - m_bottom_left.lat()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     }; // class Box
 | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Boxes are equal if both locations are equal. | ||||||
|  |      */ | ||||||
|  |     inline constexpr bool operator==(const Box& lhs, const Box& rhs) noexcept { | ||||||
|  |         return lhs.bottom_left() == rhs.bottom_left() && lhs.top_right() == rhs.top_right(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Output a box to a stream. | ||||||
|  |      */ | ||||||
|  |     template <typename TChar, typename TTraits> | ||||||
|  |     inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const osmium::Box& box) { | ||||||
|  |         if (box) { | ||||||
|  |             out << '(' | ||||||
|  |                 << box.bottom_left().lon() | ||||||
|  |                 << ',' | ||||||
|  |                 << box.bottom_left().lat() | ||||||
|  |                 << ',' | ||||||
|  |                 << box.top_right().lon() | ||||||
|  |                 << ',' | ||||||
|  |                 << box.top_right().lat() | ||||||
|  |                 << ')'; | ||||||
|  |         } else { | ||||||
|  |             out << "(undefined)"; | ||||||
|  |         } | ||||||
|  |         return out; | ||||||
|  |     } | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_OSM_BOX_HPP
 | ||||||
							
								
								
									
										325
									
								
								ThirdParty/osmium/osm/changeset.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										325
									
								
								ThirdParty/osmium/osm/changeset.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,325 @@ | |||||||
|  | #ifndef OSMIUM_OSM_CHANGESET_HPP | ||||||
|  | #define OSMIUM_OSM_CHANGESET_HPP | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 
 | ||||||
|  | This file is part of Osmium (http://osmcode.org/libosmium).
 | ||||||
|  | 
 | ||||||
|  | Copyright 2013,2014 Jochen Topf <jochen@topf.org> 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 <cstdint> | ||||||
|  | #include <cstring> | ||||||
|  | 
 | ||||||
|  | #include <osmium/memory/collection.hpp> | ||||||
|  | #include <osmium/memory/item.hpp> | ||||||
|  | #include <osmium/osm/box.hpp> | ||||||
|  | #include <osmium/osm/entity.hpp> | ||||||
|  | #include <osmium/osm/item_type.hpp> | ||||||
|  | #include <osmium/osm/tag.hpp> | ||||||
|  | #include <osmium/osm/timestamp.hpp> | ||||||
|  | #include <osmium/osm/types.hpp> | ||||||
|  | #include <osmium/util/operators.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osmium { | ||||||
|  | 
 | ||||||
|  |     namespace builder { | ||||||
|  |         template <class T> class ObjectBuilder; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * An OSM Changeset is of a group of changes made by a single user over a | ||||||
|  |      * short period of time. | ||||||
|  |      */ | ||||||
|  |     class Changeset : public osmium::OSMEntity, osmium::totally_ordered<Changeset> { | ||||||
|  | 
 | ||||||
|  |         friend class osmium::builder::ObjectBuilder<osmium::Changeset>; | ||||||
|  | 
 | ||||||
|  |         osmium::Timestamp m_created_at {}; | ||||||
|  |         osmium::Timestamp m_closed_at {}; | ||||||
|  |         osmium::Box       m_bounds {}; | ||||||
|  |         changeset_id_type m_id {0}; | ||||||
|  |         num_changes_type  m_num_changes {0}; | ||||||
|  |         user_id_type      m_uid {0}; | ||||||
|  |         string_size_type  m_user_size; | ||||||
|  | 
 | ||||||
|  |         Changeset() : | ||||||
|  |             OSMEntity(sizeof(Changeset), osmium::item_type::changeset) { | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         void user_size(string_size_type size) { | ||||||
|  |             m_user_size = size; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         unsigned char* subitems_position() { | ||||||
|  |             return data() + osmium::memory::padded_length(sizeof(Changeset) + m_user_size); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const unsigned char* subitems_position() const { | ||||||
|  |             return data() + osmium::memory::padded_length(sizeof(Changeset) + m_user_size); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         template <class T> | ||||||
|  |         T& subitem_of_type() { | ||||||
|  |             for (iterator it = begin(); it != end(); ++it) { | ||||||
|  |                 if (it->type() == T::itemtype) { | ||||||
|  |                     return reinterpret_cast<T&>(*it); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             static T subitem; | ||||||
|  |             return subitem; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         template <class T> | ||||||
|  |         const T& subitem_of_type() const { | ||||||
|  |             for (const_iterator it = cbegin(); it != cend(); ++it) { | ||||||
|  |                 if (it->type() == T::itemtype) { | ||||||
|  |                     return reinterpret_cast<const T&>(*it); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             static const T subitem; | ||||||
|  |             return subitem; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     public: | ||||||
|  | 
 | ||||||
|  |         /// Get ID of this changeset
 | ||||||
|  |         changeset_id_type id() const noexcept { | ||||||
|  |             return m_id; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Set ID of this changeset | ||||||
|  |          * | ||||||
|  |          * @return Reference to changeset to make calls chainable. | ||||||
|  |          */ | ||||||
|  |         Changeset& id(changeset_id_type id) noexcept { | ||||||
|  |             m_id = id; | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Set ID of this changeset. | ||||||
|  |          * | ||||||
|  |          * @return Reference to object to make calls chainable. | ||||||
|  |          */ | ||||||
|  |         Changeset& id(const char* id) { | ||||||
|  |             return this->id(osmium::string_to_changeset_id(id)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /// Get user id.
 | ||||||
|  |         user_id_type uid() const noexcept { | ||||||
|  |             return m_uid; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Set user id. | ||||||
|  |          * | ||||||
|  |          * @return Reference to changeset to make calls chainable. | ||||||
|  |          */ | ||||||
|  |         Changeset& 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. | ||||||
|  |          * | ||||||
|  |          * @return Reference to changeset to make calls chainable. | ||||||
|  |          */ | ||||||
|  |         Changeset& uid_from_signed(signed_user_id_type uid) noexcept { | ||||||
|  |             m_uid = uid < 0 ? 0 : static_cast<user_id_type>(uid); | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Set user id. | ||||||
|  |          * | ||||||
|  |          * @return Reference to changeset to make calls chainable. | ||||||
|  |          */ | ||||||
|  |         Changeset& uid(const char* uid) { | ||||||
|  |             return this->uid_from_signed(string_to_user_id(uid)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /// Is this user anonymous?
 | ||||||
|  |         bool user_is_anonymous() const noexcept { | ||||||
|  |             return m_uid == 0; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /// Get timestamp when this changeset was created.
 | ||||||
|  |         osmium::Timestamp created_at() const noexcept { | ||||||
|  |             return m_created_at; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Get timestamp when this changeset was closed. | ||||||
|  |          * | ||||||
|  |          * This will return the empty Timestamp when the | ||||||
|  |          * changeset is not yet closed. | ||||||
|  |          */ | ||||||
|  |         osmium::Timestamp closed_at() const noexcept { | ||||||
|  |             return m_closed_at; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         bool open() const noexcept { | ||||||
|  |             return m_closed_at == osmium::Timestamp(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         bool closed() const noexcept { | ||||||
|  |             return !open(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Set the timestamp when this changeset was created. | ||||||
|  |          * | ||||||
|  |          * @param timestamp Timestamp | ||||||
|  |          * @return Reference to changeset to make calls chainable. | ||||||
|  |          */ | ||||||
|  |         Changeset& created_at(const osmium::Timestamp timestamp) { | ||||||
|  |             m_created_at = timestamp; | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Set the timestamp when this changeset was closed. | ||||||
|  |          * | ||||||
|  |          * @param timestamp Timestamp | ||||||
|  |          * @return Reference to changeset to make calls chainable. | ||||||
|  |          */ | ||||||
|  |         Changeset& closed_at(const osmium::Timestamp timestamp) { | ||||||
|  |             m_closed_at = timestamp; | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         num_changes_type num_changes() const noexcept { | ||||||
|  |             return m_num_changes; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Changeset& 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)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         osmium::Box& bounds() noexcept { | ||||||
|  |             return m_bounds; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const osmium::Box& bounds() const noexcept { | ||||||
|  |             return m_bounds; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /// Get user name.
 | ||||||
|  |         const char* user() const { | ||||||
|  |             return reinterpret_cast<const char*>(data() + sizeof(Changeset)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /// Get the list of tags.
 | ||||||
|  |         TagList& tags() { | ||||||
|  |             return subitem_of_type<TagList>(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /// Get the list of tags.
 | ||||||
|  |         const TagList& tags() const { | ||||||
|  |             return subitem_of_type<const TagList>(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /**
 | ||||||
|  |          * Set named attribute. | ||||||
|  |          * | ||||||
|  |          * @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); | ||||||
|  |             } else if (!strcmp(attr, "num_changes")) { | ||||||
|  |                 num_changes(value); | ||||||
|  |             } else if (!strcmp(attr, "created_at")) { | ||||||
|  |                 created_at(osmium::Timestamp(value)); | ||||||
|  |             } else if (!strcmp(attr, "closed_at")) { | ||||||
|  |                 closed_at(osmium::Timestamp(value)); | ||||||
|  |             } else if (!strcmp(attr, "uid")) { | ||||||
|  |                 uid(value); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         typedef osmium::memory::CollectionIterator<Item> iterator; | ||||||
|  |         typedef osmium::memory::CollectionIterator<const Item> const_iterator; | ||||||
|  | 
 | ||||||
|  |         iterator begin() { | ||||||
|  |             return iterator(subitems_position()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         iterator end() { | ||||||
|  |             return iterator(data() + padded_size()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const_iterator cbegin() const { | ||||||
|  |             return const_iterator(subitems_position()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const_iterator cend() const { | ||||||
|  |             return const_iterator(data() + padded_size()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const_iterator begin() const { | ||||||
|  |             return cbegin(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const_iterator end() const { | ||||||
|  |             return cend(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     }; // class Changeset
 | ||||||
|  | 
 | ||||||
|  |     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. | ||||||
|  |      */ | ||||||
|  |     inline bool operator==(const Changeset& lhs, const Changeset& rhs) { | ||||||
|  |         return lhs.id() == rhs.id(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Changesets can be ordered by id. | ||||||
|  |      */ | ||||||
|  |     inline bool operator<(const Changeset& lhs, const Changeset& rhs) { | ||||||
|  |         return lhs.id() < rhs.id(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_OSM_CHANGESET_HPP
 | ||||||
							
								
								
									
										156
									
								
								ThirdParty/osmium/osm/diff_object.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								ThirdParty/osmium/osm/diff_object.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +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 <jochen@topf.org> 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 <osmium/osm/item_type.hpp> | ||||||
|  | #include <osmium/osm/object.hpp> | ||||||
|  | #include <osmium/osm/timestamp.hpp> | ||||||
|  | #include <osmium/osm/types.hpp> | ||||||
|  | 
 | ||||||
|  | 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 T> | ||||||
|  |     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<const T*>(m_prev); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const T& curr() const { | ||||||
|  |             return *static_cast<const T*>(m_curr); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const T& next() const { | ||||||
|  |             return *static_cast<const T*>(m_next); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     }; // class DiffObjectDerived
 | ||||||
|  | 
 | ||||||
|  |     typedef DiffObjectDerived<osmium::Node>     DiffNode; | ||||||
|  |     typedef DiffObjectDerived<osmium::Way>      DiffWay; | ||||||
|  |     typedef DiffObjectDerived<osmium::Relation> DiffRelation; | ||||||
|  | 
 | ||||||
|  | } // namespace osmium
 | ||||||
|  | 
 | ||||||
|  | #endif // OSMIUM_OSM_DIFF_OBJECT_HPP
 | ||||||
							
								
								
									
										55
									
								
								ThirdParty/osmium/osm/entity.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								ThirdParty/osmium/osm/entity.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | |||||||
|  | #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 <jochen@topf.org> 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 <osmium/memory/item.hpp> | ||||||
|  | 
 | ||||||
|  | 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
 | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user