Upgrade libosmium to v2.15.6

This commit is contained in:
Desone Burns II
2020-11-17 14:59:06 -07:00
parent 98fd17589d
commit dfc1bfc27e
319 changed files with 6268 additions and 3946 deletions
+98 -58
View File
@@ -5,11 +5,11 @@
C++11 wrapper classes for GDAL/OGR.
Version 1.1.1
Version 1.2.0
https://github.com/joto/gdalcpp
Copyright 2015 Jochen Topf <jochen@topf.org>
Copyright 2015-2018 Jochen Topf <jochen@topf.org>
Boost Software License - Version 1.0 - August 17th, 2003
@@ -37,17 +37,19 @@ DEALINGS IN THE SOFTWARE.
*/
#include <algorithm>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
#include <gdal_priv.h>
#include <gdal_version.h>
#include <ogr_api.h>
#include <ogrsf_frmts.h>
#include <cstdint>
#include <algorithm>
#include <memory>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
namespace gdalcpp {
#if GDAL_VERSION_MAJOR >= 2
@@ -85,23 +87,23 @@ namespace gdalcpp {
m_error(error) {
}
const std::string& driver() const {
const std::string& driver() const noexcept {
return m_driver;
}
const std::string& dataset() const {
const std::string& dataset() const noexcept {
return m_dataset;
}
const std::string& layer() const {
const std::string& layer() const noexcept {
return m_layer;
}
const std::string& field() const {
const std::string& field() const noexcept {
return m_field;
}
OGRErr error() const {
OGRErr error() const noexcept {
return m_error;
}
@@ -111,18 +113,26 @@ namespace gdalcpp {
struct init_wrapper {
#if GDAL_VERSION_MAJOR >= 2
init_wrapper() { GDALAllRegister(); }
init_wrapper() noexcept {
GDALAllRegister();
}
#else
init_wrapper() { OGRRegisterAll(); }
~init_wrapper() { OGRCleanupAll(); }
init_wrapper() noexcept {
OGRRegisterAll();
}
~init_wrapper() noexcept {
OGRCleanupAll();
}
#endif
};
}; // struct init_wrapper
struct init_library {
init_library() {
static init_wrapper iw;
}
};
}; // struct init_library
class Driver : private init_library {
@@ -138,11 +148,13 @@ namespace gdalcpp {
m_driver(OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver_name.c_str())) {
#endif
if (!m_driver) {
throw gdal_error(std::string("unknown driver: '") + driver_name + "'", OGRERR_NONE, driver_name);
throw gdal_error{std::string{"unknown driver: '"} + driver_name + "'",
OGRERR_NONE,
driver_name};
}
}
gdal_driver_type& get() const {
gdal_driver_type& get() const noexcept {
return *m_driver;
}
@@ -155,14 +167,14 @@ namespace gdalcpp {
Options(const std::vector<std::string>& options) :
m_options(options),
m_ptrs(new const char*[options.size()+1]) {
m_ptrs(new const char*[options.size() + 1]) {
std::transform(m_options.begin(), m_options.end(), m_ptrs.get(), [&](const std::string& s) {
return s.data();
});
m_ptrs[options.size()] = nullptr;
}
char** get() const {
char** get() const noexcept {
return const_cast<char**>(m_ptrs.get());
}
@@ -178,33 +190,37 @@ namespace gdalcpp {
SRS() :
m_spatial_reference() {
auto result = m_spatial_reference.SetWellKnownGeogCS("WGS84");
const auto result = m_spatial_reference.SetWellKnownGeogCS("WGS84");
if (result != OGRERR_NONE) {
throw gdal_error(std::string("can not initialize spatial reference system WGS84"), result);
throw gdal_error{std::string{"can not initialize spatial reference system WGS84"},
result};
}
}
explicit SRS(int epsg) :
m_spatial_reference() {
auto result = m_spatial_reference.importFromEPSG(epsg);
const auto result = m_spatial_reference.importFromEPSG(epsg);
if (result != OGRERR_NONE) {
throw gdal_error(std::string("can not initialize spatial reference system for EPSG:") + std::to_string(epsg), result);
throw gdal_error{std::string{"can not initialize spatial reference system for EPSG:"} + std::to_string(epsg),
result};
}
}
explicit SRS(const char* name) :
m_spatial_reference() {
auto result = m_spatial_reference.importFromProj4(name);
const auto result = m_spatial_reference.importFromProj4(name);
if (result != OGRERR_NONE) {
throw gdal_error(std::string("can not initialize spatial reference system '") + name + "'", result);
throw gdal_error{std::string{"can not initialize spatial reference system '"} + name + "'",
result};
}
}
explicit SRS(const std::string& name) :
m_spatial_reference() {
auto result = m_spatial_reference.importFromProj4(name.c_str());
const auto result = m_spatial_reference.importFromProj4(name.c_str());
if (result != OGRERR_NONE) {
throw gdal_error(std::string("can not initialize spatial reference system '") + name + "'", result);
throw gdal_error{std::string{"can not initialize spatial reference system '"} + name + "'",
result};
}
}
@@ -212,11 +228,11 @@ namespace gdalcpp {
m_spatial_reference(spatial_reference) {
}
OGRSpatialReference& get() {
OGRSpatialReference& get() noexcept {
return m_spatial_reference;
}
const OGRSpatialReference& get() const {
const OGRSpatialReference& get() const noexcept {
return m_spatial_reference;
}
@@ -257,11 +273,14 @@ namespace gdalcpp {
m_dataset(detail::Driver(driver_name).get().CreateDataSource(dataset_name.c_str(), m_options.get())) {
#endif
if (!m_dataset) {
throw gdal_error(std::string("failed to create dataset '") + dataset_name + "'", OGRERR_NONE, driver_name, dataset_name);
throw gdal_error{std::string{"failed to create dataset '"} + dataset_name + "'",
OGRERR_NONE,
driver_name,
dataset_name};
}
}
~Dataset() {
~Dataset() noexcept {
try {
if (m_edit_count > 0) {
commit_transaction();
@@ -270,24 +289,24 @@ namespace gdalcpp {
}
}
const std::string& driver_name() const {
const std::string& driver_name() const noexcept {
return m_driver_name;
}
const std::string& dataset_name() const {
const std::string& dataset_name() const noexcept {
return m_dataset_name;
}
gdal_dataset_type& get() const {
gdal_dataset_type& get() const noexcept {
return *m_dataset;
}
SRS& srs() {
SRS& srs() noexcept {
return m_srs;
}
void exec(const char* sql) {
auto result = m_dataset->ExecuteSQL(sql, nullptr, nullptr);
const auto result = m_dataset->ExecuteSQL(sql, nullptr, nullptr);
if (result) {
m_dataset->ReleaseResultSet(result);
}
@@ -334,7 +353,7 @@ namespace gdalcpp {
}
}
Dataset& enable_auto_transactions(uint64_t edits = 100000) {
Dataset& enable_auto_transactions(uint64_t edits = 100000) noexcept {
m_max_edit_count = edits;
return *this;
}
@@ -362,20 +381,23 @@ namespace gdalcpp {
m_dataset(dataset),
m_layer(dataset.get().CreateLayer(layer_name.c_str(), &dataset.srs().get(), type, m_options.get())) {
if (!m_layer) {
throw gdal_error(std::string("failed to create layer '") + layer_name + "'", OGRERR_NONE,
dataset.driver_name(), dataset.dataset_name(), layer_name);
throw gdal_error{std::string{"failed to create layer '"} + layer_name + "'",
OGRERR_NONE,
dataset.driver_name(),
dataset.dataset_name(),
layer_name};
}
}
OGRLayer& get() {
OGRLayer& get() noexcept {
return *m_layer;
}
const OGRLayer& get() const {
const OGRLayer& get() const noexcept {
return *m_layer;
}
Dataset& dataset() const {
Dataset& dataset() const noexcept {
return m_dataset;
}
@@ -389,8 +411,12 @@ namespace gdalcpp {
field.SetPrecision(precision);
if (m_layer->CreateField(&field) != OGRERR_NONE) {
throw gdal_error(std::string("failed to create field '") + field_name + "' in layer '" + name() + "'", OGRERR_NONE,
m_dataset.driver_name(), m_dataset.dataset_name(), name(), field_name);
throw gdal_error{std::string{"failed to create field '"} + field_name + "' in layer '" + name() + "'",
OGRERR_NONE,
m_dataset.driver_name(),
m_dataset.dataset_name(),
name(),
field_name};
}
return *this;
@@ -398,18 +424,25 @@ namespace gdalcpp {
void create_feature(OGRFeature* feature) {
dataset().prepare_edit();
OGRErr result = m_layer->CreateFeature(feature);
const auto result = m_layer->CreateFeature(feature);
if (result != OGRERR_NONE) {
throw gdal_error(std::string("creating feature in layer '") + name() + "' failed", result, dataset().driver_name(), dataset().dataset_name());
throw gdal_error{std::string{"creating feature in layer '"} + name() + "' failed",
result,
dataset().driver_name(),
dataset().dataset_name()};
}
dataset().finalize_edit();
}
Layer& start_transaction() {
#if GDAL_VERSION_MAJOR < 2
OGRErr result = m_layer->StartTransaction();
const auto result = m_layer->StartTransaction();
if (result != OGRERR_NONE) {
throw gdal_error(std::string("starting transaction on layer '") + name() + "' failed", result, m_dataset.driver_name(), m_dataset.dataset_name(), name());
throw gdal_error{std::string{"starting transaction on layer '"} + name() + "' failed",
result,
m_dataset.driver_name(),
m_dataset.dataset_name(),
name()};
}
#endif
return *this;
@@ -417,9 +450,13 @@ namespace gdalcpp {
Layer& commit_transaction() {
#if GDAL_VERSION_MAJOR < 2
OGRErr result = m_layer->CommitTransaction();
const auto result = m_layer->CommitTransaction();
if (result != OGRERR_NONE) {
throw gdal_error(std::string("committing transaction on layer '") + name() + "' failed", result, m_dataset.driver_name(), m_dataset.dataset_name(), name());
throw gdal_error{std::string{"committing transaction on layer '"} + name() + "' failed",
result,
m_dataset.driver_name(),
m_dataset.dataset_name(),
name()};
}
#endif
return *this;
@@ -446,11 +483,14 @@ namespace gdalcpp {
m_layer(layer),
m_feature(OGRFeature::CreateFeature(m_layer.get().GetLayerDefn())) {
if (!m_feature) {
throw std::bad_alloc();
throw std::bad_alloc{};
}
OGRErr result = m_feature->SetGeometryDirectly(geometry.release());
const auto result = m_feature->SetGeometryDirectly(geometry.release());
if (result != OGRERR_NONE) {
throw gdal_error(std::string("setting feature geometry in layer '") + m_layer.name() + "' failed", result, m_layer.dataset().driver_name(), m_layer.dataset().dataset_name());
throw gdal_error{std::string{"setting feature geometry in layer '"} + m_layer.name() + "' failed",
result,
m_layer.dataset().driver_name(),
m_layer.dataset().dataset_name()};
}
}
@@ -458,13 +498,13 @@ namespace gdalcpp {
m_layer.create_feature(m_feature.get());
}
template <class T>
template <typename T>
Feature& set_field(int n, T&& arg) {
m_feature->SetField(n, std::forward<T>(arg));
return *this;
}
template <class T>
template <typename T>
Feature& set_field(const char* name, T&& arg) {
m_feature->SetField(name, std::forward<T>(arg));
return *this;
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -72,10 +72,6 @@ namespace osmium {
*/
class AssemblerLegacy : public detail::BasicAssemblerWithTags {
void add_tags_to_area(osmium::builder::AreaBuilder& builder, const osmium::Way& way) const {
builder.add_item(way.tags());
}
void add_common_tags(osmium::builder::TagListBuilder& tl_builder, std::set<const osmium::Way*>& ways) const {
std::map<std::string, std::size_t> counter;
for (const osmium::Way* way : ways) {
@@ -166,7 +162,7 @@ namespace osmium {
const bool area_okay = create_rings();
if (area_okay || config().create_empty_areas) {
add_tags_to_area(builder, way);
builder.add_item(way.tags());
}
if (area_okay) {
add_rings_to_area(builder);
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -103,9 +103,19 @@ namespace osmium {
*/
class BasicAssembler {
static constexpr const std::size_t max_split_locations = 100ULL;
// Maximum recursion depth, stops complex multipolygons from
// breaking everything.
enum : unsigned {
max_depth = 20U
};
struct slocation {
static constexpr const uint32_t invalid_item = 1u << 30u;
enum {
invalid_item = 1U << 30U
};
uint32_t item : 31;
uint32_t reverse : 1;
@@ -269,7 +279,7 @@ namespace osmium {
using rings_stack = std::vector<rings_stack_element>;
void remove_duplicates(rings_stack& outer_rings) {
static void remove_duplicates(rings_stack& outer_rings) {
while (true) {
const auto it = std::adjacent_find(outer_rings.begin(), outer_rings.end());
if (it == outer_rings.end()) {
@@ -350,7 +360,8 @@ namespace osmium {
std::cerr << " Segment is below (nesting=" << nesting << ")\n";
}
if (segment->ring()->is_outer()) {
const double y = ay + (by - ay) * (lx - ax) / double(bx - ax);
const double y = static_cast<double>(ay) +
static_cast<double>((by - ay) * (lx - ax)) / static_cast<double>(bx - ax);
if (debug()) {
std::cerr << " Segment belongs to outer ring (y=" << y << " ring=" << *segment->ring() << ")\n";
}
@@ -500,7 +511,12 @@ namespace osmium {
void create_locations_list() {
m_locations.reserve(m_segment_list.size() * 2);
for (uint32_t n = 0; n < m_segment_list.size(); ++n) {
// static_cast is okay here: The 32bit limit is way past
// anything that makes sense here and even if there are
// 2^32 segments here, it would simply not go through
// all of them not building the multipolygon correctly.
assert(m_segment_list.size() < std::numeric_limits<uint32_t>::max());
for (uint32_t n = 0; n < static_cast<uint32_t>(m_segment_list.size()); ++n) {
m_locations.emplace_back(n, false);
m_locations.emplace_back(n, true);
}
@@ -703,7 +719,13 @@ namespace osmium {
};
void find_candidates(std::vector<candidate>& candidates, std::unordered_set<osmium::Location>& loc_done, const std::vector<location_to_ring_map>& xrings, candidate& cand) {
struct exceeded_max_depth {};
void find_candidates(std::vector<candidate>& candidates, std::unordered_set<osmium::Location>& loc_done, const std::vector<location_to_ring_map>& xrings, const candidate& cand, unsigned depth = 0) {
if (depth > max_depth) {
throw exceeded_max_depth{};
}
if (debug()) {
std::cerr << " find_candidates sum=" << cand.sum << " start=" << cand.start_location << " stop=" << cand.stop_location << "\n";
for (const auto& ring : cand.rings) {
@@ -741,13 +763,30 @@ namespace osmium {
if (debug()) {
std::cerr << " found candidate\n";
}
candidates.push_back(c);
if (candidates.empty()) {
candidates.push_back(c);
} else if (candidates.size() == 1) {
// add new candidate to vector, keep sorted
if (std::abs(c.sum) < std::abs(candidates.front().sum)) {
candidates.insert(candidates.begin(), c);
} else {
candidates.push_back(c);
}
} else {
// add new candidate if it has either smallest or largest area
if (std::abs(c.sum) < std::abs(candidates.front().sum)) {
candidates.front() = c;
} else if (std::abs(c.sum) > std::abs(candidates.back().sum)) {
candidates.back() = c;
}
}
} else if (loc_done.count(c.stop_location) == 0) {
if (debug()) {
std::cerr << " recurse...\n";
std::cerr << " recurse... (depth=" << depth << " candidates.size=" << candidates.size() << ")\n";
}
loc_done.insert(c.stop_location);
find_candidates(candidates, loc_done, xrings, c);
find_candidates(candidates, loc_done, xrings, c, depth + 1);
loc_done.erase(c.stop_location);
if (debug()) {
std::cerr << " ...back\n";
@@ -790,7 +829,7 @@ namespace osmium {
ring.reset();
}
candidate cand{*ring_min, false};
const candidate cand{*ring_min, false};
// Locations we have visited while finding candidates, used
// to detect loops.
@@ -799,7 +838,14 @@ namespace osmium {
loc_done.insert(cand.stop_location);
std::vector<candidate> candidates;
find_candidates(candidates, loc_done, xrings, cand);
try {
find_candidates(candidates, loc_done, xrings, cand);
} catch (const exceeded_max_depth&) {
if (m_config.debug_level > 0) {
std::cerr << " Exceeded max depth (" << static_cast<unsigned>(max_depth) << ")\n";
}
return false;
}
if (candidates.empty()) {
if (debug()) {
@@ -828,26 +874,20 @@ namespace osmium {
}
// Find the candidate with the smallest/largest area
const auto chosen_cand = ring_min_is_outer ?
std::min_element(candidates.cbegin(), candidates.cend(), [](const candidate& lhs, const candidate& rhs) {
return std::abs(lhs.sum) < std::abs(rhs.sum);
}) :
std::max_element(candidates.cbegin(), candidates.cend(), [](const candidate& lhs, const candidate& rhs) {
return std::abs(lhs.sum) < std::abs(rhs.sum);
});
const auto chosen_cand = ring_min_is_outer ? candidates.front() : candidates.back();
if (debug()) {
std::cerr << " Decided on: sum=" << chosen_cand->sum << "\n";
for (const auto& ring : chosen_cand->rings) {
std::cerr << " Decided on: sum=" << chosen_cand.sum << "\n";
for (const auto& ring : chosen_cand.rings) {
std::cerr << " " << ring.first.ring() << (ring.second ? " reverse" : "") << "\n";
}
}
// Join all (open) rings in the candidate to get one closed ring.
assert(chosen_cand->rings.size() > 1);
const auto& first_ring = chosen_cand->rings.front().first;
assert(chosen_cand.rings.size() > 1);
const auto& first_ring = chosen_cand.rings.front().first;
const ProtoRing& remaining_ring = first_ring.ring();
for (auto it = std::next(chosen_cand->rings.begin()); it != chosen_cand->rings.end(); ++it) {
for (auto it = std::next(chosen_cand.rings.begin()); it != chosen_cand.rings.end(); ++it) {
merge_two_rings(open_ring_its, first_ring, it->first);
}
@@ -1077,9 +1117,20 @@ namespace osmium {
timer_simple_case.start();
create_rings_simple_case();
timer_simple_case.stop();
} else if (m_split_locations.size() > max_split_locations) {
if (m_config.debug_level > 0) {
std::cerr << " Ignoring polygon with "
<< m_split_locations.size()
<< " split locations (>"
<< max_split_locations
<< ")\n";
}
return false;
} else {
if (debug()) {
std::cerr << " Found split locations -> using complex algorithm\n";
if (m_config.debug_level > 0) {
std::cerr << " Found "
<< m_split_locations.size()
<< " split locations -> using complex algorithm\n";
}
++m_stats.area_touching_rings_case;
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -38,6 +38,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/osm/node_ref.hpp>
#include <algorithm>
#include <array>
#include <cassert>
#include <cstdint>
#include <iosfwd>
@@ -101,14 +102,10 @@ namespace osmium {
NodeRefSegment() noexcept = default;
NodeRefSegment(const osmium::NodeRef& nr1, const osmium::NodeRef& nr2, role_type role, const osmium::Way* way) noexcept :
m_first(nr1),
m_second(nr2),
m_first(nr1.location() < nr2.location() ? nr1 : nr2),
m_second(nr1.location() < nr2.location() ? nr2 : nr1),
m_way(way),
m_role(role) {
if (nr2.location() < nr1.location()) {
using std::swap;
swap(m_first, m_second);
}
}
/**
@@ -195,7 +192,7 @@ namespace osmium {
}
const char* role_name() const noexcept {
static const char* names[] = { "unknown", "outer", "inner", "empty" };
static const std::array<const char*, 4> names = {{ "unknown", "outer", "inner", "empty" }};
return names[int(m_role)];
}
@@ -205,7 +202,7 @@ namespace osmium {
/**
* The "determinant" of this segment. Used for calculating
* the winding order or a ring.
* the winding order of a ring.
*/
int64_t det() const noexcept {
const vec a{start()};
@@ -348,13 +345,14 @@ namespace osmium {
osmium::Location location;
};
seg_loc sl[4];
sl[0] = {0, s1.first().location() };
sl[1] = {0, s1.second().location()};
sl[2] = {1, s2.first().location() };
sl[3] = {1, s2.second().location()};
std::array<seg_loc, 4> sl = {{
{0, s1.first().location() },
{0, s1.second().location()},
{1, s2.first().location() },
{1, s2.second().location()},
}};
std::sort(sl, sl+4, [](const seg_loc& lhs, const seg_loc& rhs) {
std::sort(sl.begin(), sl.end(), [](const seg_loc& lhs, const seg_loc& rhs) {
return lhs.location < rhs.location;
});
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -196,12 +196,14 @@ namespace osmium {
}
void join_forward(ProtoRing& other) {
m_segments.reserve(m_segments.size() + other.m_segments.size());
for (NodeRefSegment* segment : other.m_segments) {
add_segment_back(segment);
}
}
void join_backward(ProtoRing& other) {
m_segments.reserve(m_segments.size() + other.m_segments.size());
for (auto it = other.m_segments.rbegin(); it != other.m_segments.rend(); ++it) {
(*it)->reverse();
add_segment_back(*it);
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -147,14 +147,14 @@ namespace osmium {
m_debug(debug) {
}
~SegmentList() noexcept = default;
SegmentList(const SegmentList&) = delete;
SegmentList(SegmentList&&) = delete;
SegmentList& operator=(const SegmentList&) = delete;
SegmentList& operator=(SegmentList&&) = delete;
~SegmentList() noexcept = default;
/// The number of segments in the list.
std::size_t size() const noexcept {
return m_segments.size();
@@ -181,7 +181,7 @@ namespace osmium {
return m_segments[n];
}
NodeRefSegment& operator[](std::size_t n) noexcept {
NodeRefSegment& operator[](const std::size_t n) noexcept {
assert(n < m_segments.size());
return m_segments[n];
}
@@ -206,7 +206,7 @@ namespace osmium {
* Enable or disable debug output to stderr. This is used
* for debugging libosmium itself.
*/
void enable_debug_output(bool debug = true) noexcept {
void enable_debug_output(const bool debug = true) noexcept {
m_debug = debug;
}
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -68,8 +68,6 @@ namespace osmium {
detail::BasicAssembler(config) {
}
~GeomAssembler() noexcept = default;
/**
* Assemble an area from the given way.
*
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -70,6 +70,8 @@ namespace osmium {
*
* @tparam TAssembler Multipolygon Assembler class.
* @pre The Ids of all objects must be unique in the input data.
*
* @deprecated Use MultipolygonManager instead.
*/
template <typename TAssembler>
class MultipolygonCollector : public osmium::relations::Collector<MultipolygonCollector<TAssembler>, false, true, false> {
@@ -83,8 +85,13 @@ namespace osmium {
area_stats m_stats;
static constexpr size_t initial_output_buffer_size = 1024 * 1024;
static constexpr size_t max_buffer_size_for_flush = 100 * 1024;
enum {
initial_output_buffer_size = 1024UL * 1024UL
};
enum {
max_buffer_size_for_flush = 100UL * 1024UL
};
void flush_output_buffer() {
if (this->callback()) {
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -63,8 +63,8 @@ namespace osmium {
/**
* 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.
* Most of its functionality is derived from the parent template class
* osmium::relations::RelationsManager.
*
* The actual assembling of the areas is done by the assembler
* class given as template argument.
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -93,6 +93,10 @@ namespace osmium {
m_object_id = object_id;
}
osmium::object_id_type object_id() const noexcept {
return m_object_id;
}
void set_nodes(size_t nodes) noexcept {
m_nodes = nodes;
}
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+58 -13
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -45,6 +45,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/osm/relation.hpp>
#include <osmium/osm/timestamp.hpp>
#include <osmium/osm/types.hpp>
#include <osmium/util/string.hpp>
#include <cstddef>
#include <cstdint>
@@ -226,8 +227,8 @@ namespace osmium {
OSMIUM_ATTRIBUTE(node_handler, _location, osmium::Location)
constexpr explicit _location(const osmium::Location& value) noexcept :
type_wrapper(value) {}
explicit _location(double lat, double lon) :
type_wrapper(osmium::Location{lat, lon}) {}
explicit _location(double lon, double lat) :
type_wrapper(osmium::Location{lon, lat}) {}
};
OSMIUM_ATTRIBUTE(entity_handler, _user, const char*)
@@ -254,6 +255,10 @@ namespace osmium {
m_role(role) {
}
member_type(char type, osmium::object_id_type ref, const char* role = "") noexcept :
member_type(osmium::char_to_item_type(type), ref, role) {
}
constexpr osmium::item_type type() const noexcept {
return m_type;
}
@@ -282,6 +287,10 @@ namespace osmium {
m_role(std::move(role)) {
}
member_type_string(char type, osmium::object_id_type ref, std::string&& role) noexcept :
member_type_string(osmium::char_to_item_type(type), ref, std::forward<std::string>(role)) {
}
osmium::item_type type() const noexcept {
return m_type;
}
@@ -360,6 +369,15 @@ namespace osmium {
type_wrapper(std::make_pair(key, val)) {}
explicit _tag(const std::string& key, const std::string& val) :
type_wrapper(std::make_pair(key.c_str(), val.c_str())) {}
explicit _tag(const char* const key_value) :
type_wrapper(pair_of_cstrings{key_value, nullptr}) {}
explicit _tag(const std::string& key_value) :
type_wrapper(pair_of_cstrings{key_value.c_str(), nullptr}) {}
};
OSMIUM_ATTRIBUTE(tags_handler, _t, const char*)
explicit _t(const char *tags) :
type_wrapper(tags) {}
};
template <typename TTagIterator>
@@ -659,7 +677,19 @@ namespace osmium {
}
static void set_value(TagListBuilder& builder, const attr::_tag& tag) {
builder.add_tag(tag.value);
if (tag.value.second != nullptr) {
builder.add_tag(tag.value);
return;
}
const char* key = tag.value.first;
auto const equal_sign = std::strchr(key, '=');
if (!equal_sign) {
builder.add_tag(key, "");
return;
}
const char* value = equal_sign + 1;
builder.add_tag(key, equal_sign - key,
value, std::strlen(value));
}
template <typename TIterator>
@@ -669,6 +699,21 @@ namespace osmium {
}
}
static void set_value(TagListBuilder& builder, const attr::_t& tags) {
const auto taglist = osmium::split_string(tags.value, ',', true);
for (const auto& tag : taglist) {
const std::size_t pos = tag.find_first_of('=');
if (pos == std::string::npos) {
builder.add_tag(tag, "");
} else {
const char* value = tag.c_str() + pos + 1;
builder.add_tag(tag.c_str(), pos,
value, tag.size() - pos - 1);
}
}
}
}; // struct tags_handler
struct nodes_handler {
@@ -764,7 +809,7 @@ namespace osmium {
template <typename TBuilder, typename THandler, typename... TArgs>
inline typename std::enable_if<is_handled_by<THandler, TArgs...>::value>::type
add_list(osmium::builder::Builder& parent, const TArgs&... args) {
TBuilder builder(parent.buffer(), &parent);
TBuilder builder{parent.buffer(), &parent};
(void)std::initializer_list<int>{
(THandler::set_value(builder, args), 0)...
};
@@ -792,7 +837,7 @@ namespace osmium {
static_assert(detail::are_all_handled_by<detail::any_node_handlers, TArgs...>::value, "Attribute not allowed in add_node()");
{
NodeBuilder builder(buffer);
NodeBuilder builder{buffer};
detail::add_basic<detail::node_handler>(builder, args...);
detail::add_user(builder, args...);
@@ -815,7 +860,7 @@ namespace osmium {
static_assert(detail::are_all_handled_by<detail::any_way_handlers, TArgs...>::value, "Attribute not allowed in add_way()");
{
WayBuilder builder(buffer);
WayBuilder builder{buffer};
detail::add_basic<detail::object_handler>(builder, args...);
detail::add_user(builder, args...);
@@ -839,7 +884,7 @@ namespace osmium {
static_assert(detail::are_all_handled_by<detail::any_relation_handlers, TArgs...>::value, "Attribute not allowed in add_relation()");
{
RelationBuilder builder(buffer);
RelationBuilder builder{buffer};
detail::add_basic<detail::object_handler>(builder, args...);
detail::add_user(builder, args...);
@@ -863,7 +908,7 @@ namespace osmium {
static_assert(detail::are_all_handled_by<detail::any_changeset_handlers, TArgs...>::value, "Attribute not allowed in add_changeset()");
{
ChangesetBuilder builder(buffer);
ChangesetBuilder builder{buffer};
detail::add_basic<detail::changeset_handler>(builder, args...);
detail::add_user(builder, args...);
@@ -887,7 +932,7 @@ namespace osmium {
static_assert(detail::are_all_handled_by<detail::any_area_handlers, TArgs...>::value, "Attribute not allowed in add_area()");
{
AreaBuilder builder(buffer);
AreaBuilder builder{buffer};
detail::add_basic<detail::object_handler>(builder, args...);
detail::add_user(builder, args...);
@@ -914,7 +959,7 @@ namespace osmium {
static_assert(detail::are_all_handled_by<detail::nodes_handler, TArgs...>::value, "Attribute not allowed in add_way_node_list()");
{
WayNodeListBuilder builder(buffer);
WayNodeListBuilder builder{buffer};
(void)std::initializer_list<int>{
(detail::nodes_handler::set_value(builder, args), 0)...
};
@@ -936,7 +981,7 @@ namespace osmium {
static_assert(detail::are_all_handled_by<detail::tags_handler, TArgs...>::value, "Attribute not allowed in add_tag_list()");
{
TagListBuilder builder(buffer);
TagListBuilder builder{buffer};
(void)std::initializer_list<int>{
(detail::tags_handler::set_value(builder, args), 0)...
};
+5 -5
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -65,7 +65,7 @@ namespace osmium {
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_item_offset(buffer.written() - buffer.committed()) {
reserve_space(size);
assert(buffer.is_aligned());
if (m_parent) {
@@ -80,7 +80,7 @@ namespace osmium {
}
#ifdef NDEBUG
~Builder() = default;
~Builder() noexcept = default;
#else
~Builder() noexcept {
m_buffer.decrement_builder_count();
@@ -88,7 +88,7 @@ namespace osmium {
#endif
osmium::memory::Item& item() const {
return *reinterpret_cast<osmium::memory::Item*>(m_buffer.data() + m_item_offset);
return *reinterpret_cast<osmium::memory::Item*>(m_buffer.data() + m_buffer.committed() + m_item_offset);
}
unsigned char* reserve_space(std::size_t size) {
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+5 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -49,6 +49,9 @@ namespace osmium {
* An input iterator wrapping any iterator over OSMObjects. When
* dereferenced it will yield DiffObject objects pointing to the
* underlying OSMObjects.
*
* Note that this class uses a mutable member variable internally.
* It can not be used safely in multiple threads!
*/
template <typename TBasicIterator>
class DiffIterator {
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+23 -8
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -35,7 +35,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/geom/coordinates.hpp>
#include <osmium/geom/util.hpp>
#include <osmium/osm/node_ref.hpp>
#include <osmium/osm/node_ref_list.hpp>
#include <osmium/osm/way.hpp>
#include <cmath>
@@ -63,13 +63,13 @@ namespace osmium {
*
* @pre @code c1.valid() && c2.valid() @endcode
*/
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);
inline double distance(const osmium::geom::Coordinates& c1, const osmium::geom::Coordinates& c2) noexcept {
double lonh = std::sin(deg_to_rad(c1.x - c2.x) * 0.5);
lonh *= lonh;
double lath = sin(deg_to_rad(c1.y - c2.y) * 0.5);
double lath = std::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));
const double tmp = std::cos(deg_to_rad(c1.y)) * std::cos(deg_to_rad(c2.y));
return 2.0 * EARTH_RADIUS_IN_METERS * std::asin(std::sqrt(lath + tmp * lonh));
}
/**
@@ -87,6 +87,21 @@ namespace osmium {
return sum_length;
}
/**
* Calculate length of node list.
*/
inline double distance(const osmium::NodeRefList& nrl) {
double sum_length = 0;
for (auto it = nrl.begin(); it != nrl.end(); ++it) {
if (std::next(it) != nrl.end()) {
sum_length += distance(it->location(), std::next(it)->location());
}
}
return sum_length;
}
} // namespace haversine
} // namespace geom
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -49,7 +49,7 @@ namespace osmium {
constexpr double earth_radius_for_epsg3857 = 6378137.0;
constexpr double max_coordinate_epsg3857 = 20037508.34;
constexpr inline double lon_to_x(double lon) {
constexpr inline double lon_to_x(double lon) noexcept {
return earth_radius_for_epsg3857 * deg_to_rad(lon);
}
@@ -116,6 +116,9 @@ namespace osmium {
* Convert the coordinates from WGS84 lon/lat to web mercator.
*
* @pre @code c.valid() @endcode
* @pre Coordinates must be in valid range, longitude between
* -180 and +180 degree, latitude between -MERCATOR_MAX_LAT
* and MERCATOR_MAX_LAT.
*/
inline Coordinates lonlat_to_mercator(const Coordinates& c) {
return Coordinates{detail::lon_to_x(c.x), detail::lat_to_y(c.y)};
@@ -125,6 +128,8 @@ namespace osmium {
* Convert the coordinates from web mercator to WGS84 lon/lat.
*
* @pre @code c.valid() @endcode
* @pre Coordinates must be in valid range (longitude and
* latidude between -/+20037508.34).
*/
inline Coordinates mercator_to_lonlat(const Coordinates& c) {
return Coordinates{detail::x_to_lon(c.x), detail::y_to_lat(c.y)};
@@ -145,6 +150,13 @@ namespace osmium {
MercatorProjection() { // NOLINT(hicpp-use-equals-default, modernize-use-equals-default)
}
/**
* Do coordinate transformation.
*
* @pre Coordinates must be in valid range, longitude between
* -180 and +180 degree, latitude between -MERCATOR_MAX_LAT
* and MERCATOR_MAX_LAT.
*/
Coordinates operator()(osmium::Location location) const {
return Coordinates{detail::lon_to_x(location.lon()), detail::lat_to_y(location.lat())};
}
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+23 -4
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -46,8 +46,15 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/geom/mercator_projection.hpp>
#include <osmium/geom/util.hpp>
#include <osmium/osm/location.hpp>
#include <osmium/util/compatibility.hpp>
#include <proj_api.h>
#ifdef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
# include <proj_api.h>
#else
# define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
# include <proj_api.h>
# undef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
#endif
#include <memory>
#include <string>
@@ -58,6 +65,8 @@ namespace osmium {
/**
* C++ wrapper for a Coordinate Reference System of the proj library.
*
* @deprecated Only supports the old PROJ API.
*/
class CRS {
@@ -110,9 +119,11 @@ namespace osmium {
* Coordinates have to be in radians and are produced in radians.
*
* @throws osmium::projection_error if the projection fails
*
* @deprecated Only supports the old PROJ API.
*/
// cppcheck-suppress passedByValue (because c is small and we want to change it)
inline Coordinates transform(const CRS& src, const CRS& dest, Coordinates c) {
inline OSMIUM_DEPRECATED Coordinates transform(const CRS& src, const CRS& dest, Coordinates c) {
const 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)};
@@ -130,6 +141,8 @@ namespace osmium {
* implementation of the Mercator projection is used, otherwise this
* falls back to using the proj.4 library. Note that this "magic" does
* not work if you use any of the constructors taking a string.
*
* @deprecated Only supports the old PROJ API.
*/
class Projection {
@@ -158,6 +171,12 @@ namespace osmium {
m_crs_user(epsg) {
}
/**
* Do coordinate transformation.
*
* @pre Location must be in valid range (depends on projection
* used).
*/
Coordinates operator()(osmium::Location location) const {
if (m_epsg == 4326) {
return Coordinates{location.lon(), location.lat()};
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+11 -7
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -58,7 +58,7 @@ namespace osmium {
* level.
*/
inline constexpr uint32_t num_tiles_in_zoom(uint32_t zoom) noexcept {
return 1u << zoom;
return 1U << zoom;
}
/**
@@ -98,6 +98,10 @@ namespace osmium {
*/
struct Tile {
enum {
max_zoom = 30U
};
/// x coordinate
uint32_t x;
@@ -119,7 +123,7 @@ namespace osmium {
x(tx),
y(ty),
z(zoom) {
assert(zoom <= 30u);
assert(zoom <= max_zoom);
assert(x < num_tiles_in_zoom(zoom));
assert(y < num_tiles_in_zoom(zoom));
}
@@ -134,7 +138,7 @@ namespace osmium {
*/
explicit Tile(uint32_t zoom, const osmium::Location& location) :
z(zoom) {
assert(zoom <= 30u);
assert(zoom <= max_zoom);
assert(location.valid());
const auto coordinates = lonlat_to_mercator(location);
x = mercx_to_tilex(zoom, coordinates.x);
@@ -151,7 +155,7 @@ namespace osmium {
*/
explicit Tile(uint32_t zoom, const osmium::geom::Coordinates& coordinates) :
z(zoom) {
assert(zoom <= 30u);
assert(zoom <= max_zoom);
x = mercx_to_tilex(zoom, coordinates.x);
y = mercy_to_tiley(zoom, coordinates.y);
}
@@ -162,7 +166,7 @@ namespace osmium {
* each be between 0 and 2^zoom-1.
*/
bool valid() const noexcept {
if (z > 30) {
if (z > max_zoom) {
return false;
}
const auto max = num_tiles_in_zoom(z);
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+4 -5
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -35,7 +35,6 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/geom/coordinates.hpp>
#include <osmium/geom/factory.hpp>
#include <osmium/util/cast.hpp>
#include <osmium/util/endian.hpp>
#include <algorithm>
@@ -70,8 +69,8 @@ namespace osmium {
out.reserve(str.size() * 2);
for (char c : str) {
out += lookup_hex[(static_cast<unsigned int>(c) >> 4u) & 0xfu];
out += lookup_hex[ static_cast<unsigned int>(c) & 0xfu];
out += lookup_hex[(static_cast<unsigned int>(c) >> 4U) & 0xfU];
out += lookup_hex[ static_cast<unsigned int>(c) & 0xfU];
}
return out;
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -46,7 +46,9 @@ namespace osmium {
namespace detail {
constexpr size_t mmap_vector_size_increment = 1024 * 1024;
enum {
mmap_vector_size_increment = 1024UL * 1024UL
};
/**
* This is a base class for implementing classes that look like
@@ -58,12 +60,12 @@ namespace osmium {
protected:
size_t m_size = 0;
std::size_t m_size = 0;
osmium::TypedMemoryMapping<T> m_mapping;
public:
mmap_vector_base(int fd, size_t capacity, size_t size = 0) :
mmap_vector_base(const int fd, const std::size_t capacity, const std::size_t size = 0) :
m_size(size),
m_mapping(capacity, osmium::MemoryMapping::mapping_mode::write_shared, fd) {
assert(size <= capacity);
@@ -71,7 +73,7 @@ namespace osmium {
shrink_to_fit();
}
explicit mmap_vector_base(size_t capacity = mmap_vector_size_increment) :
explicit mmap_vector_base(const std::size_t capacity = mmap_vector_size_increment) :
m_mapping(capacity) {
std::fill_n(data(), capacity, osmium::index::empty_value<T>());
}
@@ -88,11 +90,11 @@ namespace osmium {
m_mapping.unmap();
}
size_t capacity() const noexcept {
std::size_t capacity() const noexcept {
return m_mapping.size();
}
size_t size() const noexcept {
std::size_t size() const noexcept {
return m_size;
}
@@ -108,17 +110,17 @@ namespace osmium {
return m_mapping.begin();
}
const_reference operator[](size_t n) const {
const_reference operator[](const std::size_t n) const {
assert(n < m_size);
return data()[n];
}
reference operator[](size_t n) {
reference operator[](const std::size_t n) {
assert(n < m_size);
return data()[n];
}
value_type at(size_t n) const {
value_type at(const std::size_t n) const {
if (n >= m_size) {
throw std::out_of_range{"out of range"};
}
@@ -140,17 +142,17 @@ namespace osmium {
data()[m_size - 1] = value;
}
void reserve(size_t new_capacity) {
void reserve(const std::size_t new_capacity) {
if (new_capacity > capacity()) {
const size_t old_capacity = capacity();
const std::size_t old_capacity = capacity();
m_mapping.resize(new_capacity);
std::fill(data() + old_capacity, data() + new_capacity, osmium::index::empty_value<value_type>());
}
}
void resize(size_t new_size) {
void resize(const std::size_t new_size) {
if (new_size > capacity()) {
reserve(new_size + osmium::detail::mmap_vector_size_increment);
reserve(new_size + mmap_vector_size_increment);
}
m_size = new_size;
}
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -53,7 +53,7 @@ namespace osmium {
template <typename T>
class mmap_vector_file : public mmap_vector_base<T> {
static std::size_t filesize(int fd) {
static std::size_t filesize(const int fd) {
const auto size = osmium::file_size(fd);
if (size % sizeof(T) != 0) {
@@ -71,10 +71,10 @@ namespace osmium {
osmium::detail::mmap_vector_size_increment) {
}
explicit mmap_vector_file(int fd) :
explicit mmap_vector_file(const int fd) :
mmap_vector_base<T>(
fd,
std::max(osmium::detail::mmap_vector_size_increment, filesize(fd)),
std::max(static_cast<std::size_t>(mmap_vector_size_increment), filesize(fd)),
filesize(fd)) {
}
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -39,8 +39,10 @@ DEALINGS IN THE SOFTWARE.
#include <algorithm>
#include <cstddef>
#include <memory>
#include <utility>
namespace osmium {
namespace index {
@@ -221,6 +223,26 @@ namespace osmium {
std::sort(m_vector.begin(), m_vector.end());
}
void dump_as_array(const int fd) final {
constexpr const size_t value_size = sizeof(TValue);
constexpr const size_t buffer_size = (10L * 1024L * 1024L) / value_size;
std::unique_ptr<TValue[]> output_buffer{new TValue[buffer_size]};
size_t buffer_start_id = 0;
for (auto it = cbegin(); it != cend();) {
std::fill_n(output_buffer.get(), buffer_size, osmium::index::empty_value<TValue>());
size_t offset = 0;
for (; offset < buffer_size && it != end(); ++offset) {
if (buffer_start_id + offset == it->first) {
output_buffer[offset] = it->second;
++it;
}
}
osmium::io::detail::reliable_write(fd, reinterpret_cast<const unsigned char*>(output_buffer.get()), offset * value_size);
buffer_start_id += buffer_size;
}
}
void dump_as_list(const int fd) final {
osmium::io::detail::reliable_write(fd, reinterpret_cast<const char*>(m_vector.data()), byte_size());
}
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+98 -34
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -37,6 +37,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/osm/types.hpp>
#include <algorithm>
#include <array>
#include <cassert>
#include <cstddef>
#include <cstring>
@@ -95,33 +96,47 @@ namespace osmium {
}; // class IdSet
template <typename T>
namespace detail {
// This value is a compromise. For node Ids it could be bigger
// which would mean less (but larger) memory allocations. For
// relations Ids it could be smaller, because they would all fit
// into a smaller allocation.
enum : std::size_t {
default_chunk_bits = 22U
};
} // namespace detail
template <typename T, std::size_t chunk_bits = detail::default_chunk_bits>
class IdSetDense;
/**
* Const_iterator for iterating over a IdSetDense.
*/
template <typename T>
template <typename T, std::size_t chunk_bits>
class IdSetDenseIterator {
static_assert(std::is_unsigned<T>::value, "Needs unsigned type");
static_assert(sizeof(T) >= 4, "Needs at least 32bit type");
const IdSetDense<T>* m_set;
using id_set = IdSetDense<T, chunk_bits>;
const id_set* m_set;
T m_value;
T m_last;
void next() noexcept {
while (m_value != m_last && !m_set->get(m_value)) {
const T cid = IdSetDense<T>::chunk_id(m_value);
const T cid = id_set::chunk_id(m_value);
assert(cid < m_set->m_data.size());
if (!m_set->m_data[cid]) {
m_value = (cid + 1) << (IdSetDense<T>::chunk_bits + 3);
m_value = (cid + 1) << (chunk_bits + 3);
} else {
const auto slot = m_set->m_data[cid][IdSetDense<T>::offset(m_value)];
const auto slot = m_set->m_data[cid][id_set::offset(m_value)];
if (slot == 0) {
m_value += 8;
m_value &= ~0x7ull;
m_value &= ~0x7ULL;
} else {
++m_value;
}
@@ -136,14 +151,14 @@ namespace osmium {
using pointer = value_type*;
using reference = value_type&;
IdSetDenseIterator(const IdSetDense<T>* set, T value, T last) noexcept :
IdSetDenseIterator(const id_set* set, T value, T last) noexcept :
m_set(set),
m_value(value),
m_last(last) {
next();
}
IdSetDenseIterator<T>& operator++() noexcept {
IdSetDenseIterator& operator++() noexcept {
if (m_value != m_last) {
++m_value;
next();
@@ -151,17 +166,17 @@ namespace osmium {
return *this;
}
IdSetDenseIterator<T> operator++(int) noexcept {
IdSetDenseIterator<T> tmp{*this};
IdSetDenseIterator operator++(int) noexcept {
IdSetDenseIterator tmp{*this};
operator++();
return tmp;
}
bool operator==(const IdSetDenseIterator<T>& rhs) const noexcept {
bool operator==(const IdSetDenseIterator& rhs) const noexcept {
return m_set == rhs.m_set && m_value == rhs.m_value;
}
bool operator!=(const IdSetDenseIterator<T>& rhs) const noexcept {
bool operator!=(const IdSetDenseIterator& rhs) const noexcept {
return !(*this == rhs);
}
@@ -179,34 +194,31 @@ namespace osmium {
* and larger Id sets. If it is not used, no memory is allocated at
* all.
*/
template <typename T>
template <typename T, std::size_t chunk_bits>
class IdSetDense : public IdSet<T> {
static_assert(std::is_unsigned<T>::value, "Needs unsigned type");
static_assert(sizeof(T) >= 4, "Needs at least 32bit type");
friend class IdSetDenseIterator<T>;
friend class IdSetDenseIterator<T, chunk_bits>;
// This value is a compromise. For node Ids it could be bigger
// which would mean less (but larger) memory allocations. For
// relations Ids it could be smaller, because they would all fit
// into a smaller allocation.
constexpr static const std::size_t chunk_bits = 22u;
constexpr static const std::size_t chunk_size = 1u << chunk_bits;
enum : std::size_t {
chunk_size = 1U << chunk_bits
};
std::vector<std::unique_ptr<unsigned char[]>> m_data;
T m_size = 0;
static std::size_t chunk_id(T id) noexcept {
return id >> (chunk_bits + 3u);
return id >> (chunk_bits + 3U);
}
static std::size_t offset(T id) noexcept {
return (id >> 3u) & ((1u << chunk_bits) - 1u);
return (id >> 3U) & ((1U << chunk_bits) - 1U);
}
static unsigned char bitmask(T id) noexcept {
return 1u << (id & 0x7u);
static unsigned int bitmask(T id) noexcept {
return 1U << (id & 0x7U);
}
T last() const noexcept {
@@ -230,10 +242,43 @@ namespace osmium {
public:
using const_iterator = IdSetDenseIterator<T>;
using const_iterator = IdSetDenseIterator<T, chunk_bits>;
friend void swap(IdSetDense& first, IdSetDense& second) noexcept {
using std::swap;
swap(first.m_data, second.m_data);
swap(first.m_size, second.m_size);
}
IdSetDense() = default;
IdSetDense(const IdSetDense& other) :
IdSet<T>(other) {
m_data.reserve(other.m_data.size());
for (const auto& ptr: other.m_data) {
if (ptr) {
m_data.emplace_back(new unsigned char[chunk_size]);
::memcpy(m_data.back().get(), ptr.get(), chunk_size);
} else {
m_data.emplace_back();
}
}
m_size = other.m_size;
}
IdSetDense& operator=(IdSetDense other) {
swap(*this, other);
return *this;
}
IdSetDense(IdSetDense&&) noexcept = default;
// This should really be noexcept, but GCC 4.8 doesn't like it.
// NOLINTNEXTLINE(hicpp-noexcept-move, performance-noexcept-move-constructor)
IdSetDense& operator=(IdSetDense&&) = default;
~IdSetDense() noexcept override = default;
/**
* Add the Id to the set if it is not already in there.
*
@@ -284,7 +329,7 @@ namespace osmium {
if (chunk_id(id) >= m_data.size()) {
return false;
}
auto* r = m_data[chunk_id(id)].get();
const auto* r = m_data[chunk_id(id)].get();
if (!r) {
return false;
}
@@ -317,11 +362,11 @@ namespace osmium {
return m_data.size() * chunk_size;
}
IdSetDenseIterator<T> begin() const {
const_iterator begin() const {
return {this, 0, last()};
}
IdSetDenseIterator<T> end() const {
const_iterator end() const {
return {this, last(), last()};
}
@@ -342,7 +387,9 @@ namespace osmium {
* Add the given Id to the set.
*/
void set(T id) final {
m_data.push_back(id);
if (m_data.empty() || m_data.back() != id) {
m_data.push_back(id);
}
}
/**
@@ -385,7 +432,8 @@ namespace osmium {
/**
* Sort the internal vector and remove any duplicates. Call this
* before using size(), get_binary_search() or using an iterator.
* before using size(), get_binary_search(), merge_sorted() or
* using an iterator.
*/
void sort_unique() {
std::sort(m_data.begin(), m_data.end());
@@ -408,6 +456,22 @@ namespace osmium {
return m_data.capacity() * sizeof(T);
}
/**
* Merge the other set into this one. The result is sorted.
*
* @pre Both sets must be sorted and must not contain any
* duplicates. Call sort_unique() if you are not sure.
*/
void merge_sorted(const IdSetSmall<T>& other) {
std::vector<T> new_data;
new_data.reserve(m_data.size() + other.m_data.size());
std::set_union(m_data.cbegin(), m_data.cend(),
other.m_data.cbegin(), other.m_data.cend(),
std::back_inserter(new_data));
using std::swap;
swap(new_data, m_data);
}
/// Iterator type. There is no non-const iterator.
using const_iterator = typename std::vector<T>::const_iterator;
@@ -435,7 +499,7 @@ namespace osmium {
using id_set_type = IdSetType<osmium::unsigned_object_id_type>;
id_set_type m_sets[3];
std::array<id_set_type, 3> m_sets;
public:
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+7 -7
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -118,7 +118,7 @@ namespace osmium {
virtual ~Map() noexcept = default;
virtual void reserve(const size_t /*size*/) {
virtual void reserve(const std::size_t /*size*/) {
// default implementation is empty
}
@@ -151,7 +151,7 @@ namespace osmium {
* 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;
virtual std::size_t size() const = 0;
/**
* Get the memory used for this storage in bytes. Note that this
@@ -160,7 +160,7 @@ namespace osmium {
* 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;
virtual std::size_t used_memory() const = 0;
/**
* Clear memory used for this storage. After this you can not
@@ -210,8 +210,6 @@ namespace osmium {
MapFactory() = default;
~MapFactory() = default;
public:
MapFactory(const MapFactory&) = delete;
@@ -220,6 +218,8 @@ namespace osmium {
MapFactory(MapFactory&&) = delete;
MapFactory& operator=(MapFactory&&) = delete;
~MapFactory() = default;
static MapFactory<id_type, value_type>& instance() {
static MapFactory<id_type, value_type> factory;
return factory;
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -62,17 +62,17 @@ namespace osmium {
// This value is based on benchmarks with a planet file and
// some smaller files.
enum constant_bits {
enum {
bits = 16
};
enum constant_block_size : uint64_t {
block_size = 1ull << bits
enum : uint64_t {
block_size = 1ULL << bits
};
// Minimum number of entries in the sparse index before we
// are considering switching to a dense index.
enum constant_min_dense_entries : int64_t {
enum : int64_t {
min_dense_entries = 0xffffff
};
@@ -81,7 +81,7 @@ namespace osmium {
// the best memory efficiency (which we would get at a factor
// of 2) and the performance (dense index is much faster then
// the sparse index).
enum constant_density_factor {
enum {
density_factor = 3
};
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -62,7 +62,9 @@ namespace osmium {
// 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;
enum {
element_size = sizeof(TId) + sizeof(TValue) + sizeof(void*) * 4U
};
std::map<TId, TValue> m_elements;
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+3 -3
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -113,7 +113,7 @@ namespace osmium {
}
virtual void dump_as_list(const int /*fd*/) {
std::runtime_error("can't dump as list");
throw std::runtime_error{"can't dump as list"};
}
}; // class Multimap
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -87,7 +87,7 @@ namespace osmium {
}
HybridIterator<TId, TValue> operator++(int) {
auto tmp(*this);
const auto tmp{*this};
operator++();
return tmp;
}
@@ -159,10 +159,10 @@ namespace osmium {
}
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));
const auto result_main = m_main.get_all(id);
const 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) {
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -53,13 +53,15 @@ namespace osmium {
* lot of memory, but might make sense for small maps.
*/
template <typename TId, typename TValue>
class SparseMemMultimap : public osmium::index::multimap::Multimap<TId, TValue> {
class SparseMemMultimap final : 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;
enum {
element_size = sizeof(TId) + sizeof(TValue) + sizeof(void*) * 4u
};
public:
@@ -77,13 +79,13 @@ namespace osmium {
SparseMemMultimap() = default;
~SparseMemMultimap() noexcept final = default;
~SparseMemMultimap() noexcept = default;
void unsorted_set(const TId id, const TValue value) {
m_elements.emplace(id, value);
}
void set(const TId id, const TValue value) final {
void set(const TId id, const TValue value) override {
m_elements.emplace(id, value);
}
@@ -113,15 +115,15 @@ namespace osmium {
return m_elements.end();
}
size_t size() const final {
size_t size() const override {
return m_elements.size();
}
size_t used_memory() const final {
size_t used_memory() const override {
return element_size * m_elements.size();
}
void clear() final {
void clear() override {
m_elements.clear();
}
@@ -129,7 +131,7 @@ namespace osmium {
// intentionally left blank
}
void dump_as_list(const int fd) final {
void dump_as_list(const int fd) override {
std::vector<element_type> v;
v.reserve(m_elements.size());
for (const auto& element : m_elements) {
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+46 -7
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -35,21 +35,60 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/osm/item_type.hpp>
#include <array>
namespace osmium {
/**
* Often some information must be kept separately for nodes, ways, and
* relations. Then this helper class becomes useful. It can keep three
* somethings (of type T) which can be accessed conveniently through
* the call operator.
*/
template <typename T>
class nwr_array {
T m_sets[3];
std::array<T, 3> m_data;
public:
T& operator()(osmium::item_type type) noexcept {
return m_sets[osmium::item_type_to_nwr_index(type)];
using iterator = typename std::array<T, 3>::iterator;
using const_iterator = typename std::array<T, 3>::const_iterator;
nwr_array() :
m_data() {
}
const T& operator()(osmium::item_type type) const noexcept {
return m_sets[osmium::item_type_to_nwr_index(type)];
T& operator()(const osmium::item_type type) noexcept {
return m_data[osmium::item_type_to_nwr_index(type)];
}
const T& operator()(const osmium::item_type type) const noexcept {
return m_data[osmium::item_type_to_nwr_index(type)];
}
iterator begin() noexcept {
return m_data.begin();
}
iterator end() noexcept {
return m_data.end();
}
const_iterator begin() const noexcept {
return m_data.cbegin();
}
const_iterator end() const noexcept {
return m_data.cend();
}
const_iterator cbegin() const noexcept {
return m_data.cbegin();
}
const_iterator cend() const noexcept {
return m_data.cend();
}
}; // class nwr_array
+10 -10
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -66,12 +66,12 @@ namespace osmium {
TKeyInternal key;
TValueInternal value;
explicit kv_pair(key_type key_id) :
explicit kv_pair(const key_type key_id) :
key(static_cast<TKeyInternal>(key_id)),
value() {
}
kv_pair(key_type key_id, value_type value_id) :
kv_pair(const key_type key_id, const value_type value_id) :
key(static_cast<TKeyInternal>(key_id)),
value(static_cast<TValueInternal>(value_id)) {
}
@@ -91,7 +91,7 @@ namespace osmium {
using const_iterator = typename std::vector<kv_pair>::const_iterator;
void set(key_type key, value_type value) {
void set(const key_type key, const value_type value) {
m_map.emplace_back(key, value);
}
@@ -119,7 +119,7 @@ namespace osmium {
m_map.erase(last, m_map.end());
}
std::pair<const_iterator, const_iterator> get(key_type key) const noexcept {
std::pair<const_iterator, const_iterator> get(const key_type key) const noexcept {
return std::equal_range(m_map.begin(), m_map.end(), kv_pair{key}, [](const kv_pair& lhs, const kv_pair& rhs) {
return lhs.key < rhs.key;
});
@@ -133,7 +133,7 @@ namespace osmium {
return m_map.size();
}
void reserve(std::size_t size) {
void reserve(const std::size_t size) {
m_map.reserve(size);
}
@@ -209,7 +209,7 @@ namespace osmium {
* (Lookup uses binary search.)
*/
template <typename TFunc>
void for_each_parent(osmium::unsigned_object_id_type member_id, TFunc&& func) const {
void for_each_parent(const osmium::unsigned_object_id_type member_id, TFunc&& func) const {
const auto parents = m_map.get(member_id);
for (auto it = parents.first; it != parents.second; ++it) {
std::forward<TFunc>(func)(it->value);
@@ -231,7 +231,7 @@ namespace osmium {
* (Lookup uses binary search.)
*/
template <typename TFunc>
void for_each(osmium::unsigned_object_id_type id, TFunc&& func) const {
void for_each(const osmium::unsigned_object_id_type id, TFunc&& func) const {
const auto parents = m_map.get(id);
for (auto it = parents.first; it != parents.second; ++it) {
std::forward<TFunc>(func)(it->value);
@@ -336,7 +336,7 @@ namespace osmium {
/**
* Add mapping from member to parent relation in the stash.
*/
void add(osmium::unsigned_object_id_type member_id, osmium::unsigned_object_id_type relation_id) {
void add(const osmium::unsigned_object_id_type member_id, const osmium::unsigned_object_id_type relation_id) {
assert(m_valid && "You can't use the RelationsMap any more after calling build_index()");
m_map.set(member_id, relation_id);
}
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
+164 -90
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -36,7 +36,7 @@ DEALINGS IN THE SOFTWARE.
/**
* @file
*
* Include this file if you want to read or write bzip2-compressed OSM XML
* Include this file if you want to read or write bzip2-compressed OSM
* files.
*
* @attention If you include this file, you'll need to link with `libbz2`.
@@ -47,7 +47,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/io/error.hpp>
#include <osmium/io/file_compression.hpp>
#include <osmium/io/writer_options.hpp>
#include <osmium/util/compatibility.hpp>
#include <osmium/util/file.hpp>
#include <bzlib.h>
@@ -70,13 +70,15 @@ namespace osmium {
*/
struct bzip2_error : public io_error {
int bzip2_error_code;
int system_errno;
int bzip2_error_code = 0;
int system_errno = 0;
bzip2_error(const std::string& what, int error_code) :
bzip2_error(const std::string& what, const int error_code) :
io_error(what),
bzip2_error_code(error_code),
system_errno(error_code == BZ_IO_ERROR ? errno : 0) {
bzip2_error_code(error_code) {
if (error_code == BZ_IO_ERROR) {
system_errno = errno;
}
}
}; // struct bzip2_error
@@ -85,36 +87,101 @@ namespace osmium {
namespace detail {
OSMIUM_NORETURN inline void throw_bzip2_error(BZFILE* bzfile, const char* msg, int bzlib_error = 0) {
[[noreturn]] inline void throw_bzip2_error(BZFILE* bzfile, const char* msg, const int bzlib_error) {
std::string error{"bzip2 error: "};
error += msg;
error += ": ";
int errnum = bzlib_error;
if (bzlib_error) {
error += std::to_string(bzlib_error);
} else {
} else if (bzfile) {
error += ::BZ2_bzerror(bzfile, &errnum);
}
throw osmium::bzip2_error{error, errnum};
}
class file_wrapper {
FILE* m_file = nullptr;
public:
file_wrapper() noexcept = default;
file_wrapper(const int fd, const char* mode) {
#ifdef _MSC_VER
osmium::detail::disable_invalid_parameter_handler diph;
#endif
m_file = fdopen(fd, mode);
if (!m_file) {
// Do not close stdout
if (fd != 1) {
::close(fd);
}
throw std::system_error{errno, std::system_category(), "fdopen failed"};
}
}
file_wrapper(const file_wrapper&) = delete;
file_wrapper& operator=(const file_wrapper&) = delete;
file_wrapper(file_wrapper&&) = delete;
file_wrapper& operator=(file_wrapper&&) = delete;
~file_wrapper() noexcept {
#ifdef _MSC_VER
osmium::detail::disable_invalid_parameter_handler diph;
#endif
if (m_file) {
fclose(m_file);
}
}
FILE* file() const noexcept {
return m_file;
}
void close() {
#ifdef _MSC_VER
osmium::detail::disable_invalid_parameter_handler diph;
#endif
if (m_file) {
FILE* file = m_file;
m_file = nullptr;
// Do not close stdout
if (fileno(file) == 1) {
return;
}
if (fclose(file) != 0) {
throw std::system_error{errno, std::system_category(), "fclose failed"};
}
}
}
}; // class file_wrapper
} // namespace detail
class Bzip2Compressor : public Compressor {
class Bzip2Compressor final : public Compressor {
FILE* m_file;
int m_bzerror;
BZFILE* m_bzfile;
detail::file_wrapper m_file;
BZFILE* m_bzfile = nullptr;
public:
explicit Bzip2Compressor(int fd, fsync sync) :
explicit Bzip2Compressor(const int fd, const fsync sync) :
Compressor(sync),
m_file(fdopen(::dup(fd), "wb")),
m_bzerror(BZ_OK),
m_bzfile(::BZ2_bzWriteOpen(&m_bzerror, m_file, 6, 0, 0)) {
m_file(fd, "wb") {
#ifdef _MSC_VER
osmium::detail::disable_invalid_parameter_handler diph;
#endif
int bzerror = BZ_OK;
m_bzfile = ::BZ2_bzWriteOpen(&bzerror, m_file.file(), 6, 0, 0);
if (!m_bzfile) {
detail::throw_bzip2_error(m_bzfile, "write open failed", m_bzerror);
throw bzip2_error{"bzip2 error: write open failed", bzerror};
}
}
@@ -124,7 +191,7 @@ namespace osmium {
Bzip2Compressor(Bzip2Compressor&&) = delete;
Bzip2Compressor& operator=(Bzip2Compressor&&) = delete;
~Bzip2Compressor() noexcept final {
~Bzip2Compressor() noexcept {
try {
close();
} catch (...) {
@@ -132,50 +199,56 @@ namespace osmium {
}
}
void write(const std::string& data) final {
int error;
void write(const std::string& data) override {
assert(data.size() < std::numeric_limits<int>::max());
::BZ2_bzWrite(&error, m_bzfile, const_cast<char*>(data.data()), static_cast<int>(data.size()));
if (error != BZ_OK && error != BZ_STREAM_END) {
detail::throw_bzip2_error(m_bzfile, "write failed", error);
assert(m_bzfile);
#ifdef _MSC_VER
osmium::detail::disable_invalid_parameter_handler diph;
#endif
int bzerror = BZ_OK;
::BZ2_bzWrite(&bzerror, m_bzfile, const_cast<char*>(data.data()), static_cast<int>(data.size()));
if (bzerror != BZ_OK && bzerror != BZ_STREAM_END) {
detail::throw_bzip2_error(m_bzfile, "write failed", bzerror);
}
}
void close() final {
void close() override {
if (m_bzfile) {
int error;
::BZ2_bzWriteClose(&error, m_bzfile, 0, nullptr, nullptr);
#ifdef _MSC_VER
osmium::detail::disable_invalid_parameter_handler diph;
#endif
int bzerror = BZ_OK;
::BZ2_bzWriteClose(&bzerror, m_bzfile, 0, nullptr, nullptr);
m_bzfile = nullptr;
if (m_file) {
if (do_fsync()) {
osmium::io::detail::reliable_fsync(::fileno(m_file));
}
if (fclose(m_file) != 0) {
throw std::system_error{errno, std::system_category(), "Close failed"};
}
if (do_fsync() && m_file.file()) {
osmium::io::detail::reliable_fsync(fileno(m_file.file()));
}
if (error != BZ_OK) {
detail::throw_bzip2_error(m_bzfile, "write close failed", error);
m_file.close();
if (bzerror != BZ_OK) {
throw bzip2_error{"bzip2 error: write close failed", bzerror};
}
}
}
}; // class Bzip2Compressor
class Bzip2Decompressor : public Decompressor {
class Bzip2Decompressor final : public Decompressor {
FILE* m_file;
int m_bzerror = BZ_OK;
BZFILE* m_bzfile;
detail::file_wrapper m_file;
BZFILE* m_bzfile = nullptr;
bool m_stream_end = false;
public:
explicit Bzip2Decompressor(int fd) :
m_file(fdopen(::dup(fd), "rb")),
m_bzfile(::BZ2_bzReadOpen(&m_bzerror, m_file, 0, 0, nullptr, 0)) {
explicit Bzip2Decompressor(const int fd) :
m_file(fd, "rb") {
#ifdef _MSC_VER
osmium::detail::disable_invalid_parameter_handler diph;
#endif
int bzerror = BZ_OK;
m_bzfile = ::BZ2_bzReadOpen(&bzerror, m_file.file(), 0, 0, nullptr, 0);
if (!m_bzfile) {
detail::throw_bzip2_error(m_bzfile, "read open failed", m_bzerror);
throw bzip2_error{"bzip2 error: read open failed", bzerror};
}
}
@@ -185,7 +258,7 @@ namespace osmium {
Bzip2Decompressor(Bzip2Decompressor&&) = delete;
Bzip2Decompressor& operator=(Bzip2Decompressor&&) = delete;
~Bzip2Decompressor() noexcept final {
~Bzip2Decompressor() noexcept {
try {
close();
} catch (...) {
@@ -193,34 +266,38 @@ namespace osmium {
}
}
std::string read() final {
std::string read() override {
#ifdef _MSC_VER
osmium::detail::disable_invalid_parameter_handler diph;
#endif
assert(m_bzfile);
std::string buffer;
if (!m_stream_end) {
buffer.resize(osmium::io::Decompressor::input_buffer_size);
int error;
int bzerror = BZ_OK;
assert(buffer.size() < std::numeric_limits<int>::max());
const int nread = ::BZ2_bzRead(&error, m_bzfile, const_cast<char*>(buffer.data()), static_cast<int>(buffer.size()));
if (error != BZ_OK && error != BZ_STREAM_END) {
detail::throw_bzip2_error(m_bzfile, "read failed", error);
const int nread = ::BZ2_bzRead(&bzerror, m_bzfile, &*buffer.begin(), static_cast<int>(buffer.size()));
if (bzerror != BZ_OK && bzerror != BZ_STREAM_END) {
detail::throw_bzip2_error(m_bzfile, "read failed", bzerror);
}
if (error == BZ_STREAM_END) {
if (bzerror == 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);
if (!feof(m_file.file())) {
::BZ2_bzReadGetUnused(&bzerror, m_bzfile, &unused, &nunused);
if (bzerror != BZ_OK) {
detail::throw_bzip2_error(m_bzfile, "get unused failed", bzerror);
}
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);
std::string unused_data{static_cast<const char*>(unused), static_cast<std::string::size_type>(nunused)};
::BZ2_bzReadClose(&bzerror, m_bzfile);
if (bzerror != BZ_OK) {
throw bzip2_error{"bzip2 error: read close failed", bzerror};
}
assert(unused_data.size() < std::numeric_limits<int>::max());
m_bzfile = ::BZ2_bzReadOpen(&error, m_file, 0, 0, const_cast<void*>(static_cast<const void*>(unused_data.data())), static_cast<int>(unused_data.size()));
if (error != BZ_OK) {
detail::throw_bzip2_error(m_bzfile, "read open failed", error);
m_bzfile = ::BZ2_bzReadOpen(&bzerror, m_file.file(), 0, 0, &*unused_data.begin(), static_cast<int>(unused_data.size()));
if (!m_bzfile) {
throw bzip2_error{"bzip2 error: read open failed", bzerror};
}
} else {
m_stream_end = true;
@@ -229,38 +306,37 @@ namespace osmium {
buffer.resize(static_cast<std::string::size_type>(nread));
}
set_offset(size_t(ftell(m_file)));
set_offset(static_cast<std::size_t>(ftell(m_file.file())));
return buffer;
}
void close() final {
void close() override {
if (m_bzfile) {
int error;
::BZ2_bzReadClose(&error, m_bzfile);
#ifdef _MSC_VER
osmium::detail::disable_invalid_parameter_handler diph;
#endif
int bzerror = BZ_OK;
::BZ2_bzReadClose(&bzerror, m_bzfile);
m_bzfile = nullptr;
if (m_file) {
if (fclose(m_file) != 0) {
throw std::system_error{errno, std::system_category(), "Close failed"};
}
}
if (error != BZ_OK) {
detail::throw_bzip2_error(m_bzfile, "read close failed", error);
m_file.close();
if (bzerror != BZ_OK) {
throw bzip2_error{"bzip2 error: read close failed", bzerror};
}
}
}
}; // class Bzip2Decompressor
class Bzip2BufferDecompressor : public Decompressor {
class Bzip2BufferDecompressor final : public Decompressor {
const char* m_buffer;
size_t m_buffer_size;
std::size_t m_buffer_size;
bz_stream m_bzstream;
public:
Bzip2BufferDecompressor(const char* buffer, size_t size) :
Bzip2BufferDecompressor(const char* buffer, const std::size_t size) :
m_buffer(buffer),
m_buffer_size(size),
m_bzstream() {
@@ -269,8 +345,7 @@ namespace osmium {
m_bzstream.avail_in = static_cast<unsigned int>(size);
const 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};
throw bzip2_error{"bzip2 error: decompression init failed: ", result};
}
}
@@ -280,7 +355,7 @@ namespace osmium {
Bzip2BufferDecompressor(Bzip2BufferDecompressor&&) = delete;
Bzip2BufferDecompressor& operator=(Bzip2BufferDecompressor&&) = delete;
~Bzip2BufferDecompressor() noexcept final {
~Bzip2BufferDecompressor() noexcept {
try {
close();
} catch (...) {
@@ -288,13 +363,13 @@ namespace osmium {
}
}
std::string read() final {
std::string read() override {
std::string output;
if (m_buffer) {
const size_t buffer_size = 10240;
const std::size_t buffer_size = 10240;
output.resize(buffer_size);
m_bzstream.next_out = const_cast<char*>(output.data());
m_bzstream.next_out = &*output.begin();
m_bzstream.avail_out = buffer_size;
const int result = BZ2_bzDecompress(&m_bzstream);
@@ -304,8 +379,7 @@ namespace osmium {
}
if (result != BZ_OK && result != BZ_STREAM_END) {
std::string message{"bzip2 error: decompress failed: "};
throw bzip2_error{message, result};
throw bzip2_error{"bzip2 error: decompress failed: ", result};
}
output.resize(static_cast<std::size_t>(m_bzstream.next_out - output.data()));
@@ -314,7 +388,7 @@ namespace osmium {
return output;
}
void close() final {
void close() override {
BZ2_bzDecompressEnd(&m_bzstream);
}
@@ -325,9 +399,9 @@ namespace osmium {
// we want the register_compression() function to run, setting
// the variable is only a side-effect, it will never be used
const bool registered_bzip2_compression = osmium::io::CompressionFactory::instance().register_compression(osmium::io::file_compression::bzip2,
[](int fd, fsync sync) { return new osmium::io::Bzip2Compressor{fd, sync}; },
[](int fd) { return new osmium::io::Bzip2Decompressor{fd}; },
[](const char* buffer, size_t size) { return new osmium::io::Bzip2BufferDecompressor{buffer, size}; }
[](const int fd, const fsync sync) { return new osmium::io::Bzip2Compressor{fd, sync}; },
[](const int fd) { return new osmium::io::Bzip2Decompressor{fd}; },
[](const char* buffer, const std::size_t size) { return new osmium::io::Bzip2BufferDecompressor{buffer, size}; }
);
// dummy function to silence the unused variable warning from above
+36 -34
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -50,12 +50,6 @@ DEALINGS IN THE SOFTWARE.
#include <tuple>
#include <utility>
#ifndef _MSC_VER
# include <unistd.h>
#else
# include <io.h>
#endif
namespace osmium {
namespace io {
@@ -66,13 +60,13 @@ namespace osmium {
protected:
bool do_fsync() const {
bool do_fsync() const noexcept {
return m_fsync == fsync::yes;
}
public:
explicit Compressor(fsync sync) :
explicit Compressor(const fsync sync) noexcept :
m_fsync(sync) {
}
@@ -97,7 +91,9 @@ namespace osmium {
public:
static constexpr unsigned int input_buffer_size = 1024 * 1024;
enum {
input_buffer_size = 1024U * 1024U
};
Decompressor() = default;
@@ -117,7 +113,7 @@ namespace osmium {
return m_file_size;
}
void set_file_size(std::size_t size) noexcept {
void set_file_size(const std::size_t size) noexcept {
m_file_size = size;
}
@@ -125,7 +121,7 @@ namespace osmium {
return m_offset;
}
void set_offset(std::size_t offset) noexcept {
void set_offset(const std::size_t offset) noexcept {
m_offset = offset;
}
@@ -158,7 +154,7 @@ namespace osmium {
CompressionFactory() = default;
const callbacks_type& find_callbacks(osmium::io::file_compression compression) const {
const callbacks_type& find_callbacks(const osmium::io::file_compression compression) const {
const auto it = m_callbacks.find(compression);
if (it != m_callbacks.end()) {
@@ -188,9 +184,9 @@ namespace osmium {
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) {
const create_compressor_type& create_compressor,
const create_decompressor_type_fd& create_decompressor_fd,
const create_decompressor_type_buffer& create_decompressor_buffer) {
compression_map_type::value_type cc{compression,
std::make_tuple(create_compressor,
@@ -201,32 +197,32 @@ namespace osmium {
}
template <typename... TArgs>
std::unique_ptr<osmium::io::Compressor> create_compressor(osmium::io::file_compression compression, TArgs&&... args) const {
std::unique_ptr<osmium::io::Compressor> create_compressor(const osmium::io::file_compression compression, TArgs&&... args) const {
const auto callbacks = find_callbacks(compression);
return std::unique_ptr<osmium::io::Compressor>(std::get<0>(callbacks)(std::forward<TArgs>(args)...));
}
std::unique_ptr<osmium::io::Decompressor> create_decompressor(osmium::io::file_compression compression, int fd) const {
std::unique_ptr<osmium::io::Decompressor> create_decompressor(const osmium::io::file_compression compression, const int fd) const {
const auto callbacks = find_callbacks(compression);
auto p = std::unique_ptr<osmium::io::Decompressor>(std::get<1>(callbacks)(fd));
p->set_file_size(osmium::file_size(fd));
return p;
}
std::unique_ptr<osmium::io::Decompressor> create_decompressor(osmium::io::file_compression compression, const char* buffer, std::size_t size) const {
std::unique_ptr<osmium::io::Decompressor> create_decompressor(const osmium::io::file_compression compression, const char* buffer, const std::size_t size) const {
const auto callbacks = find_callbacks(compression);
return std::unique_ptr<osmium::io::Decompressor>(std::get<2>(callbacks)(buffer, size));
}
}; // class CompressionFactory
class NoCompressor : public Compressor {
class NoCompressor final : public Compressor {
int m_fd;
public:
NoCompressor(int fd, fsync sync) :
NoCompressor(const int fd, const fsync sync) :
Compressor(sync),
m_fd(fd) {
}
@@ -237,7 +233,7 @@ namespace osmium {
NoCompressor(NoCompressor&&) = delete;
NoCompressor& operator=(NoCompressor&&) = delete;
~NoCompressor() noexcept final {
~NoCompressor() noexcept {
try {
close();
} catch (...) {
@@ -245,14 +241,20 @@ namespace osmium {
}
}
void write(const std::string& data) final {
void write(const std::string& data) override {
osmium::io::detail::reliable_write(m_fd, data.data(), data.size());
}
void close() final {
void close() override {
if (m_fd >= 0) {
const int fd = m_fd;
m_fd = -1;
// Do not sync or close stdout
if (fd == 1) {
return;
}
if (do_fsync()) {
osmium::io::detail::reliable_fsync(fd);
}
@@ -262,7 +264,7 @@ namespace osmium {
}; // class NoCompressor
class NoDecompressor : public Decompressor {
class NoDecompressor final : public Decompressor {
int m_fd = -1;
const char* m_buffer = nullptr;
@@ -271,11 +273,11 @@ namespace osmium {
public:
explicit NoDecompressor(int fd) :
explicit NoDecompressor(const int fd) :
m_fd(fd) {
}
NoDecompressor(const char* buffer, std::size_t size) :
NoDecompressor(const char* buffer, const std::size_t size) :
m_buffer(buffer),
m_buffer_size(size) {
}
@@ -286,7 +288,7 @@ namespace osmium {
NoDecompressor(NoDecompressor&&) = delete;
NoDecompressor& operator=(NoDecompressor&&) = delete;
~NoDecompressor() noexcept final {
~NoDecompressor() noexcept {
try {
close();
} catch (...) {
@@ -294,7 +296,7 @@ namespace osmium {
}
}
std::string read() final {
std::string read() override {
std::string buffer;
if (m_buffer) {
@@ -305,7 +307,7 @@ namespace osmium {
}
} else {
buffer.resize(osmium::io::Decompressor::input_buffer_size);
const auto nread = detail::reliable_read(m_fd, const_cast<char*>(buffer.data()), osmium::io::Decompressor::input_buffer_size);
const auto nread = detail::reliable_read(m_fd, &*buffer.begin(), osmium::io::Decompressor::input_buffer_size);
buffer.resize(std::string::size_type(nread));
}
@@ -315,7 +317,7 @@ namespace osmium {
return buffer;
}
void close() final {
void close() override {
if (m_fd >= 0) {
const int fd = m_fd;
m_fd = -1;
@@ -330,8 +332,8 @@ namespace osmium {
// we want the register_compression() function to run, setting
// the variable is only a side-effect, it will never be used
const bool registered_no_compression = osmium::io::CompressionFactory::instance().register_compression(osmium::io::file_compression::none,
[](int fd, fsync sync) { return new osmium::io::NoCompressor{fd, sync}; },
[](int fd) { return new osmium::io::NoDecompressor{fd}; },
[](const int fd, const fsync sync) { return new osmium::io::NoCompressor{fd, sync}; },
[](const int fd) { return new osmium::io::NoDecompressor{fd}; },
[](const char* buffer, std::size_t size) { return new osmium::io::NoDecompressor{buffer, size}; }
);
+2 -2
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -44,6 +44,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/osm/box.hpp>
#include <osmium/osm/changeset.hpp>
#include <osmium/osm/crc.hpp>
#include <osmium/osm/crc_zlib.hpp>
#include <osmium/osm/item_type.hpp>
#include <osmium/osm/location.hpp>
#include <osmium/osm/metadata_options.hpp>
@@ -59,9 +60,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/util/minmax.hpp>
#include <osmium/visitor.hpp>
#include <boost/crc.hpp>
#include <cinttypes>
#include <array>
#include <cmath>
#include <cstring>
#include <iterator>
@@ -112,6 +111,8 @@ namespace osmium {
*/
class DebugOutputBlock : public OutputBlock {
using crc_type = osmium::CRC_zlib;
debug_output_options m_options;
const char* m_utf8_prefix = "";
@@ -197,7 +198,12 @@ namespace osmium {
void write_counter(int width, int n) {
write_color(color_white);
#pragma GCC diagnostic push
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ > 7)
#pragma GCC diagnostic ignored "-Wformat-truncation"
#endif
output_formatted(" %0*d: ", width, n++);
#pragma GCC diagnostic pop
write_color(color_reset);
}
@@ -315,14 +321,14 @@ namespace osmium {
template <typename T>
void write_crc32(const T& object) {
write_fieldname("crc32");
osmium::CRC<boost::crc_32_type> crc32;
osmium::CRC<crc_type> crc32;
crc32.update(object);
output_formatted(" %x\n", crc32().checksum());
}
void write_crc32(const osmium::Changeset& object) {
write_fieldname("crc32");
osmium::CRC<boost::crc_32_type> crc32;
osmium::CRC<crc_type> crc32;
crc32.update(object);
output_formatted(" %x\n", crc32().checksum());
}
@@ -391,7 +397,7 @@ namespace osmium {
for (const auto& node_ref : way.nodes()) {
write_diff();
write_counter(width, n++);
output_formatted("%10" PRId64, node_ref.ref());
output_formatted("%10lld", static_cast<long long>(node_ref.ref())); // NOLINT(google-runtime-int)
if (node_ref.location().valid()) {
*m_out += " (";
node_ref.location().as_string(std::back_inserter(*m_out));
@@ -408,7 +414,7 @@ namespace osmium {
}
void relation(const osmium::Relation& relation) {
static const char* short_typename[] = { "node", "way ", "rel " };
static const std::array<const char*, 3> short_typename = {{ "node", "way ", "rel " }};
m_diff_char = m_options.format_as_diff ? relation.diff_as_char() : '\0';
@@ -427,7 +433,7 @@ namespace osmium {
write_diff();
write_counter(width, n++);
*m_out += short_typename[item_type_to_nwr_index(member.type())];
output_formatted(" %10" PRId64 " ", member.ref());
output_formatted(" %10lld ", static_cast<long long>(member.ref())); // NOLINT(google-runtime-int)
write_string(member.role());
*m_out += '\n';
}
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -57,6 +57,7 @@ DEALINGS IN THE SOFTWARE.
#include <protozero/varint.hpp>
#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <cstring>
@@ -97,14 +98,20 @@ namespace osmium {
// The following settings are from the o5m description:
// The maximum number of entries in this table.
const uint64_t number_of_entries = 15000;
enum {
number_of_entries = 15000U
};
// The size of one entry in the table.
const unsigned int entry_size = 256;
enum {
entry_size = 256U
};
// The maximum length of a string in the table including
// two \0 bytes.
const unsigned int max_length = 250 + 2;
enum {
max_length = 250U + 2U
};
// The data is stored in this string. It is default constructed
// and then resized on demand the first time something is added.
@@ -143,13 +150,16 @@ namespace osmium {
}; // class ReferenceTable
class O5mParser : public Parser {
class O5mParser final : public Parser {
static constexpr std::size_t buffer_size = 2 * 1000 * 1000;
enum {
initial_buffer_size = 1024UL * 1024UL
};
osmium::io::Header m_header{};
osmium::memory::Buffer m_buffer;
osmium::memory::Buffer m_buffer{initial_buffer_size,
osmium::memory::Buffer::auto_grow::internal};
std::string m_input{};
@@ -239,7 +249,7 @@ namespace osmium {
osmium::DeltaDecode<int64_t> m_delta_lat;
osmium::DeltaDecode<osmium::object_id_type> m_delta_way_node_id;
osmium::DeltaDecode<osmium::object_id_type> m_delta_member_ids[3];
std::array<osmium::DeltaDecode<osmium::object_id_type>, 3> m_delta_member_ids;
void reset() {
m_reference_table.clear();
@@ -356,7 +366,7 @@ namespace osmium {
object.set_timestamp(timestamp);
object.set_changeset(m_delta_changeset.update(zvarint(dataptr, end)));
if (*dataptr != end) {
auto uid_user = decode_user(dataptr, end);
const auto uid_user = decode_user(dataptr, end);
object.set_uid(uid_user.first);
user = uid_user.second;
} else {
@@ -421,7 +431,7 @@ namespace osmium {
}
}
osmium::item_type decode_member_type(char c) {
static osmium::item_type decode_member_type(char c) {
if (c < '0' || c > '2') {
throw o5m_error{"unknown member type"};
}
@@ -433,7 +443,7 @@ namespace osmium {
const char* data = decode_string(dataptr, end);
const char* start = data;
auto member_type = decode_member_type(*data++);
const auto member_type = decode_member_type(*data++);
if (data == end) {
throw o5m_error{"missing role"};
}
@@ -474,13 +484,13 @@ namespace osmium {
osmium::builder::RelationMemberListBuilder rml_builder{builder};
while (data < end_refs) {
auto delta_id = zvarint(&data, end);
const auto delta_id = zvarint(&data, end);
if (data == end) {
throw o5m_error{"relation member format error"};
}
auto type_role = decode_role(&data, end);
auto i = osmium::item_type_to_nwr_index(type_role.first);
auto ref = m_delta_member_ids[i].update(delta_id);
const auto type_role = decode_role(&data, end);
const auto i = osmium::item_type_to_nwr_index(type_role.first);
const auto ref = m_delta_member_ids[i].update(delta_id);
rml_builder.add_member(type_role.first, ref, type_role.second);
}
}
@@ -502,18 +512,11 @@ namespace osmium {
}
void decode_timestamp(const char* data, const char* const end) {
const auto timestamp = osmium::Timestamp(zvarint(&data, end)).to_iso();
const auto timestamp = osmium::Timestamp{zvarint(&data, end)}.to_iso();
m_header.set("o5m_timestamp", timestamp);
m_header.set("timestamp", timestamp);
}
void flush() {
osmium::memory::Buffer buffer{buffer_size};
using std::swap;
swap(m_buffer, buffer);
send_to_output_queue(std::move(buffer));
}
enum class dataset_type : unsigned char {
node = 0x10,
way = 0x11,
@@ -586,14 +589,15 @@ namespace osmium {
m_data += length;
if (m_buffer.committed() > buffer_size / 10 * 9) {
flush();
if (m_buffer.has_nested_buffers()) {
std::unique_ptr<osmium::memory::Buffer> buffer_ptr{m_buffer.get_last_nested()};
send_to_output_queue(std::move(*buffer_ptr));
}
}
}
if (m_buffer.committed()) {
flush();
if (m_buffer.committed() > 0) {
send_to_output_queue(std::move(m_buffer));
}
mark_header_as_done();
@@ -603,7 +607,6 @@ namespace osmium {
explicit O5mParser(parser_arguments& args) :
Parser(args),
m_buffer(buffer_size),
m_data(m_input.data()),
m_end(m_data) {
}
@@ -614,9 +617,9 @@ namespace osmium {
O5mParser(O5mParser&&) = delete;
O5mParser& operator=(O5mParser&&) = delete;
~O5mParser() noexcept final = default;
~O5mParser() noexcept = default;
void run() final {
void run() override {
osmium::thread::set_thread_name("_osmium_o5m_in");
decode_header();
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -98,21 +98,17 @@ namespace osmium {
}
}
class OPLParser : public Parser {
class OPLParser final : public Parser {
enum {
initial_buffer_size = 1024UL * 1024UL
};
osmium::memory::Buffer m_buffer{initial_buffer_size,
osmium::memory::Buffer::auto_grow::internal};
osmium::memory::Buffer m_buffer{1024*1024};
uint64_t m_line_count = 0;
void maybe_flush() {
if (m_buffer.committed() > 800*1024) {
osmium::memory::Buffer buffer{1024*1024};
using std::swap;
swap(m_buffer, buffer);
send_to_output_queue(std::move(buffer));
}
}
public:
explicit OPLParser(parser_arguments& args) :
@@ -126,16 +122,19 @@ namespace osmium {
OPLParser(OPLParser&&) = delete;
OPLParser& operator=(OPLParser&&) = delete;
~OPLParser() noexcept final = default;
~OPLParser() noexcept = default;
void parse_line(const char* data) {
if (opl_parse_line(m_line_count, data, m_buffer, read_types())) {
maybe_flush();
if (m_buffer.has_nested_buffers()) {
std::unique_ptr<osmium::memory::Buffer> buffer_ptr{m_buffer.get_last_nested()};
send_to_output_queue(std::move(*buffer_ptr));
}
}
++m_line_count;
}
void run() final {
void run() override {
osmium::thread::set_thread_name("_osmium_opl_in");
line_by_line(*this);
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -34,6 +34,7 @@ DEALINGS IN THE SOFTWARE.
*/
#include <osmium/builder/osm_object_builder.hpp>
#include <osmium/io/detail/string_util.hpp>
#include <osmium/io/error.hpp>
#include <osmium/memory/buffer.hpp>
#include <osmium/osm/box.hpp>
@@ -47,8 +48,6 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/osm/types.hpp>
#include <osmium/osm/way.hpp>
#include <utf8.h>
#include <cstdint>
#include <cstdlib>
#include <iterator>
@@ -155,11 +154,11 @@ namespace osmium {
}
if (*s == '%') {
++s;
utf8::utf32to8(&value, &value + 1, std::back_inserter(result));
append_codepoint_as_utf8(value, std::back_inserter(result));
*data = s;
return;
}
value <<= 4;
value <<= 4U;
if (*s >= '0' && *s <= '9') {
value += *s - '0';
} else if (*s >= 'a' && *s <= 'f') {
@@ -200,7 +199,9 @@ namespace osmium {
}
// Arbitrary limit how long integers can get
constexpr const int max_int_len = 16;
enum {
max_int_len = 16
};
template <typename T>
inline T opl_parse_int(const char** s) {
@@ -371,6 +372,16 @@ namespace osmium {
const char* tags_begin = nullptr;
bool has_version = false;
bool has_visible = false;
bool has_changeset_id = false;
bool has_timestamp = false;
bool has_uid = false;
bool has_user = false;
bool has_tags = false;
bool has_lon = false;
bool has_lat = false;
std::string user;
osmium::Location location;
while (**data) {
@@ -382,35 +393,71 @@ namespace osmium {
++(*data);
switch (c) {
case 'v':
if (has_version) {
throw opl_error{"Duplicate attribute: version (v)"};
}
has_version = true;
builder.set_version(opl_parse_version(data));
break;
case 'd':
if (has_visible) {
throw opl_error{"Duplicate attribute: visible (d)"};
}
has_visible = true;
builder.set_visible(opl_parse_visible(data));
break;
case 'c':
if (has_changeset_id) {
throw opl_error{"Duplicate attribute: changeset_id (c)"};
}
has_changeset_id = true;
builder.set_changeset(opl_parse_changeset_id(data));
break;
case 't':
if (has_timestamp) {
throw opl_error{"Duplicate attribute: timestamp (t)"};
}
has_timestamp = true;
builder.set_timestamp(opl_parse_timestamp(data));
break;
case 'i':
if (has_uid) {
throw opl_error{"Duplicate attribute: uid (i)"};
}
has_uid = true;
builder.set_uid(opl_parse_uid(data));
break;
case 'u':
if (has_user) {
throw opl_error{"Duplicate attribute: user (u)"};
}
has_user = true;
opl_parse_string(data, user);
break;
case 'T':
if (has_tags) {
throw opl_error{"Duplicate attribute: tags (T)"};
}
has_tags = true;
if (opl_non_empty(*data)) {
tags_begin = *data;
opl_skip_section(data);
}
break;
case 'x':
if (has_lon) {
throw opl_error{"Duplicate attribute: lon (x)"};
}
has_lon = true;
if (opl_non_empty(*data)) {
location.set_lon_partial(data);
}
break;
case 'y':
if (has_lat) {
throw opl_error{"Duplicate attribute: lat (y)"};
}
has_lat = true;
if (opl_non_empty(*data)) {
location.set_lat_partial(data);
}
@@ -442,6 +489,15 @@ namespace osmium {
const char* nodes_begin = nullptr;
const char* nodes_end = nullptr;
bool has_version = false;
bool has_visible = false;
bool has_changeset_id = false;
bool has_timestamp = false;
bool has_uid = false;
bool has_user = false;
bool has_tags = false;
bool has_nodes = false;
std::string user;
while (**data) {
opl_parse_space(data);
@@ -452,30 +508,62 @@ namespace osmium {
++(*data);
switch (c) {
case 'v':
if (has_version) {
throw opl_error{"Duplicate attribute: version (v)"};
}
has_version = true;
builder.set_version(opl_parse_version(data));
break;
case 'd':
if (has_visible) {
throw opl_error{"Duplicate attribute: visible (d)"};
}
has_visible = true;
builder.set_visible(opl_parse_visible(data));
break;
case 'c':
if (has_changeset_id) {
throw opl_error{"Duplicate attribute: changeset_id (c)"};
}
has_changeset_id = true;
builder.set_changeset(opl_parse_changeset_id(data));
break;
case 't':
if (has_timestamp) {
throw opl_error{"Duplicate attribute: timestamp (t)"};
}
has_timestamp = true;
builder.set_timestamp(opl_parse_timestamp(data));
break;
case 'i':
if (has_uid) {
throw opl_error{"Duplicate attribute: uid (i)"};
}
has_uid = true;
builder.set_uid(opl_parse_uid(data));
break;
case 'u':
if (has_user) {
throw opl_error{"Duplicate attribute: user (u)"};
}
has_user = true;
opl_parse_string(data, user);
break;
case 'T':
if (has_tags) {
throw opl_error{"Duplicate attribute: tags (T)"};
}
has_tags = true;
if (opl_non_empty(*data)) {
tags_begin = *data;
opl_skip_section(data);
}
break;
case 'N':
if (has_nodes) {
throw opl_error{"Duplicate attribute: nodes (N)"};
}
has_nodes = true;
nodes_begin = *data;
nodes_end = opl_skip_section(data);
break;
@@ -539,6 +627,15 @@ namespace osmium {
const char* members_begin = nullptr;
const char* members_end = nullptr;
bool has_version = false;
bool has_visible = false;
bool has_changeset_id = false;
bool has_timestamp = false;
bool has_uid = false;
bool has_user = false;
bool has_tags = false;
bool has_members = false;
std::string user;
while (**data) {
opl_parse_space(data);
@@ -549,30 +646,62 @@ namespace osmium {
++(*data);
switch (c) {
case 'v':
if (has_version) {
throw opl_error{"Duplicate attribute: version (v)"};
}
has_version = true;
builder.set_version(opl_parse_version(data));
break;
case 'd':
if (has_visible) {
throw opl_error{"Duplicate attribute: visible (d)"};
}
has_visible = true;
builder.set_visible(opl_parse_visible(data));
break;
case 'c':
if (has_changeset_id) {
throw opl_error{"Duplicate attribute: changeset_id (c)"};
}
has_changeset_id = true;
builder.set_changeset(opl_parse_changeset_id(data));
break;
case 't':
if (has_timestamp) {
throw opl_error{"Duplicate attribute: timestamp (t)"};
}
has_timestamp = true;
builder.set_timestamp(opl_parse_timestamp(data));
break;
case 'i':
if (has_uid) {
throw opl_error{"Duplicate attribute: uid (i)"};
}
has_uid = true;
builder.set_uid(opl_parse_uid(data));
break;
case 'u':
if (has_user) {
throw opl_error{"Duplicate attribute: user (u)"};
}
has_user = true;
opl_parse_string(data, user);
break;
case 'T':
if (has_tags) {
throw opl_error{"Duplicate attribute: tags (T)"};
}
has_tags = true;
if (opl_non_empty(*data)) {
tags_begin = *data;
opl_skip_section(data);
}
break;
case 'M':
if (has_members) {
throw opl_error{"Duplicate attribute: members (M)"};
}
has_members = true;
members_begin = *data;
members_end = opl_skip_section(data);
break;
@@ -600,6 +729,18 @@ namespace osmium {
const char* tags_begin = nullptr;
bool has_num_changes = false;
bool has_created_at = false;
bool has_closed_at = false;
bool has_num_comments = false;
bool has_uid = false;
bool has_user = false;
bool has_tags = false;
bool has_min_x = false;
bool has_min_y = false;
bool has_max_x = false;
bool has_max_y = false;
osmium::Box box;
std::string user;
while (**data) {
@@ -611,44 +752,88 @@ namespace osmium {
++(*data);
switch (c) {
case 'k':
if (has_num_changes) {
throw opl_error{"Duplicate attribute: num_changes (k)"};
}
has_num_changes = true;
builder.set_num_changes(opl_parse_int<osmium::num_changes_type>(data));
break;
case 's':
if (has_created_at) {
throw opl_error{"Duplicate attribute: created_at (s)"};
}
has_created_at = true;
builder.set_created_at(opl_parse_timestamp(data));
break;
case 'e':
if (has_closed_at) {
throw opl_error{"Duplicate attribute: closed_at (e)"};
}
has_closed_at = true;
builder.set_closed_at(opl_parse_timestamp(data));
break;
case 'd':
if (has_num_comments) {
throw opl_error{"Duplicate attribute: num_comments (d)"};
}
has_num_comments = true;
builder.set_num_comments(opl_parse_int<osmium::num_comments_type>(data));
break;
case 'i':
if (has_uid) {
throw opl_error{"Duplicate attribute: uid (i)"};
}
has_uid = true;
builder.set_uid(opl_parse_uid(data));
break;
case 'u':
if (has_user) {
throw opl_error{"Duplicate attribute: user (u)"};
}
has_user = true;
opl_parse_string(data, user);
break;
case 'x':
if (has_min_x) {
throw opl_error{"Duplicate attribute: min_x (x)"};
}
has_min_x = true;
if (opl_non_empty(*data)) {
box.bottom_left().set_lon_partial(data);
}
break;
case 'y':
if (has_min_y) {
throw opl_error{"Duplicate attribute: min_y (y)"};
}
has_min_y = true;
if (opl_non_empty(*data)) {
box.bottom_left().set_lat_partial(data);
}
break;
case 'X':
if (has_max_x) {
throw opl_error{"Duplicate attribute: max_x (X)"};
}
has_max_x = true;
if (opl_non_empty(*data)) {
box.top_right().set_lon_partial(data);
}
break;
case 'Y':
if (has_max_y) {
throw opl_error{"Duplicate attribute: max_y (Y)"};
}
has_max_y = true;
if (opl_non_empty(*data)) {
box.top_right().set_lat_partial(data);
}
break;
case 'T':
if (has_tags) {
throw opl_error{"Duplicate attribute: tags (T)"};
}
has_tags = true;
if (opl_non_empty(*data)) {
tags_begin = *data;
opl_skip_section(data);
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -83,7 +83,7 @@ namespace osmium {
char temp[20];
char *t = temp;
do {
*t++ = char(value % 10) + '0';
*t++ = static_cast<char>(value % 10) + '0'; // NOLINT(bugprone-narrowing-conversions, cppcoreguidelines-narrowing-conversions)
value /= 10;
} while (value > 0);
@@ -91,7 +91,7 @@ namespace osmium {
m_out->resize(old_size + (t - temp));
char* data = &(*m_out)[old_size];
do {
*data++ += *--t;
*data++ = *--t;
} while (t != temp);
}
@@ -199,7 +199,7 @@ namespace osmium {
}; // class OutputFormatFactory
class BlackholeOutputFormat : public osmium::io::detail::OutputFormat {
class BlackholeOutputFormat final : public osmium::io::detail::OutputFormat {
public:
@@ -213,9 +213,9 @@ namespace osmium {
BlackholeOutputFormat(BlackholeOutputFormat&&) = delete;
BlackholeOutputFormat& operator=(BlackholeOutputFormat&&) = delete;
~BlackholeOutputFormat() noexcept final = default;
~BlackholeOutputFormat() noexcept = default;
void write_buffer(osmium::memory::Buffer&& /*buffer*/) final {
void write_buffer(osmium::memory::Buffer&& /*buffer*/) override {
}
}; // class BlackholeOutputFormat
+2 -9
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -36,13 +36,6 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/io/error.hpp>
#include <osmium/osm/location.hpp>
// needed for htonl and ntohl or their equivalent in protozero
#ifndef _WIN32
# include <netinet/in.h>
#else
# include <protozero/byteswap.hpp>
#endif
#include <cstdint>
#include <string>
+109 -93
View File
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -80,7 +80,9 @@ namespace osmium {
class PBFPrimitiveBlockDecoder {
static constexpr const size_t initial_buffer_size = 2 * 1024 * 1024;
enum {
initial_buffer_size = 64UL * 1024UL
};
data_view m_data;
std::vector<osm_string_len_type> m_stringtable;
@@ -92,7 +94,7 @@ namespace osmium {
osmium::osm_entity_bits::type m_read_types;
osmium::memory::Buffer m_buffer { initial_buffer_size };
osmium::memory::Buffer m_buffer{initial_buffer_size, osmium::memory::Buffer::auto_grow::internal};
osmium::io::read_meta m_read_metadata;
@@ -258,10 +260,14 @@ namespace osmium {
}
}
int32_t convert_pbf_coordinate(int64_t c) const noexcept {
int32_t convert_pbf_lon(const int64_t c) const noexcept {
return int32_t((c * m_granularity + m_lon_offset) / resolution_convert);
}
int32_t convert_pbf_lat(const int64_t c) const noexcept {
return int32_t((c * m_granularity + m_lat_offset) / resolution_convert);
}
void decode_node(const data_view& data) {
osmium::builder::NodeBuilder builder{m_buffer};
osmium::Node& node = builder.object();
@@ -309,8 +315,8 @@ namespace osmium {
throw osmium::pbf_error{"illegal coordinate format"};
}
node.set_location(osmium::Location{
convert_pbf_coordinate(lon),
convert_pbf_coordinate(lat)
convert_pbf_lon(lon),
convert_pbf_lat(lat)
});
}
@@ -378,8 +384,8 @@ namespace osmium {
while (!refs.empty() && !lons.empty() && !lats.empty()) {
wnl_builder.add_node_ref(
ref.update(refs.front()),
osmium::Location{convert_pbf_coordinate(lon.update(lons.front())),
convert_pbf_coordinate(lat.update(lats.front()))}
osmium::Location{convert_pbf_lon(lon.update(lons.front())),
convert_pbf_lat(lat.update(lats.front()))}
);
refs.drop_front();
lons.drop_front();
@@ -517,24 +523,27 @@ namespace osmium {
throw osmium::pbf_error{"PBF format error"};
}
osmium::builder::NodeBuilder builder{m_buffer};
osmium::Node& node = builder.object();
{
osmium::builder::NodeBuilder builder{m_buffer};
osmium::Node& node = builder.object();
node.set_id(dense_id.update(ids.front()));
ids.drop_front();
node.set_id(dense_id.update(ids.front()));
ids.drop_front();
const auto lon = dense_longitude.update(lons.front());
lons.drop_front();
const auto lat = dense_latitude.update(lats.front());
lats.drop_front();
builder.object().set_location(osmium::Location(
convert_pbf_coordinate(lon),
convert_pbf_coordinate(lat)
));
const auto lon = dense_longitude.update(lons.front());
lons.drop_front();
const auto lat = dense_latitude.update(lats.front());
lats.drop_front();
builder.object().set_location(osmium::Location{
convert_pbf_lon(lon),
convert_pbf_lat(lat)
});
if (tag_it != tags.end()) {
build_tag_list_from_dense_nodes(builder, tag_it, tags.end());
if (tag_it != tags.end()) {
build_tag_list_from_dense_nodes(builder, tag_it, tags.end());
}
}
m_buffer.commit();
}
}
@@ -624,87 +633,89 @@ namespace osmium {
bool visible = true;
osmium::builder::NodeBuilder builder{m_buffer};
osmium::Node& node = builder.object();
{
osmium::builder::NodeBuilder builder{m_buffer};
osmium::Node& node = builder.object();
node.set_id(dense_id.update(ids.front()));
ids.drop_front();
node.set_id(dense_id.update(ids.front()));
ids.drop_front();
if (has_info) {
if (!versions.empty()) {
const auto version = versions.front();
versions.drop_front();
if (version < -1) {
throw osmium::pbf_error{"object version must not be negative"};
if (has_info) {
if (!versions.empty()) {
const auto version = versions.front();
versions.drop_front();
if (version < -1) {
throw osmium::pbf_error{"object version must not be negative"};
}
if (version == -1) {
node.set_version(0U);
} else {
node.set_version(static_cast<osmium::object_version_type>(version));
}
}
if (version == -1) {
node.set_version(0U);
} else {
node.set_version(static_cast<osmium::object_version_type>(version));
if (!changesets.empty()) {
const auto changeset_id = dense_changeset.update(changesets.front());
changesets.drop_front();
if (changeset_id < -1 || changeset_id >= std::numeric_limits<changeset_id_type>::max()) {
throw osmium::pbf_error{"object changeset_id must be between 0 and 2^32-1"};
}
if (changeset_id == -1) {
node.set_changeset(0U);
} else {
node.set_changeset(static_cast<osmium::changeset_id_type>(changeset_id));
}
}
if (!timestamps.empty()) {
node.set_timestamp(dense_timestamp.update(timestamps.front()) * m_date_factor / 1000);
timestamps.drop_front();
}
if (!uids.empty()) {
node.set_uid_from_signed(static_cast<osmium::signed_user_id_type>(dense_uid.update(uids.front())));
uids.drop_front();
}
if (!visibles.empty()) {
visible = (visibles.front() != 0);
visibles.drop_front();
}
node.set_visible(visible);
if (!user_sids.empty()) {
const auto& u = m_stringtable.at(dense_user_sid.update(user_sids.front()));
user_sids.drop_front();
builder.set_user(u.first, u.second);
}
}
if (!changesets.empty()) {
const auto changeset_id = dense_changeset.update(changesets.front());
changesets.drop_front();
if (changeset_id < -1 || changeset_id >= std::numeric_limits<changeset_id_type>::max()) {
throw osmium::pbf_error{"object changeset_id must be between 0 and 2^32-1"};
}
if (changeset_id == -1) {
node.set_changeset(0U);
} else {
node.set_changeset(static_cast<osmium::changeset_id_type>(changeset_id));
}
// even if the node isn't visible, there's still a record
// of its lat/lon in the dense arrays.
const auto lon = dense_longitude.update(lons.front());
lons.drop_front();
const auto lat = dense_latitude.update(lats.front());
lats.drop_front();
if (visible) {
builder.object().set_location(osmium::Location{
convert_pbf_lon(lon),
convert_pbf_lat(lat)
});
}
if (!timestamps.empty()) {
node.set_timestamp(dense_timestamp.update(timestamps.front()) * m_date_factor / 1000);
timestamps.drop_front();
}
if (!uids.empty()) {
node.set_uid_from_signed(static_cast<osmium::signed_user_id_type>(dense_uid.update(uids.front())));
uids.drop_front();
}
if (!visibles.empty()) {
visible = (visibles.front() != 0);
visibles.drop_front();
}
node.set_visible(visible);
if (!user_sids.empty()) {
const auto& u = m_stringtable.at(dense_user_sid.update(user_sids.front()));
user_sids.drop_front();
builder.set_user(u.first, u.second);
if (tag_it != tags.end()) {
build_tag_list_from_dense_nodes(builder, tag_it, tags.end());
}
}
// even if the node isn't visible, there's still a record
// of its lat/lon in the dense arrays.
const auto lon = dense_longitude.update(lons.front());
lons.drop_front();
const auto lat = dense_latitude.update(lats.front());
lats.drop_front();
if (visible) {
builder.object().set_location(osmium::Location{
convert_pbf_coordinate(lon),
convert_pbf_coordinate(lat)
});
}
if (tag_it != tags.end()) {
build_tag_list_from_dense_nodes(builder, tag_it, tags.end());
}
m_buffer.commit();
}
}
public:
PBFPrimitiveBlockDecoder(const data_view& data, osmium::osm_entity_bits::type read_types, osmium::io::read_meta read_metadata) :
PBFPrimitiveBlockDecoder(const data_view& data, const osmium::osm_entity_bits::type read_types, const osmium::io::read_meta read_metadata) :
m_data(data),
m_read_types(read_types),
m_read_metadata(read_metadata) {
@@ -808,8 +819,8 @@ namespace osmium {
}
osmium::Box box;
box.extend(osmium::Location(left / resolution_convert, bottom / resolution_convert));
box.extend(osmium::Location(right / resolution_convert, top / resolution_convert));
box.extend(osmium::Location{left / resolution_convert, bottom / resolution_convert});
box.extend(osmium::Location{right / resolution_convert, top / resolution_convert});
return box;
}
@@ -840,8 +851,13 @@ namespace osmium {
}
}
break;
case protozero::tag_and_type(OSMFormat::HeaderBlock::repeated_string_optional_features, protozero::pbf_wire_type::length_delimited):
header.set("pbf_optional_feature_" + std::to_string(i++), pbf_header_block.get_string());
case protozero::tag_and_type(OSMFormat::HeaderBlock::repeated_string_optional_features, protozero::pbf_wire_type::length_delimited): {
const auto opt = pbf_header_block.get_string();
header.set("pbf_optional_feature_" + std::to_string(i++), opt);
if (opt == "Sort.Type_then_ID") {
header.set("sorting", "Type_then_ID");
}
}
break;
case protozero::tag_and_type(OSMFormat::HeaderBlock::optional_string_writingprogram, protozero::pbf_wire_type::length_delimited):
header.set("generator", pbf_header_block.get_string());
@@ -888,7 +904,7 @@ namespace osmium {
public:
PBFDataBlobDecoder(std::string&& input_buffer, osmium::osm_entity_bits::type read_types, osmium::io::read_meta read_metadata) :
PBFDataBlobDecoder(std::string&& input_buffer, const osmium::osm_entity_bits::type read_types, const osmium::io::read_meta read_metadata) :
m_input_buffer(std::make_shared<std::string>(std::move(input_buffer))),
m_read_types(read_types),
m_read_metadata(read_metadata) {
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -62,7 +62,7 @@ namespace osmium {
namespace detail {
class PBFParser : public Parser {
class PBFParser final : public Parser {
std::string m_input_buffer{};
@@ -96,22 +96,20 @@ namespace osmium {
* the length of the following BlobHeader.
*/
uint32_t read_blob_header_size_from_file() {
uint32_t size_in_network_byte_order;
uint32_t size;
try {
const 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());
// size is encoded in network byte order
const std::string input_data{read_from_input_queue(sizeof(size))};
const char* d = input_data.data();
size = (static_cast<uint32_t>(d[3])) |
(static_cast<uint32_t>(d[2]) << 8U) |
(static_cast<uint32_t>(d[1]) << 16U) |
(static_cast<uint32_t>(d[0]) << 24U);
} catch (const osmium::pbf_error&) {
return 0; // EOF
}
#ifndef _WIN32
const uint32_t size = ntohl(size_in_network_byte_order);
#else
uint32_t size = size_in_network_byte_order;
protozero::detail::byteswap_inplace(&size);
#endif
if (size > static_cast<uint32_t>(max_blob_header_size)) {
throw osmium::pbf_error{"invalid BlobHeader size (> max_blob_header_size)"};
}
@@ -123,7 +121,7 @@ namespace osmium {
* Decode the BlobHeader. Make sure it contains the expected
* type. Return the size of the following Blob.
*/
size_t decode_blob_header(protozero::pbf_message<FileFormat::BlobHeader>&& pbf_blob_header, const char* expected_type) {
static size_t decode_blob_header(protozero::pbf_message<FileFormat::BlobHeader>&& pbf_blob_header, const char* expected_type) {
protozero::data_view blob_header_type;
size_t blob_header_datasize = 0;
@@ -205,9 +203,9 @@ namespace osmium {
PBFParser(PBFParser&&) = delete;
PBFParser& operator=(PBFParser&&) = delete;
~PBFParser() noexcept final = default;
~PBFParser() noexcept = default;
void run() final {
void run() override {
osmium::thread::set_thread_name("_osmium_pbf_in");
parse_header_blob();
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@@ -58,7 +58,6 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/osm/types.hpp>
#include <osmium/osm/way.hpp>
#include <osmium/thread/pool.hpp>
#include <osmium/util/cast.hpp>
#include <osmium/util/delta.hpp>
#include <osmium/util/misc.hpp>
#include <osmium/visitor.hpp>
@@ -123,9 +122,13 @@ namespace osmium {
* as well as Osmium implementation always
* uses at most 8k entities in a block.
*/
constexpr int32_t max_entities_per_block = 8000;
enum {
max_entities_per_block = 8000
};
constexpr int location_granularity = 100;
enum {
location_granularity = 100
};
/**
* convert a double lat or lon value to an int, respecting the granularity
@@ -185,19 +188,24 @@ namespace osmium {
protozero::pbf_builder<FileFormat::BlobHeader> pbf_blob_header{blob_header_data};
pbf_blob_header.add_string(FileFormat::BlobHeader::required_string_type, m_blob_type == pbf_blob_type::data ? "OSMData" : "OSMHeader");
pbf_blob_header.add_int32(FileFormat::BlobHeader::required_int32_datasize, static_cast_with_assert<int32_t>(blob_data.size()));
#ifndef _WIN32
const uint32_t sz = htonl(static_cast_with_assert<uint32_t>(blob_header_data.size()));
#else
uint32_t sz = static_cast_with_assert<uint32_t>(blob_header_data.size());
protozero::detail::byteswap_inplace(&sz);
#endif
// The static_cast is okay, because the size can never
// be much larger than max_uncompressed_blob_size. This
// is due to the assert above and the fact that the zlib
// library will not grow deflated data beyond the original
// data plus a few header bytes (https://zlib.net/zlib_tech.html).
pbf_blob_header.add_int32(FileFormat::BlobHeader::required_int32_datasize, static_cast<int32_t>(blob_data.size()));
// write to output: the 4-byte BlobHeader-Size followed by the BlobHeader followed by the Blob
const auto size = static_cast<uint32_t>(blob_header_data.size());
// write to output: the 4-byte BlobHeader size in network
// byte order 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.reserve(4 + blob_header_data.size() + blob_data.size());
output += static_cast<char>((size >> 24U) & 0xffU);
output += static_cast<char>((size >> 16U) & 0xffU);
output += static_cast<char>((size >> 8U) & 0xffU);
output += static_cast<char>( size & 0xffU);
output.append(blob_header_data);
output.append(blob_data);
@@ -236,7 +244,7 @@ namespace osmium {
osmium::DeltaEncode<uint32_t, int64_t> m_delta_timestamp;
osmium::DeltaEncode<changeset_id_type, int64_t> m_delta_changeset;
osmium::DeltaEncode<user_id_type, int32_t> m_delta_uid;
osmium::DeltaEncode<uint32_t, int32_t> m_delta_user_sid;
osmium::DeltaEncode<int32_t, int32_t> m_delta_user_sid;
osmium::DeltaEncode<int64_t, int64_t> m_delta_lat;
osmium::DeltaEncode<int64_t, int64_t> m_delta_lon;
@@ -284,7 +292,8 @@ namespace osmium {
m_ids.push_back(m_delta_id.update(node.id()));
if (m_options.add_metadata.version()) {
m_versions.push_back(static_cast_with_assert<int32_t>(node.version()));
assert(node.version() <= static_cast<std::size_t>(std::numeric_limits<int32_t>::max()));
m_versions.push_back(static_cast<int32_t>(node.version()));
}
if (m_options.add_metadata.timestamp()) {
m_timestamps.push_back(m_delta_timestamp.update(uint32_t(node.timestamp())));
@@ -306,8 +315,8 @@ namespace osmium {
m_lons.push_back(m_delta_lon.update(lonlat2int(node.location().lon_without_check())));
for (const auto& tag : node.tags()) {
m_tags.push_back(static_cast_with_assert<int32_t>(m_stringtable.add(tag.key())));
m_tags.push_back(static_cast_with_assert<int32_t>(m_stringtable.add(tag.value())));
m_tags.push_back(m_stringtable.add(tag.key()));
m_tags.push_back(m_stringtable.add(tag.value()));
}
m_tags.push_back(0);
}
@@ -397,10 +406,20 @@ namespace osmium {
++m_count;
}
uint32_t store_in_stringtable(const char* s) {
// There are two functions store_in_stringtable(_unsigned)
// here because of an inconsistency in the OSMPBF format
// specification. Both uint32 and sint32 types are used in
// the format for essentially the same thing.
int32_t store_in_stringtable(const char* s) {
return m_stringtable.add(s);
}
uint32_t store_in_stringtable_unsigned(const char* s) {
// static_cast okay, because result of add is always >= 0
return static_cast<uint32_t>(m_stringtable.add(s));
}
int count() const noexcept {
return m_count;
}
@@ -419,7 +438,9 @@ namespace osmium {
* enough space for the string table (which typically
* needs about 0.1 to 0.3% of the block size).
*/
constexpr static std::size_t max_used_blob_size = max_uncompressed_blob_size * 95 / 100;
enum {
max_used_blob_size = max_uncompressed_blob_size * 95U / 100U
};
bool can_add(OSMFormat::PrimitiveGroup type) const noexcept {
if (type != m_type) {
@@ -466,14 +487,14 @@ namespace osmium {
{
protozero::packed_field_uint32 field{pbf_object, protozero::pbf_tag_type(T::enum_type::packed_uint32_keys)};
for (const auto& tag : object.tags()) {
field.add_element(m_primitive_block.store_in_stringtable(tag.key()));
field.add_element(m_primitive_block.store_in_stringtable_unsigned(tag.key()));
}
}
{
protozero::packed_field_uint32 field{pbf_object, protozero::pbf_tag_type(T::enum_type::packed_uint32_vals)};
for (const auto& tag : object.tags()) {
field.add_element(m_primitive_block.store_in_stringtable(tag.value()));
field.add_element(m_primitive_block.store_in_stringtable_unsigned(tag.value()));
}
}
@@ -481,7 +502,8 @@ namespace osmium {
protozero::pbf_builder<OSMFormat::Info> pbf_info{pbf_object, T::enum_type::optional_Info_info};
if (m_options.add_metadata.version()) {
pbf_info.add_int32(OSMFormat::Info::optional_int32_version, static_cast_with_assert<int32_t>(object.version()));
assert(object.version() <= static_cast<std::size_t>(std::numeric_limits<int32_t>::max()));
pbf_info.add_int32(OSMFormat::Info::optional_int32_version, static_cast<int32_t>(object.version()));
}
if (m_options.add_metadata.timestamp()) {
pbf_info.add_int64(OSMFormat::Info::optional_int64_timestamp, uint32_t(object.timestamp()));
@@ -490,10 +512,11 @@ namespace osmium {
pbf_info.add_int64(OSMFormat::Info::optional_int64_changeset, object.changeset());
}
if (m_options.add_metadata.uid()) {
pbf_info.add_int32(OSMFormat::Info::optional_int32_uid, static_cast_with_assert<int32_t>(object.uid()));
assert(object.uid() <= static_cast<std::size_t>(std::numeric_limits<int32_t>::max()));
pbf_info.add_int32(OSMFormat::Info::optional_int32_uid, static_cast<int32_t>(object.uid()));
}
if (m_options.add_metadata.user()) {
pbf_info.add_uint32(OSMFormat::Info::optional_uint32_user_sid, m_primitive_block.store_in_stringtable(object.user()));
pbf_info.add_uint32(OSMFormat::Info::optional_uint32_user_sid, m_primitive_block.store_in_stringtable_unsigned(object.user()));
}
if (m_options.add_visible_flag) {
pbf_info.add_bool(OSMFormat::Info::optional_bool_visible, object.visible());
@@ -554,6 +577,10 @@ namespace osmium {
pbf_header_block.add_string(OSMFormat::HeaderBlock::repeated_string_optional_features, "LocationsOnWays");
}
if (header.get("sorting") == "Type_then_ID") {
pbf_header_block.add_string(OSMFormat::HeaderBlock::repeated_string_optional_features, "Sort.Type_then_ID");
}
pbf_header_block.add_string(OSMFormat::HeaderBlock::optional_string_writingprogram, header.get("generator"));
const std::string osmosis_replication_timestamp{header.get("osmosis_replication_timestamp")};
@@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

Some files were not shown because too many files have changed in this diff Show More