remove copy of libosmium, to be replaced by a subtree
This commit is contained in:
parent
ebbc168f3f
commit
d6946a8aae
783
third_party/osmium/area/assembler.hpp
vendored
783
third_party/osmium/area/assembler.hpp
vendored
@ -1,783 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MPFilter : public osmium::tags::KeyFilter {
|
||||
|
||||
MPFilter() : osmium::tags::KeyFilter(true) {
|
||||
add(false, "type");
|
||||
add(false, "created_by");
|
||||
add(false, "source");
|
||||
add(false, "note");
|
||||
add(false, "test:id");
|
||||
add(false, "test:section");
|
||||
}
|
||||
|
||||
}; // struct MPFilter
|
||||
|
||||
static MPFilter& filter() {
|
||||
static MPFilter filter;
|
||||
return filter;
|
||||
}
|
||||
|
||||
void add_tags_to_area(osmium::builder::AreaBuilder& builder, const osmium::Relation& relation) const {
|
||||
auto count = std::count_if(relation.tags().begin(), relation.tags().end(), filter());
|
||||
|
||||
if (debug()) {
|
||||
std::cerr << " found " << count << " tags on relation (without ignored ones)\n";
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// Find all closed ways that are inner rings and check their
|
||||
// tags. If they are not the same as the tags of the area we
|
||||
// just built, add them to a list and later build areas for
|
||||
// them, too.
|
||||
std::vector<const osmium::Way*> ways_that_should_be_areas;
|
||||
if (m_inner_outer_mismatches == 0) {
|
||||
auto memit = relation.members().begin();
|
||||
for (size_t offset : members) {
|
||||
if (!std::strcmp(memit->role(), "inner")) {
|
||||
const osmium::Way& way = in_buffer.get<const osmium::Way>(offset);
|
||||
if (way.is_closed() && way.tags().size() > 0) {
|
||||
auto d = std::count_if(way.tags().begin(), way.tags().end(), filter());
|
||||
if (d > 0) {
|
||||
osmium::tags::KeyFilter::iterator way_fi_begin(filter(), way.tags().begin(), way.tags().end());
|
||||
osmium::tags::KeyFilter::iterator way_fi_end(filter(), way.tags().end(), way.tags().end());
|
||||
osmium::tags::KeyFilter::iterator area_fi_begin(filter(), area_tags.begin(), area_tags.end());
|
||||
osmium::tags::KeyFilter::iterator area_fi_end(filter(), area_tags.end(), area_tags.end());
|
||||
|
||||
if (!std::equal(way_fi_begin, way_fi_end, area_fi_begin) || d != std::distance(area_fi_begin, area_fi_end)) {
|
||||
ways_that_should_be_areas.push_back(&way);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
++memit;
|
||||
}
|
||||
}
|
||||
|
||||
// Now build areas for all ways found in the last step.
|
||||
for (const osmium::Way* way : ways_that_should_be_areas) {
|
||||
Assembler assembler(m_config);
|
||||
assembler(*way, out_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
}; // class Assembler
|
||||
|
||||
} // namespace area
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_AREA_ASSEMBLER_HPP
|
262
third_party/osmium/area/detail/node_ref_segment.hpp
vendored
262
third_party/osmium/area/detail/node_ref_segment.hpp
vendored
@ -1,262 +0,0 @@
|
||||
#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>
|
||||
|
||||
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::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() noexcept :
|
||||
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 noexcept {
|
||||
return m_first;
|
||||
}
|
||||
|
||||
/// Return second NodeRef of Segment according to sorting order (bottom left to top right).
|
||||
const osmium::NodeRef& second() const noexcept {
|
||||
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 noexcept {
|
||||
return !strcmp(m_role, "outer");
|
||||
}
|
||||
|
||||
bool role_inner() const noexcept {
|
||||
return !strcmp(m_role, "inner");
|
||||
}
|
||||
|
||||
const osmium::Way* way() const noexcept {
|
||||
return m_way;
|
||||
}
|
||||
|
||||
}; // class NodeRefSegment
|
||||
|
||||
/// NodeRefSegments are equal if both their locations are equal
|
||||
inline bool operator==(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept {
|
||||
return lhs.first().location() == rhs.first().location() && lhs.second().location() == rhs.second().location();
|
||||
}
|
||||
|
||||
inline bool operator!=(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept {
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) noexcept {
|
||||
return (lhs.first().location() == rhs.first().location() && lhs.second().location() < rhs.second().location()) || lhs.first().location() < rhs.first().location();
|
||||
}
|
||||
|
||||
inline bool operator>(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept {
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
inline bool operator<=(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept {
|
||||
return ! (rhs < lhs);
|
||||
}
|
||||
|
||||
inline bool operator>=(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept {
|
||||
return ! (lhs < rhs);
|
||||
}
|
||||
|
||||
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) noexcept {
|
||||
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();
|
||||
}
|
||||
|
||||
auto d = (static_cast<int64_t>(s2.second().y()) - static_cast<int64_t>(s2.first().y())) *
|
||||
(static_cast<int64_t>(s1.second().x()) - static_cast<int64_t>(s1.first().x())) -
|
||||
(static_cast<int64_t>(s2.second().x()) - static_cast<int64_t>(s2.first().x())) *
|
||||
(static_cast<int64_t>(s1.second().y()) - static_cast<int64_t>(s1.first().y()));
|
||||
|
||||
if (d != 0) {
|
||||
double denom = ((s2.second().lat() - s2.first().lat())*(s1.second().lon() - s1.first().lon())) -
|
||||
((s2.second().lon() - s2.first().lon())*(s1.second().lat() - s1.first().lat()));
|
||||
|
||||
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
third_party/osmium/area/detail/proto_ring.hpp
vendored
274
third_party/osmium/area/detail/proto_ring.hpp
vendored
@ -1,274 +0,0 @@
|
||||
#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) noexcept :
|
||||
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 noexcept {
|
||||
return m_outer;
|
||||
}
|
||||
|
||||
void set_inner() noexcept {
|
||||
m_outer = false;
|
||||
}
|
||||
|
||||
segments_type& segments() noexcept {
|
||||
return m_segments;
|
||||
}
|
||||
|
||||
const segments_type& segments() const noexcept {
|
||||
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
third_party/osmium/area/detail/segment_list.hpp
vendored
216
third_party/osmium/area/detail/segment_list.hpp
vendored
@ -1,216 +0,0 @@
|
||||
#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) noexcept :
|
||||
m_debug(debug) {
|
||||
}
|
||||
|
||||
~SegmentList() = default;
|
||||
|
||||
SegmentList(const SegmentList&) = delete;
|
||||
SegmentList(SegmentList&&) = delete;
|
||||
|
||||
SegmentList& operator=(const SegmentList&) = delete;
|
||||
SegmentList& operator=(SegmentList&&) = delete;
|
||||
|
||||
/// The number of segments in the list.
|
||||
size_t size() const noexcept {
|
||||
return m_segments.size();
|
||||
}
|
||||
|
||||
bool empty() const noexcept {
|
||||
return m_segments.empty();
|
||||
}
|
||||
|
||||
typedef slist_type::const_iterator const_iterator;
|
||||
|
||||
const_iterator begin() const noexcept {
|
||||
return m_segments.begin();
|
||||
}
|
||||
|
||||
const_iterator end() const noexcept {
|
||||
return m_segments.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable debug output to stderr. This is for Osmium
|
||||
* developers only.
|
||||
*/
|
||||
void enable_debug_output(bool debug=true) noexcept {
|
||||
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
|
212
third_party/osmium/area/multipolygon_collector.hpp
vendored
212
third_party/osmium/area/multipolygon_collector.hpp
vendored
@ -1,212 +0,0 @@
|
||||
#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()) {
|
||||
osmium::memory::Buffer buffer(initial_output_buffer_size);
|
||||
std::swap(buffer, m_output_buffer);
|
||||
this->callback()(std::move(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
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 (osmium::relations::count_not_removed(range.first, range.second) == 1) {
|
||||
this->get_member(range.first->buffer_offset()).set_removed(true);
|
||||
}
|
||||
|
||||
for (auto it = range.first; it != range.second; ++it) {
|
||||
if (!it->removed() && relation.id() == this->get_relation(it->relation_pos()).id()) {
|
||||
it->remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void flush() {
|
||||
flush_output_buffer();
|
||||
}
|
||||
|
||||
osmium::memory::Buffer read() {
|
||||
osmium::memory::Buffer buffer(initial_output_buffer_size, osmium::memory::Buffer::auto_grow::yes);
|
||||
std::swap(buffer, m_output_buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
}; // class MultipolygonCollector
|
||||
|
||||
} // namespace area
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP
|
149
third_party/osmium/area/problem_reporter.hpp
vendored
149
third_party/osmium/area/problem_reporter.hpp
vendored
@ -1,149 +0,0 @@
|
||||
#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) noexcept {
|
||||
m_object_type = object_type;
|
||||
m_object_id = object_id;
|
||||
}
|
||||
|
||||
// Disable "unused-parameter" warning, so that the compiler will not complain.
|
||||
// We can't remove the parameter names, because then doxygen will complain.
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
/**
|
||||
* Report a duplicate node, ie. two nodes with the same location.
|
||||
*
|
||||
* @param node_id1 ID of the first node.
|
||||
* @param node_id2 ID of the second node.
|
||||
* @param location Location of both nodes.
|
||||
*/
|
||||
virtual void report_duplicate_node(osmium::object_id_type node_id1, osmium::object_id_type node_id2, osmium::Location location) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an intersection between two segments.
|
||||
*
|
||||
* @param way1_id ID of the first involved way.
|
||||
* @param way1_seg_start Location where the segment of the first way with the intersection starts
|
||||
* @param way1_seg_end Location where the segment of the first way with the intersection ends
|
||||
* @param way2_id ID of the second involved way.
|
||||
* @param way2_seg_start Location where the segment of the second way with the intersection starts
|
||||
* @param way2_seg_end Location where the segment of the second way with the intersection ends
|
||||
* @param intersection Location of the intersection. This might be slightly off the correct location due to rounding.
|
||||
*/
|
||||
virtual void report_intersection(osmium::object_id_type way1_id, osmium::Location way1_seg_start, osmium::Location way1_seg_end,
|
||||
osmium::object_id_type way2_id, osmium::Location way2_seg_start, osmium::Location way2_seg_end, osmium::Location intersection) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an open ring.
|
||||
*
|
||||
* @param end1 Location of the first open end.
|
||||
* @param end2 Location of the second open end.
|
||||
*/
|
||||
virtual void report_ring_not_closed(osmium::Location end1, osmium::Location end2) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Report a segment that should have role "outer", but has a different role.
|
||||
*
|
||||
* @param way_id ID of the way this segment is in.
|
||||
* @param seg_start Start of the segment with the wrong role.
|
||||
* @param seg_end End of the segment with the wrong role.
|
||||
*/
|
||||
virtual void report_role_should_be_outer(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Report a segment that should have role "inner", but has a different role.
|
||||
*
|
||||
* @param way_id ID of the way this segment is in.
|
||||
* @param seg_start Start of the segment with the wrong role.
|
||||
* @param seg_end End of the segment with the wrong role.
|
||||
*/
|
||||
virtual void report_role_should_be_inner(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) {
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
}; // class ProblemReporter
|
||||
|
||||
} // namespace area
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_AREA_PROBLEM_REPORTER_HPP
|
@ -1,96 +0,0 @@
|
||||
#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
|
206
third_party/osmium/area/problem_reporter_ogr.hpp
vendored
206
third_party/osmium/area/problem_reporter_ogr.hpp
vendored
@ -1,206 +0,0 @@
|
||||
#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
|
||||
#ifdef __clang__
|
||||
# pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
|
||||
#endif
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#pragma GCC diagnostic ignored "-Wpadded"
|
||||
#pragma GCC diagnostic ignored "-Wredundant-decls"
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
# 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
|
@ -1,96 +0,0 @@
|
||||
#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
|
220
third_party/osmium/builder/builder.hpp
vendored
220
third_party/osmium/builder/builder.hpp
vendored
@ -1,220 +0,0 @@
|
||||
#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 <type_traits>
|
||||
|
||||
#include <osmium/memory/buffer.hpp>
|
||||
#include <osmium/memory/item.hpp>
|
||||
#include <osmium/osm/types.hpp>
|
||||
#include <osmium/util/cast.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, osmium::memory::item_size_type size) :
|
||||
m_buffer(buffer),
|
||||
m_parent(parent),
|
||||
m_item_offset(buffer.written()) {
|
||||
m_buffer.reserve_space(size);
|
||||
assert(buffer.is_aligned());
|
||||
if (m_parent) {
|
||||
m_parent->add_size(size);
|
||||
}
|
||||
}
|
||||
|
||||
~Builder() = default;
|
||||
|
||||
osmium::memory::Item& item() const {
|
||||
return *reinterpret_cast<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) {
|
||||
auto padding = osmium::memory::align_bytes - (size() % osmium::memory::align_bytes);
|
||||
if (padding != osmium::memory::align_bytes) {
|
||||
std::memset(m_buffer.reserve_space(padding), 0, padding);
|
||||
if (self) {
|
||||
add_size(padding);
|
||||
} else if (m_parent) {
|
||||
m_parent->add_size(padding);
|
||||
assert(m_parent->size() % osmium::memory::align_bytes == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void add_size(uint32_t size) {
|
||||
item().add_size(size);
|
||||
if (m_parent) {
|
||||
m_parent->add_size(size);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t size() const noexcept {
|
||||
return item().byte_size();
|
||||
}
|
||||
|
||||
void add_item(const osmium::memory::Item* item) {
|
||||
std::memcpy(m_buffer.reserve_space(item->padded_size()), item, item->padded_size());
|
||||
add_size(item->padded_size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reserve space for an object of class T in buffer and return
|
||||
* pointer to it.
|
||||
*/
|
||||
template <class T>
|
||||
T* reserve_space_for() {
|
||||
assert(m_buffer.is_aligned());
|
||||
return reinterpret_cast<T*>(m_buffer.reserve_space(sizeof(T)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Append data to buffer.
|
||||
*
|
||||
* @param data Pointer to data.
|
||||
* @param length Length of data in bytes. If data is a
|
||||
* \0-terminated string, length must contain the
|
||||
* \0 byte.
|
||||
*/
|
||||
osmium::memory::item_size_type append(const char* data, const osmium::memory::item_size_type length) {
|
||||
std::memcpy(m_buffer.reserve_space(length), data, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append \0-terminated string to buffer.
|
||||
*/
|
||||
osmium::memory::item_size_type append(const char* str) {
|
||||
return append(str, static_cast<osmium::memory::item_size_type>(std::strlen(str) + 1));
|
||||
}
|
||||
|
||||
/// Return the buffer this builder is using.
|
||||
osmium::memory::Buffer& buffer() noexcept {
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
}; // class Builder
|
||||
|
||||
template <class TItem>
|
||||
class ObjectBuilder : public Builder {
|
||||
|
||||
static_assert(std::is_base_of<osmium::memory::Item, TItem>::value,
|
||||
"ObjectBuilder can only build objects derived from osmium::memory::Item");
|
||||
|
||||
public:
|
||||
|
||||
explicit ObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) :
|
||||
Builder(buffer, parent, sizeof(TItem)) {
|
||||
new (&item()) TItem();
|
||||
}
|
||||
|
||||
TItem& object() noexcept {
|
||||
return static_cast<TItem&>(item());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add user name to buffer.
|
||||
*
|
||||
* @param user Pointer to user name.
|
||||
* @param length Length of user name including \0 byte.
|
||||
*/
|
||||
void add_user(const char* user, const string_size_type length) {
|
||||
object().set_user_size(length);
|
||||
add_size(append(user, length));
|
||||
add_padding(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add user name to buffer.
|
||||
*
|
||||
* @param user Pointer to \0-terminated user name.
|
||||
*/
|
||||
void add_user(const char* user) {
|
||||
add_user(user, static_cast_with_assert<string_size_type>(std::strlen(user) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add user name to buffer.
|
||||
*
|
||||
* @param user User name.
|
||||
*/
|
||||
void add_user(const std::string& user) {
|
||||
add_user(user.data(), static_cast_with_assert<string_size_type>(user.size() + 1));
|
||||
}
|
||||
|
||||
}; // class ObjectBuilder
|
||||
|
||||
} // namespace builder
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_BUILDER_BUILDER_HPP
|
103
third_party/osmium/builder/builder_helper.hpp
vendored
103
third_party/osmium/builder/builder_helper.hpp
vendored
@ -1,103 +0,0 @@
|
||||
#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, const 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, const 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_from_map(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_from_func(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
|
283
third_party/osmium/builder/osm_object_builder.hpp
vendored
283
third_party/osmium/builder/osm_object_builder.hpp
vendored
@ -1,283 +0,0 @@
|
||||
#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>
|
||||
#include <osmium/util/cast.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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add tag to buffer.
|
||||
*
|
||||
* @param key Tag key.
|
||||
* @param value Tag value.
|
||||
*/
|
||||
void add_tag(const char* key, const char* value) {
|
||||
add_size(append(key) + append(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add tag to buffer.
|
||||
*
|
||||
* @param key Tag key.
|
||||
* @param value Tag value.
|
||||
*/
|
||||
void add_tag(const std::string& key, const std::string& value) {
|
||||
add_size(append(key.data(), static_cast_with_assert<string_size_type>(key.size() + 1)) +
|
||||
append(value.data(), static_cast_with_assert<string_size_type>(value.size() + 1)));
|
||||
}
|
||||
|
||||
}; // 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> {
|
||||
|
||||
/**
|
||||
* Add role to buffer.
|
||||
*
|
||||
* @param member Relation member object where the length of the role
|
||||
* will be set.
|
||||
* @param role The role.
|
||||
* @param length Length of role string including \0 termination.
|
||||
*/
|
||||
void add_role(osmium::RelationMember& member, const char* role, const string_size_type length) {
|
||||
member.set_role_size(length);
|
||||
add_size(append(role, length));
|
||||
add_padding(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add role to buffer.
|
||||
*
|
||||
* @param member Relation member object where the length of the role
|
||||
* will be set.
|
||||
* @param role \0-terminated role.
|
||||
*/
|
||||
void add_role(osmium::RelationMember& member, const char* role) {
|
||||
add_role(member, role, static_cast_with_assert<string_size_type>(std::strlen(role) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add role to buffer.
|
||||
*
|
||||
* @param member Relation member object where the length of the role
|
||||
* will be set.
|
||||
* @param role Role.
|
||||
*/
|
||||
void add_role(osmium::RelationMember& member, const std::string& role) {
|
||||
add_role(member, role.data(), static_cast_with_assert<string_size_type>(role.size() + 1));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
explicit RelationMemberListBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) :
|
||||
ObjectBuilder<RelationMemberList>(buffer, parent) {
|
||||
}
|
||||
|
||||
~RelationMemberListBuilder() {
|
||||
add_padding();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a member to the relation.
|
||||
*
|
||||
* @param type The type (node, way, or relation).
|
||||
* @param ref The ID of the member.
|
||||
* @param role The role of the member.
|
||||
* @param full_member Optional pointer to the member object. If it
|
||||
* is available a copy will be added to the
|
||||
* relation.
|
||||
*/
|
||||
void add_member(osmium::item_type type, object_id_type ref, const char* role, const osmium::OSMObject* full_member = nullptr) {
|
||||
osmium::RelationMember* member = reserve_space_for<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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a member to the relation.
|
||||
*
|
||||
* @param type The type (node, way, or relation).
|
||||
* @param ref The ID of the member.
|
||||
* @param role The role of the member.
|
||||
* @param full_member Optional pointer to the member object. If it
|
||||
* is available a copy will be added to the
|
||||
* relation.
|
||||
*/
|
||||
void add_member(osmium::item_type type, object_id_type ref, const std::string& role, const osmium::OSMObject* full_member = nullptr) {
|
||||
osmium::RelationMember* member = reserve_space_for<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(const 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(const 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.set_id(osmium::object_id_to_area_id(source.id(), source.type()));
|
||||
area.set_version(source.version());
|
||||
area.set_changeset(source.changeset());
|
||||
area.set_timestamp(source.timestamp());
|
||||
area.set_visible(source.visible());
|
||||
area.set_uid(source.uid());
|
||||
|
||||
add_user(source.user());
|
||||
}
|
||||
|
||||
}; // class AreaBuilder
|
||||
|
||||
typedef ObjectBuilder<osmium::Changeset> ChangesetBuilder;
|
||||
|
||||
} // namespace builder
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_BUILDER_OSM_OBJECT_BUILDER_HPP
|
43
third_party/osmium/config/constexpr.hpp
vendored
43
third_party/osmium/config/constexpr.hpp
vendored
@ -1,43 +0,0 @@
|
||||
#ifndef OSMIUM_CONFIG_CONSTEXPR_HPP
|
||||
#define OSMIUM_CONFIG_CONSTEXPR_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.
|
||||
|
||||
*/
|
||||
|
||||
// Workaround for MSVC which doesn't support constexpr in all cases yet
|
||||
#ifdef _MSC_VER
|
||||
# define OSMIUM_CONSTEXPR
|
||||
#else
|
||||
# define OSMIUM_CONSTEXPR constexpr
|
||||
#endif
|
||||
|
||||
#endif // OSMIUM_CONFIG_CONSTEXPR_HPP
|
67
third_party/osmium/diff_handler.hpp
vendored
67
third_party/osmium/diff_handler.hpp
vendored
@ -1,67 +0,0 @@
|
||||
#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
third_party/osmium/diff_iterator.hpp
vendored
129
third_party/osmium/diff_iterator.hpp
vendored
@ -1,129 +0,0 @@
|
||||
#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&) = default;
|
||||
DiffIterator& operator=(const DiffIterator&) = default;
|
||||
|
||||
DiffIterator(DiffIterator&&) = default;
|
||||
DiffIterator& operator=(DiffIterator&&) = 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
third_party/osmium/diff_visitor.hpp
vendored
104
third_party/osmium/diff_visitor.hpp
vendored
@ -1,104 +0,0 @@
|
||||
#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
third_party/osmium/dynamic_handler.hpp
vendored
195
third_party/osmium/dynamic_handler.hpp
vendored
@ -1,195 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
}; // class 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();
|
||||
}
|
||||
|
||||
}; // class DynamicHandler
|
||||
|
||||
} // namspace handler
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_DYNAMIC_HANDLER_HPP
|
131
third_party/osmium/experimental/flex_reader.hpp
vendored
131
third_party/osmium/experimental/flex_reader.hpp
vendored
@ -1,131 +0,0 @@
|
||||
#ifndef OSMIUM_EXPERIMENTAL_FLEX_READER_HPP
|
||||
#define OSMIUM_EXPERIMENTAL_FLEX_READER_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/handler/node_locations_for_ways.hpp>
|
||||
#include <osmium/visitor.hpp>
|
||||
#include <osmium/area/multipolygon_collector.hpp>
|
||||
#include <osmium/area/assembler.hpp>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
/**
|
||||
* Experimental code that is not "officially" supported.
|
||||
*/
|
||||
namespace experimental {
|
||||
|
||||
template <class TLocationHandler>
|
||||
class FlexReader {
|
||||
|
||||
bool m_with_areas;
|
||||
osmium::osm_entity_bits::type m_entities;
|
||||
|
||||
typename TLocationHandler::index_pos_type m_index_pos;
|
||||
typename TLocationHandler::index_neg_type m_index_neg;
|
||||
TLocationHandler m_location_handler;
|
||||
|
||||
osmium::io::Reader m_reader;
|
||||
osmium::area::Assembler::config_type m_assembler_config;
|
||||
osmium::area::MultipolygonCollector<osmium::area::Assembler> m_collector;
|
||||
|
||||
public:
|
||||
|
||||
explicit FlexReader(const osmium::io::File& file, osmium::osm_entity_bits::type entities = osmium::osm_entity_bits::nwr) :
|
||||
m_with_areas(entities & osmium::osm_entity_bits::area),
|
||||
m_entities((entities & ~osmium::osm_entity_bits::area) | (m_with_areas ? osmium::osm_entity_bits::node | osmium::osm_entity_bits::way : osmium::osm_entity_bits::nothing)),
|
||||
m_index_pos(),
|
||||
m_index_neg(),
|
||||
m_location_handler(m_index_pos, m_index_neg),
|
||||
m_reader(file, m_entities),
|
||||
m_assembler_config(),
|
||||
m_collector(m_assembler_config)
|
||||
{
|
||||
m_location_handler.ignore_errors();
|
||||
if (m_with_areas) {
|
||||
osmium::io::Reader reader(file, osmium::osm_entity_bits::relation);
|
||||
m_collector.read_relations(reader);
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
explicit FlexReader(const std::string& filename, osmium::osm_entity_bits::type entities = osmium::osm_entity_bits::nwr) :
|
||||
FlexReader(osmium::io::File(filename), entities) {
|
||||
}
|
||||
|
||||
explicit FlexReader(const char* filename, osmium::osm_entity_bits::type entities = osmium::osm_entity_bits::nwr) :
|
||||
FlexReader(osmium::io::File(filename), entities) {
|
||||
}
|
||||
|
||||
std::vector<osmium::memory::Buffer> read() {
|
||||
std::vector<osmium::memory::Buffer> buffers;
|
||||
|
||||
osmium::memory::Buffer buffer = m_reader.read();
|
||||
|
||||
if (buffer) {
|
||||
buffers.push_back(std::move(buffer));
|
||||
if (m_with_areas) {
|
||||
osmium::apply(buffers[0], m_location_handler, m_collector.handler([&buffers](osmium::memory::Buffer&& area_buffer) {
|
||||
buffers.push_back(std::move(area_buffer));
|
||||
}));
|
||||
} else if (m_entities & (osmium::osm_entity_bits::node | osmium::osm_entity_bits::way)) {
|
||||
osmium::apply(buffers[0], m_location_handler);
|
||||
}
|
||||
}
|
||||
|
||||
return buffers;
|
||||
}
|
||||
|
||||
osmium::io::Header header() const {
|
||||
return m_reader.header();
|
||||
}
|
||||
|
||||
void close() {
|
||||
return m_reader.close();
|
||||
}
|
||||
|
||||
bool eof() const {
|
||||
return m_reader.eof();
|
||||
}
|
||||
|
||||
const osmium::area::MultipolygonCollector<osmium::area::Assembler>& collector() const {
|
||||
return m_collector;
|
||||
}
|
||||
|
||||
}; // class FlexReader
|
||||
|
||||
} // namespace experimental
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_EXPERIMENTAL_FLEX_READER_HPP
|
97
third_party/osmium/geom/coordinates.hpp
vendored
97
third_party/osmium/geom/coordinates.hpp
vendored
@ -1,97 +0,0 @@
|
||||
#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>
|
||||
#include <osmium/util/double.hpp>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
namespace geom {
|
||||
|
||||
struct Coordinates {
|
||||
|
||||
double x;
|
||||
double y;
|
||||
|
||||
explicit Coordinates(double cx, double cy) noexcept : x(cx), y(cy) {
|
||||
}
|
||||
|
||||
Coordinates(const osmium::Location& location) : x(location.lon()), y(location.lat()) {
|
||||
}
|
||||
|
||||
void append_to_string(std::string& s, const char infix, int precision) const {
|
||||
osmium::util::double2string(s, x, precision);
|
||||
s += infix;
|
||||
osmium::util::double2string(s, y, precision);
|
||||
}
|
||||
|
||||
void append_to_string(std::string& s, const char prefix, const char infix, const char suffix, int precision) const {
|
||||
s += prefix;
|
||||
append_to_string(s, infix, precision);
|
||||
s += suffix;
|
||||
}
|
||||
|
||||
}; // struct coordinates
|
||||
|
||||
/**
|
||||
* Compare whether two Coordinates are identical. Might not give the
|
||||
* right result if the coordinates have been the result of some
|
||||
* calculation that introduced rounding errors.
|
||||
*/
|
||||
inline bool operator==(const Coordinates& lhs, const Coordinates& rhs) noexcept {
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
return lhs.x == rhs.x && lhs.y == rhs.y;
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
|
||||
inline bool operator!=(const Coordinates& lhs, const Coordinates& rhs) noexcept {
|
||||
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
|
328
third_party/osmium/geom/factory.hpp
vendored
328
third_party/osmium/geom/factory.hpp
vendored
@ -1,328 +0,0 @@
|
||||
#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 <cstddef>
|
||||
#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 {
|
||||
|
||||
/**
|
||||
* Exception thrown when an invalid geometry is encountered. An example
|
||||
* would be a linestring with less than two points.
|
||||
*/
|
||||
struct geometry_error : public std::runtime_error {
|
||||
|
||||
geometry_error(const std::string& what) :
|
||||
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.
|
||||
}; // enum class use_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.
|
||||
}; // enum class direction
|
||||
|
||||
/**
|
||||
* 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 noexcept {
|
||||
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:
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
|
||||
void linestring_start() {
|
||||
m_impl.linestring_start();
|
||||
}
|
||||
|
||||
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 linestring_finish(size_t num_points) {
|
||||
return m_impl.linestring_finish(num_points);
|
||||
}
|
||||
|
||||
linestring_type create_linestring(const osmium::WayNodeList& wnl, use_nodes un=use_nodes::unique, direction dir=direction::forward) {
|
||||
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 osmium::geometry_error("not enough points for linestring");
|
||||
}
|
||||
|
||||
return linestring_finish(num_points);
|
||||
}
|
||||
|
||||
linestring_type create_linestring(const osmium::Way& way, use_nodes un=use_nodes::unique, direction dir=direction::forward) {
|
||||
return create_linestring(way.nodes(), un, dir);
|
||||
}
|
||||
|
||||
/* Polygon */
|
||||
|
||||
void polygon_start() {
|
||||
m_impl.polygon_start();
|
||||
}
|
||||
|
||||
template <class TIter>
|
||||
size_t fill_polygon(TIter it, TIter end) {
|
||||
size_t num_points = 0;
|
||||
for (; it != end; ++it, ++num_points) {
|
||||
m_impl.polygon_add_location(m_projection(it->location()));
|
||||
}
|
||||
return num_points;
|
||||
}
|
||||
|
||||
template <class TIter>
|
||||
size_t fill_polygon_unique(TIter it, TIter end) {
|
||||
size_t num_points = 0;
|
||||
osmium::Location last_location;
|
||||
for (; it != end; ++it) {
|
||||
if (last_location != it->location()) {
|
||||
last_location = it->location();
|
||||
m_impl.polygon_add_location(m_projection(last_location));
|
||||
++num_points;
|
||||
}
|
||||
}
|
||||
return num_points;
|
||||
}
|
||||
|
||||
polygon_type polygon_finish(size_t num_points) {
|
||||
return m_impl.polygon_finish(num_points);
|
||||
}
|
||||
|
||||
/* MultiPolygon */
|
||||
|
||||
multipolygon_type create_multipolygon(const osmium::Area& area) {
|
||||
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 osmium::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
|
152
third_party/osmium/geom/geojson.hpp
vendored
152
third_party/osmium/geom/geojson.hpp
vendored
@ -1,152 +0,0 @@
|
||||
#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;
|
||||
int m_precision;
|
||||
|
||||
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(int precision = 7) :
|
||||
m_precision(precision) {
|
||||
}
|
||||
|
||||
/* Point */
|
||||
|
||||
// { "type": "Point", "coordinates": [100.0, 0.0] }
|
||||
point_type make_point(const osmium::geom::Coordinates& xy) const {
|
||||
std::string str {"{\"type\":\"Point\",\"coordinates\":"};
|
||||
xy.append_to_string(str, '[', ',', ']', m_precision);
|
||||
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_precision);
|
||||
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_precision);
|
||||
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
|
224
third_party/osmium/geom/geos.hpp
vendored
224
third_party/osmium/geom/geos.hpp
vendored
@ -1,224 +0,0 @@
|
||||
#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>
|
||||
|
||||
// MSVC doesn't support throw_with_nested yet
|
||||
#ifdef _MSC_VER
|
||||
# define THROW throw
|
||||
#else
|
||||
# define THROW std::throw_with_nested
|
||||
#endif
|
||||
|
||||
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&) {
|
||||
THROW(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&) {
|
||||
THROW(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&) {
|
||||
THROW(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&) {
|
||||
THROW(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&) {
|
||||
THROW(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&) {
|
||||
THROW(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&) {
|
||||
THROW(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&) {
|
||||
THROW(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&) {
|
||||
THROW(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&) {
|
||||
THROW(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&) {
|
||||
THROW(osmium::geos_geometry_error());
|
||||
}
|
||||
}
|
||||
|
||||
}; // class GEOSFactoryImpl
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class TProjection = IdentityProjection>
|
||||
using GEOSFactory = GeometryFactory<osmium::geom::detail::GEOSFactoryImpl, TProjection>;
|
||||
|
||||
} // namespace geom
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#undef THROW
|
||||
|
||||
#endif // OSMIUM_GEOM_GEOS_HPP
|
94
third_party/osmium/geom/haversine.hpp
vendored
94
third_party/osmium/geom/haversine.hpp
vendored
@ -1,94 +0,0 @@
|
||||
#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/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
third_party/osmium/geom/mercator_projection.hpp
vendored
109
third_party/osmium/geom/mercator_projection.hpp
vendored
@ -1,109 +0,0 @@
|
||||
#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 noexcept {
|
||||
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
|
179
third_party/osmium/geom/ogr.hpp
vendored
179
third_party/osmium/geom/ogr.hpp
vendored
@ -1,179 +0,0 @@
|
||||
#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 <cstddef>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#ifdef __clang__
|
||||
# pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
|
||||
#endif
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#pragma GCC diagnostic ignored "-Wpadded"
|
||||
# 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);
|
||||
}
|
||||
|
||||
/* Polygon */
|
||||
|
||||
void polygon_start() {
|
||||
m_ring = std::unique_ptr<OGRLinearRing>(new OGRLinearRing());
|
||||
}
|
||||
|
||||
void polygon_add_location(const osmium::geom::Coordinates& xy) {
|
||||
assert(!!m_ring);
|
||||
m_ring->addPoint(xy.x, xy.y);
|
||||
}
|
||||
|
||||
polygon_type polygon_finish(size_t /* num_points */) {
|
||||
std::unique_ptr<OGRPolygon> polygon = std::unique_ptr<OGRPolygon>(new OGRPolygon());
|
||||
polygon->addRingDirectly(m_ring.release());
|
||||
return polygon;
|
||||
}
|
||||
|
||||
/* 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
third_party/osmium/geom/projection.hpp
vendored
159
third_party/osmium/geom/projection.hpp
vendored
@ -1,159 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
}; // struct ProjCRSDeleter
|
||||
|
||||
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 noexcept {
|
||||
return m_epsg;
|
||||
}
|
||||
|
||||
std::string proj_string() const {
|
||||
return m_proj_string;
|
||||
}
|
||||
|
||||
}; // class Projection
|
||||
|
||||
} // namespace geom
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_GEOM_PROJECTION_HPP
|
57
third_party/osmium/geom/relations.hpp
vendored
57
third_party/osmium/geom/relations.hpp
vendored
@ -1,57 +0,0 @@
|
||||
#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
|
75
third_party/osmium/geom/util.hpp
vendored
75
third_party/osmium/geom/util.hpp
vendored
@ -1,75 +0,0 @@
|
||||
#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 {
|
||||
|
||||
/**
|
||||
* Exception thrown when a projection object can not be initialized or the
|
||||
* projection of some coordinates can not be calculated.
|
||||
*/
|
||||
struct projection_error : public std::runtime_error {
|
||||
|
||||
projection_error(const std::string& what) :
|
||||
std::runtime_error(what) {
|
||||
}
|
||||
|
||||
projection_error(const char* what) :
|
||||
std::runtime_error(what) {
|
||||
}
|
||||
|
||||
}; // struct projection_error
|
||||
|
||||
namespace geom {
|
||||
|
||||
constexpr double PI = 3.14159265358979323846;
|
||||
|
||||
/// Convert angle from degrees to radians.
|
||||
inline constexpr double deg_to_rad(double degree) noexcept {
|
||||
return degree * (PI / 180.0);
|
||||
}
|
||||
|
||||
/// Convert angle from radians to degrees.
|
||||
inline constexpr double rad_to_deg(double radians) noexcept {
|
||||
return radians * (180.0 / PI);
|
||||
}
|
||||
|
||||
} // namespace geom
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_GEOM_UTIL_HPP
|
279
third_party/osmium/geom/wkb.hpp
vendored
279
third_party/osmium/geom/wkb.hpp
vendored
@ -1,279 +0,0 @@
|
||||
#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>
|
||||
|
||||
// Windows is only available for little endian architectures
|
||||
// http://stackoverflow.com/questions/6449468/can-i-safely-assume-that-windows-installations-will-always-be-little-endian
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
# include <endian.h>
|
||||
#else
|
||||
# define __LITTLE_ENDIAN 1234
|
||||
# define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#include <osmium/geom/coordinates.hpp>
|
||||
#include <osmium/geom/factory.hpp>
|
||||
#include <osmium/util/cast.hpp>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
namespace geom {
|
||||
|
||||
enum class wkb_type : bool {
|
||||
wkb = false,
|
||||
ewkb = true
|
||||
}; // enum class wkb_type
|
||||
|
||||
enum class out_type : bool {
|
||||
binary = false,
|
||||
hex = true
|
||||
}; // enum class out_type
|
||||
|
||||
namespace detail {
|
||||
|
||||
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
|
||||
}; // enum wkbGeometryType
|
||||
|
||||
/**
|
||||
* Byte order marker in WKB geometry.
|
||||
*/
|
||||
enum class wkb_byte_order_type : uint8_t {
|
||||
XDR = 0, // Big Endian
|
||||
NDR = 1 // Little Endian
|
||||
}; // enum class wkb_byte_order_type
|
||||
|
||||
std::string m_data;
|
||||
uint32_t m_points {0};
|
||||
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 {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
str_push(str, wkb_byte_order_type::NDR);
|
||||
#else
|
||||
str_push(str, wkb_byte_order_type::XDR);
|
||||
#endif
|
||||
if (m_wkb_type == wkb_type::ewkb) {
|
||||
str_push(str, type | wkbSRID);
|
||||
str_push(str, srid);
|
||||
} 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 size_t size) {
|
||||
const uint32_t s = static_cast_with_assert<uint32_t>(size);
|
||||
memcpy(&m_data[offset], &s, 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
|
148
third_party/osmium/geom/wkt.hpp
vendored
148
third_party/osmium/geom/wkt.hpp
vendored
@ -1,148 +0,0 @@
|
||||
#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 <cstddef>
|
||||
#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;
|
||||
int m_precision;
|
||||
|
||||
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;
|
||||
|
||||
WKTFactoryImpl(int precision = 7) :
|
||||
m_precision(precision) {
|
||||
}
|
||||
|
||||
/* Point */
|
||||
|
||||
point_type make_point(const osmium::geom::Coordinates& xy) const {
|
||||
std::string str {"POINT"};
|
||||
xy.append_to_string(str, '(', ' ', ')', m_precision);
|
||||
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_precision);
|
||||
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_precision);
|
||||
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
third_party/osmium/handler.hpp
vendored
101
third_party/osmium/handler.hpp
vendored
@ -1,101 +0,0 @@
|
||||
#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
third_party/osmium/handler/chain.hpp
vendored
128
third_party/osmium/handler/chain.hpp
vendored
@ -1,128 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
}; // struct call_flush
|
||||
|
||||
template <int SIZE, class THandlers>
|
||||
struct call_flush<SIZE, SIZE, THandlers> {
|
||||
void operator()(THandlers&) {}
|
||||
}; // struct call_flush
|
||||
|
||||
OSMIUM_CHAIN_HANDLER_CALL(node, Node)
|
||||
OSMIUM_CHAIN_HANDLER_CALL(way, Way)
|
||||
OSMIUM_CHAIN_HANDLER_CALL(relation, Relation)
|
||||
OSMIUM_CHAIN_HANDLER_CALL(changeset, Changeset)
|
||||
OSMIUM_CHAIN_HANDLER_CALL(area, Area)
|
||||
|
||||
public:
|
||||
|
||||
explicit ChainHandler(THandler&... handlers) :
|
||||
m_handlers(handlers...) {
|
||||
}
|
||||
|
||||
void node(osmium::Node& node) {
|
||||
call_node<0, sizeof...(THandler), handlers_type>()(m_handlers, node);
|
||||
}
|
||||
|
||||
void way(osmium::Way& way) {
|
||||
call_way<0, sizeof...(THandler), handlers_type>()(m_handlers, way);
|
||||
}
|
||||
|
||||
void relation(osmium::Relation& relation) {
|
||||
call_relation<0, sizeof...(THandler), handlers_type>()(m_handlers, relation);
|
||||
}
|
||||
|
||||
void changeset( osmium::Changeset& changeset) {
|
||||
call_changeset<0, sizeof...(THandler), handlers_type>()(m_handlers, changeset);
|
||||
}
|
||||
|
||||
void area(osmium::Area& area) {
|
||||
call_area<0, sizeof...(THandler), handlers_type>()(m_handlers, area);
|
||||
}
|
||||
|
||||
void flush() {
|
||||
call_flush<0, sizeof...(THandler), handlers_type>()(m_handlers);
|
||||
}
|
||||
|
||||
}; // class ChainHandler
|
||||
|
||||
} // namespace handler
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_HANDLER_CHAIN_HPP
|
111
third_party/osmium/handler/disk_store.hpp
vendored
111
third_party/osmium/handler/disk_store.hpp
vendored
@ -1,111 +0,0 @@
|
||||
#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
third_party/osmium/handler/dump.hpp
vendored
294
third_party/osmium/handler/dump.hpp
vendored
@ -1,294 +0,0 @@
|
||||
#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
|
@ -1,177 +0,0 @@
|
||||
#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 <type_traits>
|
||||
|
||||
#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 {
|
||||
|
||||
static_assert(std::is_base_of<osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location>, TStoragePosIDs>::value,
|
||||
"Index class must be derived from osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location>");
|
||||
|
||||
static_assert(std::is_base_of<osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location>, TStorageNegIDs>::value,
|
||||
"Index class must be derived from osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location>");
|
||||
|
||||
public:
|
||||
|
||||
typedef TStoragePosIDs index_pos_type;
|
||||
typedef TStorageNegIDs index_neg_type;
|
||||
|
||||
private:
|
||||
|
||||
/// Object that handles the actual storage of the node locations (with positive IDs).
|
||||
TStoragePosIDs& m_storage_pos;
|
||||
|
||||
/// Object that handles the actual storage of the node locations (with negative IDs).
|
||||
TStorageNegIDs& m_storage_neg;
|
||||
|
||||
bool m_ignore_errors {false};
|
||||
|
||||
bool m_must_sort {false};
|
||||
|
||||
// It is okay to have this static dummy instance, even when using several threads,
|
||||
// because it is read-only.
|
||||
static dummy_type& get_dummy() {
|
||||
static dummy_type instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
explicit NodeLocationsForWays(TStoragePosIDs& storage_pos,
|
||||
TStorageNegIDs& storage_neg = get_dummy()) :
|
||||
m_storage_pos(storage_pos),
|
||||
m_storage_neg(storage_neg) {
|
||||
}
|
||||
|
||||
NodeLocationsForWays(const NodeLocationsForWays&) = delete;
|
||||
NodeLocationsForWays& operator=(const NodeLocationsForWays&) = delete;
|
||||
|
||||
~NodeLocationsForWays() noexcept = default;
|
||||
|
||||
void ignore_errors() {
|
||||
m_ignore_errors = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the location of the node in the storage.
|
||||
*/
|
||||
void node(const osmium::Node& node) {
|
||||
m_must_sort = true;
|
||||
const osmium::object_id_type id = node.id();
|
||||
if (id >= 0) {
|
||||
m_storage_pos.set(static_cast<osmium::unsigned_object_id_type>( id), node.location());
|
||||
} else {
|
||||
m_storage_neg.set(static_cast<osmium::unsigned_object_id_type>(-id), node.location());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get location of node with given id.
|
||||
*/
|
||||
osmium::Location get_node_location(const osmium::object_id_type id) const {
|
||||
if (id >= 0) {
|
||||
return m_storage_pos.get(static_cast<osmium::unsigned_object_id_type>( id));
|
||||
} else {
|
||||
return m_storage_neg.get(static_cast<osmium::unsigned_object_id_type>(-id));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve locations of all nodes in the way from storage and add
|
||||
* them to the way object.
|
||||
*/
|
||||
void way(osmium::Way& way) {
|
||||
if (m_must_sort) {
|
||||
m_storage_pos.sort();
|
||||
m_storage_neg.sort();
|
||||
m_must_sort = false;
|
||||
}
|
||||
bool error = false;
|
||||
for (auto& node_ref : way.nodes()) {
|
||||
try {
|
||||
node_ref.set_location(get_node_location(node_ref.ref()));
|
||||
if (!node_ref.location()) {
|
||||
error = true;
|
||||
}
|
||||
} catch (osmium::not_found&) {
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
if (error && !m_ignore_errors) {
|
||||
throw osmium::not_found("location for one or more nodes not found in node location index");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call clear on the location indexes. Makes the
|
||||
* NodeLocationsForWays handler unusable. Used to explicitly free
|
||||
* memory if thats needed.
|
||||
*/
|
||||
void clear() {
|
||||
m_storage_pos.clear();
|
||||
m_storage_neg.clear();
|
||||
}
|
||||
|
||||
}; // class NodeLocationsForWays
|
||||
|
||||
} // namespace handler
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_HANDLER_NODE_LOCATIONS_FOR_WAYS_HPP
|
106
third_party/osmium/handler/object_relations.hpp
vendored
106
third_party/osmium/handler/object_relations.hpp
vendored
@ -1,106 +0,0 @@
|
||||
#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
|
@ -1,78 +0,0 @@
|
||||
#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
third_party/osmium/index/detail/mmap_vector_base.hpp
vendored
183
third_party/osmium/index/detail/mmap_vector_base.hpp
vendored
@ -1,183 +0,0 @@
|
||||
#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) noexcept :
|
||||
m_fd(fd),
|
||||
m_capacity(capacity),
|
||||
m_size(size),
|
||||
m_data(data) {
|
||||
}
|
||||
|
||||
explicit mmap_vector_base(int fd, size_t capacity, size_t size) :
|
||||
m_fd(fd),
|
||||
m_capacity(capacity),
|
||||
m_size(size),
|
||||
m_data(osmium::detail::typed_mmap<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 noexcept {
|
||||
return m_capacity;
|
||||
}
|
||||
|
||||
size_t size() const noexcept {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
bool empty() const noexcept {
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
const T* data() const noexcept {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
T* data() noexcept {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
T& operator[](size_t n) {
|
||||
return m_data[n];
|
||||
}
|
||||
|
||||
T at(size_t n) const {
|
||||
if (n >= m_size) {
|
||||
throw std::out_of_range("out of range");
|
||||
}
|
||||
return m_data[n];
|
||||
}
|
||||
|
||||
void clear() noexcept {
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
void shrink_to_fit() {
|
||||
// XXX do something here
|
||||
}
|
||||
|
||||
void push_back(const T& value) {
|
||||
if (m_size >= m_capacity) {
|
||||
resize(m_size+1);
|
||||
}
|
||||
m_data[m_size] = value;
|
||||
++m_size;
|
||||
}
|
||||
|
||||
void resize(size_t new_size) {
|
||||
if (new_size > capacity()) {
|
||||
static_cast<TDerived<T>*>(this)->reserve(new_size + osmium::detail::mmap_vector_size_increment);
|
||||
}
|
||||
if (new_size > size()) {
|
||||
new (data() + size()) T[new_size - size()];
|
||||
}
|
||||
m_size = new_size;
|
||||
}
|
||||
|
||||
iterator begin() noexcept {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
iterator end() noexcept {
|
||||
return m_data + m_size;
|
||||
}
|
||||
|
||||
const_iterator begin() const noexcept {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
const_iterator end() const noexcept {
|
||||
return m_data + m_size;
|
||||
}
|
||||
|
||||
const_iterator cbegin() noexcept {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
const_iterator cend() noexcept {
|
||||
return m_data + m_size;
|
||||
}
|
||||
|
||||
}; // class mmap_vector_base
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_DETAIL_MMAP_VECTOR_BASE_HPP
|
@ -1,82 +0,0 @@
|
||||
#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());
|
||||
this->data(osmium::detail::typed_mmap<T>::grow_and_map(new_capacity, this->m_fd));
|
||||
this->m_capacity = new_capacity;
|
||||
}
|
||||
}
|
||||
|
||||
}; // class mmap_vector_file
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_DETAIL_MMAP_VECTOR_FILE_HPP
|
62
third_party/osmium/index/detail/tmpfile.hpp
vendored
62
third_party/osmium/index/detail/tmpfile.hpp
vendored
@ -1,62 +0,0 @@
|
||||
#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.
|
||||
*
|
||||
* @returns File descriptor of temporary file.
|
||||
* @throws 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
|
229
third_party/osmium/index/detail/typed_mmap.hpp
vendored
229
third_party/osmium/index/detail/typed_mmap.hpp
vendored
@ -1,229 +0,0 @@
|
||||
#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/stat.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <sys/mman.h>
|
||||
#else
|
||||
# include <mmap_for_windows.hpp>
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# include <unistd.h>
|
||||
#else
|
||||
# define ftruncate _chsize
|
||||
#endif
|
||||
|
||||
// for bsd systems
|
||||
#ifndef MAP_ANONYMOUS
|
||||
# define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
|
||||
#include <osmium/util/cast.hpp>
|
||||
|
||||
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
|
||||
* @returns Pointer to mapped memory
|
||||
* @throws std::system_error If mmap(2) failed
|
||||
*/
|
||||
static T* map(size_t size) {
|
||||
void* addr = ::mmap(nullptr, sizeof(T) * size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
#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
|
||||
* @returns Pointer to mapped memory
|
||||
* @throws std::system_error If mmap(2) failed
|
||||
*/
|
||||
static T* map(size_t size, int fd, bool write = false) {
|
||||
int prot = PROT_READ;
|
||||
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
|
||||
* @throws std::system_error If mremap(2) call failed
|
||||
*/
|
||||
static T* remap(T* data, size_t old_size, size_t new_size) {
|
||||
void* addr = ::mremap(reinterpret_cast<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
|
||||
* @throws 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
|
||||
* @returns Number of objects of type T in this file
|
||||
* @throws std::system_error If fstat(2) call failed
|
||||
* @throws std::length_error If size of the file isn't a multiple of sizeof(T)
|
||||
*/
|
||||
static size_t file_size(int fd) {
|
||||
struct stat s;
|
||||
if (fstat(fd, &s) < 0) {
|
||||
throw std::system_error(errno, std::system_category(), "fstat failed");
|
||||
}
|
||||
if (static_cast<size_t>(s.st_size) % sizeof(T) != 0) {
|
||||
throw std::length_error("file size has to be multiple of object size");
|
||||
}
|
||||
return static_cast<size_t>(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
|
||||
* @throws std::system_error If ftruncate(2) call failed
|
||||
*/
|
||||
static void grow_file(size_t new_size, int fd) {
|
||||
if (file_size(fd) < new_size) {
|
||||
if (::ftruncate(fd, static_cast_with_assert<off_t>(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
|
||||
* @throws 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
|
100
third_party/osmium/index/index.hpp
vendored
100
third_party/osmium/index/index.hpp
vendored
@ -1,100 +0,0 @@
|
||||
#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>
|
||||
|
||||
#include <osmium/util/compatibility.hpp>
|
||||
|
||||
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>
|
||||
OSMIUM_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 OSMIUM_CONSTEXPR size_t empty_value<size_t>() {
|
||||
return std::numeric_limits<size_t>::max();
|
||||
}
|
||||
|
||||
} // namespace index
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_INDEX_INDEX_HPP
|
155
third_party/osmium/index/map.hpp
vendored
155
third_party/osmium/index/map.hpp
vendored
@ -1,155 +0,0 @@
|
||||
#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;
|
||||
|
||||
virtual ~Map() = default;
|
||||
|
||||
virtual void reserve(const size_t) {
|
||||
// default implementation is empty
|
||||
}
|
||||
|
||||
/// Set the field with id to value.
|
||||
virtual void set(const TId id, const TValue value) = 0;
|
||||
|
||||
/// Retrieve value by id. Does not check for overflow or empty fields.
|
||||
virtual const TValue get(const TId id) const = 0;
|
||||
|
||||
/**
|
||||
* Get the approximate number of items in the storage. The storage
|
||||
* might allocate memory in blocks, so this size might not be
|
||||
* accurate. You can not use this to find out how much memory the
|
||||
* storage uses. Use used_memory() for that.
|
||||
*/
|
||||
virtual size_t size() const = 0;
|
||||
|
||||
/**
|
||||
* Get the memory used for this storage in bytes. Note that this
|
||||
* is not necessarily entirely accurate but an approximation.
|
||||
* For storage classes that store the data in memory, this is
|
||||
* the main memory used, for storage classes storing data on disk
|
||||
* this is the memory used on disk.
|
||||
*/
|
||||
virtual size_t used_memory() const = 0;
|
||||
|
||||
/**
|
||||
* Clear memory used for this storage. After this you can not
|
||||
* use the storage container any more.
|
||||
*/
|
||||
virtual void clear() = 0;
|
||||
|
||||
/**
|
||||
* Sort data in map. Call this after writing all data and
|
||||
* before reading. Not all implementations need this.
|
||||
*/
|
||||
virtual void sort() {
|
||||
// default implementation is empty
|
||||
}
|
||||
|
||||
virtual void dump_as_list(int /*fd*/) const {
|
||||
std::runtime_error("can't dump as list");
|
||||
}
|
||||
|
||||
}; // class Map
|
||||
|
||||
} // namespace map
|
||||
|
||||
} // namespace index
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_INDEX_MAP_HPP
|
87
third_party/osmium/index/map/dummy.hpp
vendored
87
third_party/osmium/index/map/dummy.hpp
vendored
@ -1,87 +0,0 @@
|
||||
#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
|
@ -1,61 +0,0 @@
|
||||
#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
|
@ -1,57 +0,0 @@
|
||||
#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
third_party/osmium/index/map/sparse_table.hpp
vendored
140
third_party/osmium/index/map/sparse_table.hpp
vendored
@ -1,140 +0,0 @@
|
||||
#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 override final {
|
||||
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
third_party/osmium/index/map/stl_map.hpp
vendored
112
third_party/osmium/index/map/stl_map.hpp
vendored
@ -1,112 +0,0 @@
|
||||
#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 override final {
|
||||
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
|
61
third_party/osmium/index/map/stl_vector.hpp
vendored
61
third_party/osmium/index/map/stl_vector.hpp
vendored
@ -1,61 +0,0 @@
|
||||
#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 T>
|
||||
using StdVectorWrap = std::vector<T>;
|
||||
|
||||
template <typename TId, typename TValue>
|
||||
using SparseMapMem = VectorBasedSparseMap<TId, TValue, StdVectorWrap>;
|
||||
|
||||
} // namespace map
|
||||
|
||||
} // namespace index
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_INDEX_MAP_STL_VECTOR_HPP
|
208
third_party/osmium/index/map/vector.hpp
vendored
208
third_party/osmium/index/map/vector.hpp
vendored
@ -1,208 +0,0 @@
|
||||
#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 override final {
|
||||
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
|
129
third_party/osmium/index/multimap.hpp
vendored
129
third_party/osmium/index/multimap.hpp
vendored
@ -1,129 +0,0 @@
|
||||
#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
|
||||
}
|
||||
|
||||
virtual void dump_as_list(int /*fd*/) const {
|
||||
std::runtime_error("can't dump as list");
|
||||
}
|
||||
|
||||
}; // class Multimap
|
||||
|
||||
} // namespace map
|
||||
|
||||
} // namespace index
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_INDEX_MULTIMAP_HPP
|
199
third_party/osmium/index/multimap/hybrid.hpp
vendored
199
third_party/osmium/index/multimap/hybrid.hpp
vendored
@ -1,199 +0,0 @@
|
||||
#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*();
|
||||
}
|
||||
|
||||
}; // class HybridIterator
|
||||
|
||||
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) override final {
|
||||
consolidate();
|
||||
m_main.dump_as_list(fd);
|
||||
}
|
||||
|
||||
void clear() override final {
|
||||
m_main.clear();
|
||||
m_extra.clear();
|
||||
}
|
||||
|
||||
void sort() override final {
|
||||
m_main.sort();
|
||||
}
|
||||
|
||||
}; // class Hybrid
|
||||
|
||||
} // namespace multimap
|
||||
|
||||
} // namespace index
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_INDEX_MULTIMAP_HYBRID_HPP
|
@ -1,58 +0,0 @@
|
||||
#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
|
@ -1,54 +0,0 @@
|
||||
#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
third_party/osmium/index/multimap/stl_multimap.hpp
vendored
151
third_party/osmium/index/multimap/stl_multimap.hpp
vendored
@ -1,151 +0,0 @@
|
||||
#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 override final {
|
||||
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
|
58
third_party/osmium/index/multimap/stl_vector.hpp
vendored
58
third_party/osmium/index/multimap/stl_vector.hpp
vendored
@ -1,58 +0,0 @@
|
||||
#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 T>
|
||||
using StdVectorWrap = std::vector<T>;
|
||||
|
||||
template <typename TId, typename TValue>
|
||||
using SparseMultimapMem = VectorBasedSparseMultimap<TId, TValue, StdVectorWrap>;
|
||||
|
||||
} // namespace multimap
|
||||
|
||||
} // namespace index
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_INDEX_MULTIMAP_STL_VECTOR_HPP
|
151
third_party/osmium/index/multimap/vector.hpp
vendored
151
third_party/osmium/index/multimap/vector.hpp
vendored
@ -1,151 +0,0 @@
|
||||
#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;
|
||||
});
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator> get_all(const TId id) const {
|
||||
const element_type element {
|
||||
id,
|
||||
osmium::index::empty_value<TValue>()
|
||||
};
|
||||
return std::equal_range(m_vector.cbegin(), m_vector.cend(), element, [](const element_type& a, const element_type& b) {
|
||||
return a.first < b.first;
|
||||
});
|
||||
}
|
||||
|
||||
size_t size() const override final {
|
||||
return m_vector.size();
|
||||
}
|
||||
|
||||
size_t byte_size() const {
|
||||
return m_vector.size() * sizeof(element_type);
|
||||
}
|
||||
|
||||
size_t used_memory() const override final {
|
||||
return sizeof(element_type) * size();
|
||||
}
|
||||
|
||||
void clear() override final {
|
||||
m_vector.clear();
|
||||
m_vector.shrink_to_fit();
|
||||
}
|
||||
|
||||
void sort() override final {
|
||||
std::sort(m_vector.begin(), m_vector.end());
|
||||
}
|
||||
|
||||
void remove(const TId id, const TValue value) {
|
||||
auto r = get_all(id);
|
||||
for (auto it = r.first; it != r.second; ++it) {
|
||||
if (it->second == value) {
|
||||
it->second = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void consolidate() {
|
||||
std::sort(m_vector.begin(), m_vector.end());
|
||||
}
|
||||
|
||||
void erase_removed() {
|
||||
m_vector.erase(
|
||||
std::remove_if(m_vector.begin(), m_vector.end(), is_removed),
|
||||
m_vector.end()
|
||||
);
|
||||
}
|
||||
|
||||
void dump_as_list(int fd) const override final {
|
||||
osmium::io::detail::reliable_write(fd, reinterpret_cast<const char*>(m_vector.data()), byte_size());
|
||||
}
|
||||
|
||||
}; // class VectorBasedSparseMultimap
|
||||
|
||||
} // namespace multimap
|
||||
|
||||
} // namespace index
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_INDEX_MULTIMAP_VECTOR_HPP
|
39
third_party/osmium/io/any_compression.hpp
vendored
39
third_party/osmium/io/any_compression.hpp
vendored
@ -1,39 +0,0 @@
|
||||
#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
third_party/osmium/io/any_input.hpp
vendored
41
third_party/osmium/io/any_input.hpp
vendored
@ -1,41 +0,0 @@
|
||||
#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
third_party/osmium/io/any_output.hpp
vendored
42
third_party/osmium/io/any_output.hpp
vendored
@ -1,42 +0,0 @@
|
||||
#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
|
277
third_party/osmium/io/bzip2_compression.hpp
vendored
277
third_party/osmium/io/bzip2_compression.hpp
vendored
@ -1,277 +0,0 @@
|
||||
#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>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <osmium/io/compression.hpp>
|
||||
#include <osmium/io/file_compression.hpp>
|
||||
#include <osmium/util/cast.hpp>
|
||||
#include <osmium/util/compatibility.hpp>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
/**
|
||||
* Exception thrown when there are problems compressing or
|
||||
* decompressing bzip2 files.
|
||||
*/
|
||||
struct bzip2_error : public std::runtime_error {
|
||||
|
||||
int bzip2_error_code;
|
||||
int system_errno;
|
||||
|
||||
bzip2_error(const std::string& what, int error_code) :
|
||||
std::runtime_error(what),
|
||||
bzip2_error_code(error_code),
|
||||
system_errno(error_code == BZ_IO_ERROR ? errno : 0) {
|
||||
}
|
||||
|
||||
}; // struct bzip2_error
|
||||
|
||||
namespace io {
|
||||
|
||||
namespace detail {
|
||||
|
||||
OSMIUM_NORETURN inline void throw_bzip2_error(BZFILE* bzfile, const char* msg, int bzlib_error=0) {
|
||||
std::string error("bzip2 error: ");
|
||||
error += msg;
|
||||
error += ": ";
|
||||
int errnum = bzlib_error;
|
||||
if (bzlib_error) {
|
||||
error += std::to_string(bzlib_error);
|
||||
} else {
|
||||
error += ::BZ2_bzerror(bzfile, &errnum);
|
||||
}
|
||||
throw osmium::bzip2_error(error, errnum);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
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(m_bzfile, "write open failed", m_bzerror);
|
||||
}
|
||||
}
|
||||
|
||||
~Bzip2Compressor() override final {
|
||||
close();
|
||||
}
|
||||
|
||||
void write(const std::string& data) override final {
|
||||
int error;
|
||||
::BZ2_bzWrite(&error, m_bzfile, const_cast<char*>(data.data()), static_cast_with_assert<int>(data.size()));
|
||||
if (error != BZ_OK && error != BZ_STREAM_END) {
|
||||
detail::throw_bzip2_error(m_bzfile, "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(m_bzfile, "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(m_bzfile, "read open failed", m_bzerror);
|
||||
}
|
||||
}
|
||||
|
||||
~Bzip2Decompressor() override final {
|
||||
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()), static_cast_with_assert<int>(buffer.size()));
|
||||
if (error != BZ_OK && error != BZ_STREAM_END) {
|
||||
detail::throw_bzip2_error(m_bzfile, "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(m_bzfile, "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(m_bzfile, "read close failed", error);
|
||||
}
|
||||
m_bzfile = ::BZ2_bzReadOpen(&error, m_file, 0, 0, const_cast<void*>(static_cast<const void*>(unused_data.data())), static_cast_with_assert<int>(unused_data.size()));
|
||||
if (error != BZ_OK) {
|
||||
detail::throw_bzip2_error(m_bzfile, "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(m_bzfile, "read close failed", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}; // class Bzip2Decompressor
|
||||
|
||||
class Bzip2BufferDecompressor : public Decompressor {
|
||||
|
||||
const char* m_buffer;
|
||||
size_t m_buffer_size;
|
||||
bz_stream m_bzstream;
|
||||
|
||||
public:
|
||||
|
||||
Bzip2BufferDecompressor(const char* buffer, size_t size) :
|
||||
m_buffer(buffer),
|
||||
m_buffer_size(size),
|
||||
m_bzstream() {
|
||||
m_bzstream.next_in = const_cast<char*>(buffer);
|
||||
m_bzstream.avail_in = static_cast_with_assert<unsigned int>(size);
|
||||
int result = BZ2_bzDecompressInit(&m_bzstream, 0, 0);
|
||||
if (result != BZ_OK) {
|
||||
std::string message("bzip2 error: decompression init failed: ");
|
||||
throw bzip2_error(message, result);
|
||||
}
|
||||
}
|
||||
|
||||
~Bzip2BufferDecompressor() override final {
|
||||
BZ2_bzDecompressEnd(&m_bzstream);
|
||||
}
|
||||
|
||||
std::string read() override final {
|
||||
if (!m_buffer) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const size_t buffer_size = 10240;
|
||||
std::string output(buffer_size, '\0');
|
||||
m_bzstream.next_out = const_cast<char*>(output.data());
|
||||
m_bzstream.avail_out = buffer_size;
|
||||
int result = BZ2_bzDecompress(&m_bzstream);
|
||||
|
||||
if (result != BZ_OK) {
|
||||
m_buffer = nullptr;
|
||||
m_buffer_size = 0;
|
||||
}
|
||||
|
||||
if (result != BZ_OK && result != BZ_STREAM_END) {
|
||||
std::string message("bzip2 error: decompress failed: ");
|
||||
throw bzip2_error(message, result);
|
||||
}
|
||||
|
||||
output.resize(static_cast<unsigned long>(m_bzstream.next_out - output.data()));
|
||||
return output;
|
||||
}
|
||||
|
||||
}; // class Bzip2BufferDecompressor
|
||||
|
||||
namespace {
|
||||
|
||||
const bool registered_bzip2_compression = osmium::io::CompressionFactory::instance().register_compression(osmium::io::file_compression::bzip2,
|
||||
[](int fd) { return new osmium::io::Bzip2Compressor(fd); },
|
||||
[](int fd) { return new osmium::io::Bzip2Decompressor(fd); },
|
||||
[](const char* buffer, size_t size) { return new osmium::io::Bzip2BufferDecompressor(buffer, size); }
|
||||
);
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
} // namespace io
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_IO_BZIP2_COMPRESSION_HPP
|
279
third_party/osmium/io/compression.hpp
vendored
279
third_party/osmium/io/compression.hpp
vendored
@ -1,279 +0,0 @@
|
||||
#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 <utility>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# include <unistd.h>
|
||||
#else
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#include <osmium/io/detail/read_write.hpp>
|
||||
#include <osmium/io/file_compression.hpp>
|
||||
#include <osmium/util/compatibility.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() {
|
||||
}
|
||||
|
||||
}; // 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_fd;
|
||||
typedef std::function<osmium::io::Decompressor*(const char*, size_t)> create_decompressor_type_buffer;
|
||||
|
||||
private:
|
||||
|
||||
typedef std::map<const osmium::io::file_compression, std::tuple<create_compressor_type, create_decompressor_type_fd, create_decompressor_type_buffer>> 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;
|
||||
|
||||
OSMIUM_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_fd create_decompressor_fd,
|
||||
create_decompressor_type_buffer create_decompressor_buffer) {
|
||||
|
||||
compression_map_type::value_type cc(compression, std::make_tuple(create_compressor, create_decompressor_fd, create_decompressor_buffer));
|
||||
return m_callbacks.insert(cc).second;
|
||||
}
|
||||
|
||||
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>(std::get<0>(it->second)(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>(std::get<1>(it->second)(fd));
|
||||
}
|
||||
|
||||
error(compression);
|
||||
}
|
||||
|
||||
std::unique_ptr<osmium::io::Decompressor> create_decompressor(osmium::io::file_compression compression, const char* buffer, size_t size) {
|
||||
auto it = m_callbacks.find(compression);
|
||||
|
||||
if (it != m_callbacks.end()) {
|
||||
return std::unique_ptr<osmium::io::Decompressor>(std::get<2>(it->second)(buffer, size));
|
||||
}
|
||||
|
||||
error(compression);
|
||||
}
|
||||
|
||||
}; // class CompressionFactory
|
||||
|
||||
class NoCompressor : public Compressor {
|
||||
|
||||
int m_fd;
|
||||
|
||||
public:
|
||||
|
||||
NoCompressor(int fd) :
|
||||
Compressor(),
|
||||
m_fd(fd) {
|
||||
}
|
||||
|
||||
~NoCompressor() override final {
|
||||
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;
|
||||
const char *m_buffer;
|
||||
size_t m_buffer_size;
|
||||
|
||||
public:
|
||||
|
||||
NoDecompressor(int fd) :
|
||||
Decompressor(),
|
||||
m_fd(fd),
|
||||
m_buffer(nullptr),
|
||||
m_buffer_size(0) {
|
||||
}
|
||||
|
||||
NoDecompressor(const char* buffer, size_t size) :
|
||||
Decompressor(),
|
||||
m_fd(-1),
|
||||
m_buffer(buffer),
|
||||
m_buffer_size(size) {
|
||||
}
|
||||
|
||||
~NoDecompressor() override final {
|
||||
close();
|
||||
}
|
||||
|
||||
std::string read() override final {
|
||||
if (m_buffer) {
|
||||
if (m_buffer_size == 0) {
|
||||
return std::string();
|
||||
}
|
||||
size_t size = m_buffer_size;
|
||||
m_buffer_size = 0;
|
||||
return std::string(m_buffer, size);
|
||||
} else {
|
||||
std::string buffer(osmium::io::Decompressor::input_buffer_size, '\0');
|
||||
ssize_t nread = ::read(m_fd, const_cast<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); },
|
||||
[](const char* buffer, size_t size) { return new osmium::io::NoDecompressor(buffer, size); }
|
||||
);
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
} // namespace io
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_IO_COMPRESSION_HPP
|
160
third_party/osmium/io/detail/input_format.hpp
vendored
160
third_party/osmium/io/detail/input_format.hpp
vendored
@ -1,160 +0,0 @@
|
||||
#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.set_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
|
315
third_party/osmium/io/detail/opl_output_format.hpp
vendored
315
third_party/osmium/io/detail/opl_output_format.hpp
vendored
@ -1,315 +0,0 @@
|
||||
#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>
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wmissing-noreturn"
|
||||
# pragma clang diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
|
||||
#if BOOST_VERSION >= 104800
|
||||
# include <boost/regex/pending/unicode_iterator.hpp>
|
||||
#else
|
||||
# include <boost_unicode_iterator.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
#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];
|
||||
|
||||
template <typename... TArgs>
|
||||
void output_formatted(const char* format, TArgs&&... args) {
|
||||
#ifndef NDEBUG
|
||||
int len =
|
||||
#endif
|
||||
#ifndef _MSC_VER
|
||||
snprintf(m_tmp_buffer, tmp_buffer_size, format, std::forward<TArgs>(args)...);
|
||||
#else
|
||||
_snprintf(m_tmp_buffer, tmp_buffer_size, format, std::forward<TArgs>(args)...);
|
||||
#endif
|
||||
assert(len > 0 && static_cast<size_t>(len) < tmp_buffer_size);
|
||||
m_out += m_tmp_buffer;
|
||||
}
|
||||
|
||||
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 += '%';
|
||||
output_formatted("%04x", c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void write_meta(const osmium::OSMObject& object) {
|
||||
output_formatted("%" PRId64 " v%d d", object.id(), object.version());
|
||||
m_out += (object.visible() ? 'V' : 'D');
|
||||
output_formatted(" c%d t", object.changeset());
|
||||
m_out += object.timestamp().to_iso();
|
||||
output_formatted(" i%d u", object.uid());
|
||||
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) {
|
||||
output_formatted(" %c%.7f %c%.7f", x, location.lon_without_check(), y, location.lat_without_check());
|
||||
} 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&&) = default;
|
||||
OPLOutputBlock& operator=(OPLOutputBlock&&) = 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 += ',';
|
||||
}
|
||||
output_formatted("n%" PRId64, node_ref.ref());
|
||||
}
|
||||
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());
|
||||
output_formatted("%" PRId64 "@", member.ref());
|
||||
m_out += member.role();
|
||||
}
|
||||
m_out += '\n';
|
||||
}
|
||||
|
||||
void changeset(const osmium::Changeset& changeset) {
|
||||
output_formatted("c%d k%d s", changeset.id(), changeset.num_changes());
|
||||
m_out += changeset.created_at().to_iso();
|
||||
m_out += " e";
|
||||
m_out += changeset.closed_at().to_iso();
|
||||
output_formatted(" i%d u", changeset.uid());
|
||||
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 {
|
||||
m_output_queue.push(osmium::thread::Pool::instance().submit(OPLOutputBlock{std::move(buffer)}));
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
const bool registered_opl_output = osmium::io::detail::OutputFormatFactory::instance().register_output_format(osmium::io::file_format::opl,
|
||||
[](const osmium::io::File& file, data_queue_type& output_queue) {
|
||||
return new osmium::io::detail::OPLOutputFormat(file, output_queue);
|
||||
});
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace io
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_IO_DETAIL_OPL_OUTPUT_FORMAT_HPP
|
156
third_party/osmium/io/detail/output_format.hpp
vendored
156
third_party/osmium/io/detail/output_format.hpp
vendored
@ -1,156 +0,0 @@
|
||||
#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
|
100
third_party/osmium/io/detail/pbf.hpp
vendored
100
third_party/osmium/io/detail/pbf.hpp
vendored
@ -1,100 +0,0 @@
|
||||
#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/io/error.hpp>
|
||||
#include <osmium/osm/item_type.hpp>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
// avoid g++ false positive
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wreturn-type"
|
||||
inline item_type osmpbf_membertype_to_item_type(const OSMPBF::Relation::MemberType mt) {
|
||||
switch (mt) {
|
||||
case OSMPBF::Relation::NODE:
|
||||
return item_type::node;
|
||||
case OSMPBF::Relation::WAY:
|
||||
return item_type::way;
|
||||
case OSMPBF::Relation::RELATION:
|
||||
return item_type::relation;
|
||||
}
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown when there was a problem with parsing the PBF format of
|
||||
* a file.
|
||||
*/
|
||||
struct pbf_error : public io_error {
|
||||
|
||||
pbf_error(const std::string& what) :
|
||||
io_error(std::string("PBF error: ") + what) {
|
||||
}
|
||||
|
||||
pbf_error(const char* what) :
|
||||
io_error(std::string("PBF error: ") + what) {
|
||||
}
|
||||
|
||||
}; // struct pbf_error
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_IO_DETAIL_PBF_HPP
|
240
third_party/osmium/io/detail/pbf_input_format.hpp
vendored
240
third_party/osmium/io/detail/pbf_input_format.hpp
vendored
@ -1,240 +0,0 @@
|
||||
#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 <type_traits>
|
||||
|
||||
#include <osmium/io/detail/input_format.hpp>
|
||||
#include <osmium/io/detail/pbf.hpp> // IWYU pragma: export
|
||||
#include <osmium/io/detail/pbf_parser.hpp>
|
||||
#include <osmium/io/error.hpp>
|
||||
#include <osmium/io/file.hpp>
|
||||
#include <osmium/io/file_format.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/pool.hpp>
|
||||
#include <osmium/thread/queue.hpp>
|
||||
#include <osmium/thread/util.hpp>
|
||||
#include <osmium/util/cast.hpp>
|
||||
#include <osmium/util/config.hpp>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
namespace io {
|
||||
|
||||
class File;
|
||||
|
||||
namespace detail {
|
||||
|
||||
typedef osmium::thread::Queue<std::future<osmium::memory::Buffer>> queue_type;
|
||||
|
||||
/**
|
||||
* Class for parsing PBF files.
|
||||
*/
|
||||
class PBFInputFormat : public osmium::io::detail::InputFormat {
|
||||
|
||||
bool m_use_thread_pool;
|
||||
queue_type m_queue;
|
||||
std::atomic<bool> m_done;
|
||||
std::thread m_reader;
|
||||
osmium::thread::Queue<std::string>& m_input_queue;
|
||||
std::string m_input_buffer;
|
||||
|
||||
/**
|
||||
* Read the given number of bytes from the input queue.
|
||||
*
|
||||
* @param size Number of bytes to read
|
||||
* @returns String with the data
|
||||
* @throws osmium::pbf_error If size bytes can't be read
|
||||
*/
|
||||
std::string read_from_input_queue(size_t size) {
|
||||
while (m_input_buffer.size() < size) {
|
||||
std::string new_data;
|
||||
m_input_queue.wait_and_pop(new_data);
|
||||
if (new_data.empty()) {
|
||||
throw osmium::pbf_error("truncated data (EOF encountered)");
|
||||
}
|
||||
m_input_buffer += new_data;
|
||||
}
|
||||
|
||||
std::string output { m_input_buffer.substr(size) };
|
||||
m_input_buffer.resize(size);
|
||||
std::swap(output, m_input_buffer);
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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").
|
||||
* @returns 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;
|
||||
|
||||
try {
|
||||
std::string input_data = read_from_input_queue(sizeof(size_in_network_byte_order));
|
||||
size_in_network_byte_order = *reinterpret_cast<const uint32_t*>(input_data.data());
|
||||
} catch (osmium::pbf_error&) {
|
||||
return 0; // EOF
|
||||
}
|
||||
|
||||
uint32_t size = ntohl(size_in_network_byte_order);
|
||||
if (size > static_cast<uint32_t>(OSMPBF::max_blob_header_size)) {
|
||||
throw osmium::pbf_error("invalid BlobHeader size (> max_blob_header_size)");
|
||||
}
|
||||
|
||||
OSMPBF::BlobHeader blob_header;
|
||||
if (!blob_header.ParseFromString(read_from_input_queue(size))) {
|
||||
throw osmium::pbf_error("failed to parse BlobHeader");
|
||||
}
|
||||
|
||||
if (blob_header.type() != expected_type) {
|
||||
throw osmium::pbf_error("blob does not have expected type (OSMHeader in first blob, OSMData in following blobs)");
|
||||
}
|
||||
|
||||
return static_cast<size_t>(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 (auto size = read_blob_header("OSMData")) {
|
||||
|
||||
if (m_use_thread_pool) {
|
||||
m_queue.push(osmium::thread::Pool::instance().submit(DataBlobParser{read_from_input_queue(size), read_types}));
|
||||
} else {
|
||||
std::promise<osmium::memory::Buffer> promise;
|
||||
m_queue.push(promise.get_future());
|
||||
DataBlobParser data_blob_parser{read_from_input_queue(size), read_types};
|
||||
promise.set_value(data_blob_parser());
|
||||
}
|
||||
++n;
|
||||
|
||||
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(osmium::config::use_pool_threads_for_pbf_parsing()),
|
||||
m_queue(20, "pbf_parser_results"), // XXX
|
||||
m_done(false),
|
||||
m_input_queue(input_queue),
|
||||
m_input_buffer() {
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
|
||||
// handle OSMHeader
|
||||
auto size = read_blob_header("OSMHeader");
|
||||
m_header = parse_header_blob(read_from_input_queue(size));
|
||||
|
||||
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
|
944
third_party/osmium/io/detail/pbf_output_format.hpp
vendored
944
third_party/osmium/io/detail/pbf_output_format.hpp
vendored
@ -1,944 +0,0 @@
|
||||
#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/util/cast.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(static_cast_with_assert<::google::protobuf::int32>(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(static_cast_with_assert<::google::protobuf::int32>(blob_data.size()));
|
||||
|
||||
std::string blob_header_data;
|
||||
pbf_blob_header.SerializeToString(&blob_header_data);
|
||||
|
||||
uint32_t sz = htonl(static_cast_with_assert<uint32_t>(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 int64_t 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;
|
||||
int 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<::google::protobuf::int32> 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);
|
||||
if (sid > 0) {
|
||||
dense->set_keys_vals(i, string_table.map_string_id(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 user_sid = string_table.map_string_id(denseinfo->user_sid(i));
|
||||
|
||||
// delta encode the string-id
|
||||
denseinfo->set_user_sid(i, m_delta_user_sid.update(user_sid));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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; mi < relation->roles_sid_size(); ++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 static_cast<int64_t>(std::round(lonlat * OSMPBF::lonlat_resolution / location_granularity()));
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a timestamp to an int, respecting the current blocks granularity
|
||||
*/
|
||||
int64_t timestamp2int(time_t timestamp) {
|
||||
return static_cast<int64_t>(std::round(timestamp * (1000.0 / 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));
|
||||
|
||||
// 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 > 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(static_cast<::google::protobuf::int32>(m_delta_uid.update(node.uid())));
|
||||
|
||||
// record the user-name to the interim stringtable and copy the
|
||||
// interim string-id to the pbf-object
|
||||
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 (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
|
449
third_party/osmium/io/detail/pbf_parser.hpp
vendored
449
third_party/osmium/io/detail/pbf_parser.hpp
vendored
@ -1,449 +0,0 @@
|
||||
#ifndef OSMIUM_IO_DETAIL_PBF_PRIMITIVE_BLOCK_PARSER_HPP
|
||||
#define OSMIUM_IO_DETAIL_PBF_PRIMITIVE_BLOCK_PARSER_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 <algorithm>
|
||||
|
||||
#include <osmpbf/osmpbf.h>
|
||||
|
||||
#include <osmium/builder/osm_object_builder.hpp>
|
||||
#include <osmium/io/detail/pbf.hpp> // IWYU pragma: export
|
||||
#include <osmium/io/detail/zlib.hpp>
|
||||
#include <osmium/io/header.hpp>
|
||||
#include <osmium/osm/location.hpp>
|
||||
#include <osmium/osm/node.hpp>
|
||||
#include <osmium/osm/types.hpp>
|
||||
#include <osmium/memory/buffer.hpp>
|
||||
#include <osmium/osm/entity_bits.hpp>
|
||||
#include <osmium/util/cast.hpp>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
namespace io {
|
||||
|
||||
namespace detail {
|
||||
|
||||
class PBFPrimitiveBlockParser {
|
||||
|
||||
static constexpr size_t initial_buffer_size = 2 * 1024 * 1024;
|
||||
|
||||
const std::string& m_data;
|
||||
|
||||
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 std::string& data, osmium::osm_entity_bits::type read_types) :
|
||||
m_data(data),
|
||||
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.ParseFromString(m_data)) {
|
||||
throw osmium::pbf_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 osmium::pbf_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.set_id(pbf_object.id());
|
||||
|
||||
if (pbf_object.has_info()) {
|
||||
object.set_version(static_cast_with_assert<object_version_type>(pbf_object.info().version()))
|
||||
.set_changeset(static_cast_with_assert<changeset_id_type>(pbf_object.info().changeset()))
|
||||
.set_timestamp(pbf_object.info().timestamp() * m_date_factor)
|
||||
.set_uid_from_signed(pbf_object.info().uid());
|
||||
if (pbf_object.info().has_visible()) {
|
||||
object.set_visible(pbf_object.info().visible());
|
||||
}
|
||||
builder.add_user(m_stringtable->s(static_cast_with_assert<int>(pbf_object.info().user_sid())));
|
||||
} else {
|
||||
builder.add_user("", 1);
|
||||
}
|
||||
}
|
||||
|
||||
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().set_location(osmium::Location(
|
||||
(pbf_node.lon() * m_granularity + m_lon_offset) / (OSMPBF::lonlat_resolution / osmium::Location::coordinate_precision),
|
||||
(pbf_node.lat() * m_granularity + m_lat_offset) / (OSMPBF::lonlat_resolution / osmium::Location::coordinate_precision)));
|
||||
}
|
||||
|
||||
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))),
|
||||
m_stringtable->s(static_cast<int>(pbf_node.vals(tag))));
|
||||
}
|
||||
}
|
||||
|
||||
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))),
|
||||
m_stringtable->s(static_cast<int>(pbf_way.vals(tag))));
|
||||
}
|
||||
}
|
||||
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
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))),
|
||||
m_stringtable->s(static_cast<int>(pbf_relation.vals(tag))));
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
m_stringtable->s(dense.keys_vals(n)));
|
||||
|
||||
++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.set_id(last_dense_id);
|
||||
|
||||
if (dense.has_denseinfo()) {
|
||||
auto v = dense.denseinfo().version(i);
|
||||
assert(v > 0);
|
||||
node.set_version(static_cast<osmium::object_version_type>(v));
|
||||
node.set_changeset(static_cast<osmium::changeset_id_type>(last_dense_changeset));
|
||||
node.set_timestamp(last_dense_timestamp * m_date_factor);
|
||||
node.set_uid_from_signed(static_cast<osmium::signed_user_id_type>(last_dense_uid));
|
||||
node.set_visible(visible);
|
||||
builder.add_user(m_stringtable->s(static_cast<int>(last_dense_user_sid)));
|
||||
} else {
|
||||
builder.add_user("", 1);
|
||||
}
|
||||
|
||||
if (visible) {
|
||||
builder.object().set_location(osmium::Location(
|
||||
(last_dense_longitude * m_granularity + m_lon_offset) / (OSMPBF::lonlat_resolution / osmium::Location::coordinate_precision),
|
||||
(last_dense_latitude * m_granularity + m_lat_offset) / (OSMPBF::lonlat_resolution / osmium::Location::coordinate_precision)));
|
||||
}
|
||||
|
||||
last_dense_tag = add_tags(dense, last_dense_tag, &builder);
|
||||
m_buffer.commit();
|
||||
}
|
||||
}
|
||||
|
||||
}; // class PBFPrimitiveBlockParser
|
||||
|
||||
/**
|
||||
* PBF blobs can optionally be packed with the zlib algorithm.
|
||||
* This function returns the raw data (if it was unpacked) or
|
||||
* the unpacked data (if it was packed).
|
||||
*
|
||||
* @param input_data Reference to input data.
|
||||
* @returns Unpacked data
|
||||
* @throws osmium::pbf_error If there was a problem parsing the PBF
|
||||
*/
|
||||
inline std::unique_ptr<const std::string> unpack_blob(const std::string& input_data) {
|
||||
OSMPBF::Blob pbf_blob;
|
||||
if (!pbf_blob.ParseFromString(input_data)) {
|
||||
throw osmium::pbf_error("failed to parse blob");
|
||||
}
|
||||
|
||||
if (pbf_blob.has_raw()) {
|
||||
return std::unique_ptr<std::string>(pbf_blob.release_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);
|
||||
return osmium::io::detail::zlib_uncompress(pbf_blob.zlib_data(), static_cast<unsigned long>(raw_size));
|
||||
} else if (pbf_blob.has_lzma_data()) {
|
||||
throw osmium::pbf_error("lzma blobs not implemented");
|
||||
} else {
|
||||
throw osmium::pbf_error("blob contains no data");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse blob as a HeaderBlock.
|
||||
*
|
||||
* @param input_buffer Blob data
|
||||
* @returns Header object
|
||||
* @throws osmium::pbf_error If there was a parsing error
|
||||
*/
|
||||
inline osmium::io::Header parse_header_blob(const std::string& input_buffer) {
|
||||
const std::unique_ptr<const std::string> data = unpack_blob(input_buffer);
|
||||
|
||||
OSMPBF::HeaderBlock pbf_header_block;
|
||||
if (!pbf_header_block.ParseFromString(*data)) {
|
||||
throw osmium::pbf_error("failed to parse HeaderBlock");
|
||||
}
|
||||
|
||||
osmium::io::Header header;
|
||||
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") {
|
||||
header.set("pbf_dense_nodes", true);
|
||||
continue;
|
||||
}
|
||||
if (feature == "HistoricalInformation") {
|
||||
header.set_has_multiple_object_versions(true);
|
||||
continue;
|
||||
}
|
||||
|
||||
throw osmium::pbf_error(std::string("required feature not supported: ") + feature);
|
||||
}
|
||||
|
||||
for (int i=0; i < pbf_header_block.optional_features_size(); ++i) {
|
||||
const std::string& feature = pbf_header_block.optional_features(i);
|
||||
header.set("pbf_optional_feature_" + std::to_string(i), feature);
|
||||
}
|
||||
|
||||
if (pbf_header_block.has_writingprogram()) {
|
||||
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));
|
||||
header.add_box(box);
|
||||
}
|
||||
|
||||
if (pbf_header_block.has_osmosis_replication_timestamp()) {
|
||||
header.set("osmosis_replication_timestamp", osmium::Timestamp(pbf_header_block.osmosis_replication_timestamp()).to_iso());
|
||||
}
|
||||
|
||||
if (pbf_header_block.has_osmosis_replication_sequence_number()) {
|
||||
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()) {
|
||||
header.set("osmosis_replication_base_url", pbf_header_block.osmosis_replication_base_url());
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
class DataBlobParser {
|
||||
|
||||
std::string m_input_buffer;
|
||||
osmium::osm_entity_bits::type m_read_types;
|
||||
|
||||
public:
|
||||
|
||||
DataBlobParser(std::string&& input_buffer, osmium::osm_entity_bits::type read_types) :
|
||||
m_input_buffer(std::move(input_buffer)),
|
||||
m_read_types(read_types) {
|
||||
if (input_buffer.size() > OSMPBF::max_uncompressed_blob_size) {
|
||||
throw osmium::pbf_error(std::string("invalid blob size: " + std::to_string(input_buffer.size())));
|
||||
}
|
||||
}
|
||||
|
||||
DataBlobParser(const DataBlobParser& other) :
|
||||
m_input_buffer(std::move(other.m_input_buffer)),
|
||||
m_read_types(other.m_read_types) {
|
||||
}
|
||||
|
||||
DataBlobParser& operator=(const DataBlobParser&) = delete;
|
||||
|
||||
osmium::memory::Buffer operator()() {
|
||||
const std::unique_ptr<const std::string> data = unpack_blob(m_input_buffer);
|
||||
PBFPrimitiveBlockParser parser(*data, m_read_types);
|
||||
return std::move(parser());
|
||||
}
|
||||
|
||||
}; // class DataBlobParser
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace io
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_IO_DETAIL_PBF_PRIMITIVE_BLOCK_PARSER_HPP
|
204
third_party/osmium/io/detail/pbf_stringtable.hpp
vendored
204
third_party/osmium/io/detail/pbf_stringtable.hpp
vendored
@ -1,204 +0,0 @@
|
||||
#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 <cstdint>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <osmpbf/osmpbf.h>
|
||||
|
||||
#include <osmium/util/cast.hpp>
|
||||
|
||||
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;
|
||||
|
||||
}; // struct string_info
|
||||
|
||||
/**
|
||||
* 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;
|
||||
info.interim_id = static_cast_with_assert<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];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
string_id_type map_string_id(const T interim_id) const {
|
||||
return map_string_id(static_cast_with_assert<string_id_type>(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
|
106
third_party/osmium/io/detail/read_thread.hpp
vendored
106
third_party/osmium/io/detail/read_thread.hpp
vendored
@ -1,106 +0,0 @@
|
||||
#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/queue.hpp>
|
||||
#include <osmium/thread/util.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) {
|
||||
}
|
||||
|
||||
bool operator()() {
|
||||
osmium::thread::set_thread_name("_osmium_input");
|
||||
|
||||
try {
|
||||
while (!m_done) {
|
||||
std::string data {m_decompressor->read()};
|
||||
if (data.empty()) {
|
||||
m_queue.push(std::move(data));
|
||||
break;
|
||||
}
|
||||
m_queue.push(std::move(data));
|
||||
while (m_queue.size() > 10 && !m_done) {
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // class ReadThread
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace io
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_IO_DETAIL_READ_THREAD_HPP
|
156
third_party/osmium/io/detail/read_write.hpp
vendored
156
third_party/osmium/io/detail/read_write.hpp
vendored
@ -1,156 +0,0 @@
|
||||
#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 <system_error>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# include <unistd.h>
|
||||
#else
|
||||
# include <io.h>
|
||||
typedef int ssize_t;
|
||||
#endif
|
||||
|
||||
#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 opened and the stdout file descriptor (1) is returned.
|
||||
*
|
||||
* @param filename Name of file to be opened.
|
||||
* @param allow_overwrite If the file exists, should it be overwritten?
|
||||
* @returns File descriptor of open file.
|
||||
* @throws system_error if the file can't be opened.
|
||||
*/
|
||||
inline int open_for_writing(const std::string& filename, osmium::io::overwrite allow_overwrite = osmium::io::overwrite::no) {
|
||||
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 opened and the stdin file descriptor (0) is returned.
|
||||
*
|
||||
* @param filename Name of file to be opened.
|
||||
* @returns File descriptor of open file.
|
||||
* @throws system_error if the file can't be opened.
|
||||
*/
|
||||
inline int open_for_reading(const std::string& filename) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given number of bytes from the output_buffer to the file descriptor.
|
||||
* This is just a wrapper around write(2), because write(2) can write less than
|
||||
* the given number of bytes.
|
||||
*
|
||||
* @param fd File descriptor.
|
||||
* @param output_buffer Buffer with data to be written. Must be at least size bytes long.
|
||||
* @param size Number of bytes to write.
|
||||
* @throws std::system_error On error.
|
||||
*/
|
||||
inline void reliable_write(const int fd, const 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given number of bytes from the output_buffer to the file descriptor.
|
||||
* This is just a wrapper around write(2), because write(2) can write less than
|
||||
* the given number of bytes.
|
||||
*
|
||||
* @param fd File descriptor.
|
||||
* @param output_buffer Buffer with data to be written. Must be at least size bytes long.
|
||||
* @param size Number of bytes to write.
|
||||
* @throws std::system_error On error.
|
||||
*/
|
||||
inline void reliable_write(const int fd, const char* output_buffer, const size_t size) {
|
||||
reliable_write(fd, reinterpret_cast<const unsigned char*>(output_buffer), size);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace io
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_IO_DETAIL_READ_WRITE_HPP
|
86
third_party/osmium/io/detail/write_thread.hpp
vendored
86
third_party/osmium/io/detail/write_thread.hpp
vendored
@ -1,86 +0,0 @@
|
||||
#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/util.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) {
|
||||
}
|
||||
|
||||
bool 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();
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // class WriteThread
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace io
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_IO_DETAIL_WRITE_THREAD_HPP
|
726
third_party/osmium/io/detail/xml_input_format.hpp
vendored
726
third_party/osmium/io/detail/xml_input_format.hpp
vendored
@ -1,726 +0,0 @@
|
||||
#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/error.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/util.hpp>
|
||||
#include <osmium/util/cast.hpp>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
/**
|
||||
* Exception thrown when the XML parser failed. The exception contains
|
||||
* information about the place where the error happened and the type of
|
||||
* error.
|
||||
*/
|
||||
struct xml_error : public io_error {
|
||||
|
||||
unsigned long line;
|
||||
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.
|
||||
*
|
||||
* This exception is never seen by user code, it is caught internally.
|
||||
*/
|
||||
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
|
||||
}; // enum class context
|
||||
|
||||
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;
|
||||
|
||||
osmium::osm_entity_bits::type m_read_types;
|
||||
|
||||
std::atomic<bool>& m_done;
|
||||
|
||||
/**
|
||||
* A C++ wrapper for the Expat parser that makes sure no memory is leaked.
|
||||
*/
|
||||
template <class T>
|
||||
class ExpatXMLParser {
|
||||
|
||||
XML_Parser m_parser;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
ExpatXMLParser(T* callback_object) :
|
||||
m_parser(XML_ParserCreate(nullptr)) {
|
||||
if (!m_parser) {
|
||||
throw osmium::io_error("Internal error: Can not create parser");
|
||||
}
|
||||
XML_SetUserData(m_parser, callback_object);
|
||||
XML_SetElementHandler(m_parser, start_element_wrapper, end_element_wrapper);
|
||||
}
|
||||
|
||||
ExpatXMLParser(const ExpatXMLParser&) = delete;
|
||||
ExpatXMLParser(ExpatXMLParser&&) = delete;
|
||||
|
||||
ExpatXMLParser& operator=(const ExpatXMLParser&) = delete;
|
||||
ExpatXMLParser& operator=(ExpatXMLParser&&) = delete;
|
||||
|
||||
~ExpatXMLParser() {
|
||||
XML_ParserFree(m_parser);
|
||||
}
|
||||
|
||||
void operator()(const std::string& data, bool last) {
|
||||
if (XML_Parse(m_parser, data.data(), static_cast_with_assert<int>(data.size()), last) == XML_STATUS_ERROR) {
|
||||
throw osmium::xml_error(m_parser);
|
||||
}
|
||||
}
|
||||
|
||||
}; // class ExpatXMLParser
|
||||
|
||||
/**
|
||||
* A helper class that makes sure a promise is kept. It stores
|
||||
* a reference to some piece of data and to a promise and, on
|
||||
* destruction, sets the value of the promise from the data.
|
||||
*/
|
||||
template <class T>
|
||||
class PromiseKeeper {
|
||||
|
||||
T& m_data;
|
||||
std::promise<T>& m_promise;
|
||||
|
||||
public:
|
||||
|
||||
PromiseKeeper(T& data, std::promise<T>& promise) :
|
||||
m_data(data),
|
||||
m_promise(promise) {
|
||||
}
|
||||
|
||||
~PromiseKeeper() {
|
||||
m_promise.set_value(m_data);
|
||||
}
|
||||
|
||||
}; // class PromiseKeeper
|
||||
|
||||
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_read_types(read_types),
|
||||
m_done(done) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The copy constructor is needed for storing XMLParser in a std::function.
|
||||
* The copy will look the same as if it has been initialized with the
|
||||
* same parameters as the original. Any state changes in the original will
|
||||
* not be reflected in the copy.
|
||||
*/
|
||||
XMLParser(const XMLParser& other) :
|
||||
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(other.m_input_queue),
|
||||
m_queue(other.m_queue),
|
||||
m_header_promise(other.m_header_promise),
|
||||
m_read_types(other.m_read_types),
|
||||
m_done(other.m_done) {
|
||||
}
|
||||
|
||||
XMLParser(XMLParser&&) = default;
|
||||
|
||||
XMLParser& operator=(const XMLParser&) = delete;
|
||||
|
||||
XMLParser& operator=(XMLParser&&) = default;
|
||||
|
||||
~XMLParser() = default;
|
||||
|
||||
bool operator()() {
|
||||
ExpatXMLParser<XMLParser> parser(this);
|
||||
PromiseKeeper<osmium::io::Header> promise_keeper(m_header, m_header_promise);
|
||||
bool last;
|
||||
do {
|
||||
std::string data;
|
||||
m_input_queue.wait_and_pop(data);
|
||||
last = data.empty();
|
||||
try {
|
||||
parser(data, last);
|
||||
} catch (ParserIsDone&) {
|
||||
return true;
|
||||
} catch (...) {
|
||||
m_queue.push(osmium::memory::Buffer()); // empty buffer to signify eof
|
||||
throw;
|
||||
}
|
||||
} while (!last && !m_done);
|
||||
if (m_buffer.committed() > 0) {
|
||||
m_queue.push(std::move(m_buffer));
|
||||
}
|
||||
m_queue.push(osmium::memory::Buffer()); // empty buffer to signify eof
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
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.set_visible(false);
|
||||
}
|
||||
|
||||
osmium::Location location;
|
||||
for (int count = 0; attrs[count]; count += 2) {
|
||||
if (!strcmp(attrs[count], "lon")) {
|
||||
location.set_lon(std::atof(attrs[count+1])); // XXX doesn't detect garbage after the number
|
||||
} else if (!strcmp(attrs[count], "lat")) {
|
||||
location.set_lat(std::atof(attrs[count+1])); // XXX doesn't detect garbage after the number
|
||||
} else if (!strcmp(attrs[count], "user")) {
|
||||
user = attrs[count+1];
|
||||
} else {
|
||||
object.set_attribute(attrs[count], attrs[count+1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (location && object.type() == osmium::item_type::node) {
|
||||
static_cast<osmium::Node&>(object).set_location(location);
|
||||
}
|
||||
|
||||
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.set_lon(atof(attrs[count+1]));
|
||||
} else if (!strcmp(attrs[count], "min_lat")) {
|
||||
min.set_lat(atof(attrs[count+1]));
|
||||
} else if (!strcmp(attrs[count], "max_lon")) {
|
||||
max.set_lon(atof(attrs[count+1]));
|
||||
} else if (!strcmp(attrs[count], "max_lat")) {
|
||||
max.set_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];
|
||||
} else 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_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.set_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.set_lon(atof(attrs[count+1]));
|
||||
} else if (!strcmp(attrs[count], "minlat")) {
|
||||
min.set_lat(atof(attrs[count+1]));
|
||||
} else if (!strcmp(attrs[count], "maxlon")) {
|
||||
max.set_lon(atof(attrs[count+1]));
|
||||
} else if (!strcmp(attrs[count], "maxlat")) {
|
||||
max.set_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);
|
||||
}
|
||||
}
|
||||
|
||||
}; // class XMLParser
|
||||
|
||||
class XMLInputFormat : public osmium::io::detail::InputFormat {
|
||||
|
||||
static constexpr size_t 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;
|
||||
std::future<bool> m_parser_future;
|
||||
|
||||
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(max_queue_size, "xml_parser_results"),
|
||||
m_done(false),
|
||||
m_header_promise(),
|
||||
m_parser_future(std::async(std::launch::async, XMLParser(input_queue, m_queue, m_header_promise, read_which_entities, m_done))) {
|
||||
}
|
||||
|
||||
~XMLInputFormat() {
|
||||
try {
|
||||
close();
|
||||
} catch (...) {
|
||||
// ignore any exceptions at this point because destructor should not throw
|
||||
}
|
||||
}
|
||||
|
||||
virtual osmium::io::Header header() override final {
|
||||
osmium::thread::check_for_exception(m_parser_future);
|
||||
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);
|
||||
}
|
||||
|
||||
osmium::thread::check_for_exception(m_parser_future);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void close() {
|
||||
m_done = true;
|
||||
osmium::thread::wait_until_done(m_parser_future);
|
||||
}
|
||||
|
||||
}; // 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
|
481
third_party/osmium/io/detail/xml_output_format.hpp
vendored
481
third_party/osmium/io/detail/xml_output_format.hpp
vendored
@ -1,481 +0,0 @@
|
||||
#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 <cassert>
|
||||
#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];
|
||||
size_t max_size = sizeof(buffer)/sizeof(char);
|
||||
#ifndef NDEBUG
|
||||
int len =
|
||||
#endif
|
||||
#ifndef _MSC_VER
|
||||
snprintf(buffer, max_size, format, value);
|
||||
#else
|
||||
_snprintf(buffer, max_size, format, value);
|
||||
#endif
|
||||
assert(len > 0 && static_cast<size_t>(len) < max_size);
|
||||
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
|
||||
}; // enum class operation
|
||||
|
||||
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&&) = default;
|
||||
XMLOutputBlock& operator=(XMLOutputBlock&&) = 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::util::double2string(std::back_inserter(m_out), node.location().lat_without_check(), 7);
|
||||
m_out += "\" lon=\"";
|
||||
osmium::util::double2string(std::back_inserter(m_out), node.location().lon_without_check(), 7);
|
||||
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 {
|
||||
m_output_queue.push(osmium::thread::Pool::instance().submit(XMLOutputBlock{std::move(buffer), m_write_visible_flag, m_file.is_true("xml_change_format")}));
|
||||
}
|
||||
|
||||
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
|
99
third_party/osmium/io/detail/zlib.hpp
vendored
99
third_party/osmium/io/detail/zlib.hpp
vendored
@ -1,99 +0,0 @@
|
||||
#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 <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
namespace io {
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* Compress data using zlib.
|
||||
*
|
||||
* @param input Data to compress.
|
||||
* @returns 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.
|
||||
* @returns Uncompressed data.
|
||||
*/
|
||||
inline std::unique_ptr<std::string> zlib_uncompress(const std::string& input, unsigned long raw_size) {
|
||||
auto output = std::unique_ptr<std::string>(new std::string(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
|
57
third_party/osmium/io/error.hpp
vendored
57
third_party/osmium/io/error.hpp
vendored
@ -1,57 +0,0 @@
|
||||
#ifndef OSMIUM_IO_ERROR_HPP
|
||||
#define OSMIUM_IO_ERROR_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>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
/**
|
||||
* Exception thrown when some kind of input/output operation failed.
|
||||
*/
|
||||
struct io_error : public std::runtime_error {
|
||||
|
||||
io_error(const std::string& what) :
|
||||
std::runtime_error(what) {
|
||||
}
|
||||
|
||||
io_error(const char* what) :
|
||||
std::runtime_error(what) {
|
||||
}
|
||||
|
||||
}; // struct io_error
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_IO_ERROR_HPP
|
343
third_party/osmium/io/file.hpp
vendored
343
third_party/osmium/io/file.hpp
vendored
@ -1,343 +0,0 @@
|
||||
#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 {
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
const char* m_buffer;
|
||||
size_t m_buffer_size;
|
||||
|
||||
std::string m_format_string;
|
||||
|
||||
file_format m_file_format {file_format::unknown};
|
||||
|
||||
file_compression m_file_compression {file_compression::none};
|
||||
|
||||
bool m_has_multiple_object_versions {false};
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create File using type and encoding from filename or given
|
||||
* format specification.
|
||||
*
|
||||
* @param filename Filename including suffix. The type and encoding
|
||||
* of the file will be taken from the suffix.
|
||||
* An empty filename or "-" means stdin or stdout.
|
||||
* @param format File format as string. See the description of the
|
||||
* parse_format() function for details.
|
||||
*/
|
||||
explicit File(const std::string& filename = "", const std::string& format = "") :
|
||||
Options(),
|
||||
m_filename(filename),
|
||||
m_buffer(nullptr),
|
||||
m_buffer_size(0),
|
||||
m_format_string(format) {
|
||||
|
||||
// stdin/stdout
|
||||
if (filename == "" || filename == "-") {
|
||||
m_filename = "";
|
||||
default_settings_for_stdinout();
|
||||
}
|
||||
|
||||
// filename is actually a URL
|
||||
std::string protocol = m_filename.substr(0, m_filename.find_first_of(':'));
|
||||
if (protocol == "http" || protocol == "https") {
|
||||
default_settings_for_url();
|
||||
}
|
||||
|
||||
detect_format_from_suffix(m_filename);
|
||||
|
||||
if (format != "") {
|
||||
parse_format(format);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create File using buffer pointer and size and type and encoding
|
||||
* from given format specification.
|
||||
*
|
||||
* @param buffer Pointer to buffer with data.
|
||||
* @param size Size of buffer.
|
||||
* @param format File format as string. See the description of the
|
||||
* parse_format() function for details.
|
||||
*/
|
||||
explicit File(const char* buffer, size_t size, const std::string& format = "") :
|
||||
Options(),
|
||||
m_filename(),
|
||||
m_buffer(buffer),
|
||||
m_buffer_size(size),
|
||||
m_format_string(format) {
|
||||
|
||||
default_settings_for_stdinout();
|
||||
|
||||
if (format != "") {
|
||||
parse_format(format);
|
||||
}
|
||||
}
|
||||
|
||||
File(const File&) = default;
|
||||
File& operator=(const File&) = default;
|
||||
|
||||
File(File&&) = default;
|
||||
File& operator=(File&&) = default;
|
||||
|
||||
~File() = default;
|
||||
|
||||
const char* buffer() const noexcept {
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
size_t buffer_size() const noexcept {
|
||||
return m_buffer_size;
|
||||
}
|
||||
|
||||
void parse_format(const std::string& format) {
|
||||
std::vector<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 noexcept {
|
||||
return m_file_format;
|
||||
}
|
||||
|
||||
File& set_format(file_format format) noexcept {
|
||||
m_file_format = format;
|
||||
return *this;
|
||||
}
|
||||
|
||||
file_compression compression() const noexcept {
|
||||
return m_file_compression;
|
||||
}
|
||||
|
||||
File& set_compression(file_compression compression) noexcept {
|
||||
m_file_compression = compression;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool has_multiple_object_versions() const noexcept {
|
||||
return m_has_multiple_object_versions;
|
||||
}
|
||||
|
||||
File& set_has_multiple_object_versions(bool value) noexcept {
|
||||
m_has_multiple_object_versions = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
File& filename(const std::string& filename) {
|
||||
if (filename == "-") {
|
||||
m_filename = "";
|
||||
} else {
|
||||
m_filename = filename;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const std::string& filename() const noexcept {
|
||||
return m_filename;
|
||||
}
|
||||
|
||||
}; // class File
|
||||
|
||||
} // namespace io
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_IO_FILE_HPP
|
72
third_party/osmium/io/file_compression.hpp
vendored
72
third_party/osmium/io/file_compression.hpp
vendored
@ -1,72 +0,0 @@
|
||||
#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
|
||||
};
|
||||
|
||||
// avoid g++ false positive
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wreturn-type"
|
||||
inline const char* as_string(file_compression compression) {
|
||||
switch (compression) {
|
||||
case file_compression::none:
|
||||
return "none";
|
||||
case file_compression::gzip:
|
||||
return "gzip";
|
||||
case file_compression::bzip2:
|
||||
return "bzip2";
|
||||
}
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
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
|
78
third_party/osmium/io/file_format.hpp
vendored
78
third_party/osmium/io/file_format.hpp
vendored
@ -1,78 +0,0 @@
|
||||
#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
|
||||
};
|
||||
|
||||
// avoid g++ false positive
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wreturn-type"
|
||||
inline const char* as_string(file_format format) {
|
||||
switch (format) {
|
||||
case file_format::unknown:
|
||||
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";
|
||||
}
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
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
|
238
third_party/osmium/io/gzip_compression.hpp
vendored
238
third_party/osmium/io/gzip_compression.hpp
vendored
@ -1,238 +0,0 @@
|
||||
#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 <errno.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include <osmium/io/compression.hpp>
|
||||
#include <osmium/io/file_compression.hpp>
|
||||
#include <osmium/util/cast.hpp>
|
||||
#include <osmium/util/compatibility.hpp>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
/**
|
||||
* Exception thrown when there are problems compressing or
|
||||
* decompressing gzip files.
|
||||
*/
|
||||
struct gzip_error : public std::runtime_error {
|
||||
|
||||
int gzip_error_code;
|
||||
int system_errno;
|
||||
|
||||
gzip_error(const std::string& what, int error_code) :
|
||||
std::runtime_error(what),
|
||||
gzip_error_code(error_code),
|
||||
system_errno(error_code == Z_ERRNO ? errno : 0) {
|
||||
}
|
||||
|
||||
}; // struct gzip_error
|
||||
|
||||
namespace io {
|
||||
|
||||
namespace detail {
|
||||
|
||||
OSMIUM_NORETURN inline void throw_gzip_error(gzFile gzfile, const char* msg, int zlib_error=0) {
|
||||
std::string error("gzip error: ");
|
||||
error += msg;
|
||||
error += ": ";
|
||||
int errnum = zlib_error;
|
||||
if (zlib_error) {
|
||||
error += std::to_string(zlib_error);
|
||||
} else {
|
||||
error += ::gzerror(gzfile, &errnum);
|
||||
}
|
||||
throw osmium::gzip_error(error, errnum);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class GzipCompressor : public Compressor {
|
||||
|
||||
gzFile m_gzfile;
|
||||
|
||||
public:
|
||||
|
||||
explicit GzipCompressor(int fd) :
|
||||
Compressor(),
|
||||
m_gzfile(::gzdopen(fd, "w")) {
|
||||
if (!m_gzfile) {
|
||||
detail::throw_gzip_error(m_gzfile, "write initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
~GzipCompressor() override final {
|
||||
close();
|
||||
}
|
||||
|
||||
void write(const std::string& data) override final {
|
||||
if (!data.empty()) {
|
||||
int nwrite = ::gzwrite(m_gzfile, data.data(), static_cast_with_assert<unsigned int>(data.size()));
|
||||
if (nwrite == 0) {
|
||||
detail::throw_gzip_error(m_gzfile, "write failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void close() override final {
|
||||
if (m_gzfile) {
|
||||
int result = ::gzclose(m_gzfile);
|
||||
m_gzfile = nullptr;
|
||||
if (result != Z_OK) {
|
||||
detail::throw_gzip_error(m_gzfile, "write close failed", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}; // class GzipCompressor
|
||||
|
||||
class GzipDecompressor : public Decompressor {
|
||||
|
||||
gzFile m_gzfile;
|
||||
|
||||
public:
|
||||
|
||||
explicit GzipDecompressor(int fd) :
|
||||
Decompressor(),
|
||||
m_gzfile(::gzdopen(fd, "r")) {
|
||||
if (!m_gzfile) {
|
||||
detail::throw_gzip_error(m_gzfile, "read initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
~GzipDecompressor() override final {
|
||||
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()), static_cast_with_assert<unsigned int>(buffer.size()));
|
||||
if (nread < 0) {
|
||||
detail::throw_gzip_error(m_gzfile, "read failed");
|
||||
}
|
||||
buffer.resize(static_cast<std::string::size_type>(nread));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void close() override final {
|
||||
if (m_gzfile) {
|
||||
int result = ::gzclose(m_gzfile);
|
||||
m_gzfile = nullptr;
|
||||
if (result != Z_OK) {
|
||||
detail::throw_gzip_error(m_gzfile, "read close failed", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}; // class GzipDecompressor
|
||||
|
||||
class GzipBufferDecompressor : public Decompressor {
|
||||
|
||||
const char* m_buffer;
|
||||
size_t m_buffer_size;
|
||||
z_stream m_zstream;
|
||||
|
||||
public:
|
||||
|
||||
GzipBufferDecompressor(const char* buffer, size_t size) :
|
||||
m_buffer(buffer),
|
||||
m_buffer_size(size),
|
||||
m_zstream() {
|
||||
m_zstream.next_in = reinterpret_cast<unsigned char*>(const_cast<char*>(buffer));
|
||||
m_zstream.avail_in = static_cast_with_assert<unsigned int>(size);
|
||||
int result = inflateInit2(&m_zstream, MAX_WBITS | 32);
|
||||
if (result != Z_OK) {
|
||||
std::string message("gzip error: decompression init failed: ");
|
||||
if (m_zstream.msg) {
|
||||
message.append(m_zstream.msg);
|
||||
}
|
||||
throw osmium::gzip_error(message, result);
|
||||
}
|
||||
}
|
||||
|
||||
~GzipBufferDecompressor() override final {
|
||||
inflateEnd(&m_zstream);
|
||||
}
|
||||
|
||||
std::string read() override final {
|
||||
if (!m_buffer) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const size_t buffer_size = 10240;
|
||||
std::string output(buffer_size, '\0');
|
||||
m_zstream.next_out = reinterpret_cast<unsigned char*>(const_cast<char*>(output.data()));
|
||||
m_zstream.avail_out = buffer_size;
|
||||
int result = inflate(&m_zstream, Z_SYNC_FLUSH);
|
||||
|
||||
if (result != Z_OK) {
|
||||
m_buffer = nullptr;
|
||||
m_buffer_size = 0;
|
||||
}
|
||||
|
||||
if (result != Z_OK && result != Z_STREAM_END) {
|
||||
std::string message("gzip error: inflate failed: ");
|
||||
if (m_zstream.msg) {
|
||||
message.append(m_zstream.msg);
|
||||
}
|
||||
throw osmium::gzip_error(message, result);
|
||||
}
|
||||
|
||||
output.resize(static_cast<unsigned long>(m_zstream.next_out - reinterpret_cast<const unsigned char*>(output.data())));
|
||||
return output;
|
||||
}
|
||||
|
||||
}; // class GzipBufferDecompressor
|
||||
|
||||
namespace {
|
||||
|
||||
const bool registered_gzip_compression = osmium::io::CompressionFactory::instance().register_compression(osmium::io::file_compression::gzip,
|
||||
[](int fd) { return new osmium::io::GzipCompressor(fd); },
|
||||
[](int fd) { return new osmium::io::GzipDecompressor(fd); },
|
||||
[](const char* buffer, size_t size) { return new osmium::io::GzipBufferDecompressor(buffer, size); }
|
||||
);
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
} // namespace io
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_IO_GZIP_COMPRESSION_HPP
|
122
third_party/osmium/io/header.hpp
vendored
122
third_party/osmium/io/header.hpp
vendored
@ -1,122 +0,0 @@
|
||||
#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(const 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() noexcept {
|
||||
return m_boxes;
|
||||
}
|
||||
|
||||
const std::vector<osmium::Box>& boxes() const noexcept {
|
||||
return m_boxes;
|
||||
}
|
||||
|
||||
Header& boxes(const std::vector<osmium::Box>& boxes) noexcept {
|
||||
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 noexcept {
|
||||
return m_has_multiple_object_versions;
|
||||
}
|
||||
|
||||
Header& set_has_multiple_object_versions(bool value) noexcept {
|
||||
m_has_multiple_object_versions = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
}; // class Header
|
||||
|
||||
} // namespace io
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_IO_HEADER_HPP
|
139
third_party/osmium/io/input_iterator.hpp
vendored
139
third_party/osmium/io/input_iterator.hpp
vendored
@ -1,139 +0,0 @@
|
||||
#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() noexcept :
|
||||
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 noexcept {
|
||||
return m_source == rhs.m_source &&
|
||||
m_buffer == rhs.m_buffer &&
|
||||
m_iter == rhs.m_iter;
|
||||
}
|
||||
|
||||
bool operator!=(const InputIterator& rhs) const noexcept {
|
||||
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
third_party/osmium/io/opl_output.hpp
vendored
39
third_party/osmium/io/opl_output.hpp
vendored
@ -1,39 +0,0 @@
|
||||
#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
|
116
third_party/osmium/io/output_iterator.hpp
vendored
116
third_party/osmium/io/output_iterator.hpp
vendored
@ -1,116 +0,0 @@
|
||||
#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) {
|
||||
}
|
||||
|
||||
}; // struct buffer_wrapper
|
||||
|
||||
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::buffer_is_full&) {
|
||||
flush();
|
||||
m_buffer_wrapper->buffer.push_back(item);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputIterator& operator=(const osmium::DiffObject& diff) {
|
||||
return this->operator=(diff.curr());
|
||||
}
|
||||
|
||||
OutputIterator& operator*() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputIterator& operator++() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputIterator& operator++(int) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
}; // class OutputIterator
|
||||
|
||||
} // namespace io
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_IO_OUTPUT_ITERATOR_HPP
|
52
third_party/osmium/io/overwrite.hpp
vendored
52
third_party/osmium/io/overwrite.hpp
vendored
@ -1,52 +0,0 @@
|
||||
#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
third_party/osmium/io/pbf_input.hpp
vendored
39
third_party/osmium/io/pbf_input.hpp
vendored
@ -1,39 +0,0 @@
|
||||
#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
third_party/osmium/io/pbf_output.hpp
vendored
39
third_party/osmium/io/pbf_output.hpp
vendored
@ -1,39 +0,0 @@
|
||||
#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
|
303
third_party/osmium/io/reader.hpp
vendored
303
third_party/osmium/io/reader.hpp
vendored
@ -1,303 +0,0 @@
|
||||
#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 <system_error>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#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/util.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;
|
||||
std::future<bool> m_read_future;
|
||||
|
||||
std::unique_ptr<osmium::io::detail::InputFormat> m_input;
|
||||
|
||||
#ifndef _WIN32
|
||||
/**
|
||||
* 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.
|
||||
* @returns File descriptor of pipe in the parent.
|
||||
* @throws std::system_error if a system call fails.
|
||||
*/
|
||||
static int execute(const std::string& command, const std::string& filename, int* childpid) {
|
||||
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];
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @returns File descriptor of open file or pipe.
|
||||
* @throws std::system_error if a system call fails.
|
||||
*/
|
||||
static int open_input_file_or_url(const std::string& filename, int* childpid) {
|
||||
std::string protocol = filename.substr(0, filename.find_first_of(':'));
|
||||
if (protocol == "http" || protocol == "https" || protocol == "ftp" || protocol == "file") {
|
||||
#ifndef _WIN32
|
||||
return execute("curl", filename, childpid);
|
||||
#else
|
||||
throw std::runtime_error("Reading OSM files from the network currently not supported on Windows.");
|
||||
#endif
|
||||
} 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(20, "raw_input"), // XXX
|
||||
m_decompressor(m_file.buffer() ?
|
||||
osmium::io::CompressionFactory::instance().create_decompressor(file.compression(), m_file.buffer(), m_file.buffer_size()) :
|
||||
osmium::io::CompressionFactory::instance().create_decompressor(file.compression(), open_input_file_or_url(m_file.filename(), &m_childpid))),
|
||||
m_read_future(std::async(std::launch::async, detail::ReadThread(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() {
|
||||
try {
|
||||
close();
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
#ifndef _WIN32
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
osmium::thread::wait_until_done(m_read_future);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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. After end-of-file all read() calls will return an
|
||||
* invalid buffer. An invalid buffer is also always returned if
|
||||
* osmium::osm_entity_bits::nothing was set when the Reader was
|
||||
* constructed.
|
||||
*
|
||||
* @returns Buffer.
|
||||
* @throws Some form of std::runtime_error if there is an error.
|
||||
*/
|
||||
osmium::memory::Buffer read() {
|
||||
// If an exception happened in the input thread, re-throw
|
||||
// it in this (the main) thread.
|
||||
osmium::thread::check_for_exception(m_read_future);
|
||||
|
||||
if (m_read_which_entities == osmium::osm_entity_bits::nothing || m_input_done) {
|
||||
// If the caller didn't want anything but the header, it will
|
||||
// always get an empty buffer here.
|
||||
return osmium::memory::Buffer();
|
||||
}
|
||||
|
||||
osmium::memory::Buffer buffer = m_input->read();
|
||||
if (!buffer) {
|
||||
m_input_done = true;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the end of file been reached? This is set after the last
|
||||
* data has been read. It is also set by calling close().
|
||||
*/
|
||||
bool eof() const {
|
||||
return m_input_done;
|
||||
}
|
||||
|
||||
}; // 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
third_party/osmium/io/reader_iterator.hpp
vendored
51
third_party/osmium/io/reader_iterator.hpp
vendored
@ -1,51 +0,0 @@
|
||||
#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
|
145
third_party/osmium/io/writer.hpp
vendored
145
third_party/osmium/io/writer.hpp
vendored
@ -1,145 +0,0 @@
|
||||
#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/util.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;
|
||||
|
||||
osmium::io::detail::data_queue_type m_output_queue;
|
||||
|
||||
std::unique_ptr<osmium::io::detail::OutputFormat> m_output;
|
||||
|
||||
std::unique_ptr<osmium::io::Compressor> m_compressor;
|
||||
|
||||
std::future<bool> m_write_future;
|
||||
|
||||
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_queue(20, "raw_output"), // XXX
|
||||
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_future(std::async(std::launch::async, detail::WriteThread(m_output_queue, m_compressor.get()))) {
|
||||
assert(!m_file.buffer());
|
||||
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) {
|
||||
osmium::thread::check_for_exception(m_write_future);
|
||||
if (buffer.committed() > 0) {
|
||||
m_output->write_buffer(std::move(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush writes to output file and closes it. If you do not
|
||||
* call this, the destructor of Writer will also do the same
|
||||
* thing. But because this call might thrown an exception,
|
||||
* it is better to call close() explicitly.
|
||||
*
|
||||
* @throws Some form of std::runtime_error when there is a problem.
|
||||
*/
|
||||
void close() {
|
||||
m_output->close();
|
||||
osmium::thread::wait_until_done(m_write_future);
|
||||
}
|
||||
|
||||
}; // class Writer
|
||||
|
||||
} // namespace io
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_IO_WRITER_HPP
|
39
third_party/osmium/io/xml_input.hpp
vendored
39
third_party/osmium/io/xml_input.hpp
vendored
@ -1,39 +0,0 @@
|
||||
#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
third_party/osmium/io/xml_output.hpp
vendored
39
third_party/osmium/io/xml_output.hpp
vendored
@ -1,39 +0,0 @@
|
||||
#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
|
534
third_party/osmium/memory/buffer.hpp
vendored
534
third_party/osmium/memory/buffer.hpp
vendored
@ -1,534 +0,0 @@
|
||||
#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 {
|
||||
|
||||
/**
|
||||
* Exception thrown by the osmium::memory::Buffer class when somebody tries
|
||||
* to write data into a buffer and it doesn't fit. Buffers with internal
|
||||
* memory management will not throw this exception, but increase their size.
|
||||
*/
|
||||
struct buffer_is_full : public std::runtime_error {
|
||||
|
||||
buffer_is_full() :
|
||||
std::runtime_error("Osmium buffer is full") {
|
||||
}
|
||||
|
||||
}; // struct buffer_is_full
|
||||
|
||||
/**
|
||||
* @brief Memory management of items in buffers and iterators over this data.
|
||||
*/
|
||||
namespace memory {
|
||||
|
||||
/**
|
||||
* 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 buffer_is_full exception.
|
||||
* You can use the set_full_callback() method to set a callback functor
|
||||
* which will be called instead of throwing an exception.
|
||||
*/
|
||||
class Buffer {
|
||||
|
||||
public:
|
||||
|
||||
enum class auto_grow : bool {
|
||||
yes = true,
|
||||
no = false
|
||||
}; // enum class auto_grow
|
||||
|
||||
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() noexcept :
|
||||
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.
|
||||
* @throws 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.
|
||||
* @throws std::invalid_argument When the capacity or committed isn't a multiple of the alignment.
|
||||
*/
|
||||
explicit Buffer(unsigned char* data, size_t capacity, size_t committed) :
|
||||
m_memory(),
|
||||
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 noexcept {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the capacity of the buffer, ie how many bytes it can contain.
|
||||
*/
|
||||
size_t capacity() const noexcept {
|
||||
return m_capacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes already filled in this buffer.
|
||||
*/
|
||||
size_t committed() const noexcept {
|
||||
return m_committed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes currently filled in this buffer that
|
||||
* are not yet committed.
|
||||
*/
|
||||
size_t written() const noexcept {
|
||||
return m_written;
|
||||
}
|
||||
|
||||
/**
|
||||
* This tests if the current state of the buffer is aligned
|
||||
* properly. Can be used for asserts.
|
||||
*/
|
||||
bool is_aligned() const noexcept {
|
||||
return (m_written % align_bytes == 0) && (m_committed % align_bytes == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set functor to be called whenever the buffer is full
|
||||
* instead of throwing buffer_is_full.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @returns 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.
|
||||
*
|
||||
* @returns 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.
|
||||
* @returns 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 buffer_is_full exception is thrown.
|
||||
*
|
||||
* @param size Number of bytes to reserve.
|
||||
* @returns Pointer to reserved space. Note that this pointer is
|
||||
* only guaranteed to be valid until the next call to
|
||||
* reserve_space().
|
||||
* @throws osmium::buffer_is_full Might be thrown if the buffer is full.
|
||||
*/
|
||||
unsigned char* reserve_space(const size_t size) {
|
||||
if (m_written + size > m_capacity) {
|
||||
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 osmium::buffer_is_full();
|
||||
}
|
||||
}
|
||||
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.
|
||||
* @returns 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) {
|
||||
if (begin() == end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
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.advance_once();
|
||||
}
|
||||
}
|
||||
|
||||
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) noexcept {
|
||||
return lhs.data() == rhs.data() && lhs.capacity() == rhs.capacity() && lhs.committed() == rhs.committed();
|
||||
}
|
||||
|
||||
inline bool operator!=(const Buffer& lhs, const Buffer& rhs) noexcept {
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
|
||||
} // namespace memory
|
||||
|
||||
} // namespace osmium
|
||||
|
||||
#endif // OSMIUM_MEMORY_BUFFER_HPP
|
153
third_party/osmium/memory/collection.hpp
vendored
153
third_party/osmium/memory/collection.hpp
vendored
@ -1,153 +0,0 @@
|
||||
#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() noexcept :
|
||||
m_data(nullptr) {
|
||||
}
|
||||
|
||||
CollectionIterator(data_type data) noexcept :
|
||||
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 noexcept {
|
||||
return m_data == rhs.m_data;
|
||||
}
|
||||
|
||||
bool operator!=(const CollectionIterator<TMember>& rhs) const noexcept {
|
||||
return m_data != rhs.m_data;
|
||||
}
|
||||
|
||||
unsigned char* data() const noexcept {
|
||||
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<const 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
|
179
third_party/osmium/memory/item.hpp
vendored
179
third_party/osmium/memory/item.hpp
vendored
@ -1,179 +0,0 @@
|
||||
#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>
|
||||
#include <type_traits>
|
||||
|
||||
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;
|
||||
|
||||
template <typename T>
|
||||
inline T padded_length(T length) noexcept {
|
||||
static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value,
|
||||
"Template parameter must be unsigned integral type");
|
||||
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() noexcept {
|
||||
return reinterpret_cast<unsigned char*>(this);
|
||||
}
|
||||
|
||||
const unsigned char* data() const noexcept {
|
||||
return reinterpret_cast<const unsigned char*>(this);
|
||||
}
|
||||
|
||||
}; // class ItemHelper
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class Item : public osmium::memory::detail::ItemHelper {
|
||||
|
||||
item_size_type m_size;
|
||||
item_type m_type;
|
||||
uint16_t m_removed : 1;
|
||||
uint16_t m_padding : 15;
|
||||
|
||||
template <class TMember>
|
||||
friend class CollectionIterator;
|
||||
|
||||
template <class TMember>
|
||||
friend class ItemIterator;
|
||||
|
||||
friend class osmium::builder::Builder;
|
||||
|
||||
Item& add_size(const item_size_type size) noexcept {
|
||||
m_size += size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
explicit Item(item_size_type size=0, item_type type=item_type()) noexcept :
|
||||
m_size(size),
|
||||
m_type(type),
|
||||
m_removed(false),
|
||||
m_padding(0) {
|
||||
}
|
||||
|
||||
Item(const Item&) = delete;
|
||||
Item(Item&&) = delete;
|
||||
|
||||
Item& operator=(const Item&) = delete;
|
||||
Item& operator=(Item&&) = delete;
|
||||
|
||||
Item& set_type(const item_type item_type) noexcept {
|
||||
m_type = item_type;
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
unsigned char* next() noexcept {
|
||||
return data() + padded_size();
|
||||
}
|
||||
|
||||
const unsigned char* next() const noexcept {
|
||||
return data() + padded_size();
|
||||
}
|
||||
|
||||
item_size_type byte_size() const noexcept {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
item_size_type padded_size() const {
|
||||
return padded_length(m_size);
|
||||
}
|
||||
|
||||
item_type type() const noexcept {
|
||||
return m_type;
|
||||
}
|
||||
|
||||
bool removed() const noexcept {
|
||||
return m_removed;
|
||||
}
|
||||
|
||||
void set_removed(bool removed) noexcept {
|
||||
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
|
234
third_party/osmium/memory/item_iterator.hpp
vendored
234
third_party/osmium/memory/item_iterator.hpp
vendored
@ -1,234 +0,0 @@
|
||||
#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/item_type.hpp>
|
||||
|
||||
namespace osmium {
|
||||
|
||||
class Node;
|
||||
class Way;
|
||||
class Relation;
|
||||
class Area;
|
||||
class Changeset;
|
||||
class OSMObject;
|
||||
class OSMEntity;
|
||||
class TagList;
|
||||
class WayNodeList;
|
||||
class RelationMemberList;
|
||||
class InnerRing;
|
||||
class OuterRing;
|
||||
|
||||
namespace memory {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
inline bool type_is_compatible(osmium::item_type) noexcept {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool type_is_compatible<osmium::Node>(osmium::item_type t) noexcept {
|
||||
return t == osmium::item_type::node;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool type_is_compatible<osmium::Way>(osmium::item_type t) noexcept {
|
||||
return t == osmium::item_type::way;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool type_is_compatible<osmium::Relation>(osmium::item_type t) noexcept {
|
||||
return t == osmium::item_type::relation;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool type_is_compatible<osmium::Area>(osmium::item_type t) noexcept {
|
||||
return t == osmium::item_type::area;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool type_is_compatible<osmium::Changeset>(osmium::item_type t) noexcept {
|
||||
return t == osmium::item_type::changeset;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool type_is_compatible<osmium::OSMObject>(osmium::item_type t) noexcept {
|
||||
return t == osmium::item_type::node || t == osmium::item_type::way || t == osmium::item_type::relation || t == osmium::item_type::area;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool type_is_compatible<osmium::OSMEntity>(osmium::item_type t) noexcept {
|
||||
return t == osmium::item_type::node || t == osmium::item_type::way || t == osmium::item_type::relation || t == osmium::item_type::area || t == osmium::item_type::changeset;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool type_is_compatible<osmium::TagList>(osmium::item_type t) noexcept {
|
||||
return t == osmium::item_type::tag_list;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool type_is_compatible<osmium::WayNodeList>(osmium::item_type t) noexcept {
|
||||
return t == osmium::item_type::way_node_list;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool type_is_compatible<osmium::RelationMemberList>(osmium::item_type t) noexcept {
|
||||
return t == osmium::item_type::relation_member_list || t == osmium::item_type::relation_member_list_with_full_members;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool type_is_compatible<osmium::OuterRing>(osmium::item_type t) noexcept {
|
||||
return t == osmium::item_type::outer_ring;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool type_is_compatible<osmium::InnerRing>(osmium::item_type t) noexcept {
|
||||
return t == osmium::item_type::inner_ring;
|
||||
}
|
||||
|
||||
} // 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() noexcept :
|
||||
m_data(nullptr),
|
||||
m_end(nullptr) {
|
||||
}
|
||||
|
||||
ItemIterator(data_type data, data_type end) :
|
||||
m_data(data),
|
||||
m_end(end) {
|
||||
advance_to_next_item_of_right_type();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
ItemIterator<T> cast() const {
|
||||
return ItemIterator<T>(m_data, m_end);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like operator++() but will NOT skip items of unwanted
|
||||
* types. Do not use this unless you know what you are
|
||||
* doing.
|
||||
*/
|
||||
ItemIterator<TMember>& advance_once() {
|
||||
assert(m_data);
|
||||
assert(m_data != m_end);
|
||||
m_data = reinterpret_cast<TMember*>(m_data)->next();
|
||||
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);
|
||||
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
third_party/osmium/object_pointer_collection.hpp
vendored
112
third_party/osmium/object_pointer_collection.hpp
vendored
@ -1,112 +0,0 @@
|
||||
#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() noexcept :
|
||||
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
third_party/osmium/osm.hpp
vendored
48
third_party/osmium/osm.hpp
vendored
@ -1,48 +0,0 @@
|
||||
#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
|
193
third_party/osmium/osm/area.hpp
vendored
193
third_party/osmium/osm/area.hpp
vendored
@ -1,193 +0,0 @@
|
||||
#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 <cassert>
|
||||
#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 noexcept {
|
||||
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;
|
||||
case osmium::item_type::tag_list:
|
||||
// ignore tags
|
||||
break;
|
||||
case osmium::item_type::undefined:
|
||||
case osmium::item_type::node:
|
||||
case osmium::item_type::way:
|
||||
case osmium::item_type::relation:
|
||||
case osmium::item_type::area:
|
||||
case osmium::item_type::changeset:
|
||||
case osmium::item_type::way_node_list:
|
||||
case osmium::item_type::relation_member_list:
|
||||
case osmium::item_type::relation_member_list_with_full_members:
|
||||
assert(false && "Children of Area can only be outer/inner_ring and tag_list.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this area a multipolygon, ie. has it more than one outer ring?
|
||||
*/
|
||||
bool is_multipolygon() const {
|
||||
return num_rings().first > 1;
|
||||
}
|
||||
|
||||
osmium::memory::ItemIterator<const osmium::InnerRing> inner_ring_cbegin(const osmium::memory::ItemIterator<const osmium::OuterRing>& it) const {
|
||||
return it.cast<const osmium::InnerRing>();
|
||||
}
|
||||
|
||||
osmium::memory::ItemIterator<const osmium::InnerRing> inner_ring_cend(const osmium::memory::ItemIterator<const osmium::OuterRing>& it) const {
|
||||
return std::next(it).cast<const osmium::InnerRing>();
|
||||
}
|
||||
|
||||
}; // 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
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user