multipolygon_collector.hpp
Go to the documentation of this file.
#ifndef OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP
#define OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP
/*
This file is part of Osmium (http://osmcode.org/libosmium).
Copyright 2013-2016 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/location.hpp>
#include <osmium/osm/node_ref.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 {
namespace relations {
class RelationMeta;
} // namespace relations
namespace area {
template <typename 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);
using std::swap;
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) {
}
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;
}
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;
}
void way_not_in_any_relation(const osmium::Way& way) {
// you need at least 4 nodes to make up a polygon
if (way.nodes().size() <= 3) {
return;
}
try {
if (!way.nodes().front().location() || !way.nodes().back().location()) {
throw osmium::invalid_location("invalid location");
}
if (way.ends_have_same_location()) {
// way is closed and has enough nodes, build simple multipolygon
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
}
}
void flush() {
flush_output_buffer();
}
osmium::memory::Buffer read() {
osmium::memory::Buffer buffer(initial_output_buffer_size, osmium::memory::Buffer::auto_grow::yes);
using std::swap;
swap(buffer, m_output_buffer);
return buffer;
}
}; // class MultipolygonCollector
} // namespace area
} // namespace osmium
#endif // OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP
osmium::Way::nodes
WayNodeList & nodes()
Definition: way.hpp:75
osmium::item_type::way
osmium::area::MultipolygonCollector::possibly_flush_output_buffer
void possibly_flush_output_buffer()
Definition: multipolygon_collector.hpp:96
osmium::osm_entity_bits::type
type
Definition: entity_bits.hpp:60
osmium::area::MultipolygonCollector::keep_member
bool keep_member(const osmium::relations::RelationMeta &, const osmium::RelationMember &member) const
Definition: multipolygon_collector.hpp:134
location.hpp
osmium::Relation::members
RelationMemberList & members()
Definition: relation.hpp:177
osmium::area::MultipolygonCollector::collector_type
osmium::relations::Collector< MultipolygonCollector< TAssembler >, false, true, false > collector_type
Definition: multipolygon_collector.hpp:77
osmium::Relation
Definition: relation.hpp:165
osmium::area::MultipolygonCollector::MultipolygonCollector
MultipolygonCollector(const assembler_config_type &assembler_config)
Definition: multipolygon_collector.hpp:104
osmium::NodeRefList::size
size_t size() const noexcept
Definition: node_ref_list.hpp:68
osmium::memory::Buffer::auto_grow::yes
osmium::osm_entity_bits::area
Definition: entity_bits.hpp:67
node_ref.hpp
osmium::memory::swap
void swap(Buffer &lhs, Buffer &rhs)
Definition: buffer.hpp:721
osmium::Way
Definition: way.hpp:65
item_type.hpp
tag.hpp
osmium::area::MultipolygonCollector::way_not_in_any_relation
void way_not_in_any_relation(const osmium::Way &way)
Definition: multipolygon_collector.hpp:145
way.hpp
osmium::RelationMember
Definition: relation.hpp:54
osmium::area::MultipolygonCollector::flush
void flush()
Definition: multipolygon_collector.hpp:182
osmium
Namespace for everything in the Osmium library.
Definition: assembler.hpp:59
osmium::relations::Collector
Definition: collector.hpp:93
osmium::invalid_location
Definition: location.hpp:53
osmium::area::MultipolygonCollector::m_assembler_config
const assembler_config_type m_assembler_config
Definition: multipolygon_collector.hpp:80
osmium::Way::ends_have_same_location
bool ends_have_same_location() const
Definition: way.hpp:106
osmium::area::MultipolygonCollector::read
osmium::memory::Buffer read()
Definition: multipolygon_collector.hpp:186
relation.hpp
osmium::area::MultipolygonCollector::keep_relation
bool keep_relation(const osmium::Relation &relation) const
Definition: multipolygon_collector.hpp:116
collector.hpp
osmium::area::MultipolygonCollector::assembler_config_type
TAssembler::config_type assembler_config_type
Definition: multipolygon_collector.hpp:79
osmium::area::MultipolygonCollector::complete_relation
void complete_relation(osmium::relations::RelationMeta &relation_meta)
Definition: multipolygon_collector.hpp:165
osmium::OSMObject::tags
const TagList & tags() const
Get the list of tags for this object.
Definition: object.hpp:295
osmium::RelationMember::type
item_type type() const noexcept
Definition: relation.hpp:126
osmium::area::MultipolygonCollector
Definition: multipolygon_collector.hpp:75
osmium::NodeRef::location
osmium::Location & location() noexcept
Definition: node_ref.hpp:79
osmium::area::MultipolygonCollector::m_output_buffer
osmium::memory::Buffer m_output_buffer
Definition: multipolygon_collector.hpp:82
osmium::memory::Buffer::committed
size_t committed() const noexcept
Definition: buffer.hpp:241
osmium::memory::Buffer
Definition: buffer.hpp:97
buffer.hpp
osmium::NodeRefList::front
const NodeRef & front() const noexcept
Definition: node_ref_list.hpp:92
osmium::NodeRefList::back
const NodeRef & back() const noexcept
Definition: node_ref_list.hpp:102
osmium::TagList::get_value_by_key
const char * get_value_by_key(const char *key, const char *default_value=nullptr) const noexcept
Definition: tag.hpp:119
osmium::area::MultipolygonCollector::flush_output_buffer
void flush_output_buffer()
Definition: multipolygon_collector.hpp:87