pull in latest osmcode/libosmium changes

This commit is contained in:
Dennis Luxen
2015-04-13 15:44:38 +02:00
69 changed files with 1906 additions and 1528 deletions
+3 -3
View File
@@ -65,7 +65,7 @@ namespace osmium {
// Enables debug output to stderr
bool debug;
explicit AssemblerConfig(osmium::area::ProblemReporter* pr = nullptr, bool d=false) :
explicit AssemblerConfig(osmium::area::ProblemReporter* pr = nullptr, bool d = false) :
problem_reporter(pr),
debug(d) {
}
@@ -74,7 +74,7 @@ namespace osmium {
* Enable or disable debug output to stderr. This is for Osmium
* developers only.
*/
void enable_debug_output(bool d=true) {
void enable_debug_output(bool d = true) {
debug = d;
}
@@ -445,7 +445,7 @@ namespace osmium {
}
bool add_to_existing_ring(osmium::area::detail::NodeRefSegment segment) {
int n=0;
int n = 0;
for (auto& ring : m_rings) {
if (debug()) {
std::cerr << " check against ring " << n << " " << ring;
@@ -99,7 +99,7 @@ namespace osmium {
* Enable or disable debug output to stderr. This is for Osmium
* developers only.
*/
void enable_debug_output(bool debug=true) noexcept {
void enable_debug_output(bool debug = true) noexcept {
m_debug = debug;
}
@@ -142,7 +142,7 @@ namespace osmium {
* 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) {
if (way.nodes().size() > 3 && way.ends_have_same_location()) {
// way is closed and has enough nodes, build simple multipolygon
try {
TAssembler assembler(m_assembler_config);
+3 -4
View File
@@ -100,7 +100,7 @@ namespace osmium {
* parent item (if any).
*
*/
void add_padding(bool self=false) {
void add_padding(bool self = false) {
auto padding = osmium::memory::align_bytes - (size() % osmium::memory::align_bytes);
if (padding != osmium::memory::align_bytes) {
std::fill_n(m_buffer.reserve_space(padding), padding, 0);
@@ -171,12 +171,11 @@ namespace osmium {
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");
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) :
explicit ObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
Builder(buffer, parent, sizeof(TItem)) {
new (&item()) TItem();
}
@@ -61,7 +61,7 @@ namespace osmium {
public:
explicit TagListBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) :
explicit TagListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
ObjectBuilder<TagList>(buffer, parent) {
}
@@ -97,7 +97,7 @@ namespace osmium {
public:
explicit NodeRefListBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) :
explicit NodeRefListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
ObjectBuilder<T>(buffer, parent) {
}
@@ -110,7 +110,7 @@ namespace osmium {
static_cast<Builder*>(this)->add_size(sizeof(osmium::NodeRef));
}
void add_node_ref(const object_id_type ref, const osmium::Location location=Location()) {
void add_node_ref(const object_id_type ref, const osmium::Location location = Location()) {
add_node_ref(NodeRef(ref, location));
}
@@ -160,7 +160,7 @@ namespace osmium {
public:
explicit RelationMemberListBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) :
explicit RelationMemberListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
ObjectBuilder<RelationMemberList>(buffer, parent) {
}
@@ -215,7 +215,7 @@ namespace osmium {
public:
explicit OSMObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) :
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));
@@ -237,7 +237,7 @@ namespace osmium {
public:
explicit WayBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) :
explicit WayBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
OSMObjectBuilder<osmium::Way>(buffer, parent) {
}
@@ -254,7 +254,7 @@ namespace osmium {
public:
explicit AreaBuilder(osmium::memory::Buffer& buffer, Builder* parent=nullptr) :
explicit AreaBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
OSMObjectBuilder<osmium::Area>(buffer, parent) {
}
+1 -1
View File
@@ -214,7 +214,7 @@ namespace osmium {
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_type create_linestring(const osmium::WayNodeList& wnl, use_nodes un = use_nodes::unique, direction dir = direction::forward) {
linestring_start();
size_t num_points = 0;
+1 -1
View File
@@ -74,7 +74,7 @@ namespace osmium {
* Calculate length of way.
*/
inline double distance(const osmium::WayNodeList& wnl) {
double sum_length=0;
double sum_length = 0;
for (auto it = wnl.begin(); it != wnl.end(); ++it) {
if (std::next(it) != wnl.end()) {
+1 -1
View File
@@ -161,7 +161,7 @@ namespace osmium {
typedef std::string multipolygon_type;
typedef std::string ring_type;
explicit WKBFactoryImpl(wkb_type wtype=wkb_type::wkb, out_type otype=out_type::binary) :
explicit WKBFactoryImpl(wkb_type wtype = wkb_type::wkb, out_type otype = out_type::binary) :
m_wkb_type(wtype),
m_out_type(otype) {
}
+1 -1
View File
@@ -136,7 +136,7 @@ namespace osmium {
public:
explicit Dump(std::ostream& out, bool with_size=true, const std::string& prefix="") :
explicit Dump(std::ostream& out, bool with_size = true, const std::string& prefix = "") :
m_out(&out),
m_with_size(with_size),
m_prefix(prefix) {
@@ -63,11 +63,9 @@ namespace osmium {
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>, 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>");
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:
+1 -2
View File
@@ -84,8 +84,7 @@ namespace osmium {
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");
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;
@@ -83,7 +83,7 @@ namespace osmium {
* The storage will grow by at least this size
* every time it runs out of space.
*/
explicit SparseMemTable(const TId grow_size=10000) :
explicit SparseMemTable(const TId grow_size = 10000) :
m_grow_size(grow_size),
m_elements(grow_size) {
}
@@ -123,7 +123,7 @@ namespace osmium {
void dump_as_list(const int fd) override final {
std::vector<std::pair<TId, TValue>> v;
int n=0;
int n = 0;
for (const TValue value : m_elements) {
if (value != osmium::index::empty_value<TValue>()) {
v.emplace_back(n, value);
+1 -2
View File
@@ -50,8 +50,7 @@ namespace osmium {
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");
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;
@@ -82,7 +82,7 @@ namespace osmium {
namespace detail {
OSMIUM_NORETURN inline void throw_bzip2_error(BZFILE* bzfile, const char* msg, int bzlib_error=0) {
OSMIUM_NORETURN inline void throw_bzip2_error(BZFILE* bzfile, const char* msg, int bzlib_error = 0) {
std::string error("bzip2 error: ");
error += msg;
error += ": ";
@@ -84,8 +84,9 @@ namespace osmium {
class PBFInputFormat : public osmium::io::detail::InputFormat {
bool m_use_thread_pool;
bool m_eof { false };
queue_type m_queue;
std::atomic<bool> m_done;
std::atomic<bool> m_quit_input_thread;
std::thread m_reader;
osmium::thread::Queue<std::string>& m_input_queue;
std::string m_input_buffer;
@@ -151,7 +152,7 @@ namespace osmium {
void parse_osm_data(osmium::osm_entity_bits::type read_types) {
osmium::thread::set_thread_name("_osmium_pbf_in");
int n=0;
int n = 0;
while (auto size = read_blob_header("OSMData")) {
if (m_use_thread_pool) {
@@ -164,11 +165,20 @@ namespace osmium {
}
++n;
if (m_done) {
if (m_quit_input_thread) {
return;
}
}
m_done = true;
// Send an empty buffer to signal the reader that we are
// done.
std::promise<osmium::memory::Buffer> promise;
m_queue.push(promise.get_future());
promise.set_value(osmium::memory::Buffer{});
}
void signal_input_thread_to_quit() {
m_quit_input_thread = true;
}
public:
@@ -184,7 +194,7 @@ namespace osmium {
osmium::io::detail::InputFormat(file, read_which_entities),
m_use_thread_pool(osmium::config::use_pool_threads_for_pbf_parsing()),
m_queue(20, "pbf_parser_results"), // XXX
m_done(false),
m_quit_input_thread(false),
m_input_queue(input_queue),
m_input_buffer() {
GOOGLE_PROTOBUF_VERIFY_VERSION;
@@ -199,30 +209,37 @@ namespace osmium {
}
~PBFInputFormat() {
m_done = true;
signal_input_thread_to_quit();
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 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);
try {
return buffer_future.get();
} catch (...) {
m_done = true;
throw;
}
osmium::memory::Buffer buffer;
if (m_eof) {
return buffer;
}
return osmium::memory::Buffer();
std::future<osmium::memory::Buffer> buffer_future;
m_queue.wait_and_pop(buffer_future);
try {
buffer = std::move(buffer_future.get());
if (!buffer) {
m_eof = true;
}
return buffer;
} catch (...) {
m_eof = true;
signal_input_thread_to_quit();
throw;
}
}
}; // class PBFInputFormat
@@ -294,6 +294,14 @@ namespace osmium {
*/
bool m_use_compression {true};
/**
* Should the string tables in the data blocks be sorted?
*
* Not sorting the string tables makes writing PBF files
* slightly faster.
*/
bool m_sort_stringtables { true };
/**
* While the .osm.pbf-format is able to carry all meta information, it is
* also able to omit this information to reduce size.
@@ -340,6 +348,21 @@ namespace osmium {
///// Blob writing /////
void delta_encode_string_ids() {
if (pbf_nodes && pbf_nodes->has_dense()) {
OSMPBF::DenseNodes* dense = pbf_nodes->mutable_dense();
if (dense->has_denseinfo()) {
OSMPBF::DenseInfo* denseinfo = dense->mutable_denseinfo();
for (int i = 0, l=denseinfo->user_sid_size(); i<l; ++i) {
auto user_sid = denseinfo->user_sid(i);
denseinfo->set_user_sid(i, m_delta_user_sid.update(user_sid));
}
}
}
}
/**
* 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.
@@ -351,7 +374,7 @@ namespace osmium {
// 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) {
for (int i = 0, l=pbf_nodes->nodes_size(); i<l; ++i) {
map_common_string_ids(pbf_nodes->mutable_nodes(i));
}
@@ -363,7 +386,7 @@ namespace osmium {
// 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) {
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) {
@@ -377,7 +400,7 @@ namespace osmium {
OSMPBF::DenseInfo* denseinfo = dense->mutable_denseinfo();
// iterate over all username string-ids
for (int i=0, l=denseinfo->user_sid_size(); i<l; ++i) {
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));
@@ -391,7 +414,7 @@ namespace osmium {
// 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) {
for (int i = 0, l=pbf_ways->ways_size(); i<l; ++i) {
map_common_string_ids(pbf_ways->mutable_ways(i));
}
}
@@ -399,7 +422,7 @@ namespace osmium {
// 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) {
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);
@@ -408,7 +431,7 @@ namespace osmium {
// 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) {
for (int mi = 0; mi < relation->roles_sid_size(); ++mi) {
relation->set_roles_sid(mi, string_table.map_string_id(relation->roles_sid(mi)));
}
}
@@ -431,7 +454,7 @@ namespace osmium {
}
// 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) {
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)));
}
@@ -518,11 +541,13 @@ namespace osmium {
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());
string_table.store_stringtable(pbf_primitive_block.mutable_stringtable(), m_sort_stringtables);
// map all interim string ids to real ids
map_string_ids();
if (m_sort_stringtables) {
map_string_ids();
} else {
delta_encode_string_ids();
}
std::promise<std::string> promise;
m_output_queue.push(promise.get_future());
@@ -743,6 +768,9 @@ namespace osmium {
if (file.get("pbf_compression") == "none" || file.get("pbf_compression") == "false") {
m_use_compression = false;
}
if (file.get("pbf_sort_stringtables") == "false") {
m_sort_stringtables = false;
}
if (file.get("pbf_add_metadata") == "false") {
m_should_add_metadata = false;
}
+12 -12
View File
@@ -106,7 +106,7 @@ namespace osmium {
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) {
for (int i = 0; i < pbf_primitive_block.primitivegroup_size(); ++i) {
const OSMPBF::PrimitiveGroup& group = pbf_primitive_block.primitivegroup(i);
if (group.has_dense()) {
@@ -148,7 +148,7 @@ namespace osmium {
}
void parse_node_group(const OSMPBF::PrimitiveGroup& group) {
for (int i=0; i < group.nodes_size(); ++i) {
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);
@@ -161,7 +161,7 @@ namespace osmium {
if (pbf_node.keys_size() > 0) {
osmium::builder::TagListBuilder tl_builder(m_buffer, &builder);
for (int tag=0; tag < pbf_node.keys_size(); ++tag) {
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))));
}
@@ -172,7 +172,7 @@ namespace osmium {
}
void parse_way_group(const OSMPBF::PrimitiveGroup& group) {
for (int i=0; i < group.ways_size(); ++i) {
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);
@@ -180,7 +180,7 @@ namespace osmium {
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) {
for (int n = 0; n < pbf_way.refs_size(); ++n) {
ref += pbf_way.refs(n);
wnl_builder.add_node_ref(ref);
}
@@ -188,7 +188,7 @@ namespace osmium {
if (pbf_way.keys_size() > 0) {
osmium::builder::TagListBuilder tl_builder(m_buffer, &builder);
for (int tag=0; tag < pbf_way.keys_size(); ++tag) {
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))));
}
@@ -199,7 +199,7 @@ namespace osmium {
}
void parse_relation_group(const OSMPBF::PrimitiveGroup& group) {
for (int i=0; i < group.relations_size(); ++i) {
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);
@@ -207,7 +207,7 @@ namespace osmium {
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) {
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)));
}
@@ -215,7 +215,7 @@ namespace osmium {
if (pbf_relation.keys_size() > 0) {
osmium::builder::TagListBuilder tl_builder(m_buffer, &builder);
for (int tag=0; tag < pbf_relation.keys_size(); ++tag) {
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))));
}
@@ -264,7 +264,7 @@ namespace osmium {
const OSMPBF::DenseNodes& dense = group.dense();
for (int i=0; i < dense.id_size(); ++i) {
for (int i = 0; i < dense.id_size(); ++i) {
bool visible = true;
last_dense_id += dense.id(i);
@@ -361,7 +361,7 @@ namespace osmium {
}
osmium::io::Header header;
for (int i=0; i < pbf_header_block.required_features_size(); ++i) {
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;
@@ -377,7 +377,7 @@ namespace osmium {
throw osmium::pbf_error(std::string("required feature not supported: ") + feature);
}
for (int i=0; i < pbf_header_block.optional_features_size(); ++i) {
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);
}
@@ -145,30 +145,44 @@ namespace osmium {
* 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) {
void store_stringtable(OSMPBF::StringTable* st, bool sort) {
// 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;
if (sort) {
std::multimap<string_info, std::string> sortedbycount;
m_id2id_map.resize(m_size+1);
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);
});
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;
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);
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;
// store the mapping from the interim-id to the real id
m_id2id_map[mapping.first.interim_id] = ++n;
}
} else {
std::vector<std::pair<string_id_type, const char*>> sortedbyid;
sortedbyid.reserve(m_strings.size());
for (const auto& p : m_strings) {
sortedbyid.emplace_back(p.second.interim_id, p.first.c_str());
}
std::sort(sortedbyid.begin(), sortedbyid.end());
for (const auto& mapping : sortedbyid) {
st->add_s(mapping.second);
}
}
}
@@ -74,8 +74,8 @@ 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.
* (if available) information about the place where the error happened
* and the type of error.
*/
struct xml_error : public io_error {
@@ -84,7 +84,7 @@ namespace osmium {
XML_Error error_code;
std::string error_string;
xml_error(XML_Parser parser) :
explicit xml_error(XML_Parser parser) :
io_error(std::string("XML parsing error at line ")
+ std::to_string(XML_GetCurrentLineNumber(parser))
+ ", column "
@@ -97,8 +97,20 @@ namespace osmium {
error_string(XML_ErrorString(error_code)) {
}
explicit xml_error(const std::string& message) :
io_error(message),
line(0),
column(0),
error_code(),
error_string(message) {
}
}; // struct xml_error
/**
* Exception thrown when an OSM XML files contains no version attribute
* on the 'osm' element or if the version is unknown.
*/
struct format_version_error : public io_error {
std::string version;
@@ -434,6 +446,8 @@ namespace osmium {
if (m_header.get("version") == "") {
throw osmium::format_version_error();
}
} else {
throw osmium::xml_error(std::string("Unknown top-level element: ") + element);
}
m_context = context::top;
break;
@@ -130,7 +130,7 @@ namespace osmium {
const bool m_write_change_ops;
void write_spaces(int num) {
for (; num!=0; --num) {
for (; num != 0; --num) {
*m_out += ' ';
}
}
@@ -76,7 +76,7 @@ namespace osmium {
namespace detail {
OSMIUM_NORETURN inline void throw_gzip_error(gzFile gzfile, const char* msg, int zlib_error=0) {
OSMIUM_NORETURN inline void throw_gzip_error(gzFile gzfile, const char* msg, int zlib_error = 0) {
std::string error("gzip error: ");
error += msg;
error += ": ";
+2 -2
View File
@@ -109,7 +109,7 @@ namespace osmium {
}
if (pid == 0) { // child
// close all file descriptors except one end of the pipe
for (int i=0; i < 32; ++i) {
for (int i = 0; i < 32; ++i) {
if (i != pipefd[1]) {
::close(i);
}
@@ -260,7 +260,7 @@ namespace osmium {
// m_input->read() can return an invalid buffer to signal EOF,
// or a valid buffer with or without data. A valid buffer
// without data is not an error, it just means we have to get
// without data is not an error, it just means we have to
// keep getting the next buffer until there is one with data.
while (true) {
osmium::memory::Buffer buffer = m_input->read();
+2 -3
View File
@@ -55,8 +55,7 @@ namespace osmium {
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");
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);
}
@@ -119,7 +118,7 @@ namespace osmium {
protected:
explicit Item(item_size_type size=0, item_type type=item_type()) noexcept :
explicit Item(item_size_type size = 0, item_type type = item_type()) noexcept :
m_size(size),
m_type(type),
m_removed(false),
+30 -9
View File
@@ -53,12 +53,14 @@ namespace osmium {
/**
* An outer ring of an Area.
*/
class OuterRing : public NodeRefList<osmium::item_type::outer_ring> {
class OuterRing : public NodeRefList {
public:
static constexpr osmium::item_type itemtype = osmium::item_type::outer_ring;
OuterRing():
NodeRefList<osmium::item_type::outer_ring>() {
NodeRefList(itemtype) {
}
}; // class OuterRing
@@ -68,12 +70,14 @@ namespace osmium {
/**
* An inner ring of an Area.
*/
class InnerRing : public NodeRefList<osmium::item_type::inner_ring> {
class InnerRing : public NodeRefList {
public:
static constexpr osmium::item_type itemtype = osmium::item_type::inner_ring;
InnerRing():
NodeRefList<osmium::item_type::inner_ring>() {
NodeRefList(itemtype) {
}
}; // class InnerRing
@@ -87,7 +91,7 @@ namespace osmium {
* @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) {
inline osmium::object_id_type object_id_to_area_id(osmium::object_id_type id, osmium::item_type type) noexcept {
osmium::object_id_type area_id = std::abs(id) * 2;
if (type == osmium::item_type::relation) {
++area_id;
@@ -101,7 +105,7 @@ namespace osmium {
* @param id Area id
* @returns Way or Relation id.
*/
inline osmium::object_id_type area_id_to_object_id(osmium::object_id_type id) {
inline osmium::object_id_type area_id_to_object_id(osmium::object_id_type id) noexcept {
return id / 2;
}
@@ -131,15 +135,17 @@ namespace osmium {
/**
* Return the Id of the way or relation this area was created from.
*/
osmium::object_id_type orig_id() const {
osmium::object_id_type orig_id() const noexcept {
return osmium::area_id_to_object_id(id());
}
/**
* Count the number of outer and inner rings of this area.
*
* @returns Pair (number outer rings, number inner rings)
*/
std::pair<int, int> num_rings() const {
std::pair<int, int> counter;
std::pair<int, int> counter { 0, 0 };
for (auto it = cbegin(); it != cend(); ++it) {
switch (it->type()) {
@@ -170,16 +176,31 @@ namespace osmium {
}
/**
* Is this area a multipolygon, ie. has it more than one outer ring?
* Check whether this area is a multipolygon, ie. whether it has more
* than one outer ring?
*/
bool is_multipolygon() const {
return num_rings().first > 1;
}
/**
* Get iterator for iterating over all inner rings in a specified outer
* ring.
*
* @param it Iterator specifying outer ring.
* @returns Iterator to first inner ring in specified outer ring.
*/
osmium::memory::ItemIterator<const osmium::InnerRing> inner_ring_cbegin(const osmium::memory::ItemIterator<const osmium::OuterRing>& it) const {
return it.cast<const osmium::InnerRing>();
}
/**
* Get iterator for iterating over all inner rings in a specified outer
* ring.
*
* @param it Iterator specifying outer ring.
* @returns Iterator one past last inner ring in specified outer ring.
*/
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>();
}
+60 -17
View File
@@ -33,6 +33,7 @@ DEALINGS IN THE SOFTWARE.
*/
#include <cassert>
#include <iosfwd>
#include <osmium/util/compatibility.hpp>
@@ -41,7 +42,10 @@ DEALINGS IN THE SOFTWARE.
namespace osmium {
/**
* Bounding box.
* Bounding box. A box is defined by two locations (bottom left location
* and top right location) or, alternatively by four coordinates (minx,
* miny, maxx, and maxy). If both locations are undefined, the box is
* undefined, too.
*/
class Box {
@@ -59,14 +63,33 @@ namespace osmium {
m_top_right() {
}
/**
* Create box from minimum and maximum coordinates.
*
* @pre @code minx <= maxx && miny <= maxy @endcode
*/
Box(double minx, double miny, double maxx, double maxy) :
m_bottom_left(minx, miny),
m_top_right(maxx, maxy) {
assert(minx <= maxx && miny <= maxy);
}
/**
* Create box from bottom left and top right locations.
*
* @pre Either both locations must be defined or neither.
* @pre If both locations are defined, the
* bottom left location must actually be to the left and below
* the top right location. Same coordinates for bottom/top or
* left/right are also okay.
*/
Box(const osmium::Location& bottom_left, const osmium::Location& top_right) :
m_bottom_left(bottom_left),
m_top_right(top_right) {
assert(
(!!bottom_left && !!top_right) ||
(bottom_left.x() <= top_right.x() && bottom_left.y() <= top_right.y())
);
}
Box(const Box&) = default;
@@ -76,8 +99,13 @@ namespace osmium {
~Box() = default;
/**
* Extend this bounding box by the given location. If the
* location is undefined, the bounding box is unchanged.
* Extend this bounding box by the specified location. If the
* location is undefined, the bounding box is unchanged. If
* the box is undefined it will only contain the location after
* this call.
*
* @param location The location we want to extend the box by.
* @returns A reference to this box.
*/
Box& extend(const Location& location) noexcept {
if (location) {
@@ -103,8 +131,11 @@ namespace osmium {
}
/**
* Extend this bounding box by the given box. If the
* box is undefined, the bounding box is unchanged.
* Extend this bounding box by the specified box. If the
* specified box is undefined, the bounding box is unchanged.
*
* @param box The box to extend by.
* @returns A reference to this box.
*/
Box& extend(const Box& box) noexcept {
extend(box.bottom_left());
@@ -113,14 +144,14 @@ namespace osmium {
}
/**
* Box are defined, ie. contains defined coordinates.
* Box is defined, ie. contains defined locations.
*/
explicit constexpr operator bool() const noexcept {
return static_cast<bool>(m_bottom_left);
}
/**
* Box are valid, ie. defined and inside usual bounds
* Box is valid, ie. defined and inside usual bounds
* (-180<=lon<=180, -90<=lat<=90).
*/
OSMIUM_CONSTEXPR bool valid() const noexcept {
@@ -128,37 +159,43 @@ namespace osmium {
}
/**
* Bottom-left location.
* Access bottom-left location.
*/
OSMIUM_CONSTEXPR Location bottom_left() const noexcept {
return m_bottom_left;
}
/**
* Bottom-left location.
* Access bottom-left location.
*/
Location& bottom_left() noexcept {
return m_bottom_left;
}
/**
* Top-right location.
* Access top-right location.
*/
OSMIUM_CONSTEXPR Location top_right() const noexcept {
return m_top_right;
}
/**
* Top-right location.
* Access top-right location.
*/
Location& top_right() noexcept {
return m_top_right;
}
/**
* Is the location inside the box?
* Check whether the location is inside the box.
*
* @pre Location must be defined.
* @pre Box must be defined.
*/
bool contains(const osmium::Location& location) const {
bool contains(const osmium::Location& location) const noexcept {
assert(bottom_left());
assert(top_right());
assert(location);
return location.x() >= bottom_left().x() && location.y() >= bottom_left().y() &&
location.x() <= top_right().x() && location.y() <= top_right().y();
}
@@ -166,7 +203,7 @@ namespace osmium {
/**
* Calculate size of the box in square degrees.
*
* @throws osmium::invalid_location unless all coordinates are valid
* @throws osmium::invalid_location unless all coordinates are valid.
*/
double size() const {
return (m_top_right.lon() - m_bottom_left.lon()) *
@@ -176,14 +213,19 @@ namespace osmium {
}; // class Box
/**
* Boxes are equal if both locations are equal.
* Boxes are equal if both locations are equal. Undefined boxes will
* compare equal.
*/
inline OSMIUM_CONSTEXPR bool operator==(const Box& lhs, const Box& rhs) noexcept {
return lhs.bottom_left() == rhs.bottom_left() && lhs.top_right() == rhs.top_right();
return lhs.bottom_left() == rhs.bottom_left() &&
lhs.top_right() == rhs.top_right();
}
/**
* Output a box to a stream.
* Output a box to a stream. The format is "(LON, LAT, LON, LAT)" or
* "(undefined)" if the box is undefined.
*
* @returns Reference to basic_ostream given as first parameter.
*/
template <typename TChar, typename TTraits>
inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const osmium::Box& box) {
@@ -202,6 +244,7 @@ namespace osmium {
}
return out;
}
} // namespace osmium
#endif // OSMIUM_OSM_BOX_HPP
+1 -2
View File
@@ -298,8 +298,7 @@ namespace osmium {
}; // class Changeset
static_assert(sizeof(Changeset) % osmium::memory::align_bytes == 0,
"Class osmium::Changeset has wrong size to be aligned properly!");
static_assert(sizeof(Changeset) % osmium::memory::align_bytes == 0, "Class osmium::Changeset has wrong size to be aligned properly!");
/**
* Changesets are equal if their IDs are equal.
+1 -1
View File
@@ -54,7 +54,7 @@ namespace osmium {
public:
NodeRef(const osmium::object_id_type ref=0, const osmium::Location& location=Location()) noexcept :
NodeRef(const osmium::object_id_type ref = 0, const osmium::Location& location = Location()) noexcept :
m_ref(ref),
m_location(location) {
}
+70 -21
View File
@@ -44,51 +44,92 @@ DEALINGS IN THE SOFTWARE.
namespace osmium {
/**
* A vector of NodeRef objects. Usually this is not instatiated directly,
* A vector of NodeRef objects. Usually this is not instantiated directly,
* but one of its subclasses are used.
*/
template <osmium::item_type TItemType>
class NodeRefList : public osmium::memory::Item {
public:
static constexpr osmium::item_type itemtype = TItemType;
NodeRefList() noexcept :
osmium::memory::Item(sizeof(NodeRefList), TItemType) {
NodeRefList(osmium::item_type itemtype) noexcept :
osmium::memory::Item(sizeof(NodeRefList), itemtype) {
}
/**
* Checks whether the node list is empty.
*/
bool empty() const noexcept {
return sizeof(NodeRefList) == byte_size();
}
/**
* Returns the number of nodes in the list.
*/
size_t size() const noexcept {
assert((osmium::memory::Item::byte_size() - sizeof(NodeRefList)) % sizeof(NodeRef) == 0);
return (osmium::memory::Item::byte_size() - sizeof(NodeRefList)) / sizeof(NodeRef);
auto size_node_refs = osmium::memory::Item::byte_size() - sizeof(NodeRefList);
assert(size_node_refs % sizeof(NodeRef) == 0);
return size_node_refs / sizeof(NodeRef);
}
const NodeRef& operator[](size_t n) const {
/**
* Access specified element.
*
* @param n Get this element of the list.
* @pre @code n < size() @endcode
*/
const NodeRef& operator[](size_t n) const noexcept {
assert(n < size());
const NodeRef* node_ref = &*(cbegin());
return node_ref[n];
}
const NodeRef& front() const {
/**
* Access the first element.
*
* @pre @code !empty() @endcode
*/
const NodeRef& front() const noexcept {
assert(!empty());
return operator[](0);
}
const NodeRef& back() const {
/**
* Access the last element.
*
* @pre @code !empty() @endcode
*/
const NodeRef& back() const noexcept {
assert(!empty());
return operator[](size()-1);
}
bool is_closed() const {
/**
* Checks whether the first and last node in the list have the same ID.
*
* @pre @code !empty() @endcode
*/
bool is_closed() const noexcept {
return front().ref() == back().ref();
}
bool ends_have_same_id() const {
/**
* Checks whether the first and last node in the list have the same ID.
*
* @pre @code !empty() @endcode
*/
bool ends_have_same_id() const noexcept {
return front().ref() == back().ref();
}
/**
* Checks whether the first and last node in the list have the same
* location. The ID is not checked.
*
* @pre @code !empty() @endcode
* @pre @code front().location() && back().location() @endcode
*/
bool ends_have_same_location() const {
assert(front().location() && back().location());
return front().location() == back().location();
}
@@ -96,35 +137,43 @@ namespace osmium {
typedef const NodeRef* const_iterator;
typedef std::reverse_iterator<const NodeRef*> const_reverse_iterator;
iterator begin() {
/// Returns an iterator to the beginning.
iterator begin() noexcept {
return iterator(data() + sizeof(NodeRefList));
}
iterator end() {
/// Returns an iterator to the end.
iterator end() noexcept {
return iterator(data() + byte_size());
}
const_iterator cbegin() const {
/// Returns an iterator to the beginning.
const_iterator cbegin() const noexcept {
return const_iterator(data() + sizeof(NodeRefList));
}
const_iterator cend() const {
/// Returns an iterator to the end.
const_iterator cend() const noexcept {
return const_iterator(data() + byte_size());
}
const_iterator begin() const {
/// Returns an iterator to the beginning.
const_iterator begin() const noexcept {
return cbegin();
}
const_iterator end() const {
/// Returns an iterator to the end.
const_iterator end() const noexcept {
return cend();
}
const_reverse_iterator crbegin() const {
/// Returns a reverse_iterator to the beginning.
const_reverse_iterator crbegin() const noexcept {
return const_reverse_iterator(cend());
}
const_reverse_iterator crend() const {
/// Returns a reverse_iterator to the end.
const_reverse_iterator crend() const noexcept {
return const_reverse_iterator(cbegin());
}
+1 -1
View File
@@ -101,7 +101,7 @@ namespace osmium {
static constexpr item_type collection_type = item_type::relation_member_list;
RelationMember(const object_id_type ref=0, const item_type type=item_type(), const bool full=false) noexcept :
RelationMember(const object_id_type ref = 0, const item_type type = item_type(), const bool full = false) noexcept :
m_ref(ref),
m_type(type),
m_flags(full ? 1 : 0) {
@@ -113,6 +113,10 @@ namespace osmium {
return static_cast<time_t>(m_timestamp);
}
explicit constexpr operator uint32_t() const noexcept {
return m_timestamp;
}
template <typename T>
void operator+=(T time_difference) noexcept {
m_timestamp += time_difference;
+4 -2
View File
@@ -49,12 +49,14 @@ namespace osmium {
/**
* List of node references (id and location) in a way.
*/
class WayNodeList : public NodeRefList<osmium::item_type::way_node_list> {
class WayNodeList : public NodeRefList {
public:
static constexpr osmium::item_type itemtype = osmium::item_type::way_node_list;
WayNodeList():
NodeRefList<osmium::item_type::way_node_list>() {
NodeRefList(itemtype) {
}
}; // class WayNodeList
@@ -389,7 +389,7 @@ namespace osmium {
RelationMeta relation_meta(offset);
int n=0;
int n = 0;
for (auto& member : m_relations_buffer.get<osmium::Relation>(offset).members()) {
if (static_cast<TCollector*>(this)->keep_member(relation_meta, member)) {
member_meta(member.type()).emplace_back(member.ref(), m_relations.size(), n);
+1 -1
View File
@@ -128,7 +128,7 @@ namespace osmium {
}
try {
for (int i=0; i < m_num_threads; ++i) {
for (int i = 0; i < m_num_threads; ++i) {
m_threads.push_back(std::thread(&Pool::worker_thread, this));
}
} catch (...) {
+4 -4
View File
@@ -49,7 +49,7 @@ namespace osmium {
namespace thread {
OSMIUM_CONSTEXPR std::chrono::milliseconds full_queue_sleep_duration { 10 }; // XXX
static const std::chrono::milliseconds full_queue_sleep_duration { 10 }; // XXX
/**
* A thread-safe queue.
@@ -137,7 +137,7 @@ namespace osmium {
m_data_available.wait(lock, [this] {
return !m_queue.empty();
});
value=std::move(m_queue.front());
value = std::move(m_queue.front());
m_queue.pop();
}
@@ -148,7 +148,7 @@ namespace osmium {
})) {
return;
}
value=std::move(m_queue.front());
value = std::move(m_queue.front());
m_queue.pop();
}
@@ -157,7 +157,7 @@ namespace osmium {
if (m_queue.empty()) {
return false;
}
value=std::move(m_queue.front());
value = std::move(m_queue.front());
m_queue.pop();
return true;
}
@@ -107,7 +107,7 @@ namespace osmium {
m_data_available.wait(lock, [this] {
return !empty_intern();
});
value=std::move(m_queue.front());
value = std::move(m_queue.front());
m_queue.pop_front();
++m_offset;
}
@@ -122,7 +122,7 @@ namespace osmium {
if (empty_intern()) {
return false;
}
value=std::move(m_queue.front());
value = std::move(m_queue.front());
m_queue.pop_front();
++m_offset;
return true;
+2 -1
View File
@@ -37,6 +37,7 @@ DEALINGS IN THE SOFTWARE.
# include <cassert>
#endif
#include <cstdint>
#include <limits>
#include <type_traits>
@@ -93,7 +94,7 @@ namespace osmium {
template <typename T, typename F, typename std::enable_if<are_real_integers<T, F>::value && !std::is_same<T, F>::value && (sizeof(T) <= sizeof(F)) && std::is_signed<T>::value && std::is_unsigned<F>::value, int>::type = 0>
inline T static_cast_with_assert(const F value) {
assert(value <= std::numeric_limits<T>::max());
assert(static_cast<int64_t>(value) <= static_cast<int64_t>(std::numeric_limits<T>::max()));
return static_cast<T>(value);
}
@@ -87,7 +87,7 @@ namespace osmium {
public:
explicit VerboseOutput(bool verbose=false) noexcept :
explicit VerboseOutput(bool verbose = false) noexcept :
m_start(time(NULL)),
m_verbose(verbose),
m_newline(true) {